1+ name : Build and Release Tauri App
2+
3+ on :
4+ push :
5+ branches :
6+ - main
7+
8+ jobs :
9+ check-version-and-tag :
10+ runs-on : ubuntu-latest
11+ steps :
12+ - name : Checkout Code
13+ uses : actions/checkout@v4
14+
15+ - name : Get Version from package.json
16+ id : get_version
17+ run : |
18+ version="v$(jq -r '.version' package.json)"
19+ echo "::set-output name=version::$version"
20+ - name : Check if Tag Exists
21+ id : check_tag
22+ run : |
23+ version="${{ steps.get_version.outputs.version }}"
24+ if git rev-parse "$version" >/dev/null 2>&1; then
25+ echo "Tag $version already exists."
26+ echo "::set-output name=tag_exists::true"
27+ else
28+ echo "Tag $version does not exist."
29+ echo "::set-output name=tag_exists::false"
30+ fi
31+ - name : Create Tag
32+ if : steps.check_tag.outputs.tag_exists == 'false'
33+ run : |
34+ version="${{ steps.get_version.outputs.version }}"
35+ git config user.name "github-actions"
36+ git config user.email "github-actions@github.com"
37+ git tag -a "$version" -m "Release version $version"
38+ git push origin "$version"
39+ build :
40+ needs : check-version-and-tag
41+ runs-on : ${{ matrix.os }}
42+ strategy :
43+ matrix :
44+ os : [macos-latest, windows-latest, ubuntu-22.04]
45+ steps :
46+ - name : Checkout Code
47+ uses : actions/checkout@v4
48+
49+ - name : Debug the runner OS
50+ run : echo "Running on ${{ runner.os }}"
51+
52+ - name : Setup Rust
53+ uses : actions-rs/toolchain@v1
54+ with :
55+ profile : minimal
56+ toolchain : stable
57+ override : true
58+
59+ - name : Setup Node.js
60+ uses : actions/setup-node@v4
61+ with :
62+ node-version : 20
63+
64+ - name : Install macOS canvas dependencies
65+ if : runner.os == 'macOS'
66+ run : |
67+ brew install pkg-config cairo pango libpng jpeg giflib librsvg
68+
69+
70+ - name : Install Dependencies
71+ run : |
72+ npm install
73+ npm install tailwindcss-animate
74+ - name : Run npm audit
75+ run : npm audit --audit-level=high
76+
77+ - name : Install GTK and Build Tools (Ubuntu only)
78+ if : runner.os == 'Linux'
79+ run : |
80+ sudo apt-get update
81+ sudo apt-get install -y libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf libudev-dev build-essential pkg-config
82+ - name : Install Tauri CLI (locally)
83+ run : npm install @tauri-apps/cli
84+
85+ - name : Clean npm cache
86+ run : npm cache clean --force
87+
88+ - name : Setup macOS Code Signing & Notarization
89+ if : runner.os == 'macOS'
90+ env :
91+ CERT_DEVELOPER_APP_BASE64 : ${{ secrets.CERT_DEVELOPER_APP_BASE64 }}
92+ CERT_DEVELOPER_INSTALL_BASE64 : ${{ secrets.CERT_DEVELOPER_INSTALL_BASE64 }}
93+ CERT_PASSWORD : ${{ secrets.CERT_PASSWORD }}
94+ APPLE_ID : ${{ secrets.APPLE_ID }}
95+ APPLE_PASSWORD : ${{ secrets.APP_PASSWORD }}
96+ TEAM_ID : ${{ secrets.TEAM_ID }}
97+ run : |
98+ echo "$CERT_DEVELOPER_APP_BASE64" | base64 --decode > developer_app.p12
99+ echo "$CERT_DEVELOPER_INSTALL_BASE64" | base64 --decode > developer_installer.p12
100+
101+ security create-keychain -p "" build.keychain-db
102+ security default-keychain -s build.keychain-db
103+ security unlock-keychain -p "" build.keychain-db
104+
105+ security import developer_app.p12 -k build.keychain-db -P "$CERT_PASSWORD" -T /usr/bin/codesign
106+ security import developer_installer.p12 -k build.keychain-db -P "$CERT_PASSWORD" -T /usr/bin/productsign
107+
108+ security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "" build.keychain-db
109+
110+ xcrun notarytool store-credentials "MAC_PASSWORD" \
111+ --apple-id "${{ secrets.APPLE_ID }}" \
112+ --team-id "${{ secrets.TEAM_ID }}" \
113+ --password "${{ secrets.APP_PASSWORD }}"
114+
115+ - name : Build Tauri App
116+ run : npx tauri build
117+
118+ - name : Extract .app from .dmg
119+ if : runner.os == 'macOS'
120+ run : |
121+ dmg_path=$(find src-tauri/target/release/bundle/dmg -name "*.dmg" | head -n 1)
122+ echo "Mounting $dmg_path"
123+ hdiutil attach "$dmg_path" -mountpoint /Volumes/MyApp
124+ mkdir -p SignedApp # Create SignedApp directory if it doesn't exist
125+ cp -R /Volumes/MyApp/*.app ./SignedApp
126+ hdiutil detach /Volumes/MyApp
127+ - name : Sign .app bundle
128+ if : runner.os == 'macOS'
129+ env :
130+ MACOS_SIGN_IDENTITY : ${{ secrets.MACOS_SIGN_IDENTITY }}
131+ run : |
132+ codesign --deep --force --verbose --options runtime \
133+ --sign "${MACOS_SIGN_IDENTITY}" \
134+ SignedApp/*.app
135+ codesign --verify --deep --strict --verbose=2 SignedApp/*.app
136+ - name : Verify SignedApp directory contents
137+ if : runner.os == 'macOS'
138+ run : |
139+ ls -l SignedApp
140+
141+ - name : Rebuild .dmg with signed .app
142+ if : runner.os == 'macOS'
143+ run : |
144+ npm install -g create-dmg
145+ mkdir -p rebuilt-dmg
146+ npx create-dmg SignedApp/*.app rebuilt-dmg --overwrite
147+ - name : Notarize macOS App
148+ if : runner.os == 'macOS'
149+ env :
150+ APPLE_ID : ${{ secrets.APPLE_ID }}
151+ APPLE_PASSWORD : ${{ secrets.APP_PASSWORD }}
152+ TEAM_ID : ${{ secrets.TEAM_ID }}
153+ run : |
154+ dmg_path=$(find rebuilt-dmg -name "*.dmg" | head -n 1)
155+ echo "Submitting for notarization: $dmg_path"
156+ xcrun notarytool submit "$dmg_path" \
157+ --keychain-profile "MAC_PASSWORD" \
158+ --wait
159+
160+
161+ - name : Staple Notarization Ticket
162+ if : runner.os == 'macOS'
163+ run : |
164+ dmg_path=$(find rebuilt-dmg -name "*.dmg" | head -n 1)
165+ xcrun stapler staple "$dmg_path"
166+ - name : Upload Artifact for macOS
167+ if : runner.os == 'macOS'
168+ uses : actions/upload-artifact@v4
169+ with :
170+ name : tauri-app-macos
171+ path : rebuilt-dmg/*.dmg
172+
173+
174+ - name : Upload Artifact for Windows
175+ if : runner.os == 'Windows'
176+ uses : actions/upload-artifact@v4
177+ with :
178+ name : tauri-app-windows
179+ path : src-tauri/target/release/bundle/msi/*.msi
180+
181+ - name : Upload Artifact for Linux (deb)
182+ if : runner.os == 'Linux'
183+ uses : actions/upload-artifact@v4
184+ with :
185+ name : tauri-app-linux-deb
186+ path : src-tauri/target/release/bundle/deb/*.deb
187+
188+ - name : Upload Artifact for Linux (rpm)
189+ if : runner.os == 'Linux'
190+ uses : actions/upload-artifact@v4
191+ with :
192+ name : tauri-app-linux-rpm
193+ path : src-tauri/target/release/bundle/rpm
194+
195+ release :
196+ needs : [build, check-version-and-tag]
197+ runs-on : ubuntu-latest
198+ steps :
199+ - name : Checkout Code
200+ uses : actions/checkout@v4
201+
202+ - name : Fetch All Tags
203+ run : git fetch --tags
204+
205+ - name : Verify Created Tag
206+ id : verified_version
207+ run : |
208+ version="v$(jq -r '.version' package.json)"
209+ echo "::set-output name=version::$version"
210+ echo "Verifying tag $version"
211+ if ! git tag -l | grep -q "$version"; then
212+ echo "Error: Tag $version not found locally."
213+ exit 1
214+ fi
215+ # Download platform-specific artifacts
216+ - name : Download macOS Artifact
217+ uses : actions/download-artifact@v4
218+ with :
219+ name : tauri-app-macos
220+ path : src-tauri/target/release/bundle/dmg
221+
222+ - name : Download Windows Artifact
223+ uses : actions/download-artifact@v4
224+ with :
225+ name : tauri-app-windows
226+ path : src-tauri/target/release/bundle/msi
227+
228+ - name : Download Linux Artifact (deb)
229+ uses : actions/download-artifact@v4
230+ with :
231+ name : tauri-app-linux-deb
232+ path : src-tauri/target/release/bundle/deb
233+
234+ - name : Download Linux Artifact (rpm)
235+ uses : actions/download-artifact@v4
236+ with :
237+ name : tauri-app-linux-rpm
238+ path : src-tauri/target/release/bundle/rpm
239+
240+ # Create GitHub Release with only artifacts
241+ - name : Create Release
242+ uses : softprops/action-gh-release@v1
243+ with :
244+ tag_name : " ${{ steps.verified_version.outputs.version }}"
245+ files : |
246+ src-tauri/target/release/bundle/dmg/*.dmg
247+ src-tauri/target/release/bundle/msi/*.msi
248+ src-tauri/target/release/bundle/deb/*.deb
249+ src-tauri/target/release/bundle/rpm/*.rpm
250+ draft : false
251+ env :
252+ GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
0 commit comments