Skip to content

Commit 844e8a8

Browse files
committed
Enhance macOS DMG workflow with optional Developer ID signing and notarization steps, including support for both API key and Apple ID methods. Added verification of permissions and Info.plist, along with improved error handling for signing processes.
1 parent feda6ac commit 844e8a8

File tree

1 file changed

+108
-0
lines changed

1 file changed

+108
-0
lines changed

.github/workflows/macos-dmg.yml

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,44 @@ jobs:
312312
codesign --force --deep --sign - --timestamp=none "$APP"
313313
codesign --verify --deep --verbose=2 "$APP" || (codesign --display --verbose=5 "$APP"; exit 1)
314314
315+
- name: Verify permissions and Info.plist
316+
run: |
317+
set -euxo pipefail
318+
APP="dist/SSH Studio.app"
319+
chmod +x "$APP/Contents/MacOS/ssh-studio"
320+
plutil -lint "$APP/Contents/Info.plist"
321+
# Show signature and linkage (non-fatal)
322+
codesign -dv --verbose=4 "$APP" || true
323+
otool -L "$APP/Contents/MacOS/ssh-studio" || true
324+
325+
- name: Gatekeeper assessment (non-fatal)
326+
run: |
327+
set -euxo pipefail
328+
APP="dist/SSH Studio.app"
329+
spctl --assess --type execute -v "$APP" || true
330+
331+
- name: Developer ID sign app (optional)
332+
env:
333+
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }}
334+
APPLE_DEVELOPER_CERT_BASE64: ${{ secrets.APPLE_DEVELOPER_CERT_BASE64 }}
335+
APPLE_DEVELOPER_CERT_PASSWORD: ${{ secrets.APPLE_DEVELOPER_CERT_PASSWORD }}
336+
run: |
337+
set -euxo pipefail
338+
APP="dist/SSH Studio.app"
339+
if [ -z "${APPLE_SIGNING_IDENTITY:-}" ] || [ -z "${APPLE_DEVELOPER_CERT_BASE64:-}" ] || [ -z "${APPLE_DEVELOPER_CERT_PASSWORD:-}" ]; then
340+
echo "Signing secrets not provided; skipping Developer ID signing."; exit 0; fi
341+
KEYCHAIN_PATH="$RUNNER_TEMP/build.keychain-db"
342+
KEYCHAIN_PWD="$(openssl rand -hex 12)"
343+
security create-keychain -p "$KEYCHAIN_PWD" "$KEYCHAIN_PATH"
344+
security set-keychain-settings -lut 21600 "$KEYCHAIN_PATH"
345+
security unlock-keychain -p "$KEYCHAIN_PWD" "$KEYCHAIN_PATH"
346+
echo "$APPLE_DEVELOPER_CERT_BASE64" | base64 --decode > "$RUNNER_TEMP/dev_cert.p12"
347+
security import "$RUNNER_TEMP/dev_cert.p12" -k "$KEYCHAIN_PATH" -P "$APPLE_DEVELOPER_CERT_PASSWORD" -A
348+
security list-keychain -d user -s "$KEYCHAIN_PATH" login.keychain-db
349+
# Re-sign app with Developer ID (replaces ad-hoc)
350+
codesign --force --deep --options runtime --timestamp --sign "$APPLE_SIGNING_IDENTITY" "$APP"
351+
codesign --verify --deep --strict --verbose=2 "$APP"
352+
315353
316354
- name: Create DMG
317355
run: |
@@ -324,6 +362,76 @@ jobs:
324362
ln -s /Applications dmgroot/Applications
325363
hdiutil create -volname "SSH Studio" -srcfolder dmgroot -ov -fs HFS+ "ssh-studio-${VER}-${ARCH}.dmg"
326364
365+
- name: Developer ID sign DMG (optional)
366+
env:
367+
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }}
368+
APPLE_DEVELOPER_CERT_BASE64: ${{ secrets.APPLE_DEVELOPER_CERT_BASE64 }}
369+
APPLE_DEVELOPER_CERT_PASSWORD: ${{ secrets.APPLE_DEVELOPER_CERT_PASSWORD }}
370+
run: |
371+
set -euxo pipefail
372+
if [ -z "${APPLE_SIGNING_IDENTITY:-}" ] || [ -z "${APPLE_DEVELOPER_CERT_BASE64:-}" ] || [ -z "${APPLE_DEVELOPER_CERT_PASSWORD:-}" ]; then
373+
echo "Signing secrets not provided; skipping DMG signing."; exit 0; fi
374+
VER=$(sed -n "s/.*version: '\([^']*\)'.*/\1/p" meson.build | head -n1)
375+
ARCH=$(uname -m)
376+
DMG="ssh-studio-${VER}-${ARCH}.dmg"
377+
KEYCHAIN_PATH="$RUNNER_TEMP/build.keychain-db"
378+
if [ ! -f "$RUNNER_TEMP/dev_cert.p12" ]; then
379+
echo "$APPLE_DEVELOPER_CERT_BASE64" | base64 --decode > "$RUNNER_TEMP/dev_cert.p12"
380+
fi
381+
if [ ! -f "$KEYCHAIN_PATH" ]; then
382+
KEYCHAIN_PWD="$(openssl rand -hex 12)"
383+
security create-keychain -p "$KEYCHAIN_PWD" "$KEYCHAIN_PATH"
384+
security set-keychain-settings -lut 21600 "$KEYCHAIN_PATH"
385+
security unlock-keychain -p "$KEYCHAIN_PWD" "$KEYCHAIN_PATH"
386+
security import "$RUNNER_TEMP/dev_cert.p12" -k "$KEYCHAIN_PATH" -P "$APPLE_DEVELOPER_CERT_PASSWORD" -A
387+
security list-keychain -d user -s "$KEYCHAIN_PATH" login.keychain-db
388+
fi
389+
codesign --force --timestamp --sign "$APPLE_SIGNING_IDENTITY" "$DMG"
390+
spctl --assess --type open -v "$DMG" || true
391+
392+
- name: Notarize DMG with notarytool (API key) (optional)
393+
env:
394+
NOTARYTOOL_KEY_ID: ${{ secrets.NOTARYTOOL_KEY_ID }}
395+
NOTARYTOOL_ISSUER_ID: ${{ secrets.NOTARYTOOL_ISSUER_ID }}
396+
NOTARYTOOL_PRIVATE_KEY: ${{ secrets.NOTARYTOOL_PRIVATE_KEY }}
397+
run: |
398+
set -euxo pipefail
399+
if [ -z "${NOTARYTOOL_KEY_ID:-}" ] || [ -z "${NOTARYTOOL_ISSUER_ID:-}" ] || [ -z "${NOTARYTOOL_PRIVATE_KEY:-}" ]; then
400+
echo "Notary API key secrets not provided; skipping API-key notarization."; exit 0; fi
401+
VER=$(sed -n "s/.*version: '\([^']*\)'.*/\1/p" meson.build | head -n1)
402+
ARCH=$(uname -m)
403+
DMG="ssh-studio-${VER}-${ARCH}.dmg"
404+
KEYFILE="$RUNNER_TEMP/AuthKey.p8"
405+
echo "$NOTARYTOOL_PRIVATE_KEY" > "$KEYFILE"
406+
xcrun notarytool submit "$DMG" \
407+
--key "$KEYFILE" \
408+
--key-id "$NOTARYTOOL_KEY_ID" \
409+
--issuer "$NOTARYTOOL_ISSUER_ID" \
410+
--wait
411+
xcrun stapler staple "$DMG"
412+
413+
- name: Notarize DMG with notarytool (Apple ID) (optional)
414+
env:
415+
APPLE_ID: ${{ secrets.APPLE_ID }}
416+
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
417+
APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }}
418+
run: |
419+
set -euxo pipefail
420+
# Only run if API key secrets are missing but Apple ID-based secrets are present
421+
if [ -n "${NOTARYTOOL_KEY_ID:-}" ] && [ -n "${NOTARYTOOL_ISSUER_ID:-}" ] && [ -n "${NOTARYTOOL_PRIVATE_KEY:-}" ]; then
422+
echo "API key provided; skipping Apple ID notarization path."; exit 0; fi
423+
if [ -z "${APPLE_ID:-}" ] || [ -z "${APPLE_TEAM_ID:-}" ] || [ -z "${APPLE_APP_SPECIFIC_PASSWORD:-}" ]; then
424+
echo "Apple ID notarization secrets not provided; skipping."; exit 0; fi
425+
VER=$(sed -n "s/.*version: '\([^']*\)'.*/\1/p" meson.build | head -n1)
426+
ARCH=$(uname -m)
427+
DMG="ssh-studio-${VER}-${ARCH}.dmg"
428+
xcrun notarytool submit "$DMG" \
429+
--apple-id "$APPLE_ID" \
430+
--team-id "$APPLE_TEAM_ID" \
431+
--password "$APPLE_APP_SPECIFIC_PASSWORD" \
432+
--wait
433+
xcrun stapler staple "$DMG"
434+
327435
328436
- name: Upload artifact
329437
uses: actions/upload-artifact@v4

0 commit comments

Comments
 (0)