013 — Release refuses a dirty tree (#35)
Status: shipped (v0.8.0)
Why
Releasing pta2svg v0.2.0, Execute step 1 (git add -A) swept an untracked
.vscode/settings.json into the "Release prep" commit (#35). The step
shows git status and asks "Add all changes?", but the answer is yes by
habit and always yes under --yes, and the question is the wrong one:
the release cannot tell the story's last edits from a stray file, and
neither can the person at a glance. Every other release commit adds only
what its own step changed, because the tree is clean when it runs; the
dirty-tree commit is the one place the release commits work it did not
make. The "Release prep" commit has been used three times across
task-plus and gobank; the practice the method asks for is to commit the
work, then release.
What changes
tp releasefails in Gather when the working tree has changes, in every mode and in--dry-run: "working tree is dirty; commit, stash or ignore before releasing", followed bygit status --short. The tag runs already refused a dirty tree; now every run does..tp-release-commentis tp's own file: it does not make the tree dirty and no release commit stages it, whether or not the project ignores it.- The "Add all changes?" and "Commit message" questions go, with Execute
step 1. The release comment's default chain loses the commit message;
.tp-release-commentstays its fallback. - Rollback of a pull request run leaves the tree clean: the release branch carried only the release's own edits, which the next run remakes, so there is no longer any work to keep as uncommitted changes.
docs/release-workflow.mdandREADME.mddescribe the rule.
Acceptance
| Working tree | Run | Outcome |
|---|---|---|
| clean | any | as before |
| tracked file modified | direct | error naming the file; nothing committed, no tag |
| untracked file | release PR from the base branch | error; no release branch, no PR |
| untracked file | story branch | error; nothing pushed, no PR |
| untracked file | --dry-run |
same error |
only .tp-release-comment, not ignored |
any | treated as clean; the file is not committed |
| PR creation fails after the release branch is made | base | rollback returns to base with a clean tree |
| dirty, merged release PR or prepared heading on base | base | error, as before |
Out of scope
- Staging a chosen subset of the changes: the person commits what the release should carry.
tp checkreporting a dirty tree.
Decisions
None recorded as an ADR. The fork was between filtering the sweep
(tracked files only, or named release files only) and refusing the tree.
Filtering keeps a convenience used three times and needs every later
git add in the release to become path-specific, including the WASM
build whose outputs it cannot name; refusing is one check with one
message, and matches the rule the tag runs already apply.
Done when
- tests express the acceptance table and pass
- spec updated (
docs/release-workflow.md,README.md) - roadmap ticked and stamped; changelog entry
- issue closed with a link to the release (v0.8.0)