1- // Runner-routing regression guards for ci.yml and serve-ab.yml .
1+ // Runner-routing regression guards for ci.yml.
22//
33// classify_pr carries the routing logic TWICE — the `runs-on` expression
44// (which selects the classify job's own runner) and the `pick_runner` shell
@@ -21,10 +21,6 @@ const workflowsDir = join(
2121 'workflows' ,
2222) ;
2323const ciDoc = parse ( readFileSync ( join ( workflowsDir , 'ci.yml' ) , 'utf8' ) ) ;
24- const serveAbDoc = parse (
25- readFileSync ( join ( workflowsDir , 'serve-ab.yml' ) , 'utf8' ) ,
26- ) ;
27-
2824const TRUSTED = [ 'OWNER' , 'MEMBER' , 'COLLABORATOR' ] ;
2925const ECS = '["self-hosted", "linux", "x64", "ecs-qwen"]' ;
3026const HOSTED = '["ubuntu-latest"]' ;
@@ -38,16 +34,28 @@ const pickRunner = ciDoc.jobs.classify_pr.steps.find(
3834// routing-relevant inputs: contains(list, '') is false, a missing
3935// pull_request (merge_group / dispatch) yields '' for both head.repo and
4036// author_association.
41- function simulateRunsOn ( { ecsDisabled, sameRepo, assoc, mergeGroup } ) {
37+ function simulateRunsOn ( {
38+ ecsDisabled,
39+ sameRepo,
40+ assoc,
41+ mergeGroup,
42+ qwenRepo = true ,
43+ } ) {
4244 const trusted = TRUSTED . includes ( assoc ) ;
43- const ecs =
44- ! ecsDisabled && ( sameRepo || trusted || mergeGroup ) ;
45+ const ecs = qwenRepo && ! ecsDisabled && ( sameRepo || trusted || mergeGroup ) ;
4546 return ecs ? ECS : HOSTED ;
4647}
4748
4849// Executes the real pick_runner shell with the same inputs and returns the
4950// selected runner exactly as CI would publish it.
50- function runPickRunner ( { ecsDisabled, sameRepo, assoc, eventName, dispatch } ) {
51+ function runPickRunner ( {
52+ ecsDisabled,
53+ sameRepo,
54+ assoc,
55+ eventName,
56+ dispatch,
57+ qwenRepo = true ,
58+ } ) {
5159 const tmp = mkdtempSync ( join ( tmpdir ( ) , 'pick-runner-' ) ) ;
5260 const outputFile = join ( tmp , 'github_output' ) ;
5361 const result = spawnSync ( 'bash' , [ '-c' , pickRunner . run ] , {
@@ -57,6 +65,9 @@ function runPickRunner({ ecsDisabled, sameRepo, assoc, eventName, dispatch }) {
5765 ECS_DISABLED : ecsDisabled ? 'true' : '' ,
5866 EVENT_NAME : eventName ,
5967 DISPATCH_LINUX_RUNNER : dispatch ?? '' ,
68+ GITHUB_REPOSITORY : qwenRepo
69+ ? 'QwenLM/qwen-code'
70+ : 'modelstudioai/openwork' ,
6071 GITHUB_OUTPUT : outputFile ,
6172 } ,
6273 encoding : 'utf8' ,
@@ -162,38 +173,31 @@ describe('ci.yml classify_pr runner routing', () => {
162173 ) ;
163174 } ) ;
164175
176+ it ( 'uses hosted runners outside the QwenLM repository' , ( ) => {
177+ assert . equal (
178+ runPickRunner ( {
179+ ecsDisabled : false ,
180+ sameRepo : true ,
181+ assoc : 'OWNER' ,
182+ eventName : 'pull_request' ,
183+ qwenRepo : false ,
184+ } ) ,
185+ HOSTED ,
186+ ) ;
187+ } ) ;
188+
165189 it ( 'the runs-on expression keeps the trusted clause and kill-switch' , ( ) => {
166190 // Structural pins for the expression half of the drift guard — the
167191 // simulation above re-implements it, so pin the real text too.
168192 assert . match (
169193 classifyRunsOn ,
170194 / c o n t a i n s \( f r o m J S O N \( ' \[ " O W N E R " , " M E M B E R " , " C O L L A B O R A T O R " \] ' \) , g i t h u b \. e v e n t \. p u l l _ r e q u e s t \. a u t h o r _ a s s o c i a t i o n \) / ,
171195 ) ;
172- assert . match ( classifyRunsOn , / v a r s \. M A I N T A I N E R _ E C S _ R U N N E R _ D I S A B L E D ! = ' t r u e ' / ) ;
173- assert . match ( classifyRunsOn , / g i t h u b \. e v e n t _ n a m e = = ' m e r g e _ g r o u p ' / ) ;
174- } ) ;
175- } ) ;
176-
177- describe ( 'serve-ab.yml runner routing' , ( ) => {
178- const runsOn = String ( serveAbDoc . jobs . ab [ 'runs-on' ] ) ;
179-
180- it ( 'admits same-repo and write-access fork PRs, guarded by the kill-switch' , ( ) => {
181- assert . match ( runsOn , / h e a d \. r e p o \. f u l l _ n a m e = = g i t h u b \. r e p o s i t o r y / ) ;
182196 assert . match (
183- runsOn ,
184- / c o n t a i n s \( f r o m J S O N \( ' \[ " O W N E R " , " M E M B E R " , " C O L L A B O R A T O R " \] ' \) , g i t h u b \. e v e n t \. p u l l _ r e q u e s t \. a u t h o r _ a s s o c i a t i o n \) / ,
185- ) ;
186- assert . match ( runsOn , / v a r s \. M A I N T A I N E R _ E C S _ R U N N E R _ D I S A B L E D ! = ' t r u e ' / ) ;
187- assert . match ( runsOn , / e c s - q w e n / ) ;
188- assert . match ( runsOn , / u b u n t u - l a t e s t / ) ;
189- } ) ;
190-
191- it ( 'wipes the reused workspace before checking out PR code' , ( ) => {
192- const wipe = serveAbDoc . jobs . ab . steps . find (
193- ( s ) => s . name === 'Wipe stale workspace before checkout' ,
197+ classifyRunsOn ,
198+ / v a r s \. M A I N T A I N E R _ E C S _ R U N N E R _ D I S A B L E D ! = ' t r u e ' / ,
194199 ) ;
195- assert . ok ( wipe , 'self-hosted reuse must not bleed one PR into the next' ) ;
196- assert . equal ( wipe . if , "${{ runner.environment == 'self-hosted' }}" ) ;
197- assert . match ( wipe . run , / f i n d " \$ G I T H U B _ W O R K S P A C E " - m i n d e p t h 1 - m a x d e p t h 1 - e x e c r m - r f / ) ;
200+ assert . match ( classifyRunsOn , / g i t h u b \. r e p o s i t o r y = = ' Q w e n L M \/ q w e n - c o d e ' / ) ;
201+ assert . match ( classifyRunsOn , / g i t h u b \. e v e n t _ n a m e = = ' m e r g e _ g r o u p ' / ) ;
198202 } ) ;
199203} ) ;
0 commit comments