@@ -122,46 +122,91 @@ jobs:
122122 APPLE_API_KEY_BASE64 : ${{ secrets.GWS_APPLE_API_KEY_BASE64 }}
123123 APPLE_API_KEY : ${{ secrets.GWS_APPLE_API_KEY }}
124124
125- - name : Configure macOS installer signing
125+ - name : Import signing certificates
126126 env :
127- APPLE_SIGN_IDENTITY : ${{ secrets.GWS_APPLE_SIGN_IDENTITY }}
127+ APPLICATION_P12 : ${{ secrets.GWS_APPLE_SIGN_APPLICATION_P12 }}
128+ INSTALLER_P12 : ${{ secrets.GWS_APPLE_SIGN_INSTALLER_P12 }}
129+ P12_PASSWORD : ${{ secrets.GWS_APPLE_SIGN_PW }}
128130 run : |
129- cat <<EOF >> src/Cargo.toml
130-
131- [package.metadata.packager.macos]
132- signing-identity = "${APPLE_SIGN_IDENTITY}"
133- entitlements = "entitlements.plist"
134- EOF
135-
136- - name : Install cargo-packager
137- run : cargo install cargo-packager --locked
131+ KEYCHAIN_PATH="$RUNNER_TEMP/signing.keychain-db"
132+ KEYCHAIN_PW="$(openssl rand -hex 32)"
133+ security create-keychain -p "$KEYCHAIN_PW" "$KEYCHAIN_PATH"
134+ security set-keychain-settings "$KEYCHAIN_PATH"
135+ security unlock-keychain -p "$KEYCHAIN_PW" "$KEYCHAIN_PATH"
136+ echo -n "$APPLICATION_P12" | base64 --decode -o "$RUNNER_TEMP/app.p12"
137+ echo -n "$INSTALLER_P12" | base64 --decode -o "$RUNNER_TEMP/inst.p12"
138+ security import "$RUNNER_TEMP/app.p12" -P "$P12_PASSWORD" -k "$KEYCHAIN_PATH" -T /usr/bin/codesign -T /usr/bin/pkgbuild
139+ security import "$RUNNER_TEMP/inst.p12" -P "$P12_PASSWORD" -k "$KEYCHAIN_PATH" -T /usr/bin/codesign -T /usr/bin/pkgbuild
140+ security set-key-partition-list -S apple-tool:,apple: -s -k "$KEYCHAIN_PW" "$KEYCHAIN_PATH"
141+ security list-keychains -d user -s "$KEYCHAIN_PATH" $(security list-keychains -d user | tr -d '"')
142+
143+ - name : Compute version from tag
144+ run : |
145+ VERSION="${GITHUB_REF_NAME#v}"
146+ echo "VERSION=$VERSION" >> "$GITHUB_ENV"
138147
139148 - name : Build ggsql binary (x86_64)
140149 run : cargo build --release --bin ggsql --bin ggsql-jupyter
141150
142- - name : Bundle and sign dynamic library dependencies
151+ - name : Bundle dynamic library dependencies
143152 run : |
144- dylibbundler -cd -of -b -x target/release/ggsql -d ./libs/ -p @executable_path/../Resources/libs/
145- dylibbundler -cd -of -b -x target/release/ggsql-jupyter -d ./libs/ -p @executable_path/../Resources/libs/
153+ dylibbundler -cd -of -b -x target/release/ggsql -d ./libs/ -p " @executable_path/../lib/ggsql$VERSION/"
154+ dylibbundler -cd -of -b -x target/release/ggsql-jupyter -d ./libs/ -p " @executable_path/../lib/ggsql$VERSION/"
146155
147- - name : Ad-hoc sign binaries
156+ - name : Sign binaries and dylibs (Developer ID Application)
157+ env :
158+ SIGN_ID : " Developer ID Application: ${{ secrets.GWS_APPLE_SIGN_IDENTITY }}"
148159 run : |
149- codesign --force --sign - target/release/ggsql
150- codesign --force --sign - target/release/ggsql-jupyter
151-
152- - name : Build DMG installer (x86_64)
153- run : cargo packager --release --formats dmg
160+ # Sign bundled dylibs first (inside-out), replacing dylibbundler's ad-hoc sigs
161+ find ./libs -type f \( -name "*.dylib" -o -name "*.so" \) -print0 | \
162+ xargs -0 -I{} codesign --force --options runtime --timestamp --sign "$SIGN_ID" "{}"
163+ # Then sign the executables with hardened runtime + entitlements
164+ codesign --force --options runtime --timestamp \
165+ --entitlements src/entitlements.plist \
166+ --sign "$SIGN_ID" target/release/ggsql
167+ codesign --force --options runtime --timestamp \
168+ --entitlements src/entitlements.plist \
169+ --sign "$SIGN_ID" target/release/ggsql-jupyter
170+
171+ - name : Build and notarize PKG installer (x86_64)
172+ # NOTE: --sign uses the Developer ID *Installer* cert (signs .pkg only),
173+ # distinct from the Developer ID Application cert used to sign Mach-O above.
154174 env :
155- APPLE_CERTIFICATE : ${{ secrets.GWS_APPLE_SIGN_P12 }}
156- APPLE_CERTIFICATE_PASSWORD : ${{ secrets.GWS_APPLE_SIGN_PW }}
175+ SIGN_ID : " Developer ID Installer: ${{ secrets.GWS_APPLE_SIGN_IDENTITY }}"
157176 APPLE_API_KEY : ${{ secrets.GWS_APPLE_API_KEY }}
158177 APPLE_API_ISSUER : ${{ secrets.GWS_APPLE_API_ISSUER }}
159-
160- - name : Upload DMG installer (x86_64)
178+ run : |
179+ PKG_NAME="ggsql_${VERSION}_x86_64.pkg"
180+ mkdir -p pkg-payload/usr/local/bin "pkg-payload/usr/local/lib/ggsql$VERSION"
181+ cp target/release/ggsql pkg-payload/usr/local/bin/
182+ cp target/release/ggsql-jupyter pkg-payload/usr/local/bin/
183+ cp -R ./libs/. "pkg-payload/usr/local/lib/ggsql$VERSION/"
184+ mkdir -p pkg-scripts
185+ cat > pkg-scripts/postinstall <<EOF
186+ #!/bin/sh
187+ mkdir -p /usr/local/bin /usr/local/lib/ggsql$VERSION
188+ EOF
189+ chmod 755 pkg-scripts/postinstall
190+ pkgbuild \
191+ --root ./pkg-payload \
192+ --install-location / \
193+ --identifier co.posit.ggsql \
194+ --version "$VERSION" \
195+ --scripts ./pkg-scripts \
196+ --sign "$SIGN_ID" \
197+ "$PKG_NAME"
198+ xcrun notarytool submit "$PKG_NAME" \
199+ --key ~/.private_keys/AuthKey_${APPLE_API_KEY}.p8 \
200+ --key-id "$APPLE_API_KEY" \
201+ --issuer "$APPLE_API_ISSUER" \
202+ --wait
203+ xcrun stapler staple "$PKG_NAME"
204+
205+ - name : Upload PKG installer (x86_64)
161206 uses : actions/upload-artifact@v4
162207 with :
163- name : ggsql-macos-dmg -x86_64
164- path : src/target/release/packager/*.dmg
208+ name : ggsql-macos-pkg -x86_64
209+ path : ggsql_*_x86_64.pkg
165210 retention-days : 30
166211
167212 build-macos-aarch64 :
@@ -200,41 +245,91 @@ jobs:
200245 APPLE_API_KEY_BASE64 : ${{ secrets.GWS_APPLE_API_KEY_BASE64 }}
201246 APPLE_API_KEY : ${{ secrets.GWS_APPLE_API_KEY }}
202247
203- - name : Configure macOS installer signing
248+ - name : Import signing certificates
204249 env :
205- APPLE_SIGN_IDENTITY : ${{ secrets.GWS_APPLE_SIGN_IDENTITY }}
250+ APPLICATION_P12 : ${{ secrets.GWS_APPLE_SIGN_APPLICATION_P12 }}
251+ INSTALLER_P12 : ${{ secrets.GWS_APPLE_SIGN_INSTALLER_P12 }}
252+ P12_PASSWORD : ${{ secrets.GWS_APPLE_SIGN_PW }}
206253 run : |
207- cat <<EOF >> src/Cargo.toml
208-
209- [package.metadata.packager.macos]
210- signing-identity = "${APPLE_SIGN_IDENTITY}"
211- entitlements = "entitlements.plist"
212- EOF
213-
214- - name : Install cargo-packager
215- run : cargo install cargo-packager --locked
254+ KEYCHAIN_PATH="$RUNNER_TEMP/signing.keychain-db"
255+ KEYCHAIN_PW="$(openssl rand -hex 32)"
256+ security create-keychain -p "$KEYCHAIN_PW" "$KEYCHAIN_PATH"
257+ security set-keychain-settings "$KEYCHAIN_PATH"
258+ security unlock-keychain -p "$KEYCHAIN_PW" "$KEYCHAIN_PATH"
259+ echo -n "$APPLICATION_P12" | base64 --decode -o "$RUNNER_TEMP/app.p12"
260+ echo -n "$INSTALLER_P12" | base64 --decode -o "$RUNNER_TEMP/inst.p12"
261+ security import "$RUNNER_TEMP/app.p12" -P "$P12_PASSWORD" -k "$KEYCHAIN_PATH" -T /usr/bin/codesign -T /usr/bin/pkgbuild
262+ security import "$RUNNER_TEMP/inst.p12" -P "$P12_PASSWORD" -k "$KEYCHAIN_PATH" -T /usr/bin/codesign -T /usr/bin/pkgbuild
263+ security set-key-partition-list -S apple-tool:,apple: -s -k "$KEYCHAIN_PW" "$KEYCHAIN_PATH"
264+ security list-keychains -d user -s "$KEYCHAIN_PATH" $(security list-keychains -d user | tr -d '"')
265+
266+ - name : Compute version from tag
267+ run : |
268+ VERSION="${GITHUB_REF_NAME#v}"
269+ echo "VERSION=$VERSION" >> "$GITHUB_ENV"
216270
217271 - name : Build ggsql binary (aarch64)
218272 run : cargo build --release --bin ggsql --bin ggsql-jupyter
219273
220- - name : Bundle and sign dynamic library dependencies
274+ - name : Bundle dynamic library dependencies
221275 run : |
222- dylibbundler -cd -of -b -x target/release/ggsql -d ./libs/ -p @executable_path/../Resources/libs/
223- dylibbundler -cd -of -b -x target/release/ggsql-jupyter -d ./libs/ -p @executable_path/../Resources/libs/
276+ dylibbundler -cd -of -b -x target/release/ggsql -d ./libs/ -p " @executable_path/../lib/ggsql$VERSION/"
277+ dylibbundler -cd -of -b -x target/release/ggsql-jupyter -d ./libs/ -p " @executable_path/../lib/ggsql$VERSION/"
224278
225- - name : Build DMG installer (aarch64)
226- run : cargo packager --release --formats dmg
279+ - name : Sign binaries and dylibs (Developer ID Application)
227280 env :
228- APPLE_CERTIFICATE : ${{ secrets.GWS_APPLE_SIGN_P12 }}
229- APPLE_CERTIFICATE_PASSWORD : ${{ secrets.GWS_APPLE_SIGN_PW }}
281+ SIGN_ID : " Developer ID Application: ${{ secrets.GWS_APPLE_SIGN_IDENTITY }}"
282+ run : |
283+ # Sign bundled dylibs first (inside-out), replacing dylibbundler's ad-hoc sigs
284+ find ./libs -type f \( -name "*.dylib" -o -name "*.so" \) -print0 | \
285+ xargs -0 -I{} codesign --force --options runtime --timestamp --sign "$SIGN_ID" "{}"
286+ # Then sign the executables with hardened runtime + entitlements
287+ codesign --force --options runtime --timestamp \
288+ --entitlements src/entitlements.plist \
289+ --sign "$SIGN_ID" target/release/ggsql
290+ codesign --force --options runtime --timestamp \
291+ --entitlements src/entitlements.plist \
292+ --sign "$SIGN_ID" target/release/ggsql-jupyter
293+
294+ - name : Build and notarize PKG installer (aarch64)
295+ # NOTE: --sign uses the Developer ID *Installer* cert (signs .pkg only),
296+ # distinct from the Developer ID Application cert used to sign Mach-O above.
297+ env :
298+ SIGN_ID : " Developer ID Installer: ${{ secrets.GWS_APPLE_SIGN_IDENTITY }}"
230299 APPLE_API_KEY : ${{ secrets.GWS_APPLE_API_KEY }}
231300 APPLE_API_ISSUER : ${{ secrets.GWS_APPLE_API_ISSUER }}
232-
233- - name : Upload DMG installer (aarch64)
301+ run : |
302+ PKG_NAME="ggsql_${VERSION}_aarch64.pkg"
303+ mkdir -p pkg-payload/usr/local/bin "pkg-payload/usr/local/lib/ggsql$VERSION"
304+ cp target/release/ggsql pkg-payload/usr/local/bin/
305+ cp target/release/ggsql-jupyter pkg-payload/usr/local/bin/
306+ cp -R ./libs/. "pkg-payload/usr/local/lib/ggsql$VERSION/"
307+ mkdir -p pkg-scripts
308+ cat > pkg-scripts/postinstall <<EOF
309+ #!/bin/sh
310+ mkdir -p /usr/local/bin /usr/local/lib/ggsql$VERSION
311+ EOF
312+ chmod 755 pkg-scripts/postinstall
313+ pkgbuild \
314+ --root ./pkg-payload \
315+ --install-location / \
316+ --identifier co.posit.ggsql \
317+ --version "$VERSION" \
318+ --scripts ./pkg-scripts \
319+ --sign "$SIGN_ID" \
320+ "$PKG_NAME"
321+ xcrun notarytool submit "$PKG_NAME" \
322+ --key ~/.private_keys/AuthKey_${APPLE_API_KEY}.p8 \
323+ --key-id "$APPLE_API_KEY" \
324+ --issuer "$APPLE_API_ISSUER" \
325+ --wait
326+ xcrun stapler staple "$PKG_NAME"
327+
328+ - name : Upload PKG installer (aarch64)
234329 uses : actions/upload-artifact@v4
235330 with :
236- name : ggsql-macos-dmg -aarch64
237- path : src/target/release/packager/*.dmg
331+ name : ggsql-macos-pkg -aarch64
332+ path : ggsql_*_aarch64.pkg
238333 retention-days : 30
239334
240335 build-linux-x86_64 :
@@ -412,7 +507,7 @@ jobs:
412507 files : |
413508 artifacts/**/*.exe
414509 artifacts/**/*.msi
415- artifacts/**/*.dmg
510+ artifacts/**/*.pkg
416511 artifacts/**/*.deb
417512 env :
418513 GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
0 commit comments