@@ -2676,10 +2676,47 @@ describe("PR review-state workflow concurrency groups (#1707)", () => {
26762676 ]
26772677
26782678 for ( const context of triggerContexts ) {
2679- expect ( shardGroupFor ( context , { pr_number : 1664 } ) ) . toBe ( "label-pr-review-state-1664" )
2679+ expect ( shardGroupFor ( context , { pr_number : 1664 } ) ) . toBe ( "label-pr-review-state-reconcile-1664" )
2680+ }
2681+ expect ( shardGroupFor ( triggerContexts [ 0 ] , { pr_number : 1707 } ) ) . toBe ( "label-pr-review-state-reconcile-1707" )
2682+ expect ( shardGroupFor ( triggerContexts [ 0 ] , { pr_number : 1707 } ) ) . not . toBe ( "label-pr-review-state-reconcile-1664" )
2683+ } )
2684+
2685+ it ( "keeps workflow-level and job-level groups disjoint for every trigger path" , ( ) => {
2686+ // Live regression (run 35548066989): for direct single-PR triggers the
2687+ // shard group equaled the workflow-level group its own run held, and
2688+ // GitHub failed the job at startup with no logs — concurrency groups are
2689+ // one repo-wide namespace across workflow and job levels. The same
2690+ // collision would apply to a workflow_run.id that numerically matches a
2691+ // PR number. The `-reconcile-` infix makes the two levels disjoint.
2692+ const contexts = [
2693+ contextFor ( { event_name : "pull_request_target" , event : { pull_request : { number : 1664 } } } ) ,
2694+ contextFor ( { event_name : "pull_request_review" , event : { pull_request : { number : 1664 } } } ) ,
2695+ contextFor ( { event_name : "issue_comment" , event : { issue : { number : 1664 } } } ) ,
2696+ contextFor ( { event_name : "workflow_dispatch" , event : { inputs : { pull_request_number : 1664 } } } ) ,
2697+ // workflow_run.id numerically equal to the PR number: the exact
2698+ // overlap the distinct namespace also has to cover.
2699+ contextFor ( {
2700+ event_name : "workflow_run" ,
2701+ event : { workflow_run : { id : 1664 , pull_requests : [ { number : 1664 } ] } } ,
2702+ } ) ,
2703+ contextFor ( {
2704+ event_name : "workflow_run" ,
2705+ event : { workflow_run : { id : 999 , pull_requests : [ { number : 1664 } , { number : 1707 } ] } } ,
2706+ } ) ,
2707+ contextFor ( { event_name : "schedule" } ) ,
2708+ contextFor ( { event_name : "push" } ) ,
2709+ ]
2710+
2711+ for ( const context of contexts ) {
2712+ const workflowGroup = workflowGroupFor ( context )
2713+ // The disjointness is structural: workflow-level groups never carry
2714+ // the reconcile infix that every shard group carries.
2715+ expect ( workflowGroup ) . not . toContain ( "-reconcile-" )
2716+ for ( const prNumber of [ 1664 , 1707 , 1437 , 999 ] ) {
2717+ expect ( shardGroupFor ( context , { pr_number : prNumber } ) ) . not . toBe ( workflowGroup )
2718+ }
26802719 }
2681- expect ( shardGroupFor ( triggerContexts [ 0 ] , { pr_number : 1707 } ) ) . toBe ( "label-pr-review-state-1707" )
2682- expect ( shardGroupFor ( triggerContexts [ 0 ] , { pr_number : 1707 } ) ) . not . toBe ( "label-pr-review-state-1664" )
26832720 } )
26842721
26852722 it ( "keeps the empty-resolution shard fallback unique per run" , ( ) => {
@@ -2696,10 +2733,10 @@ describe("PR review-state workflow concurrency groups (#1707)", () => {
26962733
26972734 const groupA = shardGroupFor ( runA , { pr_number : null } )
26982735 const groupB = shardGroupFor ( runB , { pr_number : null } )
2699- expect ( groupA ) . toBe ( "label-pr-review-state-555000111" )
2700- expect ( groupB ) . toBe ( "label-pr-review-state-555000222" )
2736+ expect ( groupA ) . toBe ( "label-pr-review-state-reconcile- 555000111" )
2737+ expect ( groupB ) . toBe ( "label-pr-review-state-reconcile- 555000222" )
27012738 expect ( groupA ) . not . toBe ( groupB )
2702- expect ( groupA ) . not . toBe ( "label-pr-review-state-1664" )
2739+ expect ( groupA ) . not . toBe ( "label-pr-review-state-reconcile- 1664" )
27032740 } )
27042741
27052742 it ( "fans out one serialized shard per resolved PR" , ( ) => {
@@ -2719,7 +2756,9 @@ describe("PR review-state workflow concurrency groups (#1707)", () => {
27192756 expect ( resolution . prNumbers ( ) ) . toEqual ( [ 1437 ] )
27202757
27212758 const context = contextFor ( { event_name : "pull_request_target" , event : { pull_request : { number : 1437 } } } )
2722- expect ( shardGroupFor ( context , { pr_number : resolution . prNumbers ( ) ?. [ 0 ] } ) ) . toBe ( "label-pr-review-state-1437" )
2759+ expect ( shardGroupFor ( context , { pr_number : resolution . prNumbers ( ) ?. [ 0 ] } ) ) . toBe (
2760+ "label-pr-review-state-reconcile-1437" ,
2761+ )
27232762 } )
27242763
27252764 it ( "resolves a sweep to one shard per open PR, each serializing with direct runs for that PR" , async ( ) => {
@@ -2732,9 +2771,9 @@ describe("PR review-state workflow concurrency groups (#1707)", () => {
27322771 shardGroupFor ( sweepContext , { pr_number : prNumber } ) ,
27332772 )
27342773 expect ( groups ) . toEqual ( [
2735- "label-pr-review-state-1664" ,
2736- "label-pr-review-state-1665" ,
2737- "label-pr-review-state-1666" ,
2774+ "label-pr-review-state-reconcile- 1664" ,
2775+ "label-pr-review-state-reconcile- 1665" ,
2776+ "label-pr-review-state-reconcile- 1666" ,
27382777 ] )
27392778
27402779 // A direct event for one of those PRs lands in the identical group, so the
@@ -2756,8 +2795,8 @@ describe("PR review-state workflow concurrency groups (#1707)", () => {
27562795 event : { workflow_run : { id : 123456 , pull_requests : [ { number : 1664 } , { number : 1707 } ] } } ,
27572796 } )
27582797 expect ( workflowGroupFor ( context ) ) . toBe ( "label-pr-review-state-123456" )
2759- expect ( shardGroupFor ( context , { pr_number : 1664 } ) ) . toBe ( "label-pr-review-state-1664" )
2760- expect ( shardGroupFor ( context , { pr_number : 1707 } ) ) . toBe ( "label-pr-review-state-1707" )
2798+ expect ( shardGroupFor ( context , { pr_number : 1664 } ) ) . toBe ( "label-pr-review-state-reconcile- 1664" )
2799+ expect ( shardGroupFor ( context , { pr_number : 1707 } ) ) . toBe ( "label-pr-review-state-reconcile- 1707" )
27612800 } )
27622801
27632802 it ( "demonstrates the stale-overwrite race that per-PR shard serialization prevents" , async ( ) => {
@@ -2816,7 +2855,7 @@ describe("PR review-state workflow concurrency groups (#1707)", () => {
28162855 event : { pull_request : { number : 1437 } } ,
28172856 } )
28182857 const sweepContext = contextFor ( { event_name : "schedule" } )
2819- expect ( shardGroupFor ( directContext , { pr_number : 1437 } ) ) . toBe ( "label-pr-review-state-1437" )
2858+ expect ( shardGroupFor ( directContext , { pr_number : 1437 } ) ) . toBe ( "label-pr-review-state-reconcile- 1437" )
28202859 expect ( shardGroupFor ( sweepContext , { pr_number : 1437 } ) ) . toBe ( shardGroupFor ( directContext , { pr_number : 1437 } ) )
28212860 } )
28222861
0 commit comments