Skip to content

Standing PR (streamlined selection): holding back packages can ship a fixed/linked group split #657

Open

Description

@goosewobbler

Problem

Lockstep groups (version.groups.<name>.sync: "fixed" | "linked") are meant to release together. In the flat and granular selection lists that holds: unticking one member is ignored with a warning and the row re-ticks (packages/release/src/standing-pr/standing-pr.ts:1216-1229).

In the default streamlined mode (ci.standingPr.primaryPackages set, selection ≠ granular), that per-package lockstep guard is skipped — the code assumes primaries' cascades keep groups whole ("the entire group is held together, never split", standing-pr.ts:1209-1211). They don't always. Reviewers confirmed three ways by running cascadeDeselection (selection-region.ts:144-219) directly:

  1. Group with no declared primary. Its members render as orphan checkboxes (selection-region.ts:189-191, 451-461), and an orphan untick is honoured unconditionally (:214). Unticking one member of a fixed group → effective = ['lib-x']; the rest ships.
  2. Two primaries in one fixed group. Fixed group {a, b, c} with primaries a and b: unticking a holds back only ['a']; b and c ship. (Note: the two-primaries case is deliberately tested for a linked group — selection-region.spec.ts:280-299 — so the intended semantics need deciding.)
  3. A fixed member that's also a prerequisite of another selected primary. Fixed group {a, b, c} with primary a, where c is a prerequisite of primary p: unticking a holds back ['a','b']; c ships (reference counting keeps a child released while any owner is).

The version stage's fixed-group warning (packages/version/src/core/groupStrategy.ts:529-548) is the only signal.

Expected

In every selection mode, holding back part of a fixed group never ships the rest of it — either the untick is ignored (as in flat/granular), or it holds back the whole group. Decide whether linked follows the same rule (case 2's existing test suggests linked groups may intentionally split by primary).

Proposed fix

After cascadeDeselection in the streamlined branch, apply a lockstep pass: for each fixed (and, if decided, linked) group with any member held back, either restore the held-back members (with the existing warning) or hold back the whole group, consistently with flat/granular. Correct the standing-pr.ts:1209-1211 comment. Tests for all three cases above.

Found while reviewing #619, which documents the checklist.

Activity

  1. changed the title [-]Standing PR (streamlined selection): unticking a fixed/linked group member with no declared primary ships the group split[/-] [+]Standing PR (streamlined selection): holding back packages can ship a fixed/linked group split[/+] on Oct 9, 2026
  2. modified the milestones: 0.43.0, 0.44.0 on Oct 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    type:bugSomething isn't working

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions