Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 11 additions & 7 deletions .github/workflows/auto-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ name: Auto-release
#
# Optional secrets (unsigned local-style build until these exist):
# MACOS_CERT_P12_BASE64, MACOS_CERT_PASSWORD Developer ID signing
# NOTARY_APPLE_ID, NOTARY_TEAM_ID, NOTARY_PASSWORD notarization
# NOTARY_KEY, NOTARY_KEY_ID, NOTARY_ISSUER_ID notarization (App Store
# Connect API key — the team Apple ID is Microsoft-federated, so
# app-specific passwords don't exist for it)
# TAP_DEPLOY_KEY SSH deploy key with write access to tutorintelligence/homebrew-tap
# SPARKLE_ED_PRIVATE_KEY signs update zips for the Sparkle appcast
on:
Expand Down Expand Up @@ -73,16 +75,18 @@ jobs:
fi

- name: Notarize and staple
if: steps.ver.outputs.next != '' && env.NOTARY_APPLE_ID != ''
if: steps.ver.outputs.next != '' && env.NOTARY_KEY_ID != ''
env:
NOTARY_APPLE_ID: ${{ secrets.NOTARY_APPLE_ID }}
NOTARY_TEAM_ID: ${{ secrets.NOTARY_TEAM_ID }}
NOTARY_PASSWORD: ${{ secrets.NOTARY_PASSWORD }}
NOTARY_KEY: ${{ secrets.NOTARY_KEY }}
NOTARY_KEY_ID: ${{ secrets.NOTARY_KEY_ID }}
NOTARY_ISSUER_ID: ${{ secrets.NOTARY_ISSUER_ID }}
run: |
echo "$NOTARY_KEY" > /tmp/notary_key.p8
ditto -c -k --keepParent dist/tingle.app dist/notarize.zip
xcrun notarytool submit dist/notarize.zip --apple-id "$NOTARY_APPLE_ID" \
--team-id "$NOTARY_TEAM_ID" --password "$NOTARY_PASSWORD" --wait
xcrun notarytool submit dist/notarize.zip --key /tmp/notary_key.p8 \
--key-id "$NOTARY_KEY_ID" --issuer "$NOTARY_ISSUER_ID" --wait
xcrun stapler staple dist/tingle.app
rm /tmp/notary_key.p8

- name: Package artifact
if: steps.ver.outputs.next != ''
Expand Down
6 changes: 4 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,5 +164,7 @@ SPARKLE_ED_PRIVATE_KEY repo secret and Josh's login keychain, account
tutorintelligence/homebrew-tap. `tools/test_next_version.py` covers the
version math. Until the Apple Developer secrets land the build is unsigned
but releases still cut. Optional secrets: MACOS_CERT_P12_BASE64,
MACOS_CERT_PASSWORD, NOTARY_APPLE_ID, NOTARY_TEAM_ID, NOTARY_PASSWORD,
TAP_DEPLOY_KEY (SSH deploy key that pushes the cask bump to tutorintelligence/homebrew-tap).
MACOS_CERT_PASSWORD, NOTARY_KEY / NOTARY_KEY_ID / NOTARY_ISSUER_ID (App
Store Connect API key — the team Apple ID is Microsoft-federated, so
app-specific passwords are unavailable), TAP_DEPLOY_KEY (SSH deploy key
that pushes the cask bump to tutorintelligence/homebrew-tap).
14 changes: 14 additions & 0 deletions packaging/entitlements.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<!-- Hardened runtime strips capabilities unless re-granted here.
Mic: beacon detection + dictation capture. Apple Events: the
summon-agent shell scripts drive apps via osascript, attributed
to tingle as the responsible process. Not sandboxed. -->
<key>com.apple.security.device.audio-input</key>
<true/>
<key>com.apple.security.automation.apple-events</key>
<true/>
</dict>
</plist>
18 changes: 17 additions & 1 deletion scripts/bundle.sh
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ cat > "$APP/Contents/Info.plist" <<PLIST
<string>3BlTef+CpeHVRaFJfuvpqt1XGbVZe1HDPo3C127U70E=</string>
<key>SUEnableAutomaticChecks</key>
<true/>
<key>NSAppleEventsUsageDescription</key>
<string>tingle's summon-agent button brings your coding app to the front.</string>
<key>NSMicrophoneUsageDescription</key>
<string>tingle listens to your line-in to detect the ting's ultrasonic signals and to transcribe dictation from its microphone.</string>
<key>NSHumanReadableCopyright</key>
Expand All @@ -80,5 +82,19 @@ cat > "$APP/Contents/Info.plist" <<PLIST
</plist>
PLIST

codesign --force --deep --sign "$IDENTITY" "$APP"
# Hardened runtime is REQUIRED for notarization; the entitlements re-grant
# mic capture and Apple Events under it. Sign Sparkle's nested code first
# (its XPC services must each carry hardened runtime), then the app.
if [ "$IDENTITY" != "-" ]; then
find "$APP/Contents/Frameworks/Sparkle.framework" \
\( -name "*.xpc" -o -name "*.app" \) -maxdepth 5 | while read -r NESTED; do
codesign --force --options runtime --sign "$IDENTITY" "$NESTED"
done
codesign --force --options runtime --sign "$IDENTITY" "$APP/Contents/Frameworks/Sparkle.framework"
codesign --force --options runtime \
--entitlements packaging/entitlements.plist \
--sign "$IDENTITY" "$APP"
else
codesign --force --deep --sign "$IDENTITY" "$APP"
fi
echo "built $APP (version $VERSION, signed: $IDENTITY)"
Loading