From 137a9b62a52ee925eb960941abf1f9aaf91e96ab Mon Sep 17 00:00:00 2001 From: MDietermann Date: Tue, 14 Apr 2026 21:30:01 +0200 Subject: [PATCH] docs(plan): Plan 4d CI workflow implementation plan --- .../plans/2026-04-14-ci-workflow.md | 205 ++++++++++++++++++ 1 file changed, 205 insertions(+) create mode 100644 docs/superpowers/plans/2026-04-14-ci-workflow.md diff --git a/docs/superpowers/plans/2026-04-14-ci-workflow.md b/docs/superpowers/plans/2026-04-14-ci-workflow.md new file mode 100644 index 0000000..a6131df --- /dev/null +++ b/docs/superpowers/plans/2026-04-14-ci-workflow.md @@ -0,0 +1,205 @@ +# CI Workflow Implementation Plan (Plan 4d) + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Add a single Gitea Actions CI workflow that runs `go vet` + `gofmt` check + `go build` + `go test -race` + `shellcheck` + `goreleaser check` inside an `archlinux:latest` container on every push and PR. + +**Architecture:** One workflow file (`.gitea/workflows/ci.yml`), one job with sequential steps. The Arch container gives environmental fidelity; `actions/setup-go@v5` pins Go via `go-version-file: go.mod` for reproducibility. + +**Tech Stack:** Gitea Actions, archlinux:latest container, Go (version pinned in go.mod), shellcheck, goreleaser v2. + +**Spec:** `docs/superpowers/specs/2026-04-14-ci-workflow-design.md` + +--- + +## File Structure + +**New files:** +- `.gitea/workflows/ci.yml` — single-job CI workflow + +**No other files change.** + +--- + +## Task 1: Pre-flight — verify all CI steps pass locally + +Before writing the workflow, run every command it will execute locally to confirm the repo is in a CI-passing state. If any command fails, either the plan's step is wrong or the repo has a latent issue — either way, CI will fail without this check. + +**Files:** none (validation only) + +- [ ] **Step 1: `go vet ./...`** + +```bash +cd /home/marvin/git-clones/ArduinoArchSetup +go vet ./... +``` + +Expected: exit 0, no output. + +If warnings appear, STOP and report — fixing them is out of scope for this plan but must happen before CI can land. + +- [ ] **Step 2: `gofmt` check** + +```bash +cd /home/marvin/git-clones/ArduinoArchSetup +diff=$(gofmt -l .) +if [ -n "$diff" ]; then echo "FILES NEEDING FMT:"; echo "$diff"; exit 1; fi +echo "gofmt clean" +``` + +Expected: `gofmt clean`. + +If any files are listed, STOP and report. Fixing formatting is out of scope — do NOT auto-fix in this plan. The user should decide whether to format in a separate commit first. + +- [ ] **Step 3: `go build ./...`** + +```bash +cd /home/marvin/git-clones/ArduinoArchSetup +go build ./... +``` + +Expected: exit 0, no output. + +- [ ] **Step 4: `go test -race ./...`** + +```bash +cd /home/marvin/git-clones/ArduinoArchSetup +go test -race ./... +``` + +Expected: all packages report `ok` or `no test files`. Failures = STOP and report. Race detector findings = STOP and report (they indicate real concurrency bugs). + +- [ ] **Step 5: `shellcheck bootstrap.sh`** + +```bash +command -v shellcheck || { echo "shellcheck not installed; install via: sudo pacman -S shellcheck"; exit 1; } +shellcheck /home/marvin/git-clones/ArduinoArchSetup/bootstrap.sh +``` + +Expected: exit 0, no output. + +If shellcheck isn't installed locally, install it (`sudo pacman -S shellcheck`) and retry. If findings appear, STOP and report — bootstrap.sh was validated by `bash -n` only, so this is the first shellcheck run. + +- [ ] **Step 6: `goreleaser check`** + +```bash +command -v goreleaser || command -v /home/marvin/go/bin/goreleaser || { echo "goreleaser missing"; exit 1; } +(command -v goreleaser && goreleaser check) || /home/marvin/go/bin/goreleaser check +``` + +Expected: `• 1 configuration file(s) validated` or equivalent success message. + +- [ ] **Step 7: No commit** + +This task is informational. If all six steps passed, proceed to Task 2. If any failed, report findings to the controller and HALT — the CI workflow cannot land until the repo is in a passing state. + +--- + +## Task 2: Author `.gitea/workflows/ci.yml` + +**Files:** +- Create: `.gitea/workflows/ci.yml` + +- [ ] **Step 1: Write the workflow file** + +Create `/home/marvin/git-clones/ArduinoArchSetup/.gitea/workflows/ci.yml`: + +```yaml +name: ci + +on: + push: + pull_request: + +jobs: + test: + runs-on: ubuntu-latest + container: + image: archlinux:latest + steps: + - name: Install container prereqs + run: pacman -Sy --needed --noconfirm base-devel git shellcheck + + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 1 + + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version-file: go.mod + cache: true + + - name: go vet + run: go vet ./... + + - name: gofmt check + run: | + diff=$(gofmt -l .) + if [ -n "$diff" ]; then + echo "files need gofmt:" + echo "$diff" + exit 1 + fi + + - name: go build + run: go build ./... + + - name: go test -race + run: go test -race ./... + + - name: shellcheck bootstrap.sh + run: shellcheck bootstrap.sh + + - name: Install goreleaser + run: go install github.com/goreleaser/goreleaser/v2@latest + + - name: goreleaser check + run: $(go env GOPATH)/bin/goreleaser check +``` + +- [ ] **Step 2: Validate YAML syntax** + +```bash +cd /home/marvin/git-clones/ArduinoArchSetup +python3 -c "import yaml; yaml.safe_load(open('.gitea/workflows/ci.yml'))" && echo "yaml ok" +``` + +Expected: `yaml ok`. + +- [ ] **Step 3: Sanity-check step ordering against spec** + +Open the file and confirm the step order matches the spec's Section "Job steps": +1. Install container prereqs +2. Checkout +3. Setup Go +4. go vet +5. gofmt check +6. go build +7. go test -race +8. shellcheck bootstrap.sh +9. Install goreleaser +10. goreleaser check + +No grouping or reordering. This is only a human-verified check (no command). + +- [ ] **Step 4: Commit** + +```bash +cd /home/marvin/git-clones/ArduinoArchSetup +git add .gitea/workflows/ci.yml +git commit -m "ci: add Gitea Actions workflow for test, vet, fmt, build, shellcheck, goreleaser check" +``` + +Do NOT add any Co-Authored-By trailer — repo convention forbids it. + +--- + +## Notes for the executing agent + +- **One file, one job.** Don't split into multiple jobs or multiple workflows. The spec is explicit. +- **Do not try to run the workflow itself** — that requires a Gitea Actions runner (Plan 4c Task 9, currently deferred). The workflow will queue when pushed until a runner is online; that's fine. +- **If Task 1 reveals failures** in `go vet`, `gofmt`, `go test -race`, or `shellcheck`, stop and escalate. Those are pre-existing issues the controller needs to address in a separate commit/plan; this plan only adds the workflow that detects them. +- **Why `$(go env GOPATH)/bin/goreleaser` explicitly** in step 10: `go install` puts binaries in `GOPATH/bin`, which isn't on `$PATH` inside the stock Arch container. Using the absolute path is simpler than mutating PATH. +- **YAML indentation is significant.** Use 2-space indents matching the example above. Do not substitute tabs.