Skip to content

Commit 16e628a

Browse files
committed
release: update macOS signing
Update macOS component of release workflow to use GitHub certificates for signing and notarization.
1 parent 27d7636 commit 16e628a

File tree

4 files changed

+123
-199
lines changed

4 files changed

+123
-199
lines changed

.github/workflows/release.yml

Lines changed: 78 additions & 194 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,13 @@ jobs:
2121
id: version
2222

2323
# ================================
24-
# macOS
24+
# macOS
2525
# ================================
26-
osx-build:
27-
name: Build macOS
26+
create-macos-artifacts:
27+
name: Create macOS artifacts
2828
runs-on: macos-latest
2929
environment: release
30+
needs: prereqs
3031
strategy:
3132
matrix:
3233
runtime: [ osx-x64, osx-arm64 ]
@@ -38,9 +39,6 @@ jobs:
3839
with:
3940
dotnet-version: 7.0.x
4041

41-
- name: Install dependencies
42-
run: dotnet restore
43-
4442
- name: Build
4543
run: |
4644
dotnet build src/osx/Installer.Mac/*.csproj \
@@ -57,203 +55,88 @@ jobs:
5755
--configuration=MacRelease --output=payload \
5856
--symbol-output=symbols --runtime=${{ matrix.runtime }}
5957
60-
- name: Create keychain
58+
- name: Set up signing/notarization infrastructure
6159
env:
62-
CERT_BASE64: ${{ secrets.DEVELOPER_CERTIFICATE_BASE64 }}
63-
CERT_PASSPHRASE: ${{ secrets.DEVELOPER_CERTIFICATE_PASSWORD }}
64-
run: |
60+
A1: ${{ secrets.APPLICATION_CERTIFICATE_BASE64 }}
61+
A2: ${{ secrets.APPLICATION_CERTIFICATE_PASSWORD }}
62+
I1: ${{ secrets.INSTALLER_CERTIFICATE_BASE64 }}
63+
I2: ${{ secrets.INSTALLER_CERTIFICATE_PASSWORD }}
64+
N1: ${{ secrets.APPLE_TEAM_ID }}
65+
N2: ${{ secrets.APPLE_DEVELOPER_ID }}
66+
N3: ${{ secrets.APPLE_DEVELOPER_PASSWORD }}
67+
N4: ${{ secrets.APPLE_KEYCHAIN_PROFILE }}
68+
run: |
69+
echo "Setting up signing certificates"
6570
security create-keychain -p pwd $RUNNER_TEMP/buildagent.keychain
6671
security default-keychain -s $RUNNER_TEMP/buildagent.keychain
6772
security unlock-keychain -p pwd $RUNNER_TEMP/buildagent.keychain
68-
echo $CERT_BASE64 | base64 -D > $RUNNER_TEMP/cert.p12
69-
security import $RUNNER_TEMP/cert.p12 -k $RUNNER_TEMP/buildagent.keychain -P $CERT_PASSPHRASE -T /usr/bin/codesign
70-
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k pwd $RUNNER_TEMP/buildagent.keychain
71-
72-
- name: Developer sign
73-
env:
74-
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
75-
run: |
76-
.github/run_developer_signing.sh payload $APPLE_TEAM_ID $GITHUB_WORKSPACE/src/osx/Installer.Mac/entitlements.xml
77-
78-
- name: Upload macOS artifacts
79-
uses: actions/upload-artifact@v3
80-
with:
81-
name: tmp.${{ matrix.runtime }}-build
82-
path: |
83-
payload
84-
symbols
85-
86-
osx-payload-sign:
87-
name: Sign macOS payload
88-
# ESRP service requires signing to run on Windows
89-
runs-on: windows-latest
90-
environment: release
91-
strategy:
92-
matrix:
93-
runtime: [ osx-x64, osx-arm64 ]
94-
needs: osx-build
95-
steps:
96-
- uses: actions/checkout@v4
97-
98-
- name: Download payload
99-
uses: actions/download-artifact@v3
100-
with:
101-
name: tmp.${{ matrix.runtime }}-build
102-
103-
- name: Zip unsigned payload
104-
shell: pwsh
105-
run: |
106-
Compress-Archive -Path payload payload/payload.zip
107-
cd payload
108-
Get-ChildItem -Exclude payload.zip | Remove-Item -Recurse -Force
10973
110-
- uses: azure/login@v1
111-
with:
112-
creds: ${{ secrets.AZURE_CREDENTIALS }}
113-
114-
- name: Set up ESRP client
115-
shell: pwsh
116-
env:
117-
AZURE_VAULT: ${{ secrets.AZURE_VAULT }}
118-
AUTH_CERT: ${{ secrets.AZURE_VAULT_AUTH_CERT_NAME }}
119-
REQUEST_SIGNING_CERT: ${{ secrets.AZURE_VAULT_REQUEST_SIGNING_CERT_NAME }}
120-
run: |
121-
.github\set_up_esrp.ps1
122-
123-
- name: Run ESRP client
124-
shell: pwsh
74+
echo $A1 | base64 -D > $RUNNER_TEMP/cert.p12
75+
security import $RUNNER_TEMP/cert.p12 \
76+
-k $RUNNER_TEMP/buildagent.keychain \
77+
-P $A2 \
78+
-T /usr/bin/codesign
79+
security set-key-partition-list \
80+
-S apple-tool:,apple:,codesign: \
81+
-s -k pwd \
82+
$RUNNER_TEMP/buildagent.keychain
83+
84+
echo $I1 | base64 -D > $RUNNER_TEMP/cert.p12
85+
security import $RUNNER_TEMP/cert.p12 \
86+
-k $RUNNER_TEMP/buildagent.keychain \
87+
-P $I2 \
88+
-T /usr/bin/productbuild
89+
security set-key-partition-list \
90+
-S apple-tool:,apple:,productbuild: \
91+
-s -k pwd \
92+
$RUNNER_TEMP/buildagent.keychain
93+
94+
echo "Setting up notarytool"
95+
xcrun notarytool store-credentials \
96+
--team-id $N1 \
97+
--apple-id $N2 \
98+
--password $N3 \
99+
"$N4"
100+
101+
- name: Run codesign against payload
125102
env:
126-
AZURE_AAD_ID: ${{ secrets.AZURE_AAD_ID }}
127-
APPLE_KEY_CODE: ${{ secrets.APPLE_KEY_CODE }}
128-
APPLE_SIGNING_OP_CODE: ${{ secrets.APPLE_SIGNING_OPERATION_CODE }}
103+
A3: ${{ secrets.APPLE_APPLICATION_SIGNING_IDENTITY }}
129104
run: |
130-
python .github\run_esrp_signing.py payload `
131-
$env:APPLE_KEY_CODE $env:APPLE_SIGNING_OP_CODE `
132-
--params 'Hardening' '--options=runtime'
133-
134-
- name: Unzip signed payload
135-
shell: pwsh
136-
run: |
137-
Expand-Archive signed/payload.zip -DestinationPath signed
138-
Remove-Item signed/payload.zip
139-
140-
- name: Upload signed payload
141-
uses: actions/upload-artifact@v3
142-
with:
143-
name: ${{ matrix.runtime }}-payload-sign
144-
path: |
145-
signed
146-
147-
osx-pack:
148-
name: Package macOS payload
149-
runs-on: macos-latest
150-
strategy:
151-
matrix:
152-
runtime: [ osx-x64, osx-arm64 ]
153-
needs: osx-payload-sign
154-
steps:
155-
- uses: actions/checkout@v4
156-
157-
- name: Set version environment variable
158-
run: echo "VERSION=$(cat VERSION | sed -E 's/.[0-9]+$//')" >> $GITHUB_ENV
159-
160-
- name: Set up .NET
161-
uses: actions/[email protected]
162-
with:
163-
dotnet-version: 7.0.x
164-
165-
- name: Download signed payload
166-
uses: actions/download-artifact@v3
167-
with:
168-
name: ${{ matrix.runtime }}-payload-sign
105+
./src/osx/Installer.Mac/codesign.sh "payload" "$A3" \
106+
"$GITHUB_WORKSPACE/src/osx/Installer.Mac/entitlements.xml"
169107
170108
- name: Create component package
171109
run: |
172-
src/osx/Installer.Mac/pack.sh --payload=payload \
173-
--version=$VERSION \
174-
--output=components/com.microsoft.gitcredentialmanager.component.pkg
175-
176-
- name: Create product archive
177-
run: |
178-
src/osx/Installer.Mac/dist.sh --package-path=components \
179-
--version=$VERSION --runtime=${{ matrix.runtime }} \
180-
--output=pkg/gcm-${{ matrix.runtime }}-$VERSION.pkg || exit 1
110+
src/osx/Installer.Mac/pack.sh --payload="payload" \
111+
--version="${{ needs.prereqs.outputs.version }}" \
112+
--output="components/com.microsoft.gitcredentialmanager.component.pkg"
181113
182-
- name: Upload package
183-
uses: actions/upload-artifact@v3
184-
with:
185-
name: tmp.${{ matrix.runtime }}-pack
186-
path: |
187-
pkg
188-
189-
osx-sign:
190-
name: Sign and notarize macOS package
191-
# ESRP service requires signing to run on Windows
192-
runs-on: windows-latest
193-
environment: release
194-
strategy:
195-
matrix:
196-
runtime: [ osx-x64, osx-arm64 ]
197-
needs: osx-pack
198-
steps:
199-
- uses: actions/checkout@v4
200-
201-
- name: Download unsigned package
202-
uses: actions/download-artifact@v3
203-
with:
204-
name: tmp.${{ matrix.runtime }}-pack
205-
path: pkg
206-
207-
- name: Zip unsigned package
208-
shell: pwsh
209-
run: |
210-
Compress-Archive -Path pkg/*.pkg pkg/gcm-pkg.zip
211-
cd pkg
212-
Get-ChildItem -Exclude gcm-pkg.zip | Remove-Item -Recurse -Force
213-
214-
- uses: azure/login@v1
215-
with:
216-
creds: ${{ secrets.AZURE_CREDENTIALS }}
217-
218-
- name: Set up ESRP client
219-
shell: pwsh
114+
- name: Create and sign product archive
220115
env:
221-
AZURE_VAULT: ${{ secrets.AZURE_VAULT }}
222-
AUTH_CERT: ${{ secrets.AZURE_VAULT_AUTH_CERT_NAME }}
223-
REQUEST_SIGNING_CERT: ${{ secrets.AZURE_VAULT_REQUEST_SIGNING_CERT_NAME }}
116+
I3: ${{ secrets.APPLE_INSTALLER_SIGNING_IDENTITY }}
224117
run: |
225-
.github\set_up_esrp.ps1
226-
227-
- name: Sign package
228-
shell: pwsh
229-
env:
230-
AZURE_AAD_ID: ${{ secrets.AZURE_AAD_ID }}
231-
APPLE_KEY_CODE: ${{ secrets.APPLE_KEY_CODE }}
232-
APPLE_SIGNING_OP_CODE: ${{ secrets.APPLE_SIGNING_OPERATION_CODE }}
233-
run: |
234-
python .github\run_esrp_signing.py pkg $env:APPLE_KEY_CODE $env:APPLE_SIGNING_OP_CODE
235-
236-
- name: Unzip signed package
237-
shell: pwsh
238-
run: |
239-
mkdir unsigned
240-
Expand-Archive -LiteralPath signed\gcm-pkg.zip -DestinationPath .\unsigned -Force
241-
Remove-Item signed\gcm-pkg.zip -Force
118+
src/osx/Installer.Mac/dist.sh --package-path=components \
119+
--version="${{ needs.prereqs.outputs.version }}" \
120+
--runtime="${{ matrix.runtime }}" \
121+
--output="pkg/gcm-${{ matrix.runtime }}-${{ needs.prereqs.outputs.version }}.pkg" \
122+
--identity="$I3" || exit 1
242123
243-
- name: Notarize signed package
244-
shell: pwsh
124+
- name: Notarize product archive
245125
env:
246-
AZURE_AAD_ID: ${{ secrets.AZURE_AAD_ID }}
247-
APPLE_KEY_CODE: ${{ secrets.APPLE_KEY_CODE }}
248-
APPLE_NOTARIZATION_OP_CODE: ${{ secrets.APPLE_NOTARIZATION_OPERATION_CODE }}
126+
N4: ${{ secrets.APPLE_KEYCHAIN_PROFILE }}
249127
run: |
250-
python .github\run_esrp_signing.py unsigned $env:APPLE_KEY_CODE $env:APPLE_NOTARIZATION_OP_CODE --params 'BundleId' 'com.microsoft.gitcredentialmanager'
128+
src/osx/Installer.Mac/notarize.sh \
129+
--package="pkg/gcm-${{ matrix.runtime }}-${{ needs.prereqs.outputs.version }}.pkg" \
130+
--keychain-profile="$N4"
251131
252-
- name: Publish signed package
132+
- name: Upload artifacts
253133
uses: actions/upload-artifact@v3
254134
with:
255-
name: ${{ matrix.runtime }}-sign
256-
path: signed/*.pkg
135+
name: macos-${{ matrix.runtime }}-artifacts
136+
path: |
137+
./pkg/*
138+
./symbols/*
139+
./payload/*
257140
258141
# ================================
259142
# Windows
@@ -624,7 +507,7 @@ jobs:
624507
command: git-credential-manager
625508
description: linux
626509
- os: macos-latest
627-
artifact: osx-x64-sign
510+
artifact: macos-osx-x64-artifacts
628511
command: git-credential-manager
629512
description: osx-x64
630513
- os: windows-latest
@@ -640,7 +523,7 @@ jobs:
640523
command: git-credential-manager
641524
description: dotnet-tool
642525
runs-on: ${{ matrix.component.os }}
643-
needs: [ osx-sign, win-sign, create-linux-artifacts, dotnet-tool-sign ]
526+
needs: [ create-macos-artifacts, win-sign, create-linux-artifacts, dotnet-tool-sign ]
644527
steps:
645528
- uses: actions/checkout@v4
646529

@@ -670,15 +553,15 @@ jobs:
670553
if: contains(matrix.component.description, 'linux')
671554
run: |
672555
# Ensure we find only the source tarball, not the symbols
673-
tarpath=$(find ./tar -name '*[[:digit:]].tar.gz')
556+
tarpath=$(find . -name '*[[:digit:]].tar.gz')
674557
tar -xvf $tarpath -C /usr/local/bin
675558
"${{ matrix.component.command }}" configure
676559
677560
- name: Install macOS
678561
if: contains(matrix.component.description, 'osx-x64')
679562
run: |
680563
# Only validate x64, given arm64 agents are not available
681-
pkgpath=$(find ./*.pkg)
564+
pkgpath=$(find ./pkg/*.pkg)
682565
sudo installer -pkg $pkgpath -target /
683566
684567
- name: Install .NET tool
@@ -716,13 +599,14 @@ jobs:
716599

717600
- name: Archive macOS payload and symbols
718601
run: |
602+
version="${{ needs.prereqs.outputs.version }}"
719603
mkdir osx-payload-and-symbols
720604
721-
tar -C osx-x64-payload-sign -czf osx-payload-and-symbols/gcm-osx-x64-$VERSION.tar.gz .
722-
tar -C tmp.osx-x64-build/symbols -czf osx-payload-and-symbols/gcm-osx-x64-$VERSION-symbols.tar.gz .
605+
tar -C macos-osx-x64-artifacts/payload -czf osx-payload-and-symbols/gcm-osx-x64-$version.tar.gz .
606+
tar -C macos-osx-x64-artifacts/symbols -czf osx-payload-and-symbols/gcm-osx-x64-$version-symbols.tar.gz .
723607
724-
tar -C osx-arm64-payload-sign -czf osx-payload-and-symbols/gcm-osx-arm64-$VERSION.tar.gz .
725-
tar -C tmp.osx-arm64-build/symbols -czf osx-payload-and-symbols/gcm-osx-arm64-$VERSION-symbols.tar.gz .
608+
tar -C macos-osx-arm64-artifacts -czf osx-payload-and-symbols/gcm-osx-arm64-$version.tar.gz .
609+
tar -C macos-osx-arm64-artifacts/symbols -czf osx-payload-and-symbols/gcm-osx-arm64-$version-symbols.tar.gz .
726610
727611
- name: Archive Windows payload and symbols
728612
run: |
@@ -780,8 +664,8 @@ jobs:
780664
uploadDirectoryToRelease('win-x86-payload-and-symbols'),
781665
782666
// Upload macOS artifacts
783-
uploadDirectoryToRelease('osx-x64-sign'),
784-
uploadDirectoryToRelease('osx-arm64-sign'),
667+
uploadDirectoryToRelease('macos-osx-x64-artifacts/pkg'),
668+
uploadDirectoryToRelease('macos-osx-arm64-artifacts/pkg'),
785669
uploadDirectoryToRelease('osx-payload-and-symbols'),
786670
787671
// Upload Linux artifacts

.github/run_developer_signing.sh renamed to src/osx/Installer.Mac/codesign.sh

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@ for f in *
2626
do
2727
macho=$(file --mime $f | grep mach)
2828
# Runtime sign dylibs and Mach-O binaries
29-
if [[ $f == *.dylib ]] || [ ! -z "$macho" ];
30-
then
31-
echo "Runtime Signing $f"
29+
if [[ $f == *.dylib ]] || [ ! -z "$macho" ];
30+
then
31+
echo "Runtime Signing $f"
3232
codesign -s "$DEVELOPER_ID" $f --timestamp --force --options=runtime --entitlements $ENTITLEMENTS_FILE
3333
elif [ -d "$f" ];
3434
then
@@ -39,8 +39,8 @@ do
3939
codesign -s "$DEVELOPER_ID" $i --timestamp --force
4040
done
4141
cd ..
42-
else
42+
else
4343
echo "Signing $f"
4444
codesign -s "$DEVELOPER_ID" $f --timestamp --force
4545
fi
46-
done
46+
done

0 commit comments

Comments
 (0)