@@ -10,9 +10,19 @@ permissions:
1010 id-token : write
1111
1212jobs :
13- build-binary :
14- name : Build darwin-arm64
15- runs-on : macos-14
13+ build-binaries :
14+ name : Build ${{ matrix.asset_suffix }}
15+ runs-on : ${{ matrix.runner }}
16+ strategy :
17+ fail-fast : false
18+ matrix :
19+ include :
20+ - runner : macos-14
21+ target : aarch64-apple-darwin
22+ asset_suffix : darwin-arm64
23+ - runner : macos-13
24+ target : x86_64-apple-darwin
25+ asset_suffix : darwin-x64
1626 steps :
1727 - name : Checkout
1828 uses : actions/checkout@v4
@@ -30,37 +40,150 @@ jobs:
3040 npm ci
3141
3242 - name : Setup Rust
43+ uses : dtolnay/rust-toolchain@stable
44+ with :
45+ targets : ${{ matrix.target }}
46+
47+ - name : Cache Rust
48+ uses : Swatinem/rust-cache@v2
49+
50+ - name : Build release binary
51+ run : cargo build --release --target ${{ matrix.target }} --locked
52+
53+ - name : Prepare binary assets
54+ env :
55+ TAG : ${{ github.ref_name }}
56+ TARGET : ${{ matrix.target }}
57+ ASSET_SUFFIX : ${{ matrix.asset_suffix }}
58+ run : |
59+ VERSION="${TAG#v}"
60+ mkdir -p dist
61+ cp "target/${TARGET}/release/attn" "dist/attn-v${VERSION}-${ASSET_SUFFIX}"
62+ chmod +x "dist/attn-v${VERSION}-${ASSET_SUFFIX}"
63+ shasum -a 256 "dist/attn-v${VERSION}-${ASSET_SUFFIX}" > "dist/attn-v${VERSION}-${ASSET_SUFFIX}.sha256"
64+
65+ - name : Upload binary artifacts
66+ uses : actions/upload-artifact@v4
67+ with :
68+ name : release-${{ matrix.asset_suffix }}
69+ path : dist/*
70+ retention-days : 7
71+
72+ build-signed-dmg :
73+ name : Build, sign & notarize DMG
74+ runs-on : macos-14
75+ if : ${{ secrets.APPLE_CERTIFICATE != '' && secrets.APPLE_CERTIFICATE_PASSWORD != '' && secrets.KEYCHAIN_PASSWORD != '' && secrets.APPLE_SIGNING_IDENTITY != '' && secrets.APPLE_ID != '' && secrets.APPLE_APP_SPECIFIC_PASSWORD != '' && secrets.APPLE_TEAM_ID != '' }}
76+ steps :
77+ - name : Checkout
78+ uses : actions/checkout@v4
79+
80+ - name : Setup Node
81+ uses : actions/setup-node@v4
82+ with :
83+ node-version : " 20"
84+ cache : npm
85+ cache-dependency-path : web/package-lock.json
86+
87+ - name : Setup Rust toolchain
3388 uses : dtolnay/rust-toolchain@stable
3489 with :
3590 targets : aarch64-apple-darwin
3691
3792 - name : Cache Rust
3893 uses : Swatinem/rust-cache@v2
3994
40- - name : Build production binary
41- run : cargo build --release --target aarch64-apple-darwin --locked
95+ - name : Install cargo-bundle
96+ uses : taiki-e/cache-cargo-install-action@v2
97+ with :
98+ tool : cargo-bundle
99+
100+ - name : Install frontend dependencies
101+ run : |
102+ cd web
103+ npm ci
42104
43- - name : Prepare release assets
105+ - name : Import code signing certificate
106+ env :
107+ CERTIFICATE_BASE64 : ${{ secrets.APPLE_CERTIFICATE }}
108+ CERTIFICATE_PASSWORD : ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
109+ KEYCHAIN_PASSWORD : ${{ secrets.KEYCHAIN_PASSWORD }}
110+ run : |
111+ CERTIFICATE_PATH="$RUNNER_TEMP/build_certificate.p12"
112+ KEYCHAIN_PATH="$RUNNER_TEMP/app-signing.keychain-db"
113+
114+ echo -n "$CERTIFICATE_BASE64" | base64 --decode > "$CERTIFICATE_PATH" || \
115+ echo -n "$CERTIFICATE_BASE64" | base64 -D > "$CERTIFICATE_PATH"
116+
117+ security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
118+ security set-keychain-settings -lut 21600 "$KEYCHAIN_PATH"
119+ security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
120+ security import "$CERTIFICATE_PATH" -P "$CERTIFICATE_PASSWORD" -A -t cert -f pkcs12 -k "$KEYCHAIN_PATH"
121+ security set-key-partition-list -S apple-tool:,apple: -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
122+ security list-keychain -d user -s "$KEYCHAIN_PATH"
123+
124+ echo "KEYCHAIN_PATH=$KEYCHAIN_PATH" >> "$GITHUB_ENV"
125+
126+ - name : Build app bundle
127+ run : |
128+ scripts/macos-build-bundle.sh prod aarch64-apple-darwin
129+
130+ APP_PATH="$(find target/aarch64-apple-darwin -path '*/bundle/osx/*.app' -maxdepth 6 | head -n1)"
131+ if [ -z "$APP_PATH" ]; then
132+ echo "No app bundle found" >&2
133+ exit 1
134+ fi
135+
136+ DMG_PATH="$(dirname "$APP_PATH")/attn.dmg"
137+ echo "APP_PATH=$APP_PATH" >> "$GITHUB_ENV"
138+ echo "DMG_PATH=$DMG_PATH" >> "$GITHUB_ENV"
139+
140+ - name : Sign app bundle
141+ env :
142+ APPLE_SIGNING_IDENTITY : ${{ secrets.APPLE_SIGNING_IDENTITY }}
143+ run : scripts/macos-sign-app.sh "$APP_PATH" "$APPLE_SIGNING_IDENTITY"
144+
145+ - name : Create DMG
146+ env :
147+ APPLE_SIGNING_IDENTITY : ${{ secrets.APPLE_SIGNING_IDENTITY }}
148+ run : scripts/macos-create-dmg.sh "$APP_PATH" "$DMG_PATH"
149+
150+ - name : Notarize DMG
151+ env :
152+ APPLE_ID : ${{ secrets.APPLE_ID }}
153+ APPLE_APP_SPECIFIC_PASSWORD : ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }}
154+ APPLE_TEAM_ID : ${{ secrets.APPLE_TEAM_ID }}
155+ run : scripts/macos-notarize-dmg.sh "$DMG_PATH"
156+
157+ - name : Prepare DMG assets
44158 env :
45159 TAG : ${{ github.ref_name }}
46160 run : |
47161 VERSION="${TAG#v}"
48162 mkdir -p dist
49- cp "target/aarch64-apple-darwin/release/attn" "dist/attn-v${VERSION}-darwin-arm64"
50- chmod +x "dist/attn-v${VERSION}-darwin-arm64"
51- shasum -a 256 "dist/attn-v${VERSION}-darwin-arm64" > "dist/attn-v${VERSION}-darwin-arm64.sha256"
163+ cp "$DMG_PATH" "dist/attn-v${VERSION}-darwin-arm64.dmg"
164+ shasum -a 256 "dist/attn-v${VERSION}-darwin-arm64.dmg" > "dist/attn-v${VERSION}-darwin-arm64.dmg.sha256"
52165
53- - name : Upload build artifacts
166+ - name : Upload DMG artifacts
54167 uses : actions/upload-artifact@v4
55168 with :
56- name : release-darwin-arm64
169+ name : release-dmg- darwin-arm64
57170 path : dist/*
58171 retention-days : 7
59172
173+ - name : Cleanup keychain
174+ if : always()
175+ run : |
176+ if [ -n "${KEYCHAIN_PATH:-}" ] && [ -f "$KEYCHAIN_PATH" ]; then
177+ security delete-keychain "$KEYCHAIN_PATH"
178+ fi
179+
60180 publish-release :
61181 name : Publish GitHub Release
62182 runs-on : ubuntu-latest
63- needs : build-binary
183+ needs :
184+ - build-binaries
185+ - build-signed-dmg
186+ if : ${{ always() && needs.build-binaries.result == 'success' && (needs.build-signed-dmg.result == 'success' || needs.build-signed-dmg.result == 'skipped') }}
64187 steps :
65188 - name : Checkout
66189 uses : actions/checkout@v4
@@ -71,11 +194,8 @@ jobs:
71194 uses : actions/download-artifact@v4
72195 with :
73196 path : dist
74-
75- - name : Flatten artifact directories
76- run : |
77- mkdir -p release-assets
78- find dist -type f -maxdepth 3 -exec cp {} release-assets/ \;
197+ pattern : release-*
198+ merge-multiple : true
79199
80200 - name : Create or update release
81201 env :
89209 --title "$TAG" \
90210 --notes "Automated release for $TAG."
91211 fi
92- gh release upload "$TAG" release-assets /* --clobber
212+ gh release upload "$TAG" dist /* --clobber
93213
94214 publish-crates :
95215 name : Publish crates.io
0 commit comments