@@ -2,8 +2,14 @@ name: Build and Release
22
33on :
44 push :
5- branches :
6- - main
5+ tags :
6+ - ' v*'
7+ workflow_dispatch :
8+ inputs :
9+ version :
10+ description : ' Version to release (e.g., 1.1.0)'
11+ required : true
12+ type : string
713
814permissions :
915 contents : write
1319 TAURI_SIGNING_PRIVATE_KEY_PASSWORD : ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
1420
1521jobs :
22+ # ===========================================
23+ # 1. Create Release + Version Bump
24+ # ===========================================
1625 create-release :
1726 runs-on : ubuntu-latest
1827 outputs :
@@ -21,12 +30,48 @@ jobs:
2130 steps :
2231 - name : Checkout
2332 uses : actions/checkout@v4
33+ with :
34+ fetch-depth : 0
35+ token : ${{ secrets.GITHUB_TOKEN }}
2436
25- - name : Get version from tauri.conf.json
37+ - name : Get version
2638 id : get_version
2739 run : |
28- VERSION=$(jq -r '.version' src-tauri/tauri.conf.json)
40+ if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
41+ VERSION="${{ github.event.inputs.version }}"
42+ else
43+ VERSION="${GITHUB_REF#refs/tags/v}"
44+ fi
45+ VERSION="${VERSION#v}"
2946 echo "version=$VERSION" >> $GITHUB_OUTPUT
47+ echo "Releasing version: $VERSION"
48+
49+ - name : Bump version in project files
50+ run : |
51+ chmod +x ./scripts/bump-version.sh
52+ ./scripts/bump-version.sh "${{ steps.get_version.outputs.version }}"
53+
54+ - name : Commit version bump
55+ run : |
56+ git config user.name "github-actions[bot]"
57+ git config user.email "github-actions[bot]@users.noreply.github.com"
58+
59+ if git diff --quiet package.json src-tauri/tauri.conf.json src-tauri/Cargo.toml; then
60+ echo "No version changes to commit"
61+ else
62+ git add package.json src-tauri/tauri.conf.json src-tauri/Cargo.toml
63+ git commit -m "chore: bump version to ${{ steps.get_version.outputs.version }} [skip ci]"
64+ git push origin HEAD:main
65+ fi
66+
67+ - name : Create tag (for workflow_dispatch)
68+ if : github.event_name == 'workflow_dispatch'
69+ run : |
70+ TAG_NAME="v${{ steps.get_version.outputs.version }}"
71+ if ! git tag -l | grep -q "^${TAG_NAME}$"; then
72+ git tag -a "${TAG_NAME}" -m "Release ${{ steps.get_version.outputs.version }}"
73+ git push origin "${TAG_NAME}"
74+ fi
3075
3176 - name : Create draft release
3277 id : create_release
@@ -36,13 +81,24 @@ jobs:
3681 name : ZeroLimit v${{ steps.get_version.outputs.version }}
3782 draft : true
3883 generate_release_notes : true
84+ body : |
85+
86+ > ⚠️ **Note**: macOS builds won't be code-signed unless you add Apple signing secrets. Unsigned macOS apps require users to run:
87+ > ```bash
88+ > xattr -cr /Applications/ZeroLimit.app
89+ > ```
3990
91+ # ===========================================
92+ # 2. Build Windows x64
93+ # ===========================================
4094 build-windows-x64 :
4195 needs : create-release
4296 runs-on : windows-latest
4397 steps :
4498 - name : Checkout
4599 uses : actions/checkout@v4
100+ with :
101+ ref : main
46102
47103 - name : Setup Node.js
48104 uses : actions/setup-node@v4
@@ -95,15 +151,20 @@ jobs:
95151 - name : Upload signatures for latest.json
96152 uses : actions/upload-artifact@v4
97153 with :
98- name : signatures-x64
154+ name : signatures-windows- x64
99155 path : src-tauri/target/x86_64-pc-windows-msvc/release/bundle/nsis/*.sig
100156
157+ # ===========================================
158+ # 3. Build Windows ARM64
159+ # ===========================================
101160 build-windows-arm64 :
102161 needs : create-release
103162 runs-on : windows-latest
104163 steps :
105164 - name : Checkout
106165 uses : actions/checkout@v4
166+ with :
167+ ref : main
107168
108169 - name : Setup Node.js
109170 uses : actions/setup-node@v4
@@ -158,51 +219,217 @@ jobs:
158219 - name : Upload signatures for latest.json
159220 uses : actions/upload-artifact@v4
160221 with :
161- name : signatures-arm64
222+ name : signatures-windows- arm64
162223 path : src-tauri/target/aarch64-pc-windows-msvc/release/bundle/nsis/*.sig
163224
225+ # ===========================================
226+ # 4. Build macOS (Universal: x64 + ARM64)
227+ # ===========================================
228+ build-macos :
229+ needs : create-release
230+ runs-on : macos-latest
231+ steps :
232+ - name : Checkout
233+ uses : actions/checkout@v4
234+ with :
235+ ref : main
236+
237+ - name : Setup Node.js
238+ uses : actions/setup-node@v4
239+ with :
240+ node-version : 20
241+
242+ - name : Setup pnpm
243+ uses : pnpm/action-setup@v4
244+
245+ - name : Setup Rust
246+ uses : dtolnay/rust-toolchain@stable
247+ with :
248+ targets : aarch64-apple-darwin,x86_64-apple-darwin
249+
250+ - name : Cache Cargo
251+ uses : actions/cache@v4
252+ with :
253+ path : |
254+ ~/.cargo/bin/
255+ ~/.cargo/registry/index/
256+ ~/.cargo/registry/cache/
257+ ~/.cargo/git/db/
258+ src-tauri/target/
259+ key : ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
260+ restore-keys : |
261+ ${{ runner.os }}-cargo-
262+
263+ - name : Install frontend dependencies
264+ run : pnpm install
265+
266+ - name : Build Tauri (Apple Silicon)
267+ run : pnpm tauri build --target aarch64-apple-darwin
268+
269+ - name : Build Tauri (Intel)
270+ run : pnpm tauri build --target x86_64-apple-darwin
271+
272+ - name : Upload artifacts to release
273+ uses : softprops/action-gh-release@v2
274+ with :
275+ tag_name : v${{ needs.create-release.outputs.version }}
276+ draft : true
277+ files : |
278+ src-tauri/target/aarch64-apple-darwin/release/bundle/dmg/*.dmg
279+ src-tauri/target/aarch64-apple-darwin/release/bundle/macos/*.app.tar.gz
280+ src-tauri/target/aarch64-apple-darwin/release/bundle/macos/*.app.tar.gz.sig
281+ src-tauri/target/x86_64-apple-darwin/release/bundle/dmg/*.dmg
282+ src-tauri/target/x86_64-apple-darwin/release/bundle/macos/*.app.tar.gz
283+ src-tauri/target/x86_64-apple-darwin/release/bundle/macos/*.app.tar.gz.sig
284+
285+ - name : Upload signatures for latest.json
286+ uses : actions/upload-artifact@v4
287+ with :
288+ name : signatures-macos
289+ path : |
290+ src-tauri/target/aarch64-apple-darwin/release/bundle/macos/*.app.tar.gz.sig
291+ src-tauri/target/x86_64-apple-darwin/release/bundle/macos/*.app.tar.gz.sig
292+
293+ # ===========================================
294+ # 5. Build Linux x64
295+ # ===========================================
296+ build-linux :
297+ needs : create-release
298+ runs-on : ubuntu-22.04
299+ steps :
300+ - name : Checkout
301+ uses : actions/checkout@v4
302+ with :
303+ ref : main
304+
305+ - name : Install system dependencies
306+ run : |
307+ sudo apt-get update
308+ sudo apt-get install -y \
309+ libwebkit2gtk-4.1-dev \
310+ libappindicator3-dev \
311+ librsvg2-dev \
312+ patchelf \
313+ libssl-dev \
314+ libgtk-3-dev \
315+ libsoup-3.0-dev \
316+ javascriptcoregtk-4.1-dev
317+
318+ - name : Setup Node.js
319+ uses : actions/setup-node@v4
320+ with :
321+ node-version : 20
322+
323+ - name : Setup pnpm
324+ uses : pnpm/action-setup@v4
325+
326+ - name : Setup Rust
327+ uses : dtolnay/rust-toolchain@stable
328+
329+ - name : Cache Cargo
330+ uses : actions/cache@v4
331+ with :
332+ path : |
333+ ~/.cargo/bin/
334+ ~/.cargo/registry/index/
335+ ~/.cargo/registry/cache/
336+ ~/.cargo/git/db/
337+ src-tauri/target/
338+ key : ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
339+ restore-keys : |
340+ ${{ runner.os }}-cargo-
341+
342+ - name : Install frontend dependencies
343+ run : pnpm install
344+
345+ - name : Build Tauri
346+ run : pnpm tauri build
347+
348+ - name : Upload artifacts to release
349+ uses : softprops/action-gh-release@v2
350+ with :
351+ tag_name : v${{ needs.create-release.outputs.version }}
352+ draft : true
353+ files : |
354+ src-tauri/target/release/bundle/deb/*.deb
355+ src-tauri/target/release/bundle/rpm/*.rpm
356+ src-tauri/target/release/bundle/appimage/*.AppImage
357+ src-tauri/target/release/bundle/appimage/*.AppImage.tar.gz
358+ src-tauri/target/release/bundle/appimage/*.AppImage.tar.gz.sig
359+
360+ - name : Upload signatures for latest.json
361+ uses : actions/upload-artifact@v4
362+ with :
363+ name : signatures-linux
364+ path : src-tauri/target/release/bundle/appimage/*.AppImage.tar.gz.sig
365+
366+ # ===========================================
367+ # 6. Publish Release + Generate latest.json
368+ # ===========================================
164369 publish-release :
165- needs : [create-release, build-windows-x64, build-windows-arm64]
370+ needs : [create-release, build-windows-x64, build-windows-arm64, build-macos, build-linux ]
166371 runs-on : ubuntu-latest
167372 steps :
168373 - name : Checkout
169374 uses : actions/checkout@v4
170375
171- - name : Download signatures
376+ - name : Download all signatures
172377 uses : actions/download-artifact@v4
173378 with :
174379 pattern : signatures-*
175380 merge-multiple : true
176381 path : signatures
177382
383+ - name : List signatures (debug)
384+ run : find signatures -type f | sort
385+
178386 - name : Generate latest.json
179387 run : |
180388 VERSION="${{ needs.create-release.outputs.version }}"
181389 REPO="${{ github.repository }}"
182390 DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
183391
184- # Read signature files
185- # Use specific version to avoid matching multiple files if present
186- X64_SIG=$(cat signatures/*_${VERSION}_x64*.exe.sig | head -n 1)
187- ARM64_SIG=$(cat signatures/*_${VERSION}_arm64*.exe.sig | head -n 1)
188-
189- cat > latest.json << EOF
190- {
191- "version": "$VERSION",
192- "notes": "See release notes on GitHub",
193- "pub_date": "$DATE",
194- "platforms": {
195- "windows-x86_64": {
196- "signature": "$X64_SIG",
197- "url": "https://github.com/$REPO/releases/download/v$VERSION/ZeroLimit_${VERSION}_x64-setup.exe"
198- },
199- "windows-aarch64": {
200- "signature": "$ARM64_SIG",
201- "url": "https://github.com/$REPO/releases/download/v$VERSION/ZeroLimit_${VERSION}_arm64-setup.exe"
202- }
203- }
204- }
205- EOF
392+ # Read signature files (use find to be resilient to naming variations)
393+ WIN_X64_SIG=$(find signatures -name "*x64*setup*.sig" -o -name "*x86_64*setup*.sig" | head -1 | xargs cat 2>/dev/null || echo "")
394+ WIN_ARM64_SIG=$(find signatures -name "*arm64*setup*.sig" -o -name "*aarch64*setup*.sig" | head -1 | xargs cat 2>/dev/null || echo "")
395+ MACOS_ARM64_SIG=$(find signatures -path "*aarch64-apple*" -name "*.sig" | head -1 | xargs cat 2>/dev/null || echo "")
396+ MACOS_X64_SIG=$(find signatures -path "*x86_64-apple*" -name "*.sig" | head -1 | xargs cat 2>/dev/null || echo "")
397+ LINUX_SIG=$(find signatures -name "*.AppImage.tar.gz.sig" | head -1 | xargs cat 2>/dev/null || echo "")
398+
399+ # Build platforms JSON dynamically
400+ PLATFORMS="{"
401+
402+ if [ -n "$WIN_X64_SIG" ]; then
403+ PLATFORMS="$PLATFORMS\"windows-x86_64\":{\"signature\":\"$WIN_X64_SIG\",\"url\":\"https://github.com/$REPO/releases/download/v$VERSION/ZeroLimit_${VERSION}_x64-setup.exe\"},"
404+ fi
405+
406+ if [ -n "$WIN_ARM64_SIG" ]; then
407+ PLATFORMS="$PLATFORMS\"windows-aarch64\":{\"signature\":\"$WIN_ARM64_SIG\",\"url\":\"https://github.com/$REPO/releases/download/v$VERSION/ZeroLimit_${VERSION}_arm64-setup.exe\"},"
408+ fi
409+
410+ if [ -n "$MACOS_ARM64_SIG" ]; then
411+ MACOS_ARM64_FILENAME=$(find signatures -path "*aarch64-apple*" -name "*.sig" | head -1 | xargs basename | sed 's/.sig$//')
412+ PLATFORMS="$PLATFORMS\"darwin-aarch64\":{\"signature\":\"$MACOS_ARM64_SIG\",\"url\":\"https://github.com/$REPO/releases/download/v$VERSION/$MACOS_ARM64_FILENAME\"},"
413+ fi
414+
415+ if [ -n "$MACOS_X64_SIG" ]; then
416+ MACOS_X64_FILENAME=$(find signatures -path "*x86_64-apple*" -name "*.sig" | head -1 | xargs basename | sed 's/.sig$//')
417+ PLATFORMS="$PLATFORMS\"darwin-x86_64\":{\"signature\":\"$MACOS_X64_SIG\",\"url\":\"https://github.com/$REPO/releases/download/v$VERSION/$MACOS_X64_FILENAME\"},"
418+ fi
419+
420+ if [ -n "$LINUX_SIG" ]; then
421+ LINUX_FILENAME=$(find signatures -name "*.AppImage.tar.gz.sig" | head -1 | xargs basename | sed 's/.sig$//')
422+ PLATFORMS="$PLATFORMS\"linux-x86_64\":{\"signature\":\"$LINUX_SIG\",\"url\":\"https://github.com/$REPO/releases/download/v$VERSION/$LINUX_FILENAME\"},"
423+ fi
424+
425+ # Remove trailing comma and close
426+ PLATFORMS="${PLATFORMS%,}}"
427+
428+ # Write latest.json
429+ echo "{\"version\":\"$VERSION\",\"notes\":\"See release notes on GitHub\",\"pub_date\":\"$DATE\",\"platforms\":$PLATFORMS}" | jq '.' > latest.json
430+
431+ echo "Generated latest.json:"
432+ cat latest.json
206433
207434 - name : Upload latest.json
208435 uses : softprops/action-gh-release@v2
0 commit comments