Skip to content

Commit 25e17bb

Browse files
committed
Setup publish stage in release pipeline
This splits the release into three stages: build, sign, and publish. The last stage requires a manual approval on its deployment job's associated environment. When approved, it creates a draft GitHub release using our ReleaseTools module and securely uploads the artifacts directly from the build agent, thus taking developer machines out of the release process.
1 parent f2f2ed3 commit 25e17bb

File tree

3 files changed

+82
-35
lines changed

3 files changed

+82
-35
lines changed

.vsts-ci/azure-pipelines-release.yml

Lines changed: 41 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
name: Release-$(Build.SourceBranchName)-$(Date:yyyyMMdd)$(Rev:.rr)
2+
13
variables:
24
# Don't download unneeded packages
35
- name: DOTNET_SKIP_FIRST_TIME_EXPERIENCE
@@ -18,24 +20,45 @@ resources:
1820
repositories:
1921
- repository: ComplianceRepo
2022
type: github
21-
endpoint: ComplianceGHRepo
23+
endpoint: GitHub
2224
name: PowerShell/compliance
25+
- repository: vscode-powershell
26+
type: git
27+
name: vscode-powershell
28+
29+
stages:
30+
- stage: Build
31+
displayName: Build the release
32+
jobs:
33+
- job: Build
34+
pool:
35+
vmImage: vs2017-win2016
36+
steps:
37+
- template: templates/ci-general.yml
2338

24-
jobs:
25-
- job: 'ReleaseBuild'
26-
displayName: 'Build release'
27-
pool:
28-
vmImage: 'vs2017-win2016'
29-
steps:
30-
- template: templates/ci-general.yml
39+
- stage: Sign
40+
displayName: Sign the release
41+
jobs:
42+
- job: Sign
43+
pool:
44+
name: 1ES
45+
demands: ImageOverride -equals MMS2019
46+
variables:
47+
- group: ESRP
48+
steps:
49+
- template: templates/release-general.yml
3150

32-
- job: 'SignBuild'
33-
displayName: Signing Build
34-
dependsOn: 'ReleaseBuild'
35-
pool:
36-
name: '1ES'
37-
demands: ImageOverride -equals MMS2019
38-
variables:
39-
- group: ESRP
40-
steps:
41-
- template: templates/release-general.yml
51+
- stage: Publish
52+
displayName: Publish the draft release
53+
jobs:
54+
- deployment: Publish
55+
environment: PowerShellEditorServices
56+
pool:
57+
name: 1ES
58+
variables:
59+
- group: Publish
60+
strategy:
61+
runOnce:
62+
deploy:
63+
steps:
64+
- template: templates/publish-general.yml
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
steps:
2+
- checkout: self
3+
- checkout: vscode-powershell
4+
- pwsh: |
5+
Set-PSRepository -Name PSGallery -InstallationPolicy Trusted | Out-Null
6+
Install-Module -Name PowerShellForGitHub -Scope CurrentUser -Force -Confirm:$false
7+
Import-Module '$(Build.SourcesDirectory)/vscode-powershell/tools/ReleaseTools.psm1'
8+
Set-GitHubConfiguration -SuppressTelemetryReminder
9+
$password = ConvertTo-SecureString -String '$(GitHubToken)' -AsPlainText -Force
10+
Set-GitHubAuthentication -Credential (New-Object System.Management.Automation.PSCredential ("token", $password))
11+
New-DraftRelease -RepositoryName PowerShellEditorServices -Assets '$(Pipeline.Workspace)/PowerShellEditorServices/PowerShellEditorServices.zip'
12+
displayName: Drafting a GitHub Release

.vsts-ci/templates/release-general.yml

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,29 @@
11
steps:
22

3+
# TODO: Replace build artifacts with pipeline artifacts
34
- task: DownloadBuildArtifacts@0
4-
displayName: 'Download Build Artifacts'
5+
displayName: Download build artifacts
56
inputs:
67
downloadType: specific
78

