|
1 | | -name: Build All Platforms & Deploy |
| 1 | +name: Deploy Web to GitHub Pages |
2 | 2 |
|
3 | 3 | on: |
4 | 4 | push: |
5 | 5 | branches: ["master"] |
6 | 6 | workflow_dispatch: |
7 | 7 |
|
8 | 8 | permissions: |
9 | | - contents: write |
| 9 | + contents: read |
10 | 10 | pages: write |
11 | 11 | id-token: write |
12 | 12 |
|
13 | 13 | concurrency: |
14 | | - group: "deploy-all" |
| 14 | + group: "pages" |
15 | 15 | cancel-in-progress: true |
16 | 16 |
|
17 | 17 | jobs: |
18 | | - build-desktop: |
19 | | - name: Build Desktop Apps |
20 | | - strategy: |
21 | | - fail-fast: false |
22 | | - matrix: |
23 | | - include: |
24 | | - - os: ubuntu-latest |
25 | | - target: x86_64-unknown-linux-gnu |
26 | | - name: linux |
27 | | - - os: windows-latest |
28 | | - target: x86_64-pc-windows-msvc |
29 | | - name: windows |
30 | | - - os: macos-latest |
31 | | - target: x86_64-apple-darwin |
32 | | - name: macos-intel |
33 | | - - os: macos-latest |
34 | | - target: aarch64-apple-darwin |
35 | | - name: macos-apple-silicon |
36 | | - runs-on: ${{ matrix.os }} |
37 | | - steps: |
38 | | - - name: Checkout |
39 | | - uses: actions/checkout@v4 |
40 | | - |
41 | | - - name: Setup Node.js |
42 | | - uses: actions/setup-node@v4 |
43 | | - with: |
44 | | - node-version: 22 |
45 | | - cache: "npm" |
46 | | - |
47 | | - - name: Install Dependencies |
48 | | - run: npm install |
49 | | - |
50 | | - - name: Install Rust Toolchain |
51 | | - uses: dtolnay/rust-toolchain@stable |
52 | | - with: |
53 | | - targets: ${{ matrix.target }} |
54 | | - |
55 | | - - name: Cache Rust Dependencies |
56 | | - uses: actions/cache@v4 |
57 | | - with: |
58 | | - path: | |
59 | | - ~/.cargo/registry |
60 | | - ~/.cargo/git |
61 | | - src-tauri/target |
62 | | - key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} |
63 | | - |
64 | | - - name: Install Linux Dependencies |
65 | | - if: matrix.os == 'ubuntu-latest' |
66 | | - run: | |
67 | | - sudo apt update |
68 | | - sudo apt install -y libgtk-3-dev libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf |
69 | | -
|
70 | | - - name: Install macOS Dependencies |
71 | | - if: matrix.os == 'macos-latest' |
72 | | - run: | |
73 | | - # Install genisoimage for DMG creation |
74 | | - brew install genisoimage || echo "genisoimage already installed or not needed" |
75 | | -
|
76 | | - - name: Debug Build Environment |
77 | | - run: | |
78 | | - echo "OS: ${{ matrix.os }}" |
79 | | - echo "Target: ${{ matrix.target }}" |
80 | | - echo "Node version: $(node --version)" |
81 | | - echo "npm version: $(npm --version)" |
82 | | - echo "Rust version: $(rustc --version)" |
83 | | - echo "Cargo version: $(cargo --version)" |
84 | | - if [ "${{ matrix.os }}" = "macos-latest" ]; then |
85 | | - echo "macOS version: $(sw_vers)" |
86 | | - echo "Available disk space: $(df -h)" |
87 | | - fi |
88 | | - shell: bash |
89 | | - |
90 | | - - name: Build Tauri App |
91 | | - run: | |
92 | | - # Build based on platform |
93 | | - if [ "${{ matrix.os }}" = "ubuntu-latest" ]; then |
94 | | - npx tauri build --target ${{ matrix.target }} --bundles deb,appimage |
95 | | - elif [ "${{ matrix.os }}" = "windows-latest" ]; then |
96 | | - npx tauri build --target ${{ matrix.target }} --bundles nsis,msi |
97 | | - elif [ "${{ matrix.os }}" = "macos-latest" ]; then |
98 | | - # Build only dmg for macOS |
99 | | - npx tauri build --target ${{ matrix.target }} --bundles dmg |
100 | | - fi |
101 | | - shell: bash |
102 | | - |
103 | | - - name: List Build Output |
104 | | - run: | |
105 | | - echo "Build output structure:" |
106 | | - find src-tauri/target/${{ matrix.target }}/release/bundle -type f -name "*" 2>/dev/null | head -20 || echo "No bundle files found" |
107 | | - shell: bash |
108 | | - |
109 | | - - name: Upload Release Artifact |
110 | | - uses: actions/upload-artifact@v4 |
111 | | - with: |
112 | | - name: ${{ matrix.name }}-build |
113 | | - path: | |
114 | | - src-tauri/target/${{ matrix.target }}/release/bundle |
115 | | - !**/*.dSYM |
116 | | - if-no-files-found: warn |
117 | | - |
118 | | - build-android: |
119 | | - name: Build Android APK |
120 | | - runs-on: ubuntu-latest |
121 | | - steps: |
122 | | - - name: Checkout |
123 | | - uses: actions/checkout@v4 |
124 | | - |
125 | | - - name: Setup Node.js |
126 | | - uses: actions/setup-node@v4 |
127 | | - with: |
128 | | - node-version: 22 |
129 | | - cache: "npm" |
130 | | - |
131 | | - - name: Install Dependencies |
132 | | - run: npm install |
133 | | - |
134 | | - - name: Setup Java |
135 | | - uses: actions/setup-java@v4 |
136 | | - with: |
137 | | - distribution: "temurin" |
138 | | - java-version: "17" |
139 | | - |
140 | | - - name: Setup Android SDK |
141 | | - uses: android-actions/setup-android@v3 |
142 | | - |
143 | | - - name: Cache Android Dependencies |
144 | | - uses: actions/cache@v4 |
145 | | - with: |
146 | | - path: | |
147 | | - ~/.android/cache |
148 | | - ~/.gradle/caches |
149 | | - ~/.gradle/wrapper |
150 | | - src-tauri/gen/android/.gradle |
151 | | - key: ${{ runner.os }}-android-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} |
152 | | - |
153 | | - - name: Install Rust Toolchain |
154 | | - uses: dtolnay/rust-toolchain@stable |
155 | | - |
156 | | - - name: Cache Rust Dependencies |
157 | | - uses: actions/cache@v4 |
158 | | - with: |
159 | | - path: | |
160 | | - ~/.cargo/registry |
161 | | - ~/.cargo/git |
162 | | - src-tauri/target |
163 | | - key: ${{ runner.os }}-android-cargo-${{ hashFiles('**/Cargo.lock') }} |
164 | | - |
165 | | - - name: Install Android Rust Targets |
166 | | - run: | |
167 | | - rustup target add aarch64-linux-android armv7-linux-androideabi i686-linux-android x86_64-linux-android |
168 | | -
|
169 | | - - name: Setup Android NDK |
170 | | - run: | |
171 | | - echo "ANDROID_NDK_HOME=$ANDROID_SDK_ROOT/ndk/27.2.12479018" >> $GITHUB_ENV |
172 | | - echo "NDK_HOME=$ANDROID_SDK_ROOT/ndk/27.2.12479018" >> $GITHUB_ENV |
173 | | -
|
174 | | - - name: Install Android NDK |
175 | | - run: | |
176 | | - sdkmanager "ndk;27.2.12479018" |
177 | | -
|
178 | | - - name: Initialize Android Project |
179 | | - run: | |
180 | | - # Remove existing Android project to avoid package name conflicts |
181 | | - if [ -d "src-tauri/gen/android" ]; then |
182 | | - echo "Removing existing Android project to avoid package conflicts..." |
183 | | - rm -rf src-tauri/gen/android |
184 | | - fi |
185 | | - echo "Initializing Android project..." |
186 | | - npx tauri android init |
187 | | -
|
188 | | - - name: Update Android Icons |
189 | | - run: | |
190 | | - echo "Regenerating Android icons with latest logo..." |
191 | | - npx tauri icon public/logo.png |
192 | | - echo "Android icons updated successfully!" |
193 | | -
|
194 | | - - name: Update Android Theme |
195 | | - run: | |
196 | | - echo "Updating Android theme to follow system theme..." |
197 | | - node update-android-theme.js |
198 | | - - name: Setup Android Signing |
199 | | - run: | |
200 | | - cd src-tauri/gen/android |
201 | | - echo "keyAlias=${{ secrets.ANDROID_KEY_ALIAS }}" > keystore.properties |
202 | | - echo "password=${{ secrets.ANDROID_KEY_PASSWORD }}" >> keystore.properties |
203 | | - base64 -d <<< "${{ secrets.ANDROID_KEY_BASE64 }}" > $RUNNER_TEMP/keystore.jks |
204 | | - echo "storeFile=$RUNNER_TEMP/keystore.jks" >> keystore.properties |
205 | | - echo "Keystore properties configured:" |
206 | | - cat keystore.properties | sed 's/password=.*/password=***/' |
207 | | -
|
208 | | - - name: Build Signed Android APK (Release) |
209 | | - run: | |
210 | | - echo "Building signed APK..." |
211 | | - npx tauri android build --apk --split-per-abi |
212 | | -
|
213 | | - - name: Sign APKs with apksigner |
214 | | - run: | |
215 | | - echo "Signing APKs with apksigner..." |
216 | | -
|
217 | | - # Find and sign all unsigned APKs |
218 | | - find src-tauri/gen/android/app/build/outputs/apk -name "*-unsigned.apk" -type f | while read unsigned_apk; do |
219 | | - # Create signed APK filename |
220 | | - signed_apk="${unsigned_apk/-unsigned.apk/-signed.apk}" |
221 | | - |
222 | | - echo "Signing: $unsigned_apk -> $signed_apk" |
223 | | - |
224 | | - # Sign the APK |
225 | | - $ANDROID_HOME/build-tools/34.0.0/apksigner sign \ |
226 | | - --ks $RUNNER_TEMP/keystore.jks \ |
227 | | - --ks-key-alias ${{ secrets.ANDROID_KEY_ALIAS }} \ |
228 | | - --ks-pass pass:${{ secrets.ANDROID_KEY_PASSWORD }} \ |
229 | | - --key-pass pass:${{ secrets.ANDROID_KEY_PASSWORD }} \ |
230 | | - --out "$signed_apk" \ |
231 | | - "$unsigned_apk" |
232 | | - |
233 | | - # Verify the signed APK |
234 | | - echo "Verifying signed APK: $signed_apk" |
235 | | - $ANDROID_HOME/build-tools/34.0.0/apksigner verify "$signed_apk" |
236 | | - |
237 | | - if [ $? -eq 0 ]; then |
238 | | - echo "✅ Successfully signed and verified: $(basename "$signed_apk")" |
239 | | - else |
240 | | - echo "❌ Failed to verify: $(basename "$signed_apk")" |
241 | | - fi |
242 | | - done |
243 | | -
|
244 | | - - name: Verify APK Signing |
245 | | - run: | |
246 | | - echo "Verifying APK signing status..." |
247 | | - find src-tauri/gen/android/app/build/outputs/apk -name "*-signed.apk" -type f | while read apk; do |
248 | | - echo "Checking: $apk" |
249 | | - if command -v aapt &> /dev/null; then |
250 | | - aapt dump badging "$apk" | grep "package:" || true |
251 | | - fi |
252 | | - # Also check with jarsigner |
253 | | - if command -v jarsigner &> /dev/null; then |
254 | | - echo "Jarsigner verification:" |
255 | | - jarsigner -verify -verbose -certs "$apk" || true |
256 | | - fi |
257 | | - echo "---" |
258 | | - done |
259 | | -
|
260 | | - - name: List Android Build Output |
261 | | - run: | |
262 | | - echo "Contents of src-tauri/gen/android/app/build/outputs/apk:" |
263 | | - find src-tauri/gen/android/app/build/outputs/apk -name "*.apk" -type f || echo "No APK files found" |
264 | | - echo "" |
265 | | - echo "Signed APKs:" |
266 | | - find src-tauri/gen/android/app/build/outputs/apk -name "*-signed.apk" -type f || echo "No signed APK files found" |
267 | | -
|
268 | | - - name: Upload Signed Android APK |
269 | | - uses: actions/upload-artifact@v4 |
270 | | - with: |
271 | | - name: android-build-signed |
272 | | - path: | |
273 | | - src-tauri/gen/android/app/build/outputs/apk/**/*-signed.apk |
274 | | -
|
275 | 18 | web: |
276 | 19 | name: Build Web & Deploy to GitHub Pages |
277 | 20 | runs-on: ubuntu-latest |
278 | | - needs: [build-desktop, build-android] |
279 | | - # Only run GitHub Pages deployment in the forked repository |
280 | | - if: github.repository == 'image-compressor/image-compressor.github.io' |
281 | | - steps: |
282 | | - - name: Checkout |
283 | | - uses: actions/checkout@v4 |
284 | 21 |
|
285 | | - - name: Setup Node |
286 | | - uses: actions/setup-node@v4 |
287 | | - with: |
288 | | - node-version: 22 |
289 | | - cache: "npm" |
290 | | - |
291 | | - - name: Install dependencies |
292 | | - run: npm install |
293 | | - |
294 | | - - name: Build web |
295 | | - run: npm run build |
296 | | - |
297 | | - - name: Setup Pages |
298 | | - uses: actions/configure-pages@v3 |
299 | | - |
300 | | - - name: Upload artifact |
301 | | - uses: actions/upload-pages-artifact@v3 |
302 | | - with: |
303 | | - path: "./dist" |
304 | | - |
305 | | - - name: Deploy to GitHub Pages |
306 | | - id: deployment |
307 | | - uses: actions/deploy-pages@v4 |
| 22 | + # Optional: restrict to your repo only |
| 23 | + if: github.repository == 'image-compressor/image-compressor.github.io' |
308 | 24 |
|
309 | | - release: |
310 | | - name: Release to GitHub |
311 | | - runs-on: ubuntu-latest |
312 | | - needs: [build-desktop, build-android] |
313 | | - # Always run release job regardless of which repository |
314 | 25 | steps: |
315 | | - - name: Checkout |
316 | | - uses: actions/checkout@v4 |
| 26 | + - uses: actions/checkout@v4 |
317 | 27 |
|
318 | | - - name: Download all artifacts |
319 | | - uses: actions/download-artifact@v4 |
| 28 | + - uses: actions/setup-node@v4 |
320 | 29 | with: |
321 | | - path: ./artifacts |
322 | | - |
323 | | - - name: Prepare release files |
324 | | - run: | |
325 | | - mkdir -p release-files |
326 | | -
|
327 | | - # Copy Android APKs (only signed ones) |
328 | | - find artifacts/android-build-signed -name "*-signed.apk" -type f -exec cp {} release-files/ \; |
329 | | -
|
330 | | - # Copy desktop builds |
331 | | - find artifacts/windows-build -name "*.exe" -type f -exec cp {} release-files/ \; |
332 | | - find artifacts/windows-build -name "*.msi" -type f -exec cp {} release-files/ \; |
333 | | - find artifacts/macos-intel-build -name "*.dmg" -type f -exec cp {} release-files/ \; |
334 | | - find artifacts/macos-apple-silicon-build -name "*.dmg" -type f -exec cp {} release-files/ \; |
335 | | - find artifacts/linux-build -name "*.deb" -type f -exec cp {} release-files/ \; |
336 | | - find artifacts/linux-build -name "*.AppImage" -type f -exec cp {} release-files/ \; |
| 30 | + node-version: 22 |
| 31 | + cache: npm |
337 | 32 |
|
338 | | - # List all files |
339 | | - echo "Release files:" |
340 | | - ls -la release-files/ |
| 33 | + - run: npm install |
| 34 | + - run: npm run build |
341 | 35 |
|
342 | | - - name: Generate release tag |
343 | | - id: tag |
344 | | - run: | |
345 | | - # Get version from package.json |
346 | | - VERSION=$(node -p "require('./package.json').version") |
347 | | - # Create a tag with project version and git SHA |
348 | | - TAG="v${VERSION}-$(echo ${{ github.sha }} | cut -c1-7)" |
349 | | - echo "tag=$TAG" >> $GITHUB_OUTPUT |
350 | | - echo "Generated tag: $TAG" |
| 36 | + - uses: actions/configure-pages@v3 |
351 | 37 |
|
352 | | - - name: Create GitHub Release |
353 | | - uses: softprops/action-gh-release@v2 |
| 38 | + - uses: actions/upload-pages-artifact@v3 |
354 | 39 | with: |
355 | | - name: "Release ${{ steps.tag.outputs.tag }}" |
356 | | - tag_name: ${{ steps.tag.outputs.tag }} |
357 | | - body: | |
358 | | - Automated release from commit ${{ github.sha }} |
359 | | -
|
360 | | - ## Changes |
361 | | - - Built for all platforms (Windows, macOS, Linux, Android) |
362 | | - - Web deployment to GitHub Pages |
| 40 | + path: ./dist |
363 | 41 |
|
364 | | - ## Downloads |
365 | | - - **Windows**: Download `.exe` or `.msi` files |
366 | | - - **macOS**: Download `.dmg` files (recommended installer) |
367 | | - - **Linux**: Download `.deb` or `.AppImage` files |
368 | | - - **Android**: Download `.apk` files for direct installation |
369 | | - files: | |
370 | | - release-files/* |
371 | | - draft: false |
372 | | - prerelease: false |
| 42 | + - uses: actions/deploy-pages@v4 |
0 commit comments