|
4 | 4 | push: |
5 | 5 | branches: |
6 | 6 | - '**' |
| 7 | + paths-ignore: |
| 8 | + - '**/*.md' |
| 9 | + - 'doc/**' |
| 10 | + - '!doc/icon.png' |
7 | 11 | workflow_dispatch: |
8 | 12 |
|
9 | 13 | permissions: |
10 | 14 | contents: read |
11 | 15 |
|
| 16 | +concurrency: |
| 17 | + group: electron-compile-${{ github.ref }} |
| 18 | + cancel-in-progress: true |
| 19 | + |
12 | 20 | jobs: |
13 | 21 | compile: |
14 | 22 | # For multi-commit pushes, evaluate the newest commit's message. |
15 | 23 | if: github.event_name == 'workflow_dispatch' || startsWith(github.event.head_commit.message, 'fix') || startsWith(github.event.head_commit.message, 'feat') |
16 | | - name: Compile ${{ matrix.platform }} ${{ matrix.arch }} |
| 24 | + name: Compile ${{ matrix.platform }} ${{ matrix.arch }} ${{ matrix.extra-arch }} |
17 | 25 | runs-on: ${{ matrix.runner }} |
18 | 26 | timeout-minutes: 30 |
| 27 | + env: |
| 28 | + # Packaging downloads the target binary; npm only needs Electron metadata. |
| 29 | + ELECTRON_SKIP_BINARY_DOWNLOAD: '1' |
19 | 30 | strategy: |
20 | 31 | fail-fast: false |
21 | 32 | matrix: |
22 | 33 | include: |
23 | 34 | - runner: macos-15 |
24 | 35 | platform: darwin |
25 | 36 | arch: arm64 |
26 | | - electron: '' |
| 37 | + extra-arch: '' |
27 | 38 | - runner: macos-15-intel |
28 | 39 | platform: darwin |
29 | 40 | arch: x64 |
30 | | - electron: '' |
| 41 | + extra-arch: '' |
31 | 42 | - runner: windows-2022 |
32 | 43 | platform: win32 |
33 | 44 | arch: x64 |
34 | | - electron: '' |
35 | | - - runner: windows-2022 |
36 | | - platform: win32 |
37 | | - arch: ia32 |
38 | | - # Electron 43 is the last release series with 32-bit binaries. |
39 | | - electron: '43.4.1' |
| 45 | + extra-arch: ia32 |
40 | 46 | - runner: ubuntu-24.04 |
41 | 47 | platform: linux |
42 | 48 | arch: x64 |
43 | | - electron: '' |
44 | | - - runner: ubuntu-24.04 |
45 | | - platform: linux |
46 | | - arch: armv7l |
47 | | - electron: '43.4.1' |
| 49 | + extra-arch: armv7l |
48 | 50 | steps: |
49 | 51 | - uses: actions/checkout@v5 |
50 | 52 | - uses: actions/setup-node@v5 |
| 53 | + id: node |
51 | 54 | with: |
52 | 55 | node-version: '22' |
53 | 56 | cache: npm |
| 57 | + # Native dependencies require the same host OS, CPU and exact Node version. |
| 58 | + # No partial restores: changed lockfiles always require npm ci. |
| 59 | + - name: Restore installed dependencies |
| 60 | + uses: actions/cache@v4 |
| 61 | + id: dependencies |
| 62 | + with: |
| 63 | + path: node_modules |
| 64 | + key: modules-v1-${{ matrix.runner }}-${{ runner.arch }}-${{ steps.node.outputs.node-version }}-${{ hashFiles('package.json', 'package-lock.json') }} |
54 | 65 | - name: Install dependencies |
55 | | - run: npm ci |
| 66 | + if: steps.dependencies.outputs.cache-hit != 'true' |
| 67 | + run: npm ci --prefer-offline --no-audit --no-fund |
| 68 | + - name: Cache Electron downloads |
| 69 | + uses: actions/cache@v4 |
| 70 | + with: |
| 71 | + path: | |
| 72 | + ~/.cache/electron |
| 73 | + ~/Library/Caches/electron |
| 74 | + ~/AppData/Local/electron/Cache |
| 75 | + key: electron-v1-${{ matrix.platform }}-${{ matrix.arch }}-${{ matrix.extra-arch }}-${{ hashFiles('package-lock.json', '.github/workflows/electron-build.yml') }} |
| 76 | + restore-keys: | |
| 77 | + electron-v1-${{ matrix.platform }}-${{ matrix.arch }}-${{ matrix.extra-arch }}- |
56 | 78 | - name: Test PDF extraction without native architecture bindings |
57 | | - if: matrix.arch == 'ia32' || matrix.arch == 'armv7l' || (matrix.platform == 'darwin' && matrix.arch == 'x64') |
| 79 | + if: matrix.extra-arch != '' || (matrix.platform == 'darwin' && matrix.arch == 'x64') |
58 | 80 | run: node --test server/pdf-extractor.test.mjs |
59 | | - - name: Generate macOS icons and symbols |
| 81 | + - name: Cache macOS icons and symbols |
60 | 82 | if: matrix.platform == 'darwin' |
| 83 | + uses: actions/cache@v4 |
| 84 | + id: icons |
| 85 | + with: |
| 86 | + path: | |
| 87 | + electron/AppIcon.icns |
| 88 | + electron/AppIcon.ico |
| 89 | + electron/AppIcon.png |
| 90 | + public/symbols |
| 91 | + key: icons-v1-${{ matrix.runner }}-${{ hashFiles('doc/icon.png', 'electron/generate-icon.mjs', 'electron/export-symbols.swift', '.github/workflows/electron-build.yml') }} |
| 92 | + - name: Generate macOS icons and symbols |
| 93 | + if: matrix.platform == 'darwin' && steps.icons.outputs.cache-hit != 'true' |
61 | 94 | run: npm run icons:mac |
| 95 | + # Both architectures share this host installation and frontend build. |
62 | 96 | - name: Build frontend |
63 | 97 | run: npm run build |
64 | | - - name: Package Electron app without signing credentials |
65 | | - run: node electron/package.mjs --platform=${{ matrix.platform }} --arch=${{ matrix.arch }} --electron-version=${{ matrix.electron }} --unsigned |
66 | | - - name: Archive Unix app |
| 98 | + - name: Package primary architecture |
| 99 | + run: node electron/package.mjs --platform=${{ matrix.platform }} --arch=${{ matrix.arch }} --unsigned |
| 100 | + - name: Package secondary architecture |
| 101 | + if: matrix.extra-arch != '' |
| 102 | + run: node electron/package.mjs --platform=${{ matrix.platform }} --arch=${{ matrix.extra-arch }} --electron-version=43.4.1 --unsigned |
| 103 | + - name: Archive Unix apps |
67 | 104 | if: matrix.platform != 'win32' |
68 | | - run: tar -czf release/PDFMathReader-${{ matrix.platform }}-${{ matrix.arch }}.tar.gz -C release PDFMathReader-${{ matrix.platform }}-${{ matrix.arch }} |
69 | | - - name: Archive Windows app |
| 105 | + shell: bash |
| 106 | + run: | |
| 107 | + for app in release/PDFMathReader-${{ matrix.platform }}-*; do |
| 108 | + tar -czf "$app.tar.gz" -C release "$(basename "$app")" |
| 109 | + done |
| 110 | + - name: Archive Windows apps |
70 | 111 | if: matrix.platform == 'win32' |
71 | | - run: Compress-Archive -Path release/PDFMathReader-win32-${{ matrix.arch }} -DestinationPath release/PDFMathReader-win32-${{ matrix.arch }}.zip |
72 | | - - name: Upload compiled app |
| 112 | + run: | |
| 113 | + Get-ChildItem release -Directory -Filter 'PDFMathReader-win32-*' | ForEach-Object { |
| 114 | + Compress-Archive -LiteralPath $_.FullName -DestinationPath "$($_.FullName).zip" |
| 115 | + } |
| 116 | + - name: Upload primary app |
73 | 117 | uses: actions/upload-artifact@v6 |
74 | 118 | with: |
75 | 119 | name: PDFMathReader-${{ matrix.platform }}-${{ matrix.arch }} |
76 | 120 | path: | |
77 | 121 | release/PDFMathReader-${{ matrix.platform }}-${{ matrix.arch }}.tar.gz |
78 | 122 | release/PDFMathReader-${{ matrix.platform }}-${{ matrix.arch }}.zip |
79 | 123 | if-no-files-found: error |
| 124 | + compression-level: 0 |
| 125 | + retention-days: 7 |
| 126 | + - name: Upload secondary app |
| 127 | + if: matrix.extra-arch != '' |
| 128 | + uses: actions/upload-artifact@v6 |
| 129 | + with: |
| 130 | + name: PDFMathReader-${{ matrix.platform }}-${{ matrix.extra-arch }} |
| 131 | + path: | |
| 132 | + release/PDFMathReader-${{ matrix.platform }}-${{ matrix.extra-arch }}.tar.gz |
| 133 | + release/PDFMathReader-${{ matrix.platform }}-${{ matrix.extra-arch }}.zip |
| 134 | + if-no-files-found: error |
| 135 | + compression-level: 0 |
80 | 136 | retention-days: 7 |
0 commit comments