diff --git a/docs/roadmap.md b/docs/roadmap.md index bf4687e..5716073 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -1457,3 +1457,8 @@ principles named were durable, accurate and reactive. Found in rally 0x7 by plus out (saying what was pending or missing), 2 on a usage error; retries a failed read until the timeout; the Rally block in CLAUDE.md tells teams to use it; with unit tests and a CLI test against a stand-in `gh` (docs/wait-green.md). +- [ ] **RAL-186: `rally wait-green` named where it's needed.** From the watchman (2026-11-14), after RAL-185. Done + when: docs/watchman.md §4 gives `rally wait-green` in the landing commands and says to ask what a team waits + with when a green pull request isn't submitted; and a team's session start, when it has a story claimed or sent + back, says under its open stories to wait for the checks with `rally wait-green --repo ` before + submitting, and says nothing of it when all its stories are in review; with a test (docs/session-hook.md). diff --git a/docs/session-hook.md b/docs/session-hook.md index 20cd000..593f6f4 100644 --- a/docs/session-hook.md +++ b/docs/session-hook.md @@ -11,7 +11,8 @@ One block, between `` and ``, in this orde one can be found, and what that nickname was doing (below, "A restarted session", RAL-152) - the open rally, each of its projects' roadmap stages, and the cycle (RAL-131), and the stories assigned to the team (RAL-130) -- the team's open stories (claimed, in review or sent back) +- the team's open stories (claimed, in review or sent back), and, when one is claimed or sent back, to wait for its + pull request's checks with `rally wait-green --repo ` before submitting (RAL-186) - under them, what bears on them (RAL-171): each condition in force naming one of the team's stories ("a condition in force names this story: …", declared, information and never a block), and each verified pull request of the team's that has fallen behind its base, read through `gh` as the digest's RAL-105 section reads it, in what's left diff --git a/docs/watchman.md b/docs/watchman.md index 515fb05..5688f82 100644 --- a/docs/watchman.md +++ b/docs/watchman.md @@ -62,6 +62,7 @@ It holds `digest.pid` beside the pairing and logs to `digest.log`; it's found by ```sh rally waiting # oldest first rally verify --commit --note "what you read" # or: rally send-back --note "..." +rally wait-green --repo # a team waits for every check, then submits (RAL-185) gh pr merge --merge --match-head-commit # a team merges after your verify rally merge --commit rally gate .. # before moving a branch (RAL-70) @@ -90,6 +91,10 @@ rally gate .. # before moving nobody read. It says `can't tell`, never `same change`, when a commit is missing or GitHub's compare was cut short (or a patch too large to show). On GitHub, the fallback when the checkout lacks a commit, file modes and conflict resolutions can't be seen: run it in a checkout that has both commits. +- **Waiting on a submit?** A team waits for its checks with `rally wait-green --repo `, which exits + 0 once every check (ci-local's `local/*` too) is green at the pinned head, 1 on a red, 3 if the head moved. On + 11-14 a team's home-made `jq` waiter never exited, and green pull requests sat unsubmitted all night + ([wait-green.md](wait-green.md)). If a green pull request isn't submitted, ask what the team waits with. - **Read the checks yourself before a verify.** A green check can be a check that ran on another commit's build: until RAL-144, local CI's target directory was shared between commits. diff --git a/src/session.rs b/src/session.rs index 900c625..6040be8 100644 --- a/src/session.rs +++ b/src/session.rs @@ -306,8 +306,19 @@ pub fn render_in( format!("- {}: {} ({kind})", clean(id), clean(state)) }) .collect(); + // RAL-186: a story still to be submitted is one whose pull request's checks will be waited on. + let to_submit = stories + .values() + .any(|row| mine(row) && matches!(row["state"].as_str(), Some("claimed" | "sent_back"))); body.push("Your team's open stories:".into()); push_or_none(&mut body, own); + if to_submit { + body.push( + " Before you submit, wait for the checks with `rally wait-green --repo `: \ + it exits 0 once every check is green at the pinned head (docs/wait-green.md)." + .into(), + ); + } // RAL-171: what bears on the team's stories: conditions in force naming them, and a verified // pull request fallen behind its base. body.extend(extra.about_stories.iter().cloned()); @@ -677,6 +688,35 @@ mod tests { assert!(!none.contains("operator's inbox")); } + /// RAL-186: a team with a story still to submit, claimed or sent back, is told to wait for its + /// pull request's checks with `rally wait-green`; one whose stories are all in review isn't. + #[test] + fn a_team_with_a_story_to_submit_is_told_to_wait_with_wait_green() { + for (state, told) in [("claimed", true), ("sent_back", true), ("in_review", false)] { + let stories = json!({"RAL-1": {"state": state, "team": "rally"}, + "RAL-2": {"state": "claimed", "team": "other"}}); + let out = render_in( + "rally", + stories.as_object().unwrap(), + &[], + Harness::Other, + None, + None, + &Extra::default(), + ); + assert_eq!( + out.contains("rally wait-green --repo "), + told, + "{state}: {out}" + ); + if told { + let open = out.find("Your team's open stories:").unwrap(); + let line = out.find("Before you submit, wait for the checks").unwrap(); + assert!(open < line, "{out}"); + } + } + } + /// RAL-171: a condition in force naming one of the team's open stories is said under them, /// as information; another team's story, or a merged one, says nothing. #[test] @@ -709,6 +749,8 @@ mod tests { }; let out = render_in("rustdaw", stories, &[], Harness::Other, None, None, &extra); let open = out.find("Your team's open stories:").unwrap(); + // RAL-186: RAL-160 is in review, so no story waits to be submitted: no wait-green line. + assert!(!out.contains("rally wait-green"), "{out}"); let said = out.find("- RAL-160: a condition in force").unwrap(); let next = out.find("Stories you could verify").unwrap(); assert!(open < said && said < next, "{out}");