Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions docs/roadmap.md
Original file line number Diff line number Diff line change
Expand Up @@ -1462,3 +1462,9 @@ principles named were durable, accurate and reactive. Found in rally 0x7 by plus
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 <PR> --repo <owner/repo>` before
submitting, and says nothing of it when all its stories are in review; with a test (docs/session-hook.md).
- [ ] **RAL-187: The wait-green line only where stories go by pull request.** From the watchman (2026-11-14),
after RAL-186: DiscoSim's teams land by gated trains, with no pull requests. Done when: a team's session start
gives RAL-186's wait-green line only for a claimed or sent-back story whose project has no `gate` in the
projects list beside the pairing (RAL-161's field), so a team with only DSM stories, DSM gated, isn't told it,
and one with a RAL story beside them still is; an unreadable list takes every project as by pull request;
with a test (docs/session-hook.md).
4 changes: 3 additions & 1 deletion docs/session-hook.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ One block, between `<rally_state team="…">` and `</rally_state>`, in this orde
- 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), and, when one is claimed or sent back, to wait for its
pull request's checks with `rally wait-green <PR> --repo <owner/repo>` before submitting (RAL-186)
pull request's checks with `rally wait-green <PR> --repo <owner/repo>` before submitting (RAL-186); not for a
story whose project's entry in the projects list beside the pairing names a `gate` (docs/digest.md), such as
DiscoSim's gated trains, which have no pull request to wait on (RAL-187)
- 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
Expand Down
14 changes: 14 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1570,9 +1570,23 @@ fn session_start(
);
let left = rally::session::DEADLINE.saturating_sub(started.elapsed());
about_stories.extend(behind_lines(team, &stories, left));
// RAL-187: projects whose merges pass a gate, not a pull request's checks, from the
// projects list beside the pairing; unreadable, every project is taken as by PR.
let gated = projects_text(None, &path)
.ok()
.and_then(|text| web::parse_projects(&text).ok())
.map(|(projects, _)| {
projects
.into_iter()
.filter(|p| p.gate.is_some())
.map(|p| p.prefix)
.collect()
})
.unwrap_or_default();
let extra = rally::session::Extra {
resume,
about_stories,
gated,
};
println!(
"{}",
Expand Down
59 changes: 54 additions & 5 deletions src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -306,10 +306,20 @@ 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")));
// RAL-186: a story still to be submitted is one whose pull request's checks will be waited on,
// unless its project's merges go by a gate rather than a pull request (RAL-187).
let by_pull_request = |id: &str| {
let prefix = id.split_once('-').map_or(id, |(prefix, _)| prefix);
!extra
.gated
.iter()
.any(|gated| gated.eq_ignore_ascii_case(prefix))
};
let to_submit = stories.iter().any(|(id, row)| {
mine(row)
&& matches!(row["state"].as_str(), Some("claimed" | "sent_back"))
&& by_pull_request(id)
});
body.push("Your team's open stories:".into());
push_or_none(&mut body, own);
if to_submit {
Expand Down Expand Up @@ -455,6 +465,10 @@ pub const RECORD_PAGES: usize = 10;
pub struct Extra {
pub resume: Vec<String>,
pub about_stories: Vec<String>,
/// The prefixes of projects whose merges pass a gate other than CI on GitHub (the projects
/// list's `gate`, RAL-161), such as DiscoSim's gated trains: their stories have no pull
/// request to wait on, so no wait-green line is given for them (RAL-187).
pub gated: Vec<String>,
}

/// One line for each condition in force naming one of `team`'s open stories (RAL-171), from
Expand Down Expand Up @@ -717,6 +731,41 @@ mod tests {
}
}

/// RAL-187: a team whose project lands by gated trains, with no pull requests, such as
/// DiscoSim's, isn't told to wait with wait-green; a story of a pull-request project still is.
#[test]
fn a_gated_projects_team_isnt_told_to_wait_with_wait_green() {
let extra = Extra {
gated: vec!["dsm".into()],
..Extra::default()
};
let stories = json!({"DSM-56": {"state": "claimed", "team": "spry-minnow"},
"DSM-57": {"state": "sent_back", "team": "spry-minnow"}});
let out = render_in(
"spry-minnow",
stories.as_object().unwrap(),
&[],
Harness::Other,
None,
None,
&extra,
);
assert!(out.contains("- DSM-56: claimed"), "{out}");
assert!(!out.contains("rally wait-green"), "{out}");
let stories = json!({"DSM-56": {"state": "claimed", "team": "spry-minnow"},
"RAL-9": {"state": "claimed", "team": "spry-minnow"}});
let out = render_in(
"spry-minnow",
stories.as_object().unwrap(),
&[],
Harness::Other,
None,
None,
&extra,
);
assert!(out.contains("rally wait-green <PR>"), "{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]
Expand Down Expand Up @@ -744,8 +793,8 @@ mod tests {
]
);
let extra = Extra {
resume: Vec::new(),
about_stories: lines,
..Extra::default()
};
let out = render_in("rustdaw", stories, &[], Harness::Other, None, None, &extra);
let open = out.find("Your team's open stories:").unwrap();
Expand Down
Loading