From 84717c90a688a5dbbf54d9825fb68e9cb297c160 Mon Sep 17 00:00:00 2001 From: aksops Date: Sun, 26 Apr 2026 06:17:19 +0000 Subject: [PATCH] ci: build UI bundle before Go in release + add PR ci workflow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The release pipeline has been broken since 2026-04-22 (5 consecutive failed runs) because internal/serve/dist/ is gitignored and the workflow never built it before invoking go test / go build. //go:embed all:dist errors out when the directory is empty. release.yml: insert pnpm + Node setup and `make ui` between Set up Go and Run tests. The populated internal/serve/dist/ is now picked up by both the test step and the cross-compiled binary builds, and is naturally included in the air-gapped src tarball (existing tar excludes top-level dist/ only). ci.yml: new workflow gating PRs and non-main pushes on the same UI build + go build/vet/test + ui typecheck + vitest. Mirrors the release pipeline's prerequisites so a broken main is caught before merge. e2e and audit steps live in `make regression` for now — promotable to merge gates later. Co-Authored-By: Claude Opus 4.7 (1M context) --- .github/workflows/ci.yml | 70 +++++++++++++++++++++++++++++++++++ .github/workflows/release.yml | 24 ++++++++++++ 2 files changed, 94 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..096a79a --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,70 @@ +# PR + non-main-push gate. Runs the same UI build + Go build + tests +# the release pipeline depends on, so a broken main is caught before +# merge instead of after. +# +# Scope intentionally narrower than `make regression`: e2e (Playwright +# browser install + browser run), `pnpm audit`, and `govulncheck` are +# heavier and currently run via `make regression` locally — adding them +# here is a follow-up if/when they prove necessary as merge gates. + +name: CI + +on: + pull_request: + push: + branches-ignore: + # main is covered by release.yml; skipping here avoids running the + # same checks twice on every merge. + - main + +permissions: + contents: read + +concurrency: + group: ci-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + build-and-test: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version-file: go.mod + + - name: Set up pnpm + uses: pnpm/action-setup@v4 + with: + version: 10.33.0 + + - name: Set up Node + uses: actions/setup-node@v4 + with: + node-version: 22 + cache: pnpm + cache-dependency-path: ui/pnpm-lock.yaml + + - name: Build UI bundle + # Required before any Go invocation: //go:embed all:dist in + # internal/serve/assets.go errors out if internal/serve/dist/ + # is empty. + run: make ui + + - name: Go vet + run: go vet -tags sqlite_fts5 ./... + + - name: Go build + run: go build -tags sqlite_fts5 ./... + + - name: Go test + run: go test -tags sqlite_fts5 ./... + + - name: UI typecheck + run: pnpm -C ui exec tsc --noEmit + + - name: UI test + run: pnpm -C ui test diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1ecc761..80436d7 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -40,6 +40,30 @@ jobs: # and the release build succeed against the source tree. go-version-file: go.mod + - name: Set up pnpm + uses: pnpm/action-setup@v4 + with: + # Pinned to ui/package.json packageManager so a bumped lockfile + # doesn't desync from the toolchain CI runs the build with. + version: 10.33.0 + + - name: Set up Node + uses: actions/setup-node@v4 + with: + node-version: 22 + cache: pnpm + cache-dependency-path: ui/pnpm-lock.yaml + + - name: Build UI bundle + # Populates internal/serve/dist/ from ui/dist/ via rsync so the + # `//go:embed all:dist` directive in internal/serve/assets.go has + # a non-empty match. Without this, both `go test ./...` and the + # cross-compiled binary builds below fail at compile time. The + # populated dist is naturally bundled into the air-gapped source + # tarball later (the tar excludes top-level ./dist staging only, + # not internal/serve/dist). + run: make ui + - name: Run tests run: go test ./...