1parameters: 2 Include: '*.exe, *.dll, *.pyd, *.cat, *.ps1' 3 Exclude: 'vcruntime*, libffi*, libcrypto*, libssl*' 4 5jobs: 6- job: Sign_Python 7 displayName: Sign Python binaries 8 condition: and(succeeded(), variables['SigningCertificate']) 9 10 pool: 11 name: 'Windows Release' 12 13 workspace: 14 clean: all 15 16 strategy: 17 matrix: 18 win32: 19 Name: win32 20 amd64: 21 Name: amd64 22 arm64: 23 Name: arm64 24 25 steps: 26 - template: ./checkout.yml 27 - template: ./find-sdk.yml 28 29 - powershell: | 30 Write-Host "##vso[build.addbuildtag]signed" 31 displayName: 'Add build tags' 32 33 - task: DownloadPipelineArtifact@1 34 displayName: 'Download artifact: unsigned_bin_$(Name)' 35 inputs: 36 artifactName: unsigned_bin_$(Name) 37 targetPath: $(Build.BinariesDirectory)\bin 38 39 - powershell: | 40 copy "$(Build.SourcesDirectory)\Lib\venv\scripts\common\Activate.ps1" . 41 displayName: 'Copy files from source' 42 workingDirectory: $(Build.BinariesDirectory)\bin 43 44 - powershell: | 45 $files = (gi ${{ parameters.Include }} -Exclude ${{ parameters.Exclude }}) 46 signtool sign /a /n "$(SigningCertificate)" /fd sha256 /d "$(SigningDescription)" $files 47 displayName: 'Sign binaries' 48 workingDirectory: $(Build.BinariesDirectory)\bin 49 50 - powershell: | 51 $files = (gi ${{ parameters.Include }} -Exclude ${{ parameters.Exclude }}) 52 $failed = $true 53 foreach ($retry in 1..10) { 54 signtool timestamp /t http://timestamp.verisign.com/scripts/timestamp.dll $files 55 if ($?) { 56 $failed = $false 57 break 58 } 59 sleep 5 60 } 61 if ($failed) { 62 Write-Host "##vso[task.logissue type=error]Failed to timestamp files" 63 } 64 displayName: 'Timestamp binaries' 65 workingDirectory: $(Build.BinariesDirectory)\bin 66 continueOnError: true 67 68 - task: PublishPipelineArtifact@0 69 displayName: 'Publish artifact: bin_$(Name)' 70 inputs: 71 targetPath: '$(Build.BinariesDirectory)\bin' 72 artifactName: bin_$(Name) 73 74 75- job: Dump_CertInfo 76 displayName: Capture certificate info 77 condition: and(succeeded(), variables['SigningCertificate']) 78 79 pool: 80 name: 'Windows Release' 81 82 steps: 83 - checkout: none 84 85 - powershell: | 86 $m = 'CN=$(SigningCertificate)' 87 $c = ((gci Cert:\CurrentUser\My), (gci Cert:\LocalMachine\My)) | %{ $_ } | ` 88 ?{ $_.Subject -match $m } | ` 89 select -First 1 90 if (-not $c) { 91 Write-Host "Failed to find certificate for $(SigningCertificate)" 92 exit 93 } 94 $d = mkdir "$(Build.BinariesDirectory)\tmp" -Force 95 $cf = "$d\cert.cer" 96 [IO.File]::WriteAllBytes($cf, $c.Export("Cer")) 97 $csha = (certutil -dump $cf | sls "Cert Hash\(sha256\): (.+)").Matches.Groups[1].Value 98 99 $info = @{ Subject=$c.Subject; SHA256=$csha; } 100 101 $d = mkdir "$(Build.BinariesDirectory)\cert" -Force 102 $info | ConvertTo-JSON -Compress | Out-File -Encoding utf8 "$d\certinfo.json" 103 displayName: "Extract certificate info" 104 105 - task: PublishPipelineArtifact@0 106 displayName: 'Publish artifact: cert' 107 inputs: 108 targetPath: '$(Build.BinariesDirectory)\cert' 109 artifactName: cert 110 111 112- job: Mark_Unsigned 113 displayName: Tag unsigned build 114 condition: and(succeeded(), not(variables['SigningCertificate'])) 115 116 pool: 117 vmImage: windows-2019 118 119 steps: 120 - checkout: none 121 122 - powershell: | 123 Write-Host "##vso[build.addbuildtag]unsigned" 124 displayName: 'Add build tag' 125