Skip to content

Commit bd809b5

Browse files
committed
feat: add Tauri desktop build scripts and CI/CD workflows
1 parent d9e111d commit bd809b5

File tree

7 files changed

+1036
-113
lines changed

7 files changed

+1036
-113
lines changed

.github/workflows/tauri-build.yml

Lines changed: 226 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,82 +1,233 @@
11
name: Vue Simulator Desktop Release
22

33
on:
4-
pull_request:
5-
release:
6-
types: [created]
4+
pull_request:
5+
types: [opened, synchronize, reopened]
6+
release:
7+
types: [created]
78

89
permissions:
9-
contents: write
10+
contents: write
11+
actions: read
12+
13+
concurrency:
14+
group: ${{ github.workflow }}-${{ github.ref }}
15+
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
1016

1117
jobs:
12-
build-tauri:
13-
strategy:
14-
fail-fast: false
15-
matrix:
16-
include:
17-
- platform: 'macos-latest'
18-
args: '--target aarch64-apple-darwin' # Apple Silicon
19-
- platform: 'macos-latest'
20-
args: '--target x86_64-apple-darwin' # Intel Mac
21-
- platform: 'ubuntu-22.04'
22-
args: ''
23-
- platform: 'windows-latest'
24-
args: ''
25-
26-
27-
runs-on: ${{ matrix.platform }}
28-
steps:
29-
- name: Checkout repository
30-
uses: actions/checkout@v4
31-
32-
- name: Setup Node.js
33-
uses: actions/setup-node@v4
34-
with:
35-
node-version: 22
36-
37-
- name: Install Rust stable
38-
uses: dtolnay/rust-toolchain@stable
39-
with:
40-
# Targets for cross-compiling on MacOS
41-
targets: ${{ matrix.platform == 'macos-latest' && 'aarch64-apple-darwin,x86_64-apple-darwin' || '' }}
42-
43-
- name: Install Linux dependencies
44-
if: matrix.platform == 'ubuntu-22.04'
45-
run: |
46-
sudo apt-get update
47-
sudo apt-get install -y \
48-
libwebkit2gtk-4.1-dev \
49-
libappindicator3-dev \
50-
librsvg2-dev \
51-
patchelf
52-
53-
- name: Install Frontend Dependencies
54-
run: npm install
55-
working-directory: ./src
56-
57-
- name: Build Frontend (Vue)
58-
# Using npx ensures these tools work on Windows, Mac, and Linux
59-
run: |
60-
npx cross-env DESKTOP_MODE=true npm run build
61-
node -e "const fs = require('fs'); const src='./dist/index-cv.html'; const dest='./dist/index.html'; if (fs.existsSync(src)) { fs.copyFileSync(src, dest); console.log('Synced index files'); } else { console.log('index-cv.html not found, skipping sync'); }"
62-
working-directory: ./src
63-
64-
- name: Build Tauri App
65-
uses: tauri-apps/tauri-action@v0
66-
env:
67-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
68-
with:
69-
projectPath: ./src-tauri
70-
args: ${{ matrix.args }}
71-
72-
- name: Upload Artifacts
73-
uses: actions/upload-artifact@v4
74-
with:
75-
name: build-assets-${{ matrix.platform }}-${{ strategy.job-index }}
76-
path: |
77-
src-tauri/target/**/release/bundle/dmg/*.dmg
78-
src-tauri/target/**/release/bundle/macos/*.app
79-
src-tauri/target/**/release/bundle/msi/*.msi
80-
src-tauri/target/**/release/bundle/nsis/*.exe
81-
src-tauri/target/**/release/bundle/deb/*.deb
82-
src-tauri/target/**/release/bundle/appimage/*.AppImage
18+
build-tauri:
19+
name: Build Desktop App (${{ matrix.platform }})
20+
strategy:
21+
fail-fast: false
22+
matrix:
23+
include:
24+
- platform: 'macos-latest'
25+
args: '--target aarch64-apple-darwin'
26+
arch: 'arm64'
27+
- platform: 'macos-latest'
28+
args: '--target x86_64-apple-darwin'
29+
arch: 'x64'
30+
- platform: 'ubuntu-22.04'
31+
args: ''
32+
arch: 'x64'
33+
- platform: 'windows-latest'
34+
args: ''
35+
arch: 'x64'
36+
37+
runs-on: ${{ matrix.platform }}
38+
39+
steps:
40+
- name: Checkout Repository
41+
uses: actions/checkout@v4
42+
with:
43+
fetch-depth: 0
44+
45+
- name: Setup Node.js
46+
uses: actions/setup-node@v4
47+
with:
48+
node-version: 22
49+
cache: 'npm'
50+
51+
- name: Install Rust stable
52+
uses: dtolnay/rust-toolchain@stable
53+
with:
54+
targets: ${{ matrix.platform == 'macos-latest' && 'aarch64-apple-darwin,x86_64-apple-darwin' || '' }}
55+
56+
- name: Cache Rust Dependencies
57+
uses: Swatinem/rust-cache@v2
58+
with:
59+
workspaces: './src-tauri'
60+
key: ${{ matrix.platform }}-${{ matrix.arch }}-${{ hashFiles('**/Cargo.lock') }}
61+
62+
- name: Install Platform Dependencies (Linux)
63+
if: matrix.platform == 'ubuntu-22.04'
64+
run: |
65+
sudo apt-get update
66+
sudo apt-get install -y \
67+
libwebkit2gtk-4.1-dev \
68+
libappindicator3-dev \
69+
librsvg2-dev \
70+
patchelf \
71+
build-essential \
72+
curl \
73+
wget \
74+
file \
75+
libssl-dev \
76+
libxdo-dev
77+
78+
- name: Install Platform Dependencies (macOS)
79+
if: matrix.platform == 'macos-latest'
80+
run: |
81+
brew update
82+
brew install pkg-config create-dmg
83+
84+
- name: Install Platform Dependencies (Windows)
85+
if: matrix.platform == 'windows-latest'
86+
shell: powershell
87+
run: |
88+
choco install -y wixtoolset nsis webview2-runtime
89+
90+
- name: Install Dependencies
91+
run: npm ci
92+
93+
- name: Build Frontend for Desktop
94+
run: |
95+
node build-desktop.js
96+
97+
- name: Build Tauri App
98+
uses: tauri-apps/tauri-action@v0
99+
env:
100+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
101+
TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
102+
TAURI_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
103+
with:
104+
projectPath: ./src-tauri
105+
args: ${{ matrix.args }}
106+
releaseId: ${{ github.event.release.id }}
107+
108+
- name: Code Signing Setup (Windows)
109+
if: matrix.platform == 'windows-latest' && secrets.WINDOWS_CERTIFICATE_BASE64 != ''
110+
shell: powershell
111+
run: |
112+
$certBytes = [Convert]::FromBase64String("${{ secrets.WINDOWS_CERTIFICATE_BASE64 }}")
113+
$certPath = "C:\temp\codesign.pfx"
114+
[System.IO.File]::WriteAllBytes($certPath, $certBytes)
115+
Import-PfxCertificate -FilePath $certPath -CertStoreLocation Cert:\CurrentUser\My -Password (ConvertTo-SecureString "${{ secrets.WINDOWS_CERTIFICATE_PASSWORD }}" -AsPlainText -Force)
116+
117+
- name: Code Signing (Windows)
118+
if: matrix.platform == 'windows-latest' && secrets.WINDOWS_CERTIFICATE_BASE64 != ''
119+
shell: powershell
120+
run: |
121+
$filesToSign = Get-ChildItem -Path "src-tauri\target\release\bundle" -Recurse -Include @("*.exe", "*.msi")
122+
foreach ($file in $filesToSign) {
123+
& "C:\Program Files (x86)\Windows Kits\10\bin\10.0.22000.0\x64\signtool.exe" sign `
124+
/f "C:\temp\codesign.pfx" `
125+
/p "${{ secrets.WINDOWS_CERTIFICATE_PASSWORD }}" `
126+
/tr "http://timestamp.digicert.com" `
127+
/td sha256 `
128+
/fd sha256 `
129+
$file.FullName
130+
}
131+
132+
- name: Code Signing Setup (macOS)
133+
if: matrix.platform == 'macos-latest' && secrets.APPLE_CERTIFICATE_BASE64 != ''
134+
run: |
135+
echo "${{ secrets.APPLE_CERTIFICATE_BASE64 }}" | base64 --decode > /tmp/developer_certificate.p12
136+
security import /tmp/developer_certificate.p12 -k ~/Library/Keychains/login.keychain-db -P "${{ secrets.APPLE_CERTIFICATE_PASSWORD }}" -T /usr/bin/codesign
137+
security set-key-partition-list -S apple-tool:,apple: -s -k "${{ secrets.APPLE_CERTIFICATE_PASSWORD }}" ~/Library/Keychains/login.keychain-db
138+
139+
- name: Code Signing (macOS)
140+
if: matrix.platform == 'macos-latest' && secrets.APPLE_CERTIFICATE_BASE64 != ''
141+
run: |
142+
find src-tauri/target/release/bundle -name "*.app" -exec codesign --force --deep --sign "${{ secrets.APPLE_DEVELOPER_ID }}" {} \;
143+
find src-tauri/target/release/bundle -name "*.dmg" -exec codesign --force --sign "${{ secrets.APPLE_DEVELOPER_ID }}" {} \;
144+
145+
- name: Code Signing Setup (Linux)
146+
if: matrix.platform == 'ubuntu-22.04' && secrets.LINUX_GPG_PRIVATE_KEY != ''
147+
run: |
148+
echo "${{ secrets.LINUX_GPG_PRIVATE_KEY }}" | base64 --decode > /tmp/gpg_private.key
149+
gpg --import /tmp/gpg_private.key
150+
151+
- name: Code Signing (Linux)
152+
if: matrix.platform == 'ubuntu-22.04' && secrets.LINUX_GPG_PRIVATE_KEY != ''
153+
run: |
154+
for file in $(find src-tauri/target/release/bundle -name "*.deb" -o -name "*.AppImage"); do
155+
gpg --detach-sign --armor --local-user "${{ secrets.LINUX_GPG_KEY_ID }}" "$file"
156+
done
157+
158+
- name: Upload Build Artifacts
159+
uses: actions/upload-artifact@v4
160+
if: always()
161+
with:
162+
name: build-artifacts-${{ matrix.platform }}-${{ matrix.arch }}
163+
path: |
164+
src-tauri/target/**/release/bundle/
165+
!src-tauri/target/**/release/bundle/**/*.dSYM/**
166+
retention-days: 30
167+
168+
release-summary:
169+
name: Release Summary
170+
runs-on: ubuntu-latest
171+
needs: build-tauri
172+
if: github.event_name == 'release'
173+
174+
steps:
175+
- name: Download All Artifacts
176+
uses: actions/download-artifact@v4
177+
with:
178+
path: artifacts
179+
180+
- name: Generate Release Summary
181+
run: |
182+
echo "## Build Artifacts Summary" >> $GITHUB_STEP_SUMMARY
183+
echo "" >> $GITHUB_STEP_SUMMARY
184+
echo "| Platform | Architecture | Status |" >> $GITHUB_STEP_SUMMARY
185+
echo "|----------|--------------|--------|" >> $GITHUB_STEP_SUMMARY
186+
187+
for dir in artifacts/build-artifacts-*; do
188+
if [ -d "$dir" ]; then
189+
platform=$(echo "$dir" | sed 's/.*build-artifacts-\(.*\)-\(.*\)/\1/')
190+
arch=$(echo "$dir" | sed 's/.*build-artifacts-\(.*\)-\(.*\)/\2/')
191+
192+
if [ "$(find "$dir" -type f | wc -l)" -gt 0 ]; then
193+
status="Success"
194+
else
195+
status="Failed"
196+
fi
197+
198+
echo "| $platform | $arch | $status |" >> $GITHUB_STEP_SUMMARY
199+
fi
200+
done
201+
202+
echo "" >> $GITHUB_STEP_SUMMARY
203+
echo "All artifacts have been uploaded to the release assets." >> $GITHUB_STEP_SUMMARY
204+
205+
security-scan:
206+
name: Security Scan
207+
runs-on: ubuntu-latest
208+
needs: build-tauri
209+
if: github.event_name == 'release'
210+
211+
steps:
212+
- name: Checkout Repository
213+
uses: actions/checkout@v4
214+
215+
- name: Run Cargo Audit
216+
run: |
217+
cargo install cargo-audit
218+
cd src-tauri
219+
cargo audit
220+
221+
- name: Run Trivy Security Scan
222+
uses: aquasecurity/trivy-action@master
223+
with:
224+
scan-type: 'fs'
225+
scan-ref: '.'
226+
format: 'sarif'
227+
output: 'trivy-results.sarif'
228+
229+
- name: Upload Trivy Scan Results
230+
uses: github/codeql-action/upload-sarif@v3
231+
if: always()
232+
with:
233+
sarif_file: 'trivy-results.sarif'

0 commit comments

Comments
 (0)