020 — Plan-first ask: the release shows every default and asks once (#77)
Status: shipped (v0.25.0) Roadmap: #77
Why
The Ask phase of tp release is an interview: version, comment, then a
yes/no for each publishing step, each with a default that is almost
always taken. A release is eight or nine Enters, and the plan is only
shown once the last question is answered — so a wrong answer early
(the version, say) is found late. The run should lead with the plan it
would execute, with every default filled in, and ask one question:
proceed, stop, or edit. Only the edit path walks the questions one by
one, as the interview does today.
What changes
tp releaseAsk: every default is decided up front — version (suggested), comment (--comment>[Unreleased]summary bullet >.tp-release-comment), roadmap items counted done, and each publishing step that applies to the project (push, goreleaser, PyPI, cleanup, install, deploy). The plan is printed, then one prompt:Proceed? [Y/n/e].Y(or Enter) executes the plan as shown.nends the run with nothing done, exit 0, "Nothing done."ewalks the questions one by one, each defaulting to its value in the plan; the plan is printed again and the prompt repeats.
- The plan lists each publishing step that applies, as
yesorno, so a step declined in the walk is visible rather than merely absent. Steps fixed by config (install:,pypi: true) and derived steps (post-release commands) are shown as before and not asked. --yesaccepts the plan without the prompt, as it accepted every default before.- Pull request mode's prepare run (no
merge_wait) keeps its two questions — version and comment — in the walk; the plan and prompt are the same. internal/prompt:ConfirmDefault(msg, def)(a yes/no whose default may be no) andProceed(msg)(yes / no / edit).docs/release-workflow.mdAsk section and flowchart; README's--yesline.
Acceptance
--yes |
Answer to Proceed? |
Walk answers | Outcome |
|---|---|---|---|
| yes | not asked | — | plan with every default; Check and Execute follow |
| no | Y or Enter |
— | plan with every default; Check and Execute follow |
| no | n |
— | "Nothing done.", exit 0; no commit, push, tag or pull request |
| no | e |
Enter to each | plan unchanged; prompt repeats; Y proceeds |
| no | e |
push n |
plan shows Push: no; Y proceeds without pushing |
| no | e |
version v0.3.0 |
plan shows Version: v0.3.0 |
| no | e then e |
push n, then Enter |
second walk defaults push to no; it stays no |
| no | e |
version nonsense |
error, as today |
| no | EOF | — | as n |
| no | other text | — | prompt repeats |
| Step | Applies when | Default | Asked in the walk |
|---|---|---|---|
| Version | not fixed by a prepared or merged release | suggested | yes |
| Comment | always | --comment > [Unreleased] bullet > saved file |
yes |
| Roadmap #N done | item's stories all shipped | yes | yes, one per item |
| Push | always; fixed yes on a prepare run without merge_wait |
yes | yes |
| Goreleaser | binary project with .goreleaser.yaml |
yes | yes |
| PyPI | Python project, package named, pypi: unset |
yes | yes |
| PyPI | pypi: true |
yes | no |
| Cleanup | releases to delete on a forge | yes | yes |
| Install | binary, release:install task, with install: unset |
yes | yes |
| Install | install: set |
its value | no |
| Deploy docs | pages_deploy here or in the docs sibling |
yes | yes |
| Post-release | post_release set and pushing |
derived | no |
Out of scope
- Editing a single step by name (
e push): the walk is linear. - A
-preparerun (#80) and timings (#76). - Changing which steps exist or their order (#46).
Decisions
nends the run rather than meaning "skip every step": a plan the human will not execute as shown is edited or abandoned, and the previous way to abandon was Ctrl-C.- After a walk the plan is shown again and the prompt repeats, so the walk's effect is confirmed the same way as the defaults.
Done when
- tests express the acceptance table and pass
- spec updated (
docs/release-workflow.md, README) - changelog entry
- issue closed with a link to the release