89
- task: ExtractFiles@1
9-
displayName: 'Extract Build Zip'
10+
displayName: Unzip build artifacts
1011
inputs:
11-
archiveFilePatterns: '$(Build.ArtifactStagingDirectory)/PowerShellEditorServices-CI/PowerShellEditorServices*.zip'
12-
destinationFolder: '$(Build.ArtifactStagingDirectory)/PowerShellEditorServices'
12+
archiveFilePatterns: $(Build.ArtifactStagingDirectory)/PowerShellEditorServices-CI/PowerShellEditorServices*.zip
13+
destinationFolder: $(Build.ArtifactStagingDirectory)/Unsigned
1314

1415
- checkout: ComplianceRepo
15-
displayName: 'Checkout the ComplianceRepo'
1616

17+
# NOTE: The signing templates explicitly copy everything along as they run, so
18+
# the last output path has every signed (and intentionally unsigned) file.
1719
- template: EsrpSign.yml@ComplianceRepo
1820
parameters:
19-
buildOutputPath: '$(Build.ArtifactStagingDirectory)/PowerShellEditorServices'
20-
signOutputPath: '$(Build.ArtifactStagingDirectory)/FirstPartySigned'
21-
alwaysCopy: true # So publishing works
22-
certificateId: 'CP-230012' # Authenticode certificate
23-
useMinimatch: true # This enables the use of globbing
21+
buildOutputPath: $(Build.ArtifactStagingDirectory)/Unsigned
22+
signOutputPath: $(Build.ArtifactStagingDirectory)/FirstPartySigned
23+
alwaysCopy: true
24+
certificateId: CP-230012 # Authenticode certificate
2425
shouldSign: true # We always want to sign
26+
useMinimatch: true # This enables the use of globbing
2527
pattern: |
2628
# PowerShellEditorServices Script
2729
PowerShellEditorServices/*.{ps1,psd1,psm1,ps1xml}
@@ -35,12 +37,12 @@ steps:
3537
3638
- template: EsrpSign.yml@ComplianceRepo
3739
parameters:
38-
buildOutputPath: '$(Build.ArtifactStagingDirectory)/FirstPartySigned'
39-
signOutputPath: '$(Build.ArtifactStagingDirectory)/ThirdPartySigned'
40-
alwaysCopy: true # So publishing works
41-
certificateId: 'CP-231522' # Third-party certificate
42-
useMinimatch: true # This enables the use of globbing
40+
buildOutputPath: $(Build.ArtifactStagingDirectory)/FirstPartySigned
41+
signOutputPath: $(Build.ArtifactStagingDirectory)/ThirdPartySigned
42+
alwaysCopy: true
43+
certificateId: CP-231522 # Third-party certificate
4344
shouldSign: true # We always want to sign
45+
useMinimatch: true # This enables the use of globbing
4446
pattern: |
4547
**/MediatR.dll
4648
**/Nerdbank.Streams.dll
@@ -49,9 +51,19 @@ steps:
4951
**/Serilog*.dll
5052
**/UnixConsoleEcho.dll
5153
52-
- publish: $(Build.ArtifactStagingDirectory)/ThirdPartySigned
54+
- task: ArchiveFiles@2
55+
displayName: Zip finished assets
56+
inputs:
57+
rootFolderOrFile: $(Build.ArtifactStagingDirectory)/ThirdPartySigned
58+
includeRootFolder: false
59+
archiveType: zip
60+
archiveFile: $(Build.ArtifactStagingDirectory)/PowerShellEditorServices.zip
61+
replaceExistingArchive: true
62+
verbose: true
63+
64+
- publish: $(Build.ArtifactStagingDirectory)/PowerShellEditorServices.zip
5365
artifact: PowerShellEditorServices
54-
displayName: 'Publish signed (and unsigned) artifacts'
66+
displayName: Publish signed pipeline artifacts
5567

5668
- checkout: self
5769

0 commit comments

Comments
 (0)