Skip to content

Commit b8fbd0d

Browse files
[release/v7.4.16] Add macOS binary code signing and package notarization (#27431)
1 parent 4f6d7ca commit b8fbd0d

4 files changed

Lines changed: 108 additions & 12 deletions

File tree

.pipelines/templates/mac-package-build.yml

Lines changed: 53 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,14 @@ jobs:
7676
# Diagnostics is not critical it passes every time it runs
7777
continueOnError: true
7878
79+
- pwsh: |
80+
$signedDir = "$(Pipeline.Workspace)/CoOrdinatedBuildPipeline/drop_macos_sign_${{ parameters.buildArchitecture }}/Signed-${{ parameters.buildArchitecture }}"
81+
Get-ChildItem $signedDir -Recurse -Include 'pwsh', '*.dylib' | ForEach-Object {
82+
codesign --verify --deep --strict --verbose=4 $_.FullName
83+
if ($LASTEXITCODE -ne 0) { throw "codesign verification failed for $($_.FullName)" }
84+
}
85+
displayName: 'Verify Apple codesign on signed binaries'
86+
7987
- pwsh: |
8088
# Add -SkipReleaseChecks as a mitigation to unblock release.
8189
# macos-10.15 does not allow creating a folder under root. Hence, moving the folder.
@@ -158,7 +166,12 @@ jobs:
158166
Write-Host "##vso[artifact.upload containerfolder=macos-pkgs;artifactname=macos-pkgs]$file"
159167
}
160168
169+
$packageInfo = Get-MacOSPackageIdentifierInfo -Version '$(Version)' -LTS:$LTS
170+
Write-Verbose -Verbose "BundleId: $($packageInfo.PackageIdentifier)"
171+
Write-Host "##vso[task.setvariable variable=BundleId;isOutput=true]$($packageInfo.PackageIdentifier)"
172+
161173
displayName: 'Package ${{ parameters.buildArchitecture}}'
174+
name: packageStep
162175
env:
163176
__DOTNET_RUNTIME_FEED_KEY: $(RUNTIME_SOURCEFEED_KEY)
164177
@@ -178,7 +191,8 @@ jobs:
178191
value: $(Build.SourcesDirectory)/PowerShell/.config/suppress.json
179192
- name: BuildArch
180193
value: ${{ parameters.buildArchitecture }}
181-
- group: mscodehub-macos-package-signing
194+
- name: BundleId
195+
value: $[ dependencies.package_macOS_${{ parameters.buildArchitecture }}.outputs['packageStep.BundleId'] ]
182196

183197
steps:
184198
- download: current
@@ -216,32 +230,59 @@ jobs:
216230
inline_operation: |
217231
[
218232
{
219-
"KeyCode": "$(KeyCode)",
233+
"KeyCode": "CP-401337-Apple",
220234
"OperationCode": "MacAppDeveloperSign",
221235
"ToolName": "sign",
222236
"ToolVersion": "1.0",
223237
"Parameters": {
224-
"Hardening": "Enable",
225-
"OpusInfo": "http://microsoft.com"
238+
"Hardening": "--options=runtime"
226239
}
227240
}
228241
]
229242
243+
- task: onebranch.pipeline.signing@1
244+
displayName: 'OneBranch Notarize Package'
245+
inputs:
246+
command: 'sign'
247+
files_to_sign: '**/*-osx-*.zip'
248+
search_root: '$(Pipeline.Workspace)'
249+
inline_operation: |
250+
[
251+
{
252+
"KeyCode": "CP-401337-Apple",
253+
"OperationCode": "MacAppNotarize",
254+
"ToolName": "sign",
255+
"ToolVersion": "1.0",
256+
"Parameters": {
257+
"BundleId": "$(BundleId)"
258+
}
259+
}
260+
]
261+
timeoutInMinutes: 120
262+
230263
- pwsh: |
231264
$signedPkg = Get-ChildItem -Path $(Pipeline.Workspace) -Filter "*osx*.zip" -File
232265
266+
if (-not (Test-Path $(ob_outputDirectory))) {
267+
$null = New-Item -Path $(ob_outputDirectory) -ItemType Directory
268+
}
269+
270+
$expandDir = "$(Pipeline.Workspace)/pkgExpand"
271+
$null = New-Item -Path $expandDir -ItemType Directory -Force
272+
233273
$signedPkg | ForEach-Object {
234274
Write-Verbose -Verbose "Signed package zip: $_"
275+
Expand-Archive -Path $_ -DestinationPath $expandDir -Verbose
276+
}
235277
236-
if (-not (Test-Path $_)) {
237-
throw "Package not found: $_"
238-
}
239-
240-
if (-not (Test-Path $(ob_outputDirectory))) {
241-
$null = New-Item -Path $(ob_outputDirectory) -ItemType Directory
242-
}
278+
# ESRP's signing pipeline nests the PKG inside a '<hash>.zip.unzipped' subfolder
279+
$pkgFile = Get-ChildItem -Path $expandDir -Filter '*.pkg' -Recurse -File
280+
if (-not $pkgFile) {
281+
throw "Package not found in: $signedPkg"
282+
}
243283
244-
Expand-Archive -Path $_ -DestinationPath $(ob_outputDirectory) -Verbose
284+
$pkgFile | ForEach-Object {
285+
Move-Item -Path $_ -Destination $(ob_outputDirectory) -Verbose
245286
}
246287
247288
Write-Verbose -Verbose "Expanded pkg file:"

