[CONFIG] Add a daily CI check that flags drift between the bootstrap … #17
Workflow file for this run
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
| # Builds standalone haven-proxy executables (Node SEA) for Windows, macOS and | |
| # Linux. SEA cannot cross-compile, so each OS builds natively on its own runner. | |
| # | |
| # - push of a v* tag: build, smoke-test, and attach binaries to a GitHub Release | |
| # - workflow_dispatch: build + smoke-test only (artifacts downloadable from the run) | |
| name: release | |
| on: | |
| push: | |
| tags: ["v*"] | |
| release: | |
| types: [published] | |
| workflow_dispatch: | |
| # A release published via the UI with a new tag fires both the tag push and the | |
| # release event — keep only one run per ref. | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| permissions: | |
| contents: write # gh release create/upload | |
| jobs: | |
| build: | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - os: windows-latest | |
| artifact: haven-proxy-win-x64.exe | |
| built: dist/haven-proxy.exe | |
| - os: macos-latest | |
| artifact: haven-proxy-macos-arm64 | |
| built: dist/haven-proxy | |
| - os: ubuntu-latest | |
| artifact: haven-proxy-linux-x64 | |
| built: dist/haven-proxy | |
| runs-on: ${{ matrix.os }} | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - uses: actions/setup-node@v7 | |
| with: | |
| node-version: 24 | |
| - run: npm ci | |
| # The binary and installer carry the tag's version, not whatever happens to | |
| # be committed. Runs after npm ci (which validates package.json vs the lock) | |
| # and is skipped on workflow_dispatch, where committed versions stand. | |
| - name: Stamp version from tag | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| run: node scripts/set-version.mjs "${{ github.ref_name }}" | |
| - run: npm run build:exe | |
| - name: Smoke test (help + version) | |
| shell: bash | |
| run: | | |
| ./${{ matrix.built }} help | |
| ./${{ matrix.built }} --version | |
| if [[ "$GITHUB_REF" == refs/tags/v* ]]; then | |
| test "$(./${{ matrix.built }} --version)" = "haven-proxy ${GITHUB_REF_NAME#v}" | |
| fi | |
| - name: Smoke test (start → health → models → status → stop) | |
| shell: bash | |
| env: | |
| # serve requires a key but listens before validating it, so a dummy | |
| # key exercises the full daemon lifecycle; attestation/key warnings | |
| # in the log are expected and non-fatal. | |
| HAVEN_API_KEY: hvn1_dummy_ci_smoke_test | |
| run: | | |
| set -x | |
| ./${{ matrix.built }} start | |
| curl -fsS http://127.0.0.1:3301/health | |
| curl -fsS http://127.0.0.1:3301/v1/models | grep -q gpt-oss-120b | |
| ./${{ matrix.built }} status || true # balance check fails on the dummy key; must not crash | |
| ./${{ matrix.built }} stop | |
| cat ~/.haven-proxy/proxy.log | |
| - name: Rename artifact | |
| shell: bash | |
| run: cp ${{ matrix.built }} ${{ matrix.artifact }} | |
| - uses: actions/upload-artifact@v7 | |
| with: | |
| name: ${{ matrix.artifact }} | |
| path: ${{ matrix.artifact }} | |
| if-no-files-found: error | |
| - name: Attach to GitHub Release | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| shell: bash | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| # Matrix jobs race to create the release — treat "already exists" as fine. | |
| gh release create "${{ github.ref_name }}" --generate-notes || true | |
| gh release upload "${{ github.ref_name }}" "${{ matrix.artifact }}" --clobber | |
| # Electron tray app (app/): unsigned prototype installers per OS. | |
| app: | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - os: windows-latest | |
| build: --win | |
| glob: app/dist/HavenProxy-Setup-*.exe | |
| - os: macos-latest | |
| build: --mac | |
| glob: app/dist/HavenProxy-*.dmg | |
| - os: ubuntu-latest | |
| build: --linux | |
| glob: app/dist/HavenProxy-*.AppImage | |
| runs-on: ${{ matrix.os }} | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - uses: actions/setup-node@v7 | |
| with: | |
| node-version: 24 | |
| # Root deps first: app/node_modules/haven-proxy is a file:.. symlink whose | |
| # imports (the SecureClient SDK, @ai-sdk/*) resolve through the repo root's | |
| # node_modules. | |
| - run: npm ci | |
| - run: npm install | |
| working-directory: app | |
| # After both installs: electron-builder reads app/package.json's version at | |
| # build time, and stamping earlier would just make npm install rewrite it. | |
| - name: Stamp version from tag | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| run: node scripts/set-version.mjs "${{ github.ref_name }}" | |
| # Not electron-builder directly: `dist` esbuilds app/ into app/.bundle first, | |
| # and that's the directory electron-builder packages. | |
| - run: npm run dist -- ${{ matrix.build }} | |
| working-directory: app | |
| env: | |
| # No signing certs in CI — prevent electron-builder from trying. | |
| CSC_IDENTITY_AUTO_DISCOVERY: "false" | |
| - name: Check no .env leaked into the package | |
| shell: bash | |
| run: | | |
| if [ -d app/dist/win-unpacked ]; then RES=app/dist/win-unpacked/resources; | |
| elif [ -d app/dist/linux-unpacked ]; then RES=app/dist/linux-unpacked/resources; | |
| else RES=$(ls -d app/dist/mac*/ 2>/dev/null | head -1)"Haven Proxy.app/Contents/Resources"; fi | |
| if npx --prefix app asar list "$RES/app.asar" | grep -i "\.env"; then | |
| echo "::error::.env file packaged into the app"; exit 1 | |
| fi | |
| echo "asar clean ✓" | |
| - uses: actions/upload-artifact@v7 | |
| with: | |
| name: haven-proxy-app-${{ runner.os }} | |
| path: ${{ matrix.glob }} | |
| if-no-files-found: error | |
| - name: Attach to GitHub Release | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| shell: bash | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| gh release create "${{ github.ref_name }}" --generate-notes || true | |
| gh release upload "${{ github.ref_name }}" ${{ matrix.glob }} --clobber |