fix(ci): pull Git LFS in the build job — releases shipped pointer stu… #26
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Build and Release | |
| on: | |
| push: | |
| branches: | |
| - main | |
| permissions: | |
| contents: write | |
| concurrency: | |
| group: release | |
| cancel-in-progress: false | |
| jobs: | |
| # Bump the version once (on Ubuntu) and push it, so every matrix job builds the | |
| # same version. [skip ci] keeps it from re-triggering. | |
| version: | |
| if: "!contains(github.event.head_commit.message, '[skip ci]')" | |
| runs-on: ubuntu-latest | |
| outputs: | |
| version: ${{ steps.bump.outputs.version }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| fetch-depth: 0 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| - name: Bump patch version | |
| id: bump | |
| run: | | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| npm version patch --no-git-tag-version | |
| VERSION=$(node -p "require('./package.json').version") | |
| echo "version=$VERSION" >> "$GITHUB_OUTPUT" | |
| git add package.json package-lock.json | |
| git commit -m "chore: bump version to $VERSION [skip ci]" | |
| git push | |
| # Build + publish per-OS natively (native modules + platform binaries differ). | |
| build: | |
| needs: version | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| # windows-2022 = VS 2022 toolchain; windows-latest ships VS 18 (2026) | |
| # which node-gyp 11 can't parse, breaking native-module compiles. | |
| os: [macos-latest, windows-2022] | |
| runs-on: ${{ matrix.os }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| ref: main # the just-bumped commit | |
| fetch-depth: 0 | |
| lfs: true # resources/bin/* (llama-server, sd-cli, whisper, ffmpeg, dylibs) | |
| # are Git LFS — without this, CI bundles 131-byte pointer stubs | |
| # and every runtime spawn fails with ENOEXEC. | |
| - name: Pull LFS binaries | |
| run: git lfs pull | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: '20' | |
| cache: 'npm' | |
| # node-gyp (better-sqlite3-multiple-ciphers) fails on Python 3.13+; pin 3.12. | |
| - uses: actions/setup-python@v5 | |
| if: runner.os == 'Windows' | |
| with: | |
| python-version: '3.12' | |
| - name: Install dependencies | |
| run: npm ci | |
| # Windows needs win64 native runner binaries (the repo ships macOS ones). | |
| - name: Fetch Windows binaries | |
| if: runner.os == 'Windows' | |
| shell: pwsh | |
| run: ./scripts/fetch-win-binaries.ps1 | |
| # macOS signing identity (no-op if the secret is absent → unsigned build). | |
| - name: Import Apple signing certificate | |
| if: runner.os == 'macOS' && env.CSC_LINK != '' | |
| env: | |
| CSC_LINK: ${{ secrets.CSC_LINK }} | |
| run: echo "Signing cert provided via CSC_LINK" | |
| - name: Build (typecheck + bundle) | |
| run: npm run build | |
| - name: Package & publish (macOS) | |
| if: runner.os == 'macOS' | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| CSC_LINK: ${{ secrets.CSC_LINK }} | |
| CSC_KEY_PASSWORD: ${{ secrets.CSC_KEY_PASSWORD }} | |
| APPLE_API_KEY_CONTENT: ${{ secrets.APPLE_API_KEY }} | |
| APPLE_API_KEY_ID: ${{ secrets.APPLE_API_KEY_ID }} | |
| APPLE_API_ISSUER: ${{ secrets.APPLE_API_ISSUER }} | |
| APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} | |
| run: | | |
| # notarytool needs the API key as a file; write it from the secret. | |
| printf '%s' "$APPLE_API_KEY_CONTENT" > "$RUNNER_TEMP/AuthKey.p8" | |
| export APPLE_API_KEY="$RUNNER_TEMP/AuthKey.p8" | |
| npx electron-builder --mac --publish always | |
| - name: Package & publish (Windows) | |
| if: runner.os == 'Windows' | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| # Optional Windows code signing (no-op if absent → unsigned, SmartScreen warns) | |
| CSC_LINK: ${{ secrets.WIN_CSC_LINK }} | |
| CSC_KEY_PASSWORD: ${{ secrets.WIN_CSC_KEY_PASSWORD }} | |
| run: npx electron-builder --win --publish always | |
| - name: Upload artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: dist-${{ matrix.os }} | |
| path: | | |
| dist/*.dmg | |
| dist/*.exe | |
| dist/*.zip | |
| if-no-files-found: ignore |