You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Confirmed the problem and mapped the auto-rules. Here's the lay of the land and a few options:
Why it happens
Your project has 6 active workflows. The relevant ones:
#
Workflow
Trigger
Action
7
Item closed
any issue/PR closed
sets Status = Done
8
Pull request merged
PR merged
sets Status = Done
Workflow #7 fires regardless of whether a PR was merged or just closed — so abandoned/superseded PRs land in Done alongside shipped work. (Quick scan: at least 18 closed-but-unmerged PRs are currently sitting in Done — including some of yours like .github#1, tracebloc-py-package#40, and the dependabot bumps backend#578-588.)
Issues have the same problem in two flavors: closed-as-completed vs closed-as-not_planned both also land in Done.
Current Status options: Backlog → Ready → In progress → In review → Validation → Done.
Options
Option A — Add a "Cancelled" status, repurpose built-ins (lowest effort)
Add Status option Cancelled (or Won't ship).
Change workflow #7 "Item closed" → set Status = Cancelled.
❌ Issue closed-as-completed → ends up in Cancelled (wrong)
✅ Issue closed-as-not_planned → Cancelled
Works perfectly for PRs (~98% of your board today). Mis-routes completed issues — survivable but not great. Also depends on workflow #8 firing after #7, which is the observed behavior but not formally guaranteed.
Option B — Custom GitHub Action that routes properly (cleanest)
Add Status option Cancelled.
Disable built-in workflow #7 ("Item closed").
Add a small repo-level Action (in .github) listening to pull_request: closed and issues: closed, which calls the GraphQL updateProjectV2ItemFieldValue mutation to set:
PR merged → Done
PR closed unmerged → Cancelled
Issue state_reason: completed → Done
Issue state_reason: not_planned → Cancelled
Handles all four cases correctly. ~50 lines of Action code. Costs you maintaining one workflow file, but you already have .github infrastructure for this kind of thing (advance-deploy-env, set-pr-status are exactly this shape).
Option C — Add a separate "Outcome" field, leave Status alone
Add a new single-select field Outcome with values Shipped / Cancelled / Superseded, populated by an Action on close. Status stays as-is (everything closed = Done), but views can group/filter by Outcome.
Less disruptive to existing views and saved filters, but the kanban swimlanes still mix shipped and abandoned work — you have to remember to add an Outcome filter to "what shipped" reports.
Option D — View-only filter (no schema change)
Create a saved view "Done (shipped)" that filters to status:Done is:merged. Cheap, but doesn't change the underlying truth — abandoned PRs still pollute counts and most views.
My recommendation
Option B, with Option A as a fast interim if you want it landed today. Option A gets you 95% of the value in a 2-minute config change; Option B is the proper fix and is in keeping with the .github reusable-workflow pattern you've already been rolling out across repos.
Want me to draft the Action for Option B, or just flip the workflow for Option A?
Confirmed the problem and mapped the auto-rules. Here's the lay of the land and a few options:
Why it happens
Your project has 6 active workflows. The relevant ones:
Workflow #7 fires regardless of whether a PR was merged or just closed — so abandoned/superseded PRs land in Done alongside shipped work. (Quick scan: at least 18 closed-but-unmerged PRs are currently sitting in Done — including some of yours like
.github#1,tracebloc-py-package#40, and the dependabot bumpsbackend#578-588.)Issues have the same problem in two flavors: closed-as-completed vs closed-as-not_planned both also land in Done.
Current Status options: Backlog → Ready → In progress → In review → Validation → Done.
Options
Option A — Add a "Cancelled" status, repurpose built-ins (lowest effort)
Cancelled(orWon't ship).Cancelled.Done.How it routes:
Works perfectly for PRs (~98% of your board today). Mis-routes completed issues — survivable but not great. Also depends on workflow #8 firing after #7, which is the observed behavior but not formally guaranteed.
Option B — Custom GitHub Action that routes properly (cleanest)
Cancelled..github) listening topull_request: closedandissues: closed, which calls the GraphQLupdateProjectV2ItemFieldValuemutation to set:state_reason: completed→ Donestate_reason: not_planned→ CancelledHandles all four cases correctly. ~50 lines of Action code. Costs you maintaining one workflow file, but you already have
.githubinfrastructure for this kind of thing (advance-deploy-env, set-pr-status are exactly this shape).Option C — Add a separate "Outcome" field, leave Status alone
Add a new single-select field Outcome with values
Shipped/Cancelled/Superseded, populated by an Action on close. Status stays as-is (everything closed = Done), but views can group/filter by Outcome.Less disruptive to existing views and saved filters, but the kanban swimlanes still mix shipped and abandoned work — you have to remember to add an Outcome filter to "what shipped" reports.
Option D — View-only filter (no schema change)
Create a saved view "Done (shipped)" that filters to
status:Done is:merged. Cheap, but doesn't change the underlying truth — abandoned PRs still pollute counts and most views.My recommendation
Option B, with Option A as a fast interim if you want it landed today. Option A gets you 95% of the value in a 2-minute config change; Option B is the proper fix and is in keeping with the
.githubreusable-workflow pattern you've already been rolling out across repos.Want me to draft the Action for Option B, or just flip the workflow for Option A?