Skip to content

Commit 5e63f14

Browse files
authored
Migrate PSReadLine release build pipeline to OneBranch (#3975)
1 parent 5efe2ef commit 5e63f14

File tree

3 files changed

+246
-192
lines changed

3 files changed

+246
-192
lines changed

.config/tsaoptions.json

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"instanceUrl": "https://msazure.visualstudio.com",
3+
"projectName": "One",
4+
"areaPath": "One\\MGMT\\Compute\\Powershell\\Powershell\\PowerShell Core",
5+
"notificationAliases": [
6+
7+
8+
]
9+
}

.pipelines/PSReadLine-Official.yml

+237
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,237 @@
1+
#################################################################################
2+
# OneBranch Pipelines #
3+
# This pipeline was created by EasyStart from a sample located at: #
4+
# https://aka.ms/obpipelines/easystart/samples #
5+
# Documentation: https://aka.ms/obpipelines #
6+
# Yaml Schema: https://aka.ms/obpipelines/yaml/schema #
7+
# Retail Tasks: https://aka.ms/obpipelines/tasks #
8+
# Support: https://aka.ms/onebranchsup #
9+
#################################################################################
10+
11+
name: PSReadLine-ModuleBuild-$(Build.BuildId)
12+
trigger: none
13+
pr: none
14+
15+
variables:
16+
DOTNET_CLI_TELEMETRY_OPTOUT: 1
17+
POWERSHELL_TELEMETRY_OPTOUT: 1
18+
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1
19+
WindowsContainerImage: onebranch.azurecr.io/windows/ltsc2022/vse2022:latest
20+
21+
resources:
22+
repositories:
23+
- repository: onebranchTemplates
24+
type: git
25+
name: OneBranch.Pipelines/GovernedTemplates
26+
ref: refs/heads/main
27+
28+
extends:
29+
template: v2/OneBranch.Official.CrossPlat.yml@onebranchTemplates
30+
parameters:
31+
featureFlags:
32+
WindowsHostVersion: '1ESWindows2022'
33+
globalSdl:
34+
disableLegacyManifest: true
35+
sbom:
36+
enabled: true
37+
packageName: PSReadLine
38+
codeql:
39+
compiled:
40+
enabled: true
41+
asyncSdl: # https://aka.ms/obpipelines/asyncsdl
42+
enabled: true
43+
forStages: [Build]
44+
credscan:
45+
enabled: true
46+
scanFolder: $(Build.SourcesDirectory)\PSReadLine\PSReadLine
47+
binskim:
48+
enabled: true
49+
apiscan:
50+
enabled: false
51+
52+
stages:
53+
- stage: buildstage
54+
displayName: Build and Sign PSReadLine
55+
jobs:
56+
- job: buildjob
57+
displayName: Build PSReadLine Files
58+
variables:
59+
- name: ob_outputDirectory
60+
value: '$(Build.ArtifactStagingDirectory)/ONEBRANCH_ARTIFACT'
61+
- name: repoRoot
62+
value: $(Build.SourcesDirectory)\PSReadLine
63+
- name: ob_sdl_tsa_configFile
64+
value: $(repoRoot)\.config\tsaoptions.json
65+
- name: signSrcPath
66+
value: $(repoRoot)\bin\Release\PSReadLine
67+
- name: ob_sdl_sbom_enabled
68+
value: true
69+
- name: ob_signing_setup_enabled
70+
value: true
71+
#CodeQL tasks added manually to workaround signing failures
72+
- name: ob_sdl_codeql_compiled_enabled
73+
value: false
74+
75+
pool:
76+
type: windows
77+
steps:
78+
- checkout: self
79+
env:
80+
# Set ob_restore_phase to run this step before '🔒 Setup Signing' step.
81+
ob_restore_phase: true
82+
83+
- pwsh: |
84+
if (-not (Test-Path $(repoRoot)/.config/tsaoptions.json)) {
85+
throw "tsaoptions.json does not exist under $(repoRoot)/.config"
86+
}
87+
displayName: Test if tsaoptions.json exists
88+
env:
89+
# Set ob_restore_phase to run this step before '🔒 Setup Signing' step.
90+
ob_restore_phase: true
91+
92+
- pwsh: |
93+
Write-Host "PS Version: $($PSVersionTable.PSVersion)"
94+
Set-Location -Path '$(repoRoot)'
95+
.\build.ps1 -Bootstrap
96+
displayName: Bootstrap
97+
env:
98+
# Set ob_restore_phase to run this step before '🔒 Setup Signing' step.
99+
ob_restore_phase: true
100+
101+
# Add CodeQL Init task right before your 'Build' step.
102+
- task: CodeQL3000Init@0
103+
env:
104+
# Set ob_restore_phase to run this step before '🔒 Setup Signing' step.
105+
ob_restore_phase: true
106+
inputs:
107+
Enabled: true
108+
AnalyzeInPipeline: true
109+
Language: csharp
110+
111+
- pwsh: |
112+
Write-Host "PS Version: $($($PSVersionTable.PSVersion))"
113+
Set-Location -Path '$(repoRoot)'
114+
.\build.ps1 -Configuration Release -Framework net462
115+
displayName: Build
116+
env:
117+
# Set ob_restore_phase to run this step before '🔒 Setup Signing' step.
118+
ob_restore_phase: true
119+
120+
# Add CodeQL Finalize task right after your 'Build' step.
121+
- task: CodeQL3000Finalize@0
122+
condition: always()
123+
env:
124+
# Set ob_restore_phase to run this step before '🔒 Setup Signing' step.
125+
ob_restore_phase: true
126+
127+
- task: onebranch.pipeline.signing@1
128+
displayName: Sign 1st party files
129+
inputs:
130+
command: 'sign'
131+
signing_profile: external_distribution
132+
files_to_sign: '*.psd1;*.psm1;*.ps1;*.ps1xml;**\Microsoft*.dll;!Microsoft.PowerShell.Pager.dll'
133+
search_root: $(signSrcPath)
134+
135+
# Verify the signatures
136+
- pwsh: |
137+
$HasInvalidFiles = $false
138+
$WrongCert = @{}
139+
Get-ChildItem -Path $(signSrcPath) -Recurse -Include "*.dll","*.ps*1*" | `
140+
Get-AuthenticodeSignature | ForEach-Object {
141+
Write-Host "$($_.Path): $($_.Status)"
142+
if ($_.Status -ne 'Valid') { $HasInvalidFiles = $true }
143+
if ($_.SignerCertificate.Subject -notmatch 'CN=Microsoft Corporation.*') {
144+
$WrongCert.Add($_.Path, $_.SignerCertificate.Subject)
145+
}
146+
}
147+
148+
if ($HasInvalidFiles) { throw "Authenticode verification failed. There is one or more invalid files." }
149+
if ($WrongCert.Count -gt 0) {
150+
$WrongCert
151+
throw "Certificate should have the subject starts with 'Microsoft Corporation'"
152+
}
153+
154+
Write-Host "Display files in the folder ..." -ForegroundColor Yellow
155+
Get-ChildItem -Path $(signSrcPath) -Recurse | Out-String -Width 120
156+
displayName: 'Verify the signed files'
157+
158+
- task: CopyFiles@2
159+
displayName: "Copy signed files to ob_outputDirectory - '$(ob_outputDirectory)'"
160+
inputs:
161+
SourceFolder: $(signSrcPath)
162+
Contents: '**\*'
163+
TargetFolder: $(ob_outputDirectory)
164+
165+
- pwsh: |
166+
$versionInfo = Get-Item "$(signSrcPath)\Microsoft.PowerShell.PSReadLine2.dll" | ForEach-Object VersionInfo
167+
$moduleVersion = $versionInfo.ProductVersion.Split('+')[0]
168+
$vstsCommandString = "vso[task.setvariable variable=ob_sdl_sbom_packageversion]${moduleVersion}"
169+
170+
Write-Host "sending $vstsCommandString"
171+
Write-Host "##$vstsCommandString"
172+
displayName: Setup SBOM Package Version
173+
174+
- job: nupkg
175+
dependsOn: buildjob
176+
displayName: Package PSReadLine module
177+
variables:
178+
- name: ob_outputDirectory
179+
value: '$(Build.ArtifactStagingDirectory)/ONEBRANCH_ARTIFACT'
180+
- name: repoRoot
181+
value: $(Build.SourcesDirectory)\PSReadLine
182+
- name: ob_sdl_tsa_configFile
183+
value: $(repoRoot)\.config\tsaoptions.json
184+
# Disable because SBOM was already built in the previous job
185+
- name: ob_sdl_sbom_enabled
186+
value: false
187+
- name: signOutPath
188+
value: $(repoRoot)\signed\PSReadLine
189+
- name: nugetPath
190+
value: $(repoRoot)\signed\NuGetPackage
191+
- name: ob_signing_setup_enabled
192+
value: true
193+
# This job is not compiling code, so disable codeQL
194+
- name: ob_sdl_codeql_compiled_enabled
195+
value: false
196+
197+
pool:
198+
type: windows
199+
steps:
200+
- checkout: self
201+
202+
- task: DownloadPipelineArtifact@2
203+
displayName: 'Download build files'
204+
inputs:
205+
targetPath: $(signOutPath)
206+
artifact: drop_buildstage_buildjob
207+
208+
- pwsh: |
209+
Get-ChildItem $(signOutPath) -Recurse
210+
New-Item -Path $(nugetPath) -ItemType Directory > $null
211+
displayName: Capture artifacts structure
212+
213+
- pwsh: |
214+
try {
215+
$RepoName = "PSRLLocal"
216+
Register-PSRepository -Name $RepoName -SourceLocation $(nugetPath) -PublishLocation $(nugetPath) -InstallationPolicy Trusted
217+
Publish-Module -Repository $RepoName -Path $(signOutPath)
218+
} finally {
219+
Unregister-PSRepository -Name $RepoName -ErrorAction SilentlyContinue
220+
}
221+
Get-ChildItem -Path $(nugetPath)
222+
displayName: 'Create the NuGet package'
223+
224+
- task: onebranch.pipeline.signing@1
225+
displayName: Sign nupkg
226+
inputs:
227+
command: 'sign'
228+
signing_profile: external_default
229+
files_to_sign: '*.nupkg'
230+
search_root: $(nugetPath)
231+
232+
- task: CopyFiles@2
233+
displayName: "Copy nupkg to ob_outputDirectory - '$(ob_outputDirectory)'"
234+
inputs:
235+
SourceFolder: $(nugetPath)
236+
Contents: '**\*'
237+
TargetFolder: $(ob_outputDirectory)

0 commit comments

Comments
 (0)