name: Build Windows installer # The agent's source lives in a private repository whose Actions are currently billing-blocked. # This repository is public, so its runner minutes are free — it checks the source out with a # read-only deploy key and attaches the resulting installer to a release here. # # The installer is UNSIGNED: no Windows code-signing certificate exists yet. Once one does, the # private repo's `release-agent.yml` is the proper home for this and this workflow should go. # # Note that this repository is public and so are these logs. Keep build output out of them if a # step would ever echo source. on: workflow_dispatch: inputs: tag: description: "Release tag to attach the installer to" required: true default: "v0.1.0" ref: description: "Branch or tag of the source repo to build" required: true default: "main" permissions: contents: write # attaching the installer to this repo's release jobs: build: runs-on: windows-latest steps: - name: Check out agent source uses: actions/checkout@v4 with: repository: BigMarc/TimeBunny ref: ${{ inputs.ref }} ssh-key: ${{ secrets.SOURCE_DEPLOY_KEY }} persist-credentials: false - uses: pnpm/action-setup@v4 - uses: actions/setup-node@v4 with: node-version-file: ".nvmrc" cache: "pnpm" - uses: dtolnay/rust-toolchain@stable - uses: Swatinem/rust-cache@v2 with: workspaces: apps/agent/src-tauri - run: pnpm install --frozen-lockfile # tauri.conf.json now sets `createUpdaterArtifacts`, which makes TAURI_SIGNING_PRIVATE_KEY # mandatory — and that key deliberately does not live in this public repository. Turn the # updater bundle back off for this job: it ships installers via GitHub Releases, and the # signed updater manifest is release-agent.yml's job in the private repo. - name: Build NSIS installer working-directory: apps/agent env: TIMEBUNNY_API_URL: https://time.bunny.team TIMEBUNNY_CHANNEL: stable run: >- pnpm tauri build --bundles nsis --config "{\"bundle\":{\"createUpdaterArtifacts\":false}}" # Same gate as the private repo's release workflow: an agent baked against localhost looks # perfectly healthy in CI and is simply never heard from once someone installs it. # Deliberately not findstr: it reads a leading `/` in a path as a switch prefix, so # `src-tauri/target/...` fails with "Cannot open" and exits 2 — which reads as "string not # found" and would let a localhost build sail through the check that exists to stop it. - name: Verify the baked server URL working-directory: apps/agent run: | $exe = Join-Path $PWD "src-tauri\target\release\timebunny-agent.exe" if (-not (Test-Path $exe)) { throw "No agent binary at $exe" } $text = [System.Text.Encoding]::ASCII.GetString([System.IO.File]::ReadAllBytes($exe)) if ($text.Contains("http://localhost:3000")) { throw "Agent binary still carries the localhost fallback - TIMEBUNNY_API_URL was not set at build time" } if (-not $text.Contains("https://time.bunny.team")) { throw "Agent binary does not contain the production API URL" } Write-Host "ok: production URL baked, no localhost fallback" - name: Checksum working-directory: apps/agent run: Get-ChildItem -Recurse -Filter *.exe src-tauri/target/release/bundle/nsis | Get-FileHash -Algorithm SHA256 | Format-List - name: Attach installer to release working-directory: apps/agent env: GH_TOKEN: ${{ github.token }} run: | $exe = Get-ChildItem -Recurse -Filter *.exe src-tauri/target/release/bundle/nsis | Select-Object -First 1 if (-not $exe) { throw "No NSIS installer was produced" } gh release upload ${{ inputs.tag }} $exe.FullName --clobber --repo ${{ github.repository }} - uses: actions/upload-artifact@v4 with: name: windows-nsis-unsigned path: apps/agent/src-tauri/target/release/bundle/nsis/*.exe if-no-files-found: error