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 "[email protected] "
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