44 push :
55 tags :
66 - " v*"
7+ workflow_dispatch :
8+ inputs :
9+ tag_name :
10+ description : " Draft verification tag to create, e.g. verify-signing-2026-04-16"
11+ required : true
12+ type : string
713
814permissions :
9- contents : write
15+ contents : read
1016
1117jobs :
1218 test :
1319 runs-on : ubuntu-latest
20+ permissions :
21+ contents : read
1422
1523 steps :
1624 - uses : actions/checkout@v4
@@ -25,18 +33,26 @@ jobs:
2533
2634 build :
2735 needs : test
36+ permissions :
37+ contents : read
2838 strategy :
2939 matrix :
3040 include :
3141 - target : bun-darwin-arm64
32- artifact : polar-darwin-arm64
33- os : ubuntu-latest
42+ archive : polar-darwin-arm64.zip
43+ os : macos-15
44+ sign : true
45+ notarize : true
3446 - target : bun-darwin-x64
35- artifact : polar-darwin-x64
36- os : ubuntu-latest
47+ archive : polar-darwin-x64.zip
48+ os : macos-15
49+ sign : true
50+ notarize : true
3751 - target : bun-linux-x64
38- artifact : polar-linux-x64
52+ archive : polar-linux-x64.tar.gz
3953 os : ubuntu-latest
54+ sign : false
55+ notarize : false
4056
4157 runs-on : ${{ matrix.os }}
4258
@@ -49,33 +65,108 @@ jobs:
4965
5066 - run : bun install
5167
68+ - name : Validate macOS signing configuration
69+ if : ${{ matrix.sign }}
70+ env :
71+ MACOS_CERTIFICATE_P12_BASE64 : ${{ secrets.MACOS_CERTIFICATE_P12_BASE64 }}
72+ MACOS_CERTIFICATE_PASSWORD : ${{ secrets.MACOS_CERTIFICATE_PASSWORD }}
73+ MACOS_SIGNING_IDENTITY : ${{ secrets.MACOS_SIGNING_IDENTITY }}
74+ APP_STORE_CONNECT_API_KEY_P8 : ${{ secrets.APP_STORE_CONNECT_API_KEY_P8 }}
75+ APP_STORE_CONNECT_API_KEY_ID : ${{ secrets.APP_STORE_CONNECT_API_KEY_ID }}
76+ APP_STORE_CONNECT_ISSUER_ID : ${{ secrets.APP_STORE_CONNECT_ISSUER_ID }}
77+ run : |
78+ test -n "$MACOS_CERTIFICATE_P12_BASE64" || { echo "Missing MACOS_CERTIFICATE_P12_BASE64 secret"; exit 1; }
79+ test -n "$MACOS_CERTIFICATE_PASSWORD" || { echo "Missing MACOS_CERTIFICATE_PASSWORD secret"; exit 1; }
80+ test -n "$MACOS_SIGNING_IDENTITY" || { echo "Missing MACOS_SIGNING_IDENTITY secret"; exit 1; }
81+ test -n "$APP_STORE_CONNECT_API_KEY_P8" || { echo "Missing APP_STORE_CONNECT_API_KEY_P8 secret"; exit 1; }
82+ test -n "$APP_STORE_CONNECT_API_KEY_ID" || { echo "Missing APP_STORE_CONNECT_API_KEY_ID secret"; exit 1; }
83+ test -n "$APP_STORE_CONNECT_ISSUER_ID" || { echo "Missing APP_STORE_CONNECT_ISSUER_ID secret"; exit 1; }
84+
85+ - name : Import macOS signing certificate
86+ if : ${{ matrix.sign }}
87+ uses : apple-actions/import-codesign-certs@v6
88+ with :
89+ p12-file-base64 : ${{ secrets.MACOS_CERTIFICATE_P12_BASE64 }}
90+ p12-password : ${{ secrets.MACOS_CERTIFICATE_PASSWORD }}
91+
5292 - name : Build binary
5393 run : bun build ./src/cli.ts --compile --target=${{ matrix.target }} --outfile polar
5494
95+ - name : Sign macOS binary
96+ if : ${{ matrix.sign }}
97+ env :
98+ MACOS_SIGNING_IDENTITY : ${{ secrets.MACOS_SIGNING_IDENTITY }}
99+ run : |
100+ codesign --force --options runtime \
101+ --entitlements ./.github/macos-entitlements.plist \
102+ --sign "$MACOS_SIGNING_IDENTITY" \
103+ --timestamp \
104+ ./polar
105+
106+ - name : Verify macOS signature
107+ if : ${{ matrix.sign }}
108+ run : codesign --verify --strict --verbose=2 ./polar
109+
110+ - name : Write App Store Connect API key
111+ if : ${{ matrix.notarize }}
112+ env :
113+ APP_STORE_CONNECT_API_KEY_P8 : ${{ secrets.APP_STORE_CONNECT_API_KEY_P8 }}
114+ APP_STORE_CONNECT_API_KEY_ID : ${{ secrets.APP_STORE_CONNECT_API_KEY_ID }}
115+ run : |
116+ key_path="$RUNNER_TEMP/AuthKey_${APP_STORE_CONNECT_API_KEY_ID}.p8"
117+ printf '%s' "$APP_STORE_CONNECT_API_KEY_P8" > "$key_path"
118+ chmod 600 "$key_path"
119+ echo "APP_STORE_CONNECT_API_KEY_PATH=$key_path" >> "$GITHUB_ENV"
120+
55121 - name : Package binary
56- run : tar -czf ${{ matrix.artifact }}.tar.gz polar
122+ run : |
123+ if [[ "${{ matrix.archive }}" == *.zip ]]; then
124+ ditto -c -k --keepParent polar "${{ matrix.archive }}"
125+ else
126+ tar -czf "${{ matrix.archive }}" polar
127+ fi
128+
129+ - name : Notarize macOS archive
130+ if : ${{ matrix.notarize }}
131+ env :
132+ APP_STORE_CONNECT_API_KEY_ID : ${{ secrets.APP_STORE_CONNECT_API_KEY_ID }}
133+ APP_STORE_CONNECT_ISSUER_ID : ${{ secrets.APP_STORE_CONNECT_ISSUER_ID }}
134+ run : |
135+ xcrun notarytool submit "${{ matrix.archive }}" \
136+ --key "$APP_STORE_CONNECT_API_KEY_PATH" \
137+ --key-id "$APP_STORE_CONNECT_API_KEY_ID" \
138+ --issuer "$APP_STORE_CONNECT_ISSUER_ID" \
139+ --wait
57140
58141 - uses : actions/upload-artifact@v4
59142 with :
60- name : ${{ matrix.artifact }}
61- path : ${{ matrix.artifact }}.tar.gz
143+ name : ${{ matrix.archive }}
144+ path : ${{ matrix.archive }}
62145
63146 release :
64147 needs : build
65148 runs-on : ubuntu-latest
149+ permissions :
150+ contents : write
66151
67152 steps :
68153 - uses : actions/download-artifact@v4
69154 with :
70155 merge-multiple : true
71156
72157 - name : Generate checksums
73- run : sha256sum *.tar.gz > checksums.txt
158+ run : sha256sum *.tar.gz *.zip > checksums.txt
74159
75160 - name : Create GitHub Release
76161 uses : softprops/action-gh-release@v2
77162 with :
163+ tag_name : ${{ github.event_name == 'workflow_dispatch' && inputs.tag_name || github.ref_name }}
164+ target_commitish : ${{ github.sha }}
165+ draft : ${{ github.event_name == 'workflow_dispatch' }}
166+ prerelease : ${{ github.event_name == 'workflow_dispatch' }}
167+ name : ${{ github.event_name == 'workflow_dispatch' && format('Signing Verification {0}', inputs.tag_name) || github.ref_name }}
78168 files : |
79169 *.tar.gz
170+ *.zip
80171 checksums.txt
81172 generate_release_notes : true
0 commit comments