feat(gateway): full headless model management — pull/delete/activate/… #22
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 | |
| - 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 |