008 — Release waits for the merge and completes in one run (#31)
Status: shipped (v0.5.0)
Why
In pull request mode a release is two tp release runs (ADR 0001): one
opens the pull request, a human merges it, and a second run on main
tags and publishes. For a one-person project the human is the same person
who ran the first command: the merge is a click in the forge within a
minute or two, and the second run is pure ceremony — switch to main,
pull, type tp release again, answer the publishing questions. Forgetting
it leaves a merged version heading with no tag until the next release
notices. gobank and task-plus hit this on every release since story 005.
What changes
merge_wait: 10mintask-plus.yml(a Go duration; absent or0keeps the two-run behaviour). With it set, atp releasethat opens or updates a pull request stays running and polls the forge every 15 s for up to that long.- The publishing questions (push, goreleaser, cleanup, install, deploy) are asked before the pull request is opened, so the tag happens unattended once the merge lands. The plan summary names the wait.
- Merged in time: the run fetches, checks out the base branch (the story
branch case), fast-forwards, runs the
checkcommands again on the merged base branch, then does exactly what the tag run does: tag, publish, steps 7 to 13, release branch deleted. - Not merged in time, closed without merging, or Ctrl-C during the wait:
the run ends as it does today, pull request URL printed, nothing tagged,
exit 0. A later
tp releaseon the base branch is still the tag run. internal/forge:GetPullRequest(number)on the Forgejo repo.docs/release-workflow.mdgains a "Waiting for the merge" section;README.mdnames the key.
Acceptance
merge_wait |
Run | During the wait | Outcome |
|---|---|---|---|
| unset | any | — | as before: two runs |
| set | release PR opened from the base branch | merged | same run: fast-forward, tag, publish; release branch deleted; released = true |
| set | story PR opened or updated from the story branch | merged | same run: checkout base, fast-forward, tag, publish; work ends on the base branch |
| set | either | still open at the deadline | PR URL printed; nothing tagged; exit 0; next run on base is the tag run |
| set | either | closed without merging | says so; nothing tagged; exit 0 |
| set | either | Ctrl-C | stops waiting; PR stays open; exit 0 |
| set | either | forge unreachable on a poll | retried until the deadline; the error is reported with the timeout |
| set | either, merged | check fails on the merged base |
error naming the merged PR; the next run on base tags it |
| set | --dry-run |
— | says it would wait; no polling |
Out of scope
- Waiting on a run that only finds an existing open release PR
(
PendingPR): it prints the URL and exits as before. That path has no Ask phase, so the publishing questions would need a home first. - Waiting for CI on the pull request, or merging it: the human merges.
- A
--waitflag: the setting is per project, where the merge habit lives.
Decisions
ADR 0003: a bounded, opt-in wait on top of the two-run model, not a return to one run that waits indefinitely.
Done when
- tests express the acceptance table and pass
- spec updated (
docs/release-workflow.md,README.md) - ADR written if a fork was resolved (ADR 0003)
- roadmap ticked and stamped; changelog entry
- issue closed with a link to the release (v0.5.0)