Skip to content

Commit a6d3db0

Browse files
Sign and notarize macOS builds; bump to 0.2.1
The desktop app is now signed and notarized via tauri-action. The CLI binary is signed with hardened runtime and notarized via notarytool (no stapling — bare binaries can't carry tickets, so Gatekeeper does an online check on first launch). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 5f3b649 commit a6d3db0

7 files changed

Lines changed: 75 additions & 13 deletions

File tree

.github/workflows/release.yml

Lines changed: 67 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,53 @@ jobs:
6262
if: runner.os == 'Windows'
6363
run: cp target/${{ matrix.target }}/release/ralph.exe ${{ matrix.artifact }}.exe
6464

65+
- name: Sign and notarize (macOS)
66+
if: runner.os == 'macOS'
67+
env:
68+
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
69+
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
70+
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }}
71+
APPLE_API_KEY: ${{ secrets.APPLE_API_KEY }}
72+
APPLE_API_ISSUER: ${{ secrets.APPLE_API_ISSUER }}
73+
APPLE_API_KEY_BASE64: ${{ secrets.APPLE_API_KEY_BASE64 }}
74+
ARTIFACT: ${{ matrix.artifact }}
75+
run: |
76+
set -euo pipefail
77+
78+
# Create a temporary keychain and import the signing certificate
79+
KEYCHAIN_PATH="$RUNNER_TEMP/signing.keychain-db"
80+
KEYCHAIN_PASSWORD=$(uuidgen)
81+
security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
82+
security set-keychain-settings -lut 21600 "$KEYCHAIN_PATH"
83+
security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
84+
85+
CERT_PATH="$RUNNER_TEMP/cert.p12"
86+
echo "$APPLE_CERTIFICATE" | base64 --decode > "$CERT_PATH"
87+
security import "$CERT_PATH" -k "$KEYCHAIN_PATH" -P "$APPLE_CERTIFICATE_PASSWORD" -T /usr/bin/codesign
88+
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
89+
security list-keychains -d user -s "$KEYCHAIN_PATH" $(security list-keychains -d user | tr -d '"')
90+
91+
# Sign the binary with hardened runtime and a secure timestamp
92+
codesign --force --options runtime --timestamp \
93+
--sign "$APPLE_SIGNING_IDENTITY" "$ARTIFACT"
94+
codesign --verify --verbose "$ARTIFACT"
95+
96+
# Notarize: zip, submit, wait. Bare binaries can't be stapled, so
97+
# Gatekeeper does an online check on first run instead.
98+
API_KEY_PATH="$RUNNER_TEMP/AuthKey.p8"
99+
echo "$APPLE_API_KEY_BASE64" | base64 --decode > "$API_KEY_PATH"
100+
ZIP_PATH="$RUNNER_TEMP/$ARTIFACT.zip"
101+
/usr/bin/ditto -c -k --keepParent "$ARTIFACT" "$ZIP_PATH"
102+
xcrun notarytool submit "$ZIP_PATH" \
103+
--key "$API_KEY_PATH" \
104+
--key-id "$APPLE_API_KEY" \
105+
--issuer "$APPLE_API_ISSUER" \
106+
--wait
107+
108+
# Cleanup
109+
security delete-keychain "$KEYCHAIN_PATH"
110+
rm -f "$CERT_PATH" "$API_KEY_PATH" "$ZIP_PATH"
111+
65112
- name: Upload artifact
66113
uses: actions/upload-artifact@v4
67114
with:
@@ -106,9 +153,25 @@ jobs:
106153
sudo apt-get update
107154
sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf
108155
156+
- name: Write App Store Connect API key (macOS)
157+
if: runner.os == 'macOS'
158+
env:
159+
APPLE_API_KEY_BASE64: ${{ secrets.APPLE_API_KEY_BASE64 }}
160+
run: |
161+
mkdir -p ~/private_keys
162+
echo "$APPLE_API_KEY_BASE64" | base64 --decode > ~/private_keys/AuthKey.p8
163+
echo "APPLE_API_KEY_PATH=$HOME/private_keys/AuthKey.p8" >> $GITHUB_ENV
164+
109165
- name: Build Tauri app
110166
id: tauri
111167
uses: tauri-apps/tauri-action@v0
168+
env:
169+
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
170+
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
171+
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }}
172+
APPLE_API_ISSUER: ${{ secrets.APPLE_API_ISSUER }}
173+
APPLE_API_KEY: ${{ secrets.APPLE_API_KEY }}
174+
KEYCHAIN_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
112175
with:
113176
args: --target ${{ matrix.target }}
114177
includeUpdaterJson: false
@@ -144,9 +207,8 @@ jobs:
144207
name: v${{ steps.version.outputs.version }}
145208
generate_release_notes: true
146209
body: |
147-
## macOS CLI notice
148-
macOS may block the CLI binary with a Gatekeeper warning. To fix, run:
149-
```
150-
xattr -d com.apple.quarantine <path-to-binary>
151-
```
210+
## macOS notes
211+
The desktop app (`.dmg`) and CLI binaries are signed and notarized
212+
with a Developer ID. macOS will check Apple's notary service
213+
online on first launch — no manual `xattr` workaround needed.
152214
files: artifacts/**/*

Cargo.lock

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/ralph-cli/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "ralph-cli"
3-
version = "0.2.0"
3+
version = "0.2.1"
44
edition = "2021"
55

66
[[bin]]

crates/ralph-core/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "ralph-core"
3-
version = "0.2.0"
3+
version = "0.2.1"
44
edition = "2021"
55

66
[dependencies]

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "ralph-desktop",
33
"private": true,
4-
"version": "0.2.0",
4+
"version": "0.2.1",
55
"type": "module",
66
"scripts": {
77
"dev": "vite",

src-tauri/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "ralph-desktop"
3-
version = "0.2.0"
3+
version = "0.2.1"
44
description = "Ralph - Autonomous Coding Loop GUI"
55
authors = ["you"]
66
edition = "2021"

src-tauri/tauri.conf.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"$schema": "https://schema.tauri.app/config/2",
33
"productName": "ralph-desktop",
4-
"version": "0.2.0",
4+
"version": "0.2.1",
55
"identifier": "com.mikkeldamsgaard.ralph-desktop",
66
"build": {
77
"beforeDevCommand": "npm run dev",

0 commit comments

Comments
 (0)