diff options
author | Aditya Patwardhan <adityap@microsoft.com> | 2022-11-03 01:52:05 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-11-03 01:52:05 +0300 |
commit | 38531558acd9e52d4384d20ef9e8cf334c5ff52e (patch) | |
tree | 38eb648ac13e5a2cc5901cf3d33bf17e73e21d49 | |
parent | f2e0640dd7bf2e1f217373d628ea6a9ec45da3fa (diff) |
Add authenticode signing for assemblies on linux builds (#18440)
5 files changed, 782 insertions, 213 deletions
diff --git a/tools/releaseBuild/azureDevOps/releaseBuild.yml b/tools/releaseBuild/azureDevOps/releaseBuild.yml index 9eb2d62bbd..e21b4fe0c4 100644 --- a/tools/releaseBuild/azureDevOps/releaseBuild.yml +++ b/tools/releaseBuild/azureDevOps/releaseBuild.yml @@ -100,7 +100,7 @@ stages: - template: templates/linux.yml parameters: buildName: rpm - uploadDisplayName: Upload and Sign + parentJob: build_deb - template: templates/linux.yml parameters: @@ -111,6 +111,29 @@ stages: parameters: buildName: alpine + - template: templates/linux-authenticode-sign.yml + + - template: templates/linux-packaging.yml + parameters: + buildName: deb + parentJob: sign_linux_builds + + - template: templates/linux-packaging.yml + parameters: + buildName: rpm + uploadDisplayName: Upload and Sign + parentJob: sign_linux_builds + + - template: templates/linux-packaging.yml + parameters: + buildName: alpine + parentJob: sign_linux_builds + + - template: templates/linux-packaging.yml + parameters: + buildName: fxdependent + parentJob: sign_linux_builds + - stage: windows dependsOn: ['prep'] jobs: diff --git a/tools/releaseBuild/azureDevOps/templates/linux-authenticode-sign.yml b/tools/releaseBuild/azureDevOps/templates/linux-authenticode-sign.yml new file mode 100644 index 0000000000..d014cf7432 --- /dev/null +++ b/tools/releaseBuild/azureDevOps/templates/linux-authenticode-sign.yml @@ -0,0 +1,127 @@ +jobs: +- job: sign_linux_builds + displayName: Sign all linux builds + condition: succeeded() + pool: + name: PowerShell1ES + demands: + - ImageOverride -equals PSMMS2019-Secure + dependsOn: ['build_fxdependent', 'build_rpm'] + variables: + - name: runCodesignValidationInjection + value: false + - name: NugetSecurityAnalysisWarningLevel + value: none + - group: ESRP + + steps: + - checkout: self + clean: true + + - task: DownloadPipelineArtifact@2 + inputs: + artifact: pwshLinuxBuild + path: $(Build.ArtifactStagingDirectory)/pwshLinuxBuild + displayName: Download deb build + + - task: DownloadPipelineArtifact@2 + inputs: + artifact: pwshLinuxBuildMinSize + path: $(Build.ArtifactStagingDirectory)/pwshLinuxBuildMinSize + displayName: Download min-size build + + - task: DownloadPipelineArtifact@2 + inputs: + artifact: pwshLinuxBuildArm32 + path: $(Build.ArtifactStagingDirectory)/pwshLinuxBuildArm32 + displayName: Download arm32 build + + - task: DownloadPipelineArtifact@2 + inputs: + artifact: pwshLinuxBuildArm64 + path: $(Build.ArtifactStagingDirectory)/pwshLinuxBuildArm64 + displayName: Download arm64 build + + - task: DownloadPipelineArtifact@2 + inputs: + artifact: pwshMarinerBuildAmd64 + path: $(Build.ArtifactStagingDirectory)/pwshMarinerBuildAmd64 + displayName: Download mariner build + + - task: DownloadPipelineArtifact@2 + inputs: + artifact: pwshLinuxBuildAlpine + path: $(Build.ArtifactStagingDirectory)/pwshLinuxBuildAlpine + displayName: Download alpine build + + - task: DownloadPipelineArtifact@2 + inputs: + artifact: pwshLinuxBuildFxdependent + path: $(Build.ArtifactStagingDirectory)/pwshLinuxBuildFxdependent + displayName: Download fxdependent build + + - template: SetVersionVariables.yml + parameters: + ReleaseTagVar: $(ReleaseTagVar) + + - template: cloneToOfficialPath.yml + + - template: insert-nuget-config-azfeed.yml + parameters: + repoRoot: $(PowerShellRoot) + + - powershell: | + Set-Location $env:POWERSHELLROOT + import-module "$env:POWERSHELLROOT/build.psm1" + Sync-PSTags -AddRemoteIfMissing + displayName: SyncTags + condition: and(succeeded(), ne(variables['SkipBuild'], 'true')) + + - checkout: ComplianceRepo + clean: true + + - template: shouldSign.yml + + - template: signBuildFiles.yml + parameters: + binLocation: pwshLinuxBuild + buildPrefixName: 'PowerShell Linux' + + - template: signBuildFiles.yml + parameters: + binLocation: pwshLinuxBuildMinSize + buildPrefixName: 'PowerShell Linux Minimum Size' + + - template: signBuildFiles.yml + parameters: + binLocation: pwshLinuxBuildArm32 + buildPrefixName: 'PowerShell Linux Arm32' + + - template: signBuildFiles.yml + parameters: + binLocation: pwshLinuxBuildArm64 + buildPrefixName: 'PowerShell Linux Arm64' + + - template: signBuildFiles.yml + parameters: + binLocation: pwshMarinerBuildAmd64 + buildPrefixName: 'PowerShell Linux x64 Framework Dependent' + + - template: signBuildFiles.yml + parameters: + binLocation: pwshLinuxBuildAlpine + buildPrefixName: 'PowerShell Linux Alpine x64' + + - template: signBuildFiles.yml + parameters: + binLocation: pwshLinuxBuildFxdependent + buildPrefixName: 'PowerShell Linux Framework Dependent' + + #- template: Sbom.yml@ComplianceRepo + # parameters: + # BuildDropPath: '$(System.ArtifactsDirectory)/$(BIN_LOCATION)' + # Build_Repository_Uri: $(Github_Build_Repository_Uri) + # displayName: ${{ parameters.buildName }} SBOM + # PackageName: $(PACKAGE_NAME) + # PackageVersion: $(Version) + # sourceScanPath: '$(PowerShellRoot)/tools' diff --git a/tools/releaseBuild/azureDevOps/templates/linux-packaging.yml b/tools/releaseBuild/azureDevOps/templates/linux-packaging.yml new file mode 100644 index 0000000000..f5e298f713 --- /dev/null +++ b/tools/releaseBuild/azureDevOps/templates/linux-packaging.yml @@ -0,0 +1,391 @@ +parameters: + buildName: '' + uploadDisplayName: 'Upload' + parentJob: '' + +jobs: +- job: pkg_${{ parameters.buildName }} + displayName: Package ${{ parameters.buildName }} + condition: succeeded() + pool: + name: PowerShell1ES + demands: + - ImageOverride -equals PSMMSUbuntu20.04-Secure + dependsOn: sign_linux_builds + variables: + - name: runCodesignValidationInjection + value: false + - name: build + value: ${{ parameters.buildName }} + - name: NugetSecurityAnalysisWarningLevel + value: none + - group: ESRP + + steps: + - ${{ if or(eq(variables.build,'deb'), eq(variables.build,'rpm')) }} : + - task: DownloadPipelineArtifact@2 + inputs: + artifact: pwshLinuxBuild-signed + path: $(Build.ArtifactStagingDirectory)/pwshLinuxBuild + displayName: Download deb build + + - ${{ if eq(variables.build,'deb') }} : + - task: DownloadPipelineArtifact@2 + inputs: + artifact: pwshLinuxBuildMinSize-signed + path: $(Build.ArtifactStagingDirectory)/pwshLinuxBuildMinSize + displayName: Download min-size build + + - ${{ if eq(variables.build,'deb') }} : + - task: DownloadPipelineArtifact@2 + inputs: + artifact: pwshLinuxBuildArm32-signed + path: $(Build.ArtifactStagingDirectory)/pwshLinuxBuildArm32 + displayName: Download arm32 build + + - ${{ if eq(variables.build,'deb') }} : + - task: DownloadPipelineArtifact@2 + inputs: + artifact: pwshLinuxBuildArm64-signed + path: $(Build.ArtifactStagingDirectory)/pwshLinuxBuildArm64 + displayName: Download arm64 build + + - ${{ if eq(variables.build,'rpm') }} : + - task: DownloadPipelineArtifact@2 + inputs: + artifact: pwshMarinerBuildAmd64-signed + path: $(Build.ArtifactStagingDirectory)/pwshMarinerBuildAmd64 + displayName: Download mariner build + + - ${{ if eq(variables.build,'alpine') }} : + - task: DownloadPipelineArtifact@2 + inputs: + artifact: pwshLinuxBuildAlpine-signed + path: $(Build.ArtifactStagingDirectory)/pwshLinuxBuild + displayName: Download alpine build + + - ${{ if eq(variables.build,'fxdependent') }} : + - task: DownloadPipelineArtifact@2 + inputs: + artifact: pwshLinuxBuildFxdependent-signed + path: $(Build.ArtifactStagingDirectory)/pwshLinuxBuild + displayName: Download fxdependent build + + - ${{ if or(eq(variables.build,'deb'), eq(variables.build,'rpm')) }} : + - task: DownloadPipelineArtifact@2 + inputs: + artifact: pwshLinuxBuild-meta + path: $(Build.ArtifactStagingDirectory)/pwshLinuxBuild-meta + displayName: Download deb build meta + + - ${{ if eq(variables.build,'deb') }} : + - task: DownloadPipelineArtifact@2 + inputs: + artifact: pwshLinuxBuildMinSize-meta + path: $(Build.ArtifactStagingDirectory)/pwshLinuxBuildMinSize-meta + displayName: Download min-size build meta + + - ${{ if eq(variables.build,'deb') }} : + - task: DownloadPipelineArtifact@2 + inputs: + artifact: pwshLinuxBuildArm32-meta + path: $(Build.ArtifactStagingDirectory)/pwshLinuxBuildArm32-meta + displayName: Download arm32 build meta + + - ${{ if eq(variables.build,'deb') }} : + - task: DownloadPipelineArtifact@2 + inputs: + artifact: pwshLinuxBuildArm64-meta + path: $(Build.ArtifactStagingDirectory)/pwshLinuxBuildArm64-meta + displayName: Download arm64 build meta + + - ${{ if eq(variables.build,'rpm') }} : + - task: DownloadPipelineArtifact@2 + inputs: + artifact: pwshMarinerBuildAmd64-meta + path: $(Build.ArtifactStagingDirectory)/pwshMarinerBuildAmd64-meta + displayName: Download mariner build meta + + - ${{ if eq(variables.build,'alpine') }} : + - task: DownloadPipelineArtifact@2 + inputs: + artifact: pwshLinuxBuildAlpine-meta + path: $(Build.ArtifactStagingDirectory)/pwshLinuxBuild-meta + displayName: Download alpine build meta + + - ${{ if eq(variables.build,'fxdependent') }} : + - task: DownloadPipelineArtifact@2 + inputs: + artifact: pwshLinuxBuildFxdependent-meta + path: $(Build.ArtifactStagingDirectory)/pwshLinuxBuild-meta + displayName: Download fxdependent build meta + + - pwsh: | + Get-ChildItem '$(Build.ArtifactStagingDirectory)' | Select-Object -Property 'unixmode', 'size', 'name' + displayName: Capture downloads + + - checkout: self + clean: true + + - checkout: ComplianceRepo + clean: true + + - template: SetVersionVariables.yml + parameters: + ReleaseTagVar: $(ReleaseTagVar) + + - pwsh: | + # create folder + sudo mkdir /PowerShell + + # make the current user the owner + sudo chown $env:USER /PowerShell + displayName: 'Create /PowerShell' + + - template: cloneToOfficialPath.yml + + - template: insert-nuget-config-azfeed.yml + parameters: + repoRoot: $(PowerShellRoot) + + - powershell: | + import-module "$env:POWERSHELLROOT/build.psm1" + Sync-PSTags -AddRemoteIfMissing + displayName: SyncTags + condition: and(succeeded(), ne(variables['SkipBuild'], 'true')) + workingDirectory: $(PowerShellRoot) + + - powershell: | + Import-Module "$env:POWERSHELLROOT/build.psm1" + + Start-PSBootstrap -Package + displayName: 'Bootstrap' + condition: and(succeeded(), ne(variables['SkipBuild'], 'true')) + workingDirectory: $(PowerShellRoot) + + - powershell: | + try { + Import-Module "$env:POWERSHELLROOT/build.psm1" + Import-Module "$env:POWERSHELLROOT/tools/packaging" + + $metadata = Get-Content "$env:POWERSHELLROOT/tools/metadata.json" -Raw | ConvertFrom-Json + + # LTSRelease.Package indicates that the release should be packaged as an LTS + $LTS = $metadata.LTSRelease.Package + Write-Verbose -Verbose -Message "LTS is set to: $LTS" + + Invoke-AzDevOpsLinuxPackageCreation -ReleaseTag '$(ReleaseTagVar)' -BuildType '$(build)' + + if ($LTS) { + Write-Verbose -Verbose "Packaging LTS" + Invoke-AzDevOpsLinuxPackageCreation -LTS -ReleaseTag '$(ReleaseTagVar)' -BuildType '$(build)' + } + } catch { + Get-Error + throw + } + displayName: 'Package' + condition: and(succeeded(), ne(variables['SkipBuild'], 'true')) + workingDirectory: $(PowerShellRoot) + + - powershell: | + $linuxPackages = Get-ChildItem "$env:POWERSHELLROOT/powershell*" -Include *.deb,*.rpm,*.tar.gz + + $bucket = 'release' + foreach ($linuxPackage in $linuxPackages) + { + $filePath = $linuxPackage.FullName + Write-Verbose "Publishing $filePath to $bucket" -Verbose + Write-Host "##vso[artifact.upload containerfolder=$bucket;artifactname=$bucket]$filePath" + } + displayName: Publish artifacts + condition: and(succeeded(), ne(variables['SkipBuild'], 'true')) + workingDirectory: $(PowerShellRoot) + + - template: /tools/releaseBuild/azureDevOps/templates/step/finalize.yml + +- job: upload_${{ parameters.buildName }} + displayName: ${{ parameters.uploadDisplayName }} ${{ parameters.buildName }} + dependsOn: pkg_${{ parameters.buildName }} + condition: succeeded() + pool: + name: PowerShell1ES + demands: + - ImageOverride -equals PSMMS2019-Secure + variables: + - name: buildName + value: ${{ parameters.buildName }} + - group: ESRP + - name: runCodesignValidationInjection + value: false + - name: NugetSecurityAnalysisWarningLevel + value: none + - name: skipComponentGovernanceDetection + value: true + + steps: + - checkout: self + clean: true + + - checkout: ComplianceRepo + clean: true + + - template: SetVersionVariables.yml + parameters: + ReleaseTagVar: $(ReleaseTagVar) + - template: shouldSign.yml + + - task: DownloadBuildArtifacts@0 + displayName: 'Download Deb Artifacts' + inputs: + downloadType: specific + itemPattern: '**/*.deb' + downloadPath: '$(System.ArtifactsDirectory)\finished' + condition: and(eq(variables['buildName'], 'DEB'), succeeded()) + + - task: DownloadBuildArtifacts@0 + displayName: 'Download tar.gz Artifacts copy' + inputs: + downloadType: specific + itemPattern: '**/*.tar.gz' + downloadPath: '$(System.ArtifactsDirectory)\finished' + + - powershell: | + Write-Host 'We handle the min-size package only when uploading for deb build.' + Write-Host '- For deb build, the min-size package is moved to a separate folder "finished\minSize",' + Write-Host ' so that the min-size package can be uploaded to a different Az Blob container.' + Write-Host '- For other builds, the min-size package is removed after being downloaded, so that it' + Write-Host ' does not get accidentally uploaded to the wrong Az Blob container.' + + $minSizePkg = '$(System.ArtifactsDirectory)\finished\release\*-gc.tar.gz' + if (Test-Path -Path $minSizePkg) + { + if ('$(buildName)' -eq 'DEB') + { + $minSizeDir = '$(System.ArtifactsDirectory)\finished\minSize' + New-Item -Path $minSizeDir -Type Directory -Force > $null + Move-Item -Path $minSizePkg -Destination $minSizeDir + + Write-Host "`nCapture the min-size package moved to the target folder." + Get-ChildItem -Path $minSizeDir + } + else + { + Write-Host '$(buildName): Remove the min-size package.' + Remove-Item -Path $minSizePkg -Force + } + } + else + { + Write-Host 'min-size package not found, so skip this step.' + } + displayName: 'Move minSize package to separate folder' + + - task: DownloadBuildArtifacts@0 + displayName: 'Download rpm Artifacts copy' + inputs: + downloadType: specific + itemPattern: '**/*.rpm' + downloadPath: '$(System.ArtifactsDirectory)\rpm' + condition: and(eq(variables['buildName'], 'RPM'), succeeded()) + + - template: EsrpScan.yml@ComplianceRepo + parameters: + scanPath: $(System.ArtifactsDirectory) + pattern: | + **\*.rpm + **\*.deb + **\*.tar.gz + + - ${{ if eq(variables['buildName'], 'RPM') }}: + - template: EsrpSign.yml@ComplianceRepo + parameters: + buildOutputPath: $(System.ArtifactsDirectory)\rpm + signOutputPath: $(Build.StagingDirectory)\signedPackages + certificateId: "CP-450779-Pgp" + pattern: | + **\*.rh.*.rpm + useMinimatch: true + shouldSign: $(SHOULD_SIGN) + displayName: Sign RedHat RPM + OutputMode: AlwaysCopy + + - ${{ if eq(variables['buildName'], 'RPM') }}: + - template: EsrpSign.yml@ComplianceRepo + parameters: + # Sign in-place, previous task copied the files to this folder + buildOutputPath: $(Build.StagingDirectory)\signedPackages + signOutputPath: $(Build.StagingDirectory)\signedPackages + certificateId: "CP-459159-Pgp" + pattern: | + **\*.cm.*.rpm + **\*.cm?.*.rpm + useMinimatch: true + shouldSign: $(SHOULD_SIGN) + displayName: Sign Mariner RPM + OutputMode: NeverCopy + + # requires windows + - ${{ if ne(variables['buildName'], 'RPM') }}: + - task: AzureFileCopy@4 + displayName: 'Upload to Azure - DEB and tar.gz' + inputs: + SourcePath: '$(System.ArtifactsDirectory)\finished\release\*' + azureSubscription: '$(AzureFileCopySubscription)' + Destination: AzureBlob + storage: '$(StorageAccount)' + ContainerName: '$(AzureVersion)' + + - template: upload-final-results.yml + parameters: + artifactPath: $(System.ArtifactsDirectory)\finished\release + + # requires windows + - task: AzureFileCopy@4 + displayName: 'Upload to Azure - min-size package for Guest Config' + inputs: + SourcePath: '$(System.ArtifactsDirectory)\finished\minSize\*' + azureSubscription: '$(AzureFileCopySubscription)' + Destination: AzureBlob + storage: '$(StorageAccount)' + ContainerName: '$(AzureVersion)-gc' + condition: and(eq(variables['buildName'], 'DEB'), succeeded()) + + - template: upload-final-results.yml + parameters: + artifactPath: $(System.ArtifactsDirectory)\finished\minSize + condition: and(eq(variables['buildName'], 'DEB'), succeeded()) + + # requires windows + - task: AzureFileCopy@4 + displayName: 'Upload to Azure - RPM - Unsigned' + inputs: + SourcePath: '$(System.ArtifactsDirectory)\rpm\release\*' + azureSubscription: '$(AzureFileCopySubscription)' + Destination: AzureBlob + storage: '$(StorageAccount)' + ContainerName: '$(AzureVersion)' + condition: and(and(succeeded(), ne(variables['SHOULD_SIGN'], 'true')),eq(variables['buildName'], 'RPM')) + + # requires windows + - task: AzureFileCopy@4 + displayName: 'Upload to Azure - RPM - Signed' + inputs: + SourcePath: '$(Build.StagingDirectory)\signedPackages\release\*' + azureSubscription: '$(AzureFileCopySubscription)' + Destination: AzureBlob + storage: '$(StorageAccount)' + ContainerName: '$(AzureVersion)' + condition: and(and(succeeded(), eq(variables['SHOULD_SIGN'], 'true')),eq(variables['buildName'], 'RPM')) + + - template: upload-final-results.yml + parameters: + artifactPath: $(System.ArtifactsDirectory)\rpm\release + condition: and(and(succeeded(), ne(variables['SHOULD_SIGN'], 'true')),eq(variables['buildName'], 'RPM')) + + - template: upload-final-results.yml + parameters: + artifactPath: '$(Build.StagingDirectory)\signedPackages\release' + condition: and(and(succeeded(), eq(variables['SHOULD_SIGN'], 'true')),eq(variables['buildName'], 'RPM')) + + - template: /tools/releaseBuild/azureDevOps/templates/step/finalize.yml diff --git a/tools/releaseBuild/azureDevOps/templates/linux.yml b/tools/releaseBuild/azureDevOps/templates/linux.yml index 53057fec71..e7caa41bc3 100644 --- a/tools/releaseBuild/azureDevOps/templates/linux.yml +++ b/tools/releaseBuild/azureDevOps/templates/linux.yml @@ -124,229 +124,86 @@ jobs: PackageVersion: $(Version) sourceScanPath: '$(PowerShellRoot)/tools' - - powershell: | - try { - Import-Module "$env:POWERSHELLROOT/build.psm1" - Import-Module "$env:POWERSHELLROOT/tools/packaging" - - $metadata = Get-Content "$env:POWERSHELLROOT/tools/metadata.json" -Raw | ConvertFrom-Json - - # LTSRelease.Package indicates that the release should be packaged as an LTS - $LTS = $metadata.LTSRelease.Package - Write-Verbose -Verbose -Message "LTS is set to: $LTS" - - Invoke-AzDevOpsLinuxPackageCreation -ReleaseTag '$(ReleaseTagVar)' -BuildType '$(build)' + - ${{ if eq(variables.build,'deb') }} : + - task: PublishPipelineArtifact@1 + inputs: + path: '$(System.ArtifactsDirectory)/pwshLinuxBuild' + artifactName: pwshLinuxBuild - if ($LTS) { - Write-Verbose -Verbose "Packaging LTS" - Invoke-AzDevOpsLinuxPackageCreation -LTS -ReleaseTag '$(ReleaseTagVar)' -BuildType '$(build)' - } - } catch { - Get-Error - throw - } - displayName: 'Package' - condition: and(succeeded(), ne(variables['SkipBuild'], 'true')) - workingDirectory: $(PowerShellRoot) + - ${{ if eq(variables.build,'deb') }} : + - task: PublishPipelineArtifact@1 + inputs: + path: '$(System.ArtifactsDirectory)/pwshLinuxBuild-meta' + artifactName: pwshLinuxBuild-meta - - powershell: | - $linuxPackages = Get-ChildItem "$env:POWERSHELLROOT/powershell*" -Include *.deb,*.rpm,*.tar.gz - - $bucket = 'release' - foreach ($linuxPackage in $linuxPackages) - { - $filePath = $linuxPackage.FullName - Write-Verbose "Publishing $filePath to $bucket" -Verbose - Write-Host "##vso[artifact.upload containerfolder=$bucket;artifactname=$bucket]$filePath" - } - displayName: Publish artifacts - condition: and(succeeded(), ne(variables['SkipBuild'], 'true')) - workingDirectory: $(PowerShellRoot) + - ${{ if eq(variables.build,'deb') }} : + - task: PublishPipelineArtifact@1 + inputs: + path: '$(System.ArtifactsDirectory)/pwshLinuxBuildMinSize' + artifactName: pwshLinuxBuildMinSize - - template: /tools/releaseBuild/azureDevOps/templates/step/finalize.yml + - ${{ if eq(variables.build,'deb') }} : + - task: PublishPipelineArtifact@1 + inputs: + path: '$(System.ArtifactsDirectory)/pwshLinuxBuildMinSize-meta' + artifactName: pwshLinuxBuildMinSize-meta -- job: upload_${{ parameters.buildName }} - displayName: ${{ parameters.uploadDisplayName }} ${{ parameters.buildName }} - dependsOn: build_${{ parameters.buildName }} - condition: succeeded() - pool: - name: PowerShell1ES - demands: - - ImageOverride -equals PSMMS2019-Secure - variables: - - name: buildName - value: ${{ parameters.buildName }} - - group: ESRP - - name: runCodesignValidationInjection - value: false - - name: NugetSecurityAnalysisWarningLevel - value: none - - name: skipComponentGovernanceDetection - value: true + - ${{ if eq(variables.build,'deb') }} : + - task: PublishPipelineArtifact@1 + inputs: + path: '$(System.ArtifactsDirectory)/pwshLinuxBuildArm32' + artifactName: pwshLinuxBuildArm32 - steps: - - checkout: self - clean: true + - ${{ if eq(variables.build,'deb') }} : + - task: PublishPipelineArtifact@1 + inputs: + path: '$(System.ArtifactsDirectory)/pwshLinuxBuildArm32-meta' + artifactName: pwshLinuxBuildArm32-meta - - checkout: ComplianceRepo - clean: true + - ${{ if eq(variables.build,'deb') }} : + - task: PublishPipelineArtifact@1 + inputs: + path: '$(System.ArtifactsDirectory)/pwshLinuxBuildArm64' + artifactName: pwshLinuxBuildArm64 - - template: SetVersionVariables.yml - parameters: - ReleaseTagVar: $(ReleaseTagVar) - - template: shouldSign.yml - - - task: DownloadBuildArtifacts@0 - displayName: 'Download Deb Artifacts' - inputs: - downloadType: specific - itemPattern: '**/*.deb' - downloadPath: '$(System.ArtifactsDirectory)\finished' - condition: and(eq(variables['buildName'], 'DEB'), succeeded()) - - - task: DownloadBuildArtifacts@0 - displayName: 'Download tar.gz Artifacts copy' - inputs: - downloadType: specific - itemPattern: '**/*.tar.gz' - downloadPath: '$(System.ArtifactsDirectory)\finished' + - ${{ if eq(variables.build,'deb') }} : + - task: PublishPipelineArtifact@1 + inputs: + path: '$(System.ArtifactsDirectory)/pwshLinuxBuildArm64-meta' + artifactName: pwshLinuxBuildArm64-meta - - powershell: | - Write-Host 'We handle the min-size package only when uploading for deb build.' - Write-Host '- For deb build, the min-size package is moved to a separate folder "finished\minSize",' - Write-Host ' so that the min-size package can be uploaded to a different Az Blob container.' - Write-Host '- For other builds, the min-size package is removed after being downloaded, so that it' - Write-Host ' does not get accidentally uploaded to the wrong Az Blob container.' - - $minSizePkg = '$(System.ArtifactsDirectory)\finished\release\*-gc.tar.gz' - if (Test-Path -Path $minSizePkg) - { - if ('$(buildName)' -eq 'DEB') - { - $minSizeDir = '$(System.ArtifactsDirectory)\finished\minSize' - New-Item -Path $minSizeDir -Type Directory -Force > $null - Move-Item -Path $minSizePkg -Destination $minSizeDir - - Write-Host "`nCapture the min-size package moved to the target folder." - Get-ChildItem -Path $minSizeDir - } - else - { - Write-Host '$(buildName): Remove the min-size package.' - Remove-Item -Path $minSizePkg -Force - } - } - else - { - Write-Host 'min-size package not found, so skip this step.' - } - displayName: 'Move minSize package to separate folder' + - ${{ if eq(variables.build,'rpm') }} : + - task: PublishPipelineArtifact@1 + inputs: + path: '$(System.ArtifactsDirectory)/pwshMarinerBuildAmd64' + artifactName: pwshMarinerBuildAmd64 - - task: DownloadBuildArtifacts@0 - displayName: 'Download rpm Artifacts copy' - inputs: - downloadType: specific - itemPattern: '**/*.rpm' - downloadPath: '$(System.ArtifactsDirectory)\rpm' - condition: and(eq(variables['buildName'], 'RPM'), succeeded()) + - ${{ if eq(variables.build,'rpm') }} : + - task: PublishPipelineArtifact@1 + inputs: + path: '$(System.ArtifactsDirectory)/pwshMarinerBuildAmd64-meta' + artifactName: pwshMarinerBuildAmd64-meta - - template: EsrpScan.yml@ComplianceRepo - parameters: - scanPath: $(System.ArtifactsDirectory) - pattern: | - **\*.rpm - **\*.deb - **\*.tar.gz - - - ${{ if eq(variables['buildName'], 'RPM') }}: - - template: EsrpSign.yml@ComplianceRepo - parameters: - buildOutputPath: $(System.ArtifactsDirectory)\rpm - signOutputPath: $(Build.StagingDirectory)\signedPackages - certificateId: "CP-450779-Pgp" - pattern: | - **\*.rh.*.rpm - useMinimatch: true - shouldSign: $(SHOULD_SIGN) - displayName: Sign RedHat RPM - OutputMode: AlwaysCopy - - - ${{ if eq(variables['buildName'], 'RPM') }}: - - template: EsrpSign.yml@ComplianceRepo - parameters: - # Sign in-place, previous task copied the files to this folder - buildOutputPath: $(Build.StagingDirectory)\signedPackages - signOutputPath: $(Build.StagingDirectory)\signedPackages - certificateId: "CP-459159-Pgp" - pattern: | - **\*.cm.*.rpm - **\*.cm?.*.rpm - useMinimatch: true - shouldSign: $(SHOULD_SIGN) - displayName: Sign Mariner RPM - OutputMode: NeverCopy - - # requires windows - - ${{ if ne(variables['buildName'], 'RPM') }}: - - task: AzureFileCopy@4 - displayName: 'Upload to Azure - DEB and tar.gz' + - ${{ if eq(variables.build,'alpine') }} : + - task: PublishPipelineArtifact@1 inputs: - SourcePath: '$(System.ArtifactsDirectory)\finished\release\*' - azureSubscription: '$(AzureFileCopySubscription)' - Destination: AzureBlob - storage: '$(StorageAccount)' - ContainerName: '$(AzureVersion)' + path: '$(System.ArtifactsDirectory)/pwshLinuxBuild' + artifactName: pwshLinuxBuildAlpine - - template: upload-final-results.yml - parameters: - artifactPath: $(System.ArtifactsDirectory)\finished\release - - # requires windows - - task: AzureFileCopy@4 - displayName: 'Upload to Azure - min-size package for Guest Config' - inputs: - SourcePath: '$(System.ArtifactsDirectory)\finished\minSize\*' - azureSubscription: '$(AzureFileCopySubscription)' - Destination: AzureBlob - storage: '$(StorageAccount)' - ContainerName: '$(AzureVersion)-gc' - condition: and(eq(variables['buildName'], 'DEB'), succeeded()) - - - template: upload-final-results.yml - parameters: - artifactPath: $(System.ArtifactsDirectory)\finished\minSize - condition: and(eq(variables['buildName'], 'DEB'), succeeded()) - - # requires windows - - task: AzureFileCopy@4 - displayName: 'Upload to Azure - RPM - Unsigned' - inputs: - SourcePath: '$(System.ArtifactsDirectory)\rpm\release\*' - azureSubscription: '$(AzureFileCopySubscription)' - Destination: AzureBlob - storage: '$(StorageAccount)' - ContainerName: '$(AzureVersion)' - condition: and(and(succeeded(), ne(variables['SHOULD_SIGN'], 'true')),eq(variables['buildName'], 'RPM')) - - # requires windows - - task: AzureFileCopy@4 - displayName: 'Upload to Azure - RPM - Signed' - inputs: - SourcePath: '$(Build.StagingDirectory)\signedPackages\release\*' - azureSubscription: '$(AzureFileCopySubscription)' - Destination: AzureBlob - storage: '$(StorageAccount)' - ContainerName: '$(AzureVersion)' - condition: and(and(succeeded(), eq(variables['SHOULD_SIGN'], 'true')),eq(variables['buildName'], 'RPM')) - - - template: upload-final-results.yml - parameters: - artifactPath: $(System.ArtifactsDirectory)\rpm\release - condition: and(and(succeeded(), ne(variables['SHOULD_SIGN'], 'true')),eq(variables['buildName'], 'RPM')) + - ${{ if eq(variables.build,'alpine') }} : + - task: PublishPipelineArtifact@1 + inputs: + path: '$(System.ArtifactsDirectory)/pwshLinuxBuild-meta' + artifactName: pwshLinuxBuildAlpine-meta - - template: upload-final-results.yml - parameters: - artifactPath: '$(Build.StagingDirectory)\signedPackages\release' - condition: and(and(succeeded(), eq(variables['SHOULD_SIGN'], 'true')),eq(variables['buildName'], 'RPM')) + - ${{ if eq(variables.build,'fxdependent') }} : + - task: PublishPipelineArtifact@1 + inputs: + path: '$(System.ArtifactsDirectory)/pwshLinuxBuild' + artifactName: pwshLinuxBuildFxdependent - - template: /tools/releaseBuild/azureDevOps/templates/step/finalize.yml + - ${{ if eq(variables.build,'fxdependent') }} : + - task: PublishPipelineArtifact@1 + inputs: + path: '$(System.ArtifactsDirectory)/pwshLinuxBuild-meta' + artifactName: pwshLinuxBuildFxdependent-meta diff --git a/tools/releaseBuild/azureDevOps/templates/signBuildFiles.yml b/tools/releaseBuild/azureDevOps/templates/signBuildFiles.yml new file mode 100644 index 0000000000..e628f2ca81 --- /dev/null +++ b/tools/releaseBuild/azureDevOps/templates/signBuildFiles.yml @@ -0,0 +1,171 @@ +parameters: + binLocation: '' + buildPrefixName: '' + addWindowsModules: 'false' + +steps: +- pwsh: | + $fullSymbolsFolder = Join-Path $(System.ArtifactsDirectory) "${{ parameters.binLocation }}" + + Write-Verbose -Verbose "fullSymbolsFolder == $fullSymbolsFolder" + + Get-ChildItem -Recurse $fullSymbolsFolder | out-string | Write-Verbose -Verbose + + $filesToSignDirectory = "$(System.ArtifactsDirectory)\toBeSigned" + + if ((Test-Path -Path $filesToSignDirectory)) { + Remove-Item -Path $filesToSignDirectory -Recurse -Force + } + + $null = New-Item -ItemType Directory -Path $filesToSignDirectory -Force + + $signedFilesDirectory = "$(System.ArtifactsDirectory)\signed" + + if ((Test-Path -Path $signedFilesDirectory)) { + Remove-Item -Path $signedFilesDirectory -Recurse -Force + } + + $null = New-Item -ItemType Directory -Path $signedFilesDirectory -Force + + $itemsToCopyWithRecurse = @( + "$($fullSymbolsFolder)\*.ps1" + "$($fullSymbolsFolder)\Microsoft.PowerShell*.dll" + ) + + $itemsToCopy = @{ + "$($fullSymbolsFolder)\*.ps1" = "" + "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Host\Microsoft.PowerShell.Host.psd1" = "Modules\Microsoft.PowerShell.Host" + "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Management\Microsoft.PowerShell.Management.psd1" = "Modules\Microsoft.PowerShell.Management" + "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Security\Microsoft.PowerShell.Security.psd1" = "Modules\Microsoft.PowerShell.Security" + "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Utility\Microsoft.PowerShell.Utility.psd1" = "Modules\Microsoft.PowerShell.Utility" + "$($fullSymbolsFolder)\pwsh.dll" = "" + "$($fullSymbolsFolder)\System.Management.Automation.dll" = "" + } + + ## Windows only modules + + if('${{ parameters.addWindowsModules }}' -ne 'false') { + $itemsToCopy += @{ + "$($fullSymbolsFolder)\pwsh.exe" = "" + "$($fullSymbolsFolder)\Microsoft.Management.Infrastructure.CimCmdlets.dll" = "" + "$($fullSymbolsFolder)\Microsoft.WSMan.*.dll" = "" + "$($fullSymbolsFolder)\Modules\CimCmdlets\CimCmdlets.psd1" = "Modules\CimCmdlets" + "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Diagnostics\Diagnostics.format.ps1xml" = "Modules\Microsoft.PowerShell.Diagnostics" + "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Diagnostics\Event.format.ps1xml" = "Modules\Microsoft.PowerShell.Diagnostics" + "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Diagnostics\GetEvent.types.ps1xml" = "Modules\Microsoft.PowerShell.Diagnostics" + "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Security\Security.types.ps1xml" = "Modules\Microsoft.PowerShell.Security" + "$($fullSymbolsFolder)\Modules\Microsoft.PowerShell.Diagnostics\Microsoft.PowerShell.Diagnostics.psd1" = "Modules\Microsoft.PowerShell.Diagnostics" + "$($fullSymbolsFolder)\Modules\Microsoft.WSMan.Management\Microsoft.WSMan.Management.psd1" = "Modules\Microsoft.WSMan.Management" + "$($fullSymbolsFolder)\Modules\Microsoft.WSMan.Management\WSMan.format.ps1xml" = "Modules\Microsoft.WSMan.Management" + "$($fullSymbolsFolder)\Modules\PSDiagnostics\PSDiagnostics.ps?1" = "Modules\PSDiagnostics" + } + } + else { + $itemsToCopy += @{ + "$($fullSymbolsFolder)\pwsh" = "" + } + } + + $itemsToExclude = @( + # This package is retrieved from https://www.github.com/powershell/MarkdownRender + "$($fullSymbolsFolder)\Microsoft.PowerShell.MarkdownRender.dll" + ) + + Write-Verbose -verbose "recusively copying $($itemsToCopyWithRecurse | out-string) to $filesToSignDirectory" + Copy-Item -Path $itemsToCopyWithRecurse -Destination $filesToSignDirectory -Recurse -verbose -exclude $itemsToExclude + + foreach($pattern in $itemsToCopy.Keys) { + $destinationFolder = Join-Path $filesToSignDirectory -ChildPath $itemsToCopy.$pattern + $null = New-Item -ItemType Directory -Path $destinationFolder -Force + Write-Verbose -verbose "copying $pattern to $destinationFolder" + Copy-Item -Path $pattern -Destination $destinationFolder -Recurse -verbose + } + displayName: '${{ parameters.buildPrefixName }} - Prepare files to be signed' + +- template: EsrpSign.yml@ComplianceRepo + parameters: + buildOutputPath: $(System.ArtifactsDirectory)\toBeSigned + signOutputPath: $(System.ArtifactsDirectory)\signed + certificateId: "$(AUTHENTICODE_CERT)" + pattern: | + **\*.dll + **\*.psd1 + **\*.psm1 + **\*.ps1xml + **\*.ps1 + **\*.exe + useMinimatch: true + shouldSign: $(SHOULD_SIGN) + displayName: ${{ parameters.buildPrefixName }} - Authenticode + +- pwsh: | + Import-Module $(PowerShellRoot)/build.psm1 -Force + Import-Module $(PowerShellRoot)/tools/packaging -Force + $signedFilesPath = '$(System.ArtifactsDirectory)\signed\' + $BuildPath = Join-Path $(System.ArtifactsDirectory) '${{ parameters.binLocation }}' + Write-Verbose -Verbose -Message "BuildPath: $BuildPath" + + Update-PSSignedBuildFolder -BuildPath $BuildPath -SignedFilesPath $SignedFilesPath + $dlls = Get-ChildItem $BuildPath\*.dll, $BuildPath\*.exe -Recurse + $signatures = $dlls | Get-AuthenticodeSignature + $missingSignatures = $signatures | Where-Object { $_.status -eq 'notsigned' -or $_.SignerCertificate.Issuer -notmatch '^CN=Microsoft.*'}| select-object -ExpandProperty Path + + Write-Verbose -verbose "to be signed:`r`n $($missingSignatures | Out-String)" + + $filesToSignDirectory = "$(System.ArtifactsDirectory)\thirdPartyToBeSigned" + $null = New-Item -ItemType Directory -Path $filesToSignDirectory -Force -Verbose + + $signedFilesDirectory = "$(System.ArtifactsDirectory)\thirdPartySigned" + $null = New-Item -ItemType Directory -Path $signedFilesDirectory -Force -Verbose + + $missingSignatures | ForEach-Object { + $pathWithoutLeaf = Split-Path $_ + $relativePath = $pathWithoutLeaf.replace($BuildPath,'') + Write-Verbose -Verbose -Message "relativePath: $relativePath" + $targetDirectory = Join-Path -Path $filesToSignDirectory -ChildPath $relativePath + Write-Verbose -Verbose -Message "targetDirectory: $targetDirectory" + if(!(Test-Path $targetDirectory)) + { + $null = New-Item -ItemType Directory -Path $targetDirectory -Force -Verbose + } + Copy-Item -Path $_ -Destination $targetDirectory + } + + displayName: ${{ parameters.buildPrefixName }} - Create ThirdParty Signing Folder + condition: and(succeeded(), eq(variables['SHOULD_SIGN'], 'true')) + +- template: EsrpSign.yml@ComplianceRepo + parameters: + buildOutputPath: $(System.ArtifactsDirectory)\thirdPartyToBeSigned + signOutputPath: $(System.ArtifactsDirectory)\thirdPartySigned + certificateId: "CP-231522" + pattern: | + **\*.dll + useMinimatch: true + shouldSign: $(SHOULD_SIGN) + displayName: Sign ThirdParty binaries + +- pwsh: | + Get-ChildItem '$(System.ArtifactsDirectory)\thirdPartySigned\*' + displayName: ${{ parameters.buildPrefixName }} - Capture ThirdParty Signed files + condition: and(succeeded(), eq(variables['SHOULD_SIGN'], 'true')) + +- pwsh: | + Import-Module $(PowerShellRoot)/build.psm1 -Force + Import-Module $(PowerShellRoot)/tools/packaging -Force + $signedFilesPath = '$(System.ArtifactsDirectory)\thirdPartySigned' + $BuildPath = Join-Path $(System.ArtifactsDirectory) '${{ parameters.binLocation }}' + + Update-PSSignedBuildFolder -BuildPath $BuildPath -SignedFilesPath $SignedFilesPath + if ($env:BuildConfiguration -eq 'minSize') { + ## Remove XML files when making a min-size package. + Remove-Item "$BuildPath/*.xml" -Force + } + displayName: ${{ parameters.buildPrefixName }} - Merge ThirdParty signed files with Build + condition: and(succeeded(), eq(variables['SHOULD_SIGN'], 'true')) + +- pwsh: | + $uploadFolder = '$(System.ArtifactsDirectory)/${{ parameters.binLocation }}' + $containerName = '${{ parameters.binLocation }}-signed' + Write-Host "##vso[artifact.upload containerfolder=$containerName;artifactname=$containerName]$uploadFolder" + displayName: ${{ parameters.buildPrefixName }} - Upload signed files to artifacts |