From c3bf42e07639e6319d60e2e661505f5066d67264 Mon Sep 17 00:00:00 2001 From: tachikochoko Date: Thu, 30 Apr 2026 17:57:16 +0900 Subject: [PATCH 1/4] chore: remove backend image artifact roundtrip, run unit tests natively refs #437 Co-Authored-By: Claude Sonnet 4.6 --- .github/workflows/ci.test.mjs | 21 +++++++++++++++------ .github/workflows/ci.yml | 30 ++++++++---------------------- 2 files changed, 23 insertions(+), 28 deletions(-) diff --git a/.github/workflows/ci.test.mjs b/.github/workflows/ci.test.mjs index 0ba68aa3..9f2da8cf 100644 --- a/.github/workflows/ci.test.mjs +++ b/.github/workflows/ci.test.mjs @@ -55,37 +55,46 @@ test('frontend CI job runs the frontend test command', async () => { ) }) -test('backend CI job runs go test and go vet via docker compose prebuilt image', async () => { +test('backend CI job runs go test and go vet natively from services/api', async () => { const workflow = await readFile(workflowPath, 'utf8') const backendJob = workflowJobBlock(workflow, 'backend') assert.match( backendJob, - /- name: Run tests\n\s+run: docker compose run --pull never --no-deps --rm app go test \.\/\.\.\./, + /uses: actions\/setup-go@v5\n\s+with:\n\s+go-version-file: services\/api\/go\.mod/, ) assert.match( backendJob, - /- name: Run vet\n\s+run: docker compose run --pull never --no-deps --rm app go vet \.\/\.\.\./, + /- name: Run tests\n\s+working-directory: services\/api\n\s+run: go test \.\/\.\.\./, ) + + assert.match( + backendJob, + /- name: Run vet\n\s+working-directory: services\/api\n\s+run: go vet \.\/\.\.\./, + ) + + assert.doesNotMatch(backendJob, /actions\/download-artifact|docker load|backend-image/) }) test('backend CI vet assertion does not match vet steps from later jobs', () => { const workflow = ` backend: steps: - name: Run tests - run: docker compose run --pull never --no-deps --rm app go test ./... + working-directory: services/api + run: go test ./... frontend: steps: - name: Run vet - run: docker compose run --pull never --no-deps --rm app go vet ./... + working-directory: services/api + run: go vet ./... ` const backendJob = workflowJobBlock(workflow, 'backend') assert.doesNotMatch( backendJob, - /- name: Run vet\n\s+run: docker compose run --pull never --no-deps --rm app go vet \.\/\.\.\./, + /- name: Run vet\n\s+working-directory: services\/api\n\s+run: go vet \.\/\.\.\./, ) }) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c0426116..053475f6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -242,41 +242,27 @@ jobs: cache-from: type=gha cache-to: type=gha,mode=max - - name: Export image artifact - run: | - set -euo pipefail - docker save tachigo-app:latest | gzip -c > tachigo-app.tar.gz - test -s tachigo-app.tar.gz - - - name: Upload image artifact - uses: actions/upload-artifact@v4 - with: - name: backend-image - path: tachigo-app.tar.gz - retention-days: 1 - backend: timeout-minutes: 10 name: Backend tests - needs: [scope-gate, backend-build] + needs: [scope-gate] if: github.event_name == 'push' || needs.scope-gate.outputs.run_ci == 'true' runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - name: Download image artifact - uses: actions/download-artifact@v4 + - name: Set up Go + uses: actions/setup-go@v5 with: - name: backend-image - - - name: Load backend image - run: docker load < tachigo-app.tar.gz + go-version-file: services/api/go.mod - name: Run tests - run: docker compose run --pull never --no-deps --rm app go test ./... + working-directory: services/api + run: go test ./... - name: Run vet - run: docker compose run --pull never --no-deps --rm app go vet ./... + working-directory: services/api + run: go vet ./... backend-integration: timeout-minutes: 20 From 16d48483eb561caeaaf4d8513087c53b41962d2c Mon Sep 17 00:00:00 2001 From: tachikochoko Date: Thu, 30 Apr 2026 18:07:58 +0900 Subject: [PATCH 2/4] fix: remove load: true from backend-build, bump setup-go to v6 refs #437 Co-Authored-By: Claude Sonnet 4.6 --- .github/workflows/ci.test.mjs | 2 +- .github/workflows/ci.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.test.mjs b/.github/workflows/ci.test.mjs index 9f2da8cf..a080d27e 100644 --- a/.github/workflows/ci.test.mjs +++ b/.github/workflows/ci.test.mjs @@ -61,7 +61,7 @@ test('backend CI job runs go test and go vet natively from services/api', async assert.match( backendJob, - /uses: actions\/setup-go@v5\n\s+with:\n\s+go-version-file: services\/api\/go\.mod/, + /uses: actions\/setup-go@v6\n\s+with:\n\s+go-version-file: services\/api\/go\.mod/, ) assert.match( diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 053475f6..794b74e2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -237,7 +237,7 @@ jobs: with: context: ./services/api target: dev - load: true + load: false tags: tachigo-app:latest cache-from: type=gha cache-to: type=gha,mode=max @@ -252,7 +252,7 @@ jobs: - uses: actions/checkout@v4 - name: Set up Go - uses: actions/setup-go@v5 + uses: actions/setup-go@v6 with: go-version-file: services/api/go.mod From 366a37ff3312190bb9e212fc47a57f861ddedf12 Mon Sep 17 00:00:00 2001 From: tachikochoko Date: Thu, 30 Apr 2026 18:42:43 +0900 Subject: [PATCH 3/4] test: guard workflow CI path validation refs #437 Co-Authored-By: Codex --- .github/workflows/ci.test.mjs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/workflows/ci.test.mjs b/.github/workflows/ci.test.mjs index a080d27e..ad14f38b 100644 --- a/.github/workflows/ci.test.mjs +++ b/.github/workflows/ci.test.mjs @@ -225,6 +225,16 @@ test('docs/template-only PRs skip heavy product CI in scope gate', async () => { workflow, /Skipping heavy product CI because this PR only changes docs\/templates\/metadata\./, ) + assert.doesNotMatch( + workflow, + /name\.startsWith\('\.github\/workflows\/'\)/, + 'workflow changes must not be classified as metadata-only because they need CI validation', + ) + assert.match( + workflow, + /\^\\.github\\\/workflows\\\/ci\\.yml\$/, + 'ci.yml changes must request backend integration validation', + ) }) test('global auto-merge workflow excludes Dependabot PRs', async () => { From e858a4db8dccbdc2b5be28814cb06f6f154179d5 Mon Sep 17 00:00:00 2001 From: tachikochoko Date: Thu, 30 Apr 2026 18:45:22 +0900 Subject: [PATCH 4/4] test: update backend CI wiring guard refs #437 Co-Authored-By: Codex --- scripts/check-backend-ci-cache.sh | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/scripts/check-backend-ci-cache.sh b/scripts/check-backend-ci-cache.sh index eb7309fb..de82d45b 100644 --- a/scripts/check-backend-ci-cache.sh +++ b/scripts/check-backend-ci-cache.sh @@ -33,7 +33,15 @@ require_in "$workflow" "context: ./services/api" "backend CI should build from s require_in "$workflow" "target: dev" "backend CI should build the same dev target used by docker compose tests" require_in "$workflow" "cache-from: type=gha" "backend CI should restore Docker layers from GitHub Actions cache" require_in "$workflow" "cache-to: type=gha,mode=max" "backend CI should save Docker layers to GitHub Actions cache" -require_in "$workflow" "load: true" "backend CI should load the cached image into the local Docker daemon" +require_in "$workflow" "load: false" "backend build should validate Docker cache without loading the image" require_in "$workflow" "tags: tachigo-app:latest" "backend CI should tag the image used by docker compose" -require_in "$workflow" "docker compose run --pull never --no-deps --rm app go test ./..." "unit tests should reuse the prebuilt backend image" +require_in "$workflow" "actions/setup-go@v6" "backend unit tests should use native Go" +require_in "$workflow" "go-version-file: services/api/go.mod" "backend unit tests should read services/api/go.mod" +require_in "$workflow" "working-directory: services/api" "backend unit tests should run from services/api" +require_in "$workflow" "run: go test ./..." "backend unit tests should run natively" +require_in "$workflow" "run: go vet ./..." "backend vet should run natively" +reject_in "$workflow" "actions/download-artifact" "backend unit tests should not download a Docker image artifact" +reject_in "$workflow" "docker load" "backend unit tests should not load a Docker image artifact" +reject_in "$workflow" "backend-image" "backend image artifact roundtrip should be removed" reject_in "$workflow" "docker compose build app" "backend CI should not rebuild the app image without GHA layer cache" +reject_in "$workflow" "docker compose run --pull never --no-deps --rm app go test ./..." "unit tests should not use the prebuilt backend image"