.pipelines/templates/mac.yml

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,14 @@ jobs:
6969
$psOptPath = "$(OB_OUTPUTDIRECTORY)/psoptions.json"
7070
Save-PSOptions -PSOptionsPath $psOptPath
7171
72+
$entitlements = "$(PowerShellRoot)/assets/macos-entitlements.plist"
73+
$pwshBin = "$(OB_OUTPUTDIRECTORY)/pwsh"
74+
Write-Verbose -Verbose "Applying entitlements to $pwshBin"
75+
codesign --sign - --force --options runtime --entitlements $entitlements $pwshBin
76+
if ($LASTEXITCODE -ne 0) {
77+
throw "codesign failed with exit code $LASTEXITCODE"
78+
}
79+
7280
# Since we are using custom pool for macOS, we need to use artifact.upload to publish the artifacts
7381
Write-Host "##vso[artifact.upload containerfolder=$artifactName;artifactname=$artifactName]$(OB_OUTPUTDIRECTORY)"
7482
@@ -144,4 +152,36 @@ jobs:
144152
binPath: $(DropRootPath)
145153
OfficialBuild: $(ps_official_build)
146154

155+
# Apple-sign the Mach-O binaries inside the signed output.
156+
- pwsh: |
157+
$signedDir = "$(ob_outputDirectory)/Signed-$(Runtime)"
158+
$zipFile = "$(Pipeline.Workspace)/macho-$(BuildArchitecture).zip"
159+
Compress-Archive -Path "$signedDir/*" -DestinationPath $zipFile -Force
160+
displayName: Compress signed folder for Apple signing
161+
162+
- task: onebranch.pipeline.signing@1
163+
displayName: Apple CodeSign Mach-O binaries
164+
inputs:
165+
command: 'sign'
166+
files_to_sign: 'macho-$(BuildArchitecture).zip'
167+
search_root: '$(Pipeline.Workspace)'
168+
inline_operation: |
169+
[
170+
{
171+
"KeyCode": "CP-401337-Apple",
172+
"OperationCode": "MacAppDeveloperSign",
173+
"ToolName": "sign",
174+
"ToolVersion": "1.0",
175+
"Parameters": {
176+
"Hardening": "--options=runtime"
177+
}
178+
}
179+
]
180+
181+
- pwsh: |
182+
$signedDir = "$(ob_outputDirectory)/Signed-$(Runtime)"
183+
$zipFile = "$(Pipeline.Workspace)/macho-$(BuildArchitecture).zip"
184+
Expand-Archive -Path $zipFile -DestinationPath $signedDir -Force -Verbose
185+
displayName: Expand Apple-signed Mach-O binaries into signed output
186+
147187
- template: /.pipelines/templates/step/finalize.yml@self

assets/macos-entitlements.plist

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict>
5+
<key>com.apple.security.cs.allow-jit</key>
6+
<true/>
7+
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
8+
<true/>
9+
<key>com.apple.security.cs.allow-dyld-environment-variables</key>
10+
<true/>
11+
<key>com.apple.security.cs.disable-library-validation</key>
12+
<true/>
13+
</dict>
14+
</plist>

tools/packaging/packaging.psd1

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
'Test-PackageManifest'
2727
'Update-PSSignedBuildFolder'
2828
'Test-Bom'
29+
'Get-MacOSPackageIdentifierInfo'
2930
)
3031
RootModule = "packaging.psm1"
3132
RequiredModules = @("build")

0 commit comments

Comments
 (0)