| 1 | parameters: |
| 2 | - name: isRelease |
| 3 | type: boolean |
| 4 | default: true |
| 5 | |
| 6 | - name: nugetPackages |
| 7 | type: object |
| 8 | default: |
| 9 | - Microsoft.WSL.PluginApi.nuspec |
| 10 | |
| 11 | - name: pool |
| 12 | type: string |
| 13 | default: '' |
| 14 | |
| 15 | - name: esrp |
| 16 | type: object |
| 17 | default: |
| 18 | ConnectedServiceName: "AzureConnection-AME" |
| 19 | signConfigType: "inlineSignParams" |
| 20 | SessionTimeout: 60 |
| 21 | MaxConcurrency: 50 |
| 22 | MaxRetryAttempts: 5 |
| 23 | ServiceEndpointUrl: $(EsrpServiceEndpointUrl) |
| 24 | AuthAKVName: $(EsrpAuthAKVName) |
| 25 | AuthSignCertName: $(EsrpAuthSignCertName) |
| 26 | AppRegistrationClientId: $(EsrpAppRegistrationClientId) |
| 27 | AppRegistrationTenantId: $(EsrpAppRegistrationTenantId) |
| 28 | EsrpClientId: $(EsrpClientId) |
| 29 | |
| 30 | stages: |
| 31 | - stage: package |
| 32 | dependsOn: [build_x64, build_arm64] |
| 33 | jobs: |
| 34 | - job: package |
| 35 | displayName: "Package WSL release artifacts" |
| 36 | timeoutInMinutes: 60 |
| 37 | |
| 38 | ${{ if eq(parameters.pool, '') }}: |
| 39 | pool: {'type': 'windows'} |
| 40 | |
| 41 | ${{ else }}: |
| 42 | pool: ${{ parameters.pool }} |
| 43 | |
| 44 | variables: |
| 45 | ob_outputDirectory: '$(Build.SourcesDirectory)\out' |
| 46 | ob_artifactBaseName: 'drop_wsl' |
| 47 | ob_artifactSuffix: '_package' |
| 48 | # Outputs are explicitly signed+verified by the EsrpCodeSigning tasks below. |
| 49 | ob_sdl_codeSignValidation_enabled: false |
| 50 | buildStagePackageVersion: $[ stageDependencies.build_x64.build_x64.outputs['version.WSL_PACKAGE_VERSION'] ] |
| 51 | buildStageNugetVersion: $[ stageDependencies.build_x64.build_x64.outputs['version.WSL_NUGET_PACKAGE_VERSION'] ] |
| 52 | |
| 53 | steps: |
| 54 | - task: PowerShell@2 |
| 55 | displayName: "Set package version from build stage" |
| 56 | name: version |
| 57 | inputs: |
| 58 | targetType: inline |
| 59 | script: | |
| 60 | Write-Host "##vso[task.setvariable variable=WSL_PACKAGE_VERSION;isOutput=true]$(buildStagePackageVersion)" |
| 61 | Write-Host "##vso[task.setvariable variable=WSL_NUGET_PACKAGE_VERSION;isOutput=true]$(buildStageNugetVersion)" |
| 62 | |
| 63 | - task: DownloadPipelineArtifact@2 |
| 64 | displayName: Download x64 build artifact |
| 65 | inputs: |
| 66 | artifact: "drop_wsl_build" |
| 67 | path: $(Pipeline.Workspace)\drop_x64 |
| 68 | |
| 69 | - task: DownloadPipelineArtifact@2 |
| 70 | displayName: Download arm64 build artifact |
| 71 | inputs: |
| 72 | artifact: "drop_wsl_build_arm64" |
| 73 | path: $(Pipeline.Workspace)\drop_arm64 |
| 74 | |
| 75 | - powershell: | |
| 76 | $version = "$(version.WSL_PACKAGE_VERSION)" |
| 77 | |
| 78 | # Place per-platform msix files where cmake's bundle target expects them |
| 79 | foreach ($arch in @( |
| 80 | @{platform="x64"; dir="X64"}, |
| 81 | @{platform="arm64"; dir="arm64"} |
| 82 | )) { |
| 83 | $dest = "bin\$($arch.dir)\Release" |
| 84 | New-Item -ItemType Directory -Path $dest -Force |
| 85 | Copy-Item "$(Pipeline.Workspace)\drop_$($arch.platform)\installer\installer.$($arch.platform).msix" "$dest\installer.msix" |
| 86 | Copy-Item "$(Pipeline.Workspace)\drop_$($arch.platform)\sdk\$($arch.platform)\wslcsdk.lib" "$dest\wslcsdk.lib" |
| 87 | Copy-Item "$(Pipeline.Workspace)\drop_$($arch.platform)\sdk\$($arch.platform)\wslcsdk.dll" "$dest\wslcsdk.dll" |
| 88 | Copy-Item "$(Pipeline.Workspace)\drop_$($arch.platform)\sdk\$($arch.platform)\wslcsdkcs.dll" "$dest\wslcsdkcs.dll" |
| 89 | Copy-Item "$(Pipeline.Workspace)\drop_$($arch.platform)\sdk\$($arch.platform)\Microsoft.WSL.Containers.winmd" "$dest\Microsoft.WSL.Containers.winmd" |
| 90 | } |
| 91 | |
| 92 | # Copy MSIs to the output bundle directory |
| 93 | $bundleDir = "$(ob_outputDirectory)\bundle" |
| 94 | New-Item -ItemType Directory -Path $bundleDir -Force |
| 95 | Copy-Item "$(Pipeline.Workspace)\drop_x64\bundle\wsl.${version}.x64.msi" "$bundleDir\" |
| 96 | Copy-Item "$(Pipeline.Workspace)\drop_arm64\bundle\wsl.${version}.arm64.msi" "$bundleDir\" |
| 97 | displayName: Stage build artifacts |
| 98 | |
| 99 | - task: CMake@1 |
| 100 | displayName: "CMake configure (bundle-only)" |
| 101 | inputs: |
| 102 | workingDirectory: "." |
| 103 | cmakeArgs: . -DBUNDLE_ONLY=TRUE -DCMAKE_BUILD_TYPE=Release -DPACKAGE_VERSION=$(version.WSL_PACKAGE_VERSION) -DWSL_NUGET_PACKAGE_VERSION=$(version.WSL_NUGET_PACKAGE_VERSION) -DWSL_INCLUDE_SDK_CSHARP=true |
| 104 | |
| 105 | - script: cmake --build . --config Release --target bundle -- -m |
| 106 | displayName: Create msixbundle |
| 107 | |
| 108 | - powershell: | |
| 109 | Copy-Item "bundle\Release\*.msixbundle" "$(ob_outputDirectory)\bundle\" |
| 110 | displayName: Copy bundle to output |
| 111 | |
| 112 | - ${{ if eq(parameters.isRelease, true) }}: |
| 113 | - task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@5 |
| 114 | displayName: "Sign the bundle" |
| 115 | inputs: |
| 116 | ConnectedServiceName: ${{ parameters.esrp.ConnectedServiceName}} |
| 117 | signConfigType: ${{ parameters.esrp.signConfigType }} |
| 118 | SessionTimeout: ${{ parameters.esrp.SessionTimeout }} |
| 119 | MaxConcurrency: ${{ parameters.esrp.MaxConcurrency }} |
| 120 | MaxRetryAttempts: ${{ parameters.esrp.MaxRetryAttempts }} |
| 121 | ServiceEndpointUrl: ${{ parameters.esrp.ServiceEndpointUrl }} |
| 122 | AuthAKVName: ${{ parameters.esrp.AuthAKVName }} |
| 123 | AuthSignCertName: ${{ parameters.esrp.AuthSignCertName }} |
| 124 | AppRegistrationClientId: ${{ parameters.esrp.AppRegistrationClientId }} |
| 125 | AppRegistrationTenantId: ${{ parameters.esrp.AppRegistrationTenantId }} |
| 126 | FolderPath: "$(ob_outputDirectory)\\bundle" |
| 127 | Pattern: "*.msixbundle" |
| 128 | UseMSIAuthentication: true |
| 129 | EsrpClientId: ${{ parameters.esrp.EsrpClientId }} |
| 130 | inlineOperation: | |
| 131 | [ |
| 132 | { |
| 133 | "KeyCode": "CP-230012", |
| 134 | "OperationCode": "SigntoolSign", |
| 135 | "Parameters" : { |
| 136 | "OpusName" : "Microsoft", |
| 137 | "OpusInfo" : "http://www.microsoft.com", |
| 138 | "FileDigest" : "/fd \"SHA256\"", |
| 139 | "PageHash" : "/NPH", |
| 140 | "TimeStamp" : "/tr \"http://rfc3161.gtm.corp.microsoft.com/TSS/HttpTspServer\" /td sha256" |
| 141 | }, |
| 142 | "ToolName" : "sign", |
| 143 | "ToolVersion" : "1.0" |
| 144 | }, |
| 145 | { |
| 146 | "KeyCode" : "CP-230012", |
| 147 | "OperationCode" : "SigntoolVerify", |
| 148 | "Parameters" : {}, |
| 149 | "ToolName" : "sign", |
| 150 | "ToolVersion" : "1.0" |
| 151 | } |
| 152 | ] |
| 153 | |
| 154 | - ${{ if not(eq(parameters.isRelease, true)) }}: |
| 155 | - powershell: | |
| 156 | # Sign the bundle with the dev cert from the x64 build |
| 157 | $cert = "$(Pipeline.Workspace)\drop_x64\installer\dev-cert.pfx" |
| 158 | if (-not (Test-Path $cert)) { throw "Dev cert not found at $cert" } |
| 159 | $bundle = Get-ChildItem "$(ob_outputDirectory)\bundle\*.msixbundle" | Select-Object -First 1 |
| 160 | $signtool = Get-ChildItem "${env:ProgramFiles(x86)}\Windows Kits\10\bin\*\x64\signtool.exe" -ErrorAction Stop | Sort-Object FullName -Descending | Select-Object -First 1 -ExpandProperty FullName |
| 161 | & $signtool sign /a /v /fd SHA256 /f $cert $bundle.FullName |
| 162 | displayName: Sign bundle with dev cert |
| 163 | |
| 164 | - powershell: | |
| 165 | $version = "$(version.WSL_PACKAGE_VERSION)" |
| 166 | |
| 167 | # Collect PDBs from both platforms |
| 168 | foreach ($source in @( |
| 169 | @{arch="x64"; drop="$(Pipeline.Workspace)\drop_x64\pdb\x64\Release"}, |
| 170 | @{arch="ARM64"; drop="$(Pipeline.Workspace)\drop_arm64\pdb\arm64\Release"} |
| 171 | )) |
| 172 | { |
| 173 | $pdbFolder = Join-Path $(ob_outputDirectory) "pdb\$($source.arch)\Release" |
| 174 | New-Item -ItemType Directory -Path $pdbFolder -Force |
| 175 | if (Test-Path $source.drop) { |
| 176 | Copy-Item -Path "$($source.drop)\*" -Destination $pdbFolder -Recurse |
| 177 | } |
| 178 | } |
| 179 | displayName: Collect symbols from both platforms |
| 180 | |
| 181 | - powershell: | |
| 182 | $version = "$(version.WSL_PACKAGE_VERSION)" |
| 183 | |
| 184 | mkdir appxsym |
| 185 | foreach ($arch in @("x64", "ARM64")) |
| 186 | { |
| 187 | Get-ChildItem -Path $(ob_outputDirectory)\pdb\$arch\release\*.pdb -Exclude wsltests.pdb | Compress-Archive -DestinationPath appxsym/Microsoft.WSL_${version}_$arch.zip |
| 188 | Copy-Item -Path appxsym/Microsoft.WSL_${version}_$arch.zip -Destination appxsym/Microsoft.WSL_${version}_$arch.appxsym |
| 189 | } |
| 190 | mkdir $(ob_outputDirectory)/appxupload |
| 191 | Get-ChildItem -Path appxsym/*.appxsym,$(ob_outputDirectory)/bundle/Microsoft.WSL_${version}_x64_ARM64.msixbundle | Compress-Archive -DestinationPath $(ob_outputDirectory)/appxupload/Microsoft.WSL_${version}_x64_ARM64.zip |
| 192 | Move-Item -Path $(ob_outputDirectory)/appxupload/Microsoft.WSL_${version}_x64_ARM64.zip -Destination $(ob_outputDirectory)/appxupload/Microsoft.WSL_${version}_x64_ARM64.appxupload |
| 193 | rm appxsym/*.appxsym |
| 194 | |
| 195 | displayName: Create appxupload |
| 196 | condition: and(succeeded(), eq('${{ parameters.isRelease }}', true)) |
| 197 | |
| 198 | - script: md.exe $(ob_outputDirectory)\nuget |
| 199 | displayName: "Create the nuget directory" |
| 200 | |
| 201 | - ${{ each package in parameters.nugetPackages }}: |
| 202 | - script: nuget.exe pack ${{ package }} -OutputDirectory $(ob_outputDirectory)\nuget -NonInteractive |
| 203 | displayName: Build ${{ package }} |
| 204 | |
| 205 | - ${{ if eq(parameters.isRelease, true) }}: |
| 206 | - task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@5 |
| 207 | displayName: "Sign nuget packages" |
| 208 | inputs: |
| 209 | ConnectedServiceName: ${{ parameters.esrp.ConnectedServiceName}} |
| 210 | signConfigType: ${{ parameters.esrp.signConfigType }} |
| 211 | SessionTimeout: ${{ parameters.esrp.SessionTimeout }} |
| 212 | MaxConcurrency: ${{ parameters.esrp.MaxConcurrency }} |
| 213 | MaxRetryAttempts: ${{ parameters.esrp.MaxRetryAttempts }} |
| 214 | ServiceEndpointUrl: ${{ parameters.esrp.ServiceEndpointUrl }} |
| 215 | AuthAKVName: ${{ parameters.esrp.AuthAKVName }} |
| 216 | AuthSignCertName: ${{ parameters.esrp.AuthSignCertName }} |
| 217 | AppRegistrationClientId: ${{ parameters.esrp.AppRegistrationClientId }} |
| 218 | AppRegistrationTenantId: ${{ parameters.esrp.AppRegistrationTenantId }} |
| 219 | FolderPath: '$(ob_outputDirectory)\nuget' |
| 220 | Pattern: "*.nupkg" |
| 221 | UseMSIAuthentication: true |
| 222 | EsrpClientId: ${{ parameters.esrp.EsrpClientId }} |
| 223 | inlineOperation: | |
| 224 | [ |
| 225 | { |
| 226 | "KeyCode": "CP-401405", |
| 227 | "OperationCode": "NuGetSign", |
| 228 | "Parameters" : {}, |
| 229 | "ToolName" : "sign", |
| 230 | "ToolVersion" : "1.0" |
| 231 | }, |
| 232 | { |
| 233 | "KeyCode" : "CP-401405", |
| 234 | "OperationCode" : "NuGetVerify", |
| 235 | "Parameters" : {}, |
| 236 | "ToolName" : "sign", |
| 237 | "ToolVersion" : "1.0" |
| 238 | } |
| 239 | ] |
| 240 | |
| 241 | - ${{ if ne(parameters.pool, '') }}: |
| 242 | - task: PublishPipelineArtifact@1 |
| 243 | inputs: |
| 244 | targetPath: $(ob_outputDirectory) |
| 245 | artifactName: $(ob_artifactBaseName)$(ob_artifactSuffix) |