Skip to content

Add CI workflow so the test suite actually gates changes - #38

Open
genesis-dev-bot[bot] wants to merge 3 commits into
mainfrom
evolver/37-ci-workflow
Open

Add CI workflow so the test suite actually gates changes#38
genesis-dev-bot[bot] wants to merge 3 commits into
mainfrom
evolver/37-ci-workflow

Conversation

@genesis-dev-bot

Copy link
Copy Markdown
Contributor

Closes #37.

Problem

Genesis had no CI. The test suite ran only when a human remembered to run
uv run --frozen pytest locally, which made every guard in it advisory rather than
enforced — including test_genesis_own_claude_workflows_meet_orchestrator_floor from
#36, whose entire purpose is to fail a change that lowers a turn budget. Three recent
commits merged on the strength of a hand-run result.

What's here

.github/workflows/ci.ymlpush to main + pull_request, contents: read,
no secrets, uv run --frozen pytest tests/ -q, then git diff --exit-code uv.lock.

--frozen is load-bearing, not stylistic: a bare uv run re-resolves and rewrites
uv.lock, which is how a proxy registry's source URLs landed in f328364 and had to
be reverted in 06ad4c4. The lockfile step catches a regression if someone drops the
flag later.

tests/conftest.py — sets GIT_AUTHOR_*/GIT_COMMITTER_*.

This one wasn't in the issue and is the reason CI wouldn't have been green without it.
scaffold_new_repo ends in a real git commit, which aborts with exit 128 —
"Author identity unknown" — on a machine with no global git config. A fresh GitHub
Actions runner has none, so 19 of the 124 tests failed the first time I ran the
suite on a clean checkout, while passing on every developer machine. The suite was
silently depending on ambient host state. Env vars override config, so this holds
anywhere. Verified by reproducing the failure first, then the fix.

One new test asserting ci.yml stays pull_request-triggered, --frozen, and
free of ${{ secrets. }} — a CI job that costs money or an API key is one someone
eventually disables.

CLAUDE.md — a short CI section recording those invariants, in the same style as
the turn-budget section.

Verification

125 passed locally, uv.lock unchanged. Since this is a same-repo branch, the
workflow runs on this PR and proves itself before merge — check the CI job below.

Notes

  • A human must merge this. Genesis has no auto-merge workflow.
  • On the auto-merge question the issue raised: deliberately out of scope, and now
    filed separately. Auto-merge only makes sense once there's a real gate to auto-merge
    behind, which is what this PR adds — so it was a prerequisite, not a companion.
  • Not fixed here (separate signal, worth its own issue if it recurs): a real user
    running genesis new on a machine with no git identity hits the same exit-128 crash
    with no useful error. The fix above is test-scoped on purpose.

🤖 Generated with Claude Code

Genesis had no CI. The 124-test suite ran only when a human remembered
to, which made every guard in it advisory — including the turn-budget
floor from #36, whose whole point is to fail a change that lowers a
budget. Three recent commits merged on the strength of a hand-run result.

- .github/workflows/ci.yml: push to main + pull_request, no secrets,
  `uv run --frozen pytest tests/ -q`, plus a `git diff --exit-code
  uv.lock` step. --frozen is load-bearing: a bare `uv run` re-resolves
  and rewrites the lock, which is how a proxy registry's source URLs
  landed in 986dda6 and had to be reverted in d4da1a4.

- tests/conftest.py: set GIT_AUTHOR_*/GIT_COMMITTER_*. The scaffolding
  tests end in a real `git commit`, which aborts with exit 128 on a
  runner with no global git identity — 19 tests failed on a clean
  machine while passing on every developer's. The suite was depending
  on ambient state; now it doesn't.

- A test asserting ci.yml stays PR-triggered, --frozen, and
  secret-free, so CI can't quietly become something people disable.

Closes #37.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The first CI run on this PR died at 'Unable to resolve action
astral-sh/setup-uv@v9'. setup-uv stopped publishing floating major tags
after v7 — v8.0.0 and v9.0.0 exist, v8 and v9 do not.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Follow-up on #37: the review caveat that `--frozen` is not the protection
this workflow assumed it was. Tested rather than taken on faith, and it
holds for a reason neither the issue nor the first pass had right.

Two findings, both measured on this repo:

1. `--frozen` accepts a stale lock. With a dependency added to
   pyproject.toml and no re-lock, `uv sync --frozen` exits 0 having
   installed the *old* dependency set; `uv sync --locked` exits 1 with
   "the lockfile needs to be updated". Under `--frozen`, a PR that adds a
   dependency without re-locking goes green in CI and breaks everyone
   else — the exact class of thing CI exists to stop.

2. `--frozen` does not keep uv off the configured package index. It pins
   the dependency graph, but building this project resolves
   `build-system.requires` (hatchling), which no lockfile covers. With a
   proxy registry as the default index and the `[[tool.uv.index]]` pin
   removed, `uv run --frozen` still reached for the proxy and failed.
   The pin in pyproject.toml is what actually shields against the
   source-URL rewrite; a flag on the run command never was.

So the ordering is now `uv sync --locked` (fail loudly on a stale lock)
then `uv run --no-sync` (test step cannot touch the env or the lock).
`git diff --exit-code uv.lock` stays as belt and braces.

The ci.yml guard test is updated to match, and now scans only the `run:`
command lines — asserting over raw file text flagged the comments that
explain why `--frozen` is avoided, the same trap the secrets assertion
already sidesteps. Verified it still fails when the flags regress.

CLAUDE.md's CI section corrected; it had recorded the wrong rationale.

125 passed, uv.lock unchanged.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

No CI workflow: the test suite (including the new turn-budget guard) never runs automatically

0 participants