Skip to content

Commit abb2c92

Browse files
committed
Merge branch 'dev'
2 parents daa95cc + 2bb3ca8 commit abb2c92

File tree

25 files changed

+1098
-16
lines changed

25 files changed

+1098
-16
lines changed
Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
name: Build and Release
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
8+
permissions:
9+
contents: write
10+
11+
env:
12+
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
13+
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
14+
15+
jobs:
16+
create-release:
17+
runs-on: ubuntu-latest
18+
outputs:
19+
version: ${{ steps.get_version.outputs.version }}
20+
release_id: ${{ steps.create_release.outputs.id }}
21+
steps:
22+
- name: Checkout
23+
uses: actions/checkout@v4
24+
25+
- name: Get version from tauri.conf.json
26+
id: get_version
27+
run: |
28+
VERSION=$(jq -r '.version' src-tauri/tauri.conf.json)
29+
echo "version=$VERSION" >> $GITHUB_OUTPUT
30+
31+
- name: Create draft release
32+
id: create_release
33+
uses: softprops/action-gh-release@v2
34+
with:
35+
tag_name: v${{ steps.get_version.outputs.version }}
36+
name: ZeroLimit v${{ steps.get_version.outputs.version }}
37+
draft: true
38+
generate_release_notes: true
39+
40+
build-windows-x64:
41+
needs: create-release
42+
runs-on: windows-latest
43+
steps:
44+
- name: Checkout
45+
uses: actions/checkout@v4
46+
47+
- name: Setup Node.js
48+
uses: actions/setup-node@v4
49+
with:
50+
node-version: 20
51+
52+
- name: Setup pnpm
53+
uses: pnpm/action-setup@v4
54+
55+
- name: Setup Rust
56+
uses: dtolnay/rust-toolchain@stable
57+
58+
- name: Cache Cargo
59+
uses: actions/cache@v4
60+
with:
61+
path: |
62+
~/.cargo/bin/
63+
~/.cargo/registry/index/
64+
~/.cargo/registry/cache/
65+
~/.cargo/git/db/
66+
src-tauri/target/
67+
key: ${{ runner.os }}-cargo-x64-${{ hashFiles('**/Cargo.lock') }}
68+
restore-keys: |
69+
${{ runner.os }}-cargo-x64-
70+
71+
- name: Install frontend dependencies
72+
run: pnpm install
73+
74+
- name: Build Tauri (x64)
75+
run: pnpm tauri build --target x86_64-pc-windows-msvc
76+
77+
- name: Prepare portable executable
78+
shell: bash
79+
run: |
80+
VERSION="${{ needs.create-release.outputs.version }}"
81+
cp src-tauri/target/x86_64-pc-windows-msvc/release/zero-limit.exe "ZeroLimit_${VERSION}_portable.exe"
82+
83+
- name: Upload artifacts to release
84+
uses: softprops/action-gh-release@v2
85+
with:
86+
tag_name: v${{ needs.create-release.outputs.version }}
87+
draft: true
88+
files: |
89+
src-tauri/target/x86_64-pc-windows-msvc/release/bundle/nsis/*.exe
90+
src-tauri/target/x86_64-pc-windows-msvc/release/bundle/nsis/*.exe.sig
91+
src-tauri/target/x86_64-pc-windows-msvc/release/bundle/msi/*.msi
92+
src-tauri/target/x86_64-pc-windows-msvc/release/bundle/msi/*.msi.sig
93+
ZeroLimit_*_portable.exe
94+
95+
build-windows-arm64:
96+
needs: create-release
97+
runs-on: windows-latest
98+
steps:
99+
- name: Checkout
100+
uses: actions/checkout@v4
101+
102+
- name: Setup Node.js
103+
uses: actions/setup-node@v4
104+
with:
105+
node-version: 20
106+
107+
- name: Setup pnpm
108+
uses: pnpm/action-setup@v4
109+
110+
- name: Setup Rust
111+
uses: dtolnay/rust-toolchain@stable
112+
with:
113+
targets: aarch64-pc-windows-msvc
114+
115+
- name: Cache Cargo
116+
uses: actions/cache@v4
117+
with:
118+
path: |
119+
~/.cargo/bin/
120+
~/.cargo/registry/index/
121+
~/.cargo/registry/cache/
122+
~/.cargo/git/db/
123+
src-tauri/target/
124+
key: ${{ runner.os }}-cargo-arm64-${{ hashFiles('**/Cargo.lock') }}
125+
restore-keys: |
126+
${{ runner.os }}-cargo-arm64-
127+
128+
- name: Install frontend dependencies
129+
run: pnpm install
130+
131+
- name: Build Tauri (ARM64)
132+
run: pnpm tauri build --target aarch64-pc-windows-msvc
133+
134+
- name: Prepare portable executable
135+
shell: bash
136+
run: |
137+
VERSION="${{ needs.create-release.outputs.version }}"
138+
cp src-tauri/target/aarch64-pc-windows-msvc/release/zero-limit.exe "ZeroLimit_${VERSION}_arm64_portable.exe"
139+
140+
- name: Upload artifacts to release
141+
uses: softprops/action-gh-release@v2
142+
with:
143+
tag_name: v${{ needs.create-release.outputs.version }}
144+
draft: true
145+
files: |
146+
src-tauri/target/aarch64-pc-windows-msvc/release/bundle/nsis/*.exe
147+
src-tauri/target/aarch64-pc-windows-msvc/release/bundle/nsis/*.exe.sig
148+
src-tauri/target/aarch64-pc-windows-msvc/release/bundle/msi/*.msi
149+
src-tauri/target/aarch64-pc-windows-msvc/release/bundle/msi/*.msi.sig
150+
ZeroLimit_*_portable.exe
151+
152+
publish-release:
153+
needs: [create-release, build-windows-x64, build-windows-arm64]
154+
runs-on: ubuntu-latest
155+
steps:
156+
- name: Checkout
157+
uses: actions/checkout@v4
158+
159+
- name: Download release assets
160+
uses: robinraju/release-downloader@v1
161+
with:
162+
tag: v${{ needs.create-release.outputs.version }}
163+
fileName: "*.sig"
164+
out-file-path: signatures
165+
166+
- name: Generate latest.json
167+
run: |
168+
VERSION="${{ needs.create-release.outputs.version }}"
169+
REPO="${{ github.repository }}"
170+
DATE=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
171+
172+
# Read signature files
173+
X64_SIG=$(cat signatures/*x64*.exe.sig 2>/dev/null || echo "")
174+
ARM64_SIG=$(cat signatures/*arm64*.exe.sig 2>/dev/null || echo "")
175+
176+
cat > latest.json << EOF
177+
{
178+
"version": "$VERSION",
179+
"notes": "See release notes on GitHub",
180+
"pub_date": "$DATE",
181+
"platforms": {
182+
"windows-x86_64": {
183+
"signature": "$X64_SIG",
184+
"url": "https://github.com/$REPO/releases/download/v$VERSION/ZeroLimit_${VERSION}_x64-setup.exe"
185+
},
186+
"windows-aarch64": {
187+
"signature": "$ARM64_SIG",
188+
"url": "https://github.com/$REPO/releases/download/v$VERSION/ZeroLimit_${VERSION}_arm64-setup.exe"
189+
}
190+
}
191+
}
192+
EOF
193+
194+
- name: Upload latest.json
195+
uses: softprops/action-gh-release@v2
196+
with:
197+
tag_name: v${{ needs.create-release.outputs.version }}
198+
draft: false
199+
files: latest.json

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,8 @@ dist-ssr
2727
#
2828
pnpm-lock.yaml
2929
Cargo.lock
30+
31+
# Tauri signing keys
32+
~/.tauri/
33+
*.key
34+
*.key.pub
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# GitHub Actions Build & Release Workflow
2+
3+
Auto-build and release ZeroLimit on push to `main` with Tauri updater support.
4+
5+
## Summary
6+
7+
| Aspect | Decision |
8+
|--------|----------|
9+
| Trigger | Push to `main` |
10+
| Platforms | Windows x64, Windows ARM64 |
11+
| Artifacts | NSIS (.exe), MSI, Portable + signatures |
12+
| Release | Auto-create GitHub Release with `latest.json` |
13+
| Updater | Signed bundles for Tauri auto-update |
14+
15+
## Workflow Structure
16+
17+
```
18+
create-release → build-windows-x64 → publish-release
19+
→ build-windows-arm64 ↗
20+
```
21+
22+
1. **create-release**: Creates draft release, outputs `release_id`
23+
2. **build-windows-x64/arm64**: Parallel builds, uploads artifacts
24+
3. **publish-release**: Generates `latest.json`, publishes release
25+
26+
## Required Secrets
27+
28+
| Secret | Purpose |
29+
|--------|---------|
30+
| `TAURI_SIGNING_PRIVATE_KEY` | Signs update bundles |
31+
| `TAURI_SIGNING_PRIVATE_KEY_PASSWORD` | Key password |
32+
33+
## Artifacts per Architecture
34+
35+
- `ZeroLimit_{version}_{arch}-setup.exe` (NSIS)
36+
- `ZeroLimit_{version}_{arch}.msi` (MSI)
37+
- `*.sig` signature files
38+
- `latest.json` (for updater)
39+
40+
## One-time Setup
41+
42+
1. Generate keys: `pnpm tauri signer generate -w ~/.tauri/zero-limit.key`
43+
2. Add secrets to GitHub repository settings
44+
3. Add public key to `tauri.conf.json` updater config
45+
46+
## Version Handling
47+
48+
- Reads from `src-tauri/tauri.conf.json`
49+
- Creates tag `v{version}` (e.g., `v1.0.0`)

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "zero-limit",
3-
"version": "1.0.0",
3+
"version": "1.0.5",
44
"private": true,
55
"type": "module",
66
"scripts": {
@@ -21,6 +21,7 @@
2121
"@tauri-apps/plugin-opener": "^2.5.2",
2222
"@tauri-apps/plugin-process": "^2.3.1",
2323
"@tauri-apps/plugin-shell": "^2.3.3",
24+
"@tauri-apps/plugin-updater": "^2.9.0",
2425
"axios": "^1.13.2",
2526
"class-variance-authority": "^0.7.1",
2627
"clsx": "^2.1.1",

src-tauri/Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,12 @@ tauri-build = { version = "2", features = [] }
1616
tauri = { version = "2", features = ["tray-icon"] }
1717
tauri-plugin-opener = "2"
1818
tauri-plugin-shell = "2"
19+
tauri-plugin-dialog = "2"
20+
tauri-plugin-updater = "2"
21+
tauri-plugin-process = "2"
1922
serde = { version = "1", features = ["derive"] }
2023
serde_json = "1"
2124
reqwest = { version = "0.12", features = ["json", "multipart"] }
2225
tokio = { version = "1", features = ["full"] }
2326
thiserror = "1"
2427
opener = "0.7"
25-
tauri-plugin-dialog = "2.4.2"

src-tauri/capabilities/default.json

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,12 @@
33
"identifier": "default",
44
"description": "Capability for the main window",
55
"windows": ["main"],
6-
"permissions": ["core:default", "opener:default", "shell:default", "dialog:default"]
6+
"permissions": [
7+
"core:default",
8+
"opener:default",
9+
"shell:default",
10+
"dialog:default",
11+
"updater:default",
12+
"process:allow-restart"
13+
]
714
}

src-tauri/src/lib.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,13 @@ pub fn run() {
4545
.plugin(tauri_plugin_opener::init())
4646
.plugin(tauri_plugin_shell::init())
4747
.plugin(tauri_plugin_dialog::init())
48+
.plugin(tauri_plugin_process::init())
4849
.setup(|app| {
50+
#[cfg(desktop)]
51+
{
52+
app.handle()
53+
.plugin(tauri_plugin_updater::Builder::new().build())?;
54+
}
4955
tray::setup_tray(app)?;
5056
Ok(())
5157
})

src-tauri/tauri.conf.json

Lines changed: 10 additions & 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": "ZeroLimit",
4-
"version": "1.0.0",
4+
"version": "1.0.5",
55
"identifier": "com.0xtbug.zero-limit",
66
"build": {
77
"beforeDevCommand": "pnpm dev",
@@ -26,12 +26,21 @@
2626
"bundle": {
2727
"active": true,
2828
"targets": "all",
29+
"createUpdaterArtifacts": true,
2930
"icon": [
3031
"icons/32x32.png",
3132
"icons/128x128.png",
3233
"icons/128x128@2x.png",
3334
"icons/icon.icns",
3435
"icons/icon.ico"
3536
]
37+
},
38+
"plugins": {
39+
"updater": {
40+
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IDdBMTkyRDU2NjBDNTcyNkQKUldSdGNzVmdWaTBaZXVuWXlkenZyNHJrUzRyYk4vOTFnRkpBWllyWXhHeUllUXhlL0VMMTcvcmcK",
41+
"endpoints": [
42+
"https://github.com/0xtbug/zero-limit/releases/latest/download/latest.json"
43+
]
44+
}
3645
}
3746
}

src/App.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { useEffect } from 'react'
2-
import { useAuthStore, useThemeStore, useCliProxyStore } from '@/stores'
2+
import { useAuthStore, useThemeStore, useCliProxyStore, useUpdateStore } from '@/stores'
33
import { ProtectedRoute } from '@/router/ProtectedRoute'
44
import { MainRoutes } from '@/router/MainRoutes'
55
import { LoginPage } from '@/pages/LoginPage'
@@ -10,6 +10,7 @@ function App() {
1010
const { isAuthenticated, restoreSession, connectionStatus } = useAuthStore()
1111
const { theme, setTheme } = useThemeStore()
1212
const { exePath, autoStart, runInBackground, startServer } = useCliProxyStore()
13+
const { checkForUpdates } = useUpdateStore()
1314

1415
useEffect(() => {
1516
restoreSession()
@@ -23,6 +24,11 @@ function App() {
2324
if (autoStart && exePath) {
2425
startServer()
2526
}
27+
28+
// Check for updates in background on startup
29+
checkForUpdates().catch(() => {
30+
// Silently ignore update check errors on startup
31+
})
2632
}, []) // Only run once on mount
2733

2834
// Show loading during session restore

0 commit comments

Comments
 (0)