@@ -2118,6 +2118,79 @@ function validateTrustedE2eDispatchReceipt(
21182118 }
21192119}
21202120
2121+ function validateTrustedE2ePlannerBoundary (
2122+ errors : string [ ] ,
2123+ generateSteps : WorkflowRecord [ ] ,
2124+ generate : WorkflowRecord | undefined ,
2125+ candidateCheckout : WorkflowRecord | undefined ,
2126+ ) : void {
2127+ const trustedPlannerCheckout = requireStep (
2128+ errors ,
2129+ generateSteps ,
2130+ "Check out trusted E2E planner" ,
2131+ ) ;
2132+ const trustedPlannerSetup = requireStep (
2133+ errors ,
2134+ generateSteps ,
2135+ "Set up Node for trusted E2E planning" ,
2136+ ) ;
2137+ const trustedPlannerInstall = requireStep (
2138+ errors ,
2139+ generateSteps ,
2140+ "Install trusted E2E planner dependencies" ,
2141+ ) ;
2142+ requireFullShaAction ( errors , trustedPlannerCheckout , "trusted E2E planner checkout" ) ;
2143+ if (
2144+ ! isDeepStrictEqual ( asRecord ( trustedPlannerCheckout ?. with ) , {
2145+ ref : "${{ github.workflow_sha }}" ,
2146+ "fetch-depth" : 0 ,
2147+ "persist-credentials" : false ,
2148+ } )
2149+ ) {
2150+ errors . push ( "trusted E2E planner checkout must use the workflow commit without credentials" ) ;
2151+ }
2152+ requireFullShaAction ( errors , trustedPlannerSetup , "trusted E2E planner Node setup" ) ;
2153+ if (
2154+ ! isDeepStrictEqual ( asRecord ( trustedPlannerSetup ?. with ) , {
2155+ "node-version" : 22 ,
2156+ } )
2157+ ) {
2158+ errors . push ( "trusted E2E planner must use Node 22" ) ;
2159+ }
2160+ if ( trustedPlannerInstall ?. run !== "npm ci --ignore-scripts --no-audit --no-fund" ) {
2161+ errors . push ( "trusted E2E planner dependencies must install without lifecycle scripts" ) ;
2162+ }
2163+ const trustedPlannerIndex = trustedPlannerCheckout
2164+ ? generateSteps . indexOf ( trustedPlannerCheckout )
2165+ : - 1 ;
2166+ const trustedSetupIndex = trustedPlannerSetup ? generateSteps . indexOf ( trustedPlannerSetup ) : - 1 ;
2167+ const trustedInstallIndex = trustedPlannerInstall
2168+ ? generateSteps . indexOf ( trustedPlannerInstall )
2169+ : - 1 ;
2170+ const generateIndex = generate ? generateSteps . indexOf ( generate ) : - 1 ;
2171+ const candidateCheckoutIndex = candidateCheckout ? generateSteps . indexOf ( candidateCheckout ) : - 1 ;
2172+ if (
2173+ trustedPlannerIndex < 0 ||
2174+ trustedSetupIndex <= trustedPlannerIndex ||
2175+ trustedInstallIndex <= trustedSetupIndex ||
2176+ generateIndex <= trustedInstallIndex ||
2177+ candidateCheckoutIndex <= generateIndex
2178+ ) {
2179+ errors . push ( "trusted E2E planning must finish before candidate checkout and execution" ) ;
2180+ }
2181+
2182+ const generateEnv = asRecord ( generate ?. env ) ;
2183+ if (
2184+ generateEnv . NEMOCLAW_E2E_CREDENTIALS_ALLOWED !==
2185+ "${{ (inputs.checkout_sha == '' || steps.candidate_authorization.outputs.nvidia_owned == 'true') && 'true' || 'false' }}"
2186+ ) {
2187+ errors . push ( "matrix generation step must bind NVIDIA-owned candidate authorization" ) ;
2188+ }
2189+ if ( generateEnv . NVIDIA_OWNED !== "${{ steps.candidate_authorization.outputs.nvidia_owned }}" ) {
2190+ errors . push ( "matrix generation step must bind the authenticated PR repository owner" ) ;
2191+ }
2192+ }
2193+
21212194export function validateE2eWorkflow ( workflowValue : unknown ) : string [ ] {
21222195 const workflow = asRecord ( workflowValue ) ;
21232196 const errors : string [ ] = [ ] ;
@@ -2311,21 +2384,6 @@ export function validateE2eWorkflow(workflowValue: unknown): string[] {
23112384 controllerMatrix ,
23122385 `printf 'matrix=%s\\n' "\${matrix}" >> "\${GITHUB_OUTPUT}"` ,
23132386 ) ;
2314- const trustedPlannerCheckout = requireStep (
2315- errors ,
2316- generateSteps ,
2317- "Check out trusted E2E planner" ,
2318- ) ;
2319- const trustedPlannerSetup = requireStep (
2320- errors ,
2321- generateSteps ,
2322- "Set up Node for trusted E2E planning" ,
2323- ) ;
2324- const trustedPlannerInstall = requireStep (
2325- errors ,
2326- generateSteps ,
2327- "Install trusted E2E planner dependencies" ,
2328- ) ;
23292387 const generateCheckout = requireStep ( errors , generateSteps , "Check out E2E candidate" ) ;
23302388 if ( ! generateCheckout ) errors . push ( "generate-matrix job missing checkout step" ) ;
23312389 const candidateAuthorization = generateSteps . find (
@@ -2351,45 +2409,7 @@ export function validateE2eWorkflow(workflowValue: unknown): string[] {
23512409 }
23522410 validateLargerRunnerRouting ( errors , jobs , generateMatrix , generateSteps , generateCheckout ) ;
23532411 const generate = requireStep ( errors , generateSteps , "Generate E2E target matrix" ) ;
2354- requireFullShaAction ( errors , trustedPlannerCheckout , "trusted E2E planner checkout" ) ;
2355- if (
2356- ! isDeepStrictEqual ( asRecord ( trustedPlannerCheckout ?. with ) , {
2357- ref : "${{ github.workflow_sha }}" ,
2358- "fetch-depth" : 0 ,
2359- "persist-credentials" : false ,
2360- } )
2361- ) {
2362- errors . push ( "trusted E2E planner checkout must use the workflow commit without credentials" ) ;
2363- }
2364- requireFullShaAction ( errors , trustedPlannerSetup , "trusted E2E planner Node setup" ) ;
2365- if (
2366- ! isDeepStrictEqual ( asRecord ( trustedPlannerSetup ?. with ) , {
2367- "node-version" : 22 ,
2368- } )
2369- ) {
2370- errors . push ( "trusted E2E planner must use Node 22" ) ;
2371- }
2372- if ( trustedPlannerInstall ?. run !== "npm ci --ignore-scripts --no-audit --no-fund" ) {
2373- errors . push ( "trusted E2E planner dependencies must install without lifecycle scripts" ) ;
2374- }
2375- const trustedPlannerIndex = trustedPlannerCheckout
2376- ? generateSteps . indexOf ( trustedPlannerCheckout )
2377- : - 1 ;
2378- const trustedSetupIndex = trustedPlannerSetup ? generateSteps . indexOf ( trustedPlannerSetup ) : - 1 ;
2379- const trustedInstallIndex = trustedPlannerInstall
2380- ? generateSteps . indexOf ( trustedPlannerInstall )
2381- : - 1 ;
2382- const generateIndex = generate ? generateSteps . indexOf ( generate ) : - 1 ;
2383- const candidateCheckoutIndex = generateCheckout ? generateSteps . indexOf ( generateCheckout ) : - 1 ;
2384- if (
2385- trustedPlannerIndex < 0 ||
2386- trustedSetupIndex <= trustedPlannerIndex ||
2387- trustedInstallIndex <= trustedSetupIndex ||
2388- generateIndex <= trustedInstallIndex ||
2389- candidateCheckoutIndex <= generateIndex
2390- ) {
2391- errors . push ( "trusted E2E planning must finish before candidate checkout and execution" ) ;
2392- }
2412+ validateTrustedE2ePlannerBoundary ( errors , generateSteps , generate , generateCheckout ) ;
23932413 const generateEnv = asRecord ( generate ?. env ) ;
23942414 if ( generateEnv . CHECKOUT_SHA !== "${{ inputs.checkout_sha }}" ) {
23952415 errors . push ( "matrix generation step must bind controller checkout through CHECKOUT_SHA env" ) ;
@@ -2406,17 +2426,6 @@ export function validateE2eWorkflow(workflowValue: unknown): string[] {
24062426 if ( generateEnv . TARGETS !== "${{ inputs.targets }}" ) {
24072427 errors . push ( "matrix generation step must pass targets through TARGETS env" ) ;
24082428 }
2409- if (
2410- generateEnv . NEMOCLAW_E2E_CREDENTIALS_ALLOWED !==
2411- "${{ (inputs.checkout_sha == '' || steps.candidate_authorization.outputs.nvidia_owned == 'true') && 'true' || 'false' }}"
2412- ) {
2413- errors . push ( "matrix generation step must bind NVIDIA-owned candidate authorization" ) ;
2414- }
2415- if (
2416- generateEnv . NVIDIA_OWNED !== "${{ steps.candidate_authorization.outputs.nvidia_owned }}"
2417- ) {
2418- errors . push ( "matrix generation step must bind the authenticated PR repository owner" ) ;
2419- }
24202429 validateInferenceModeGeneration ( errors , generate , generateEnv ) ;
24212430 requireRunContains ( errors , generate , "npx --no-install tsx tools/e2e/workflow-plan.mts" ) ;
24222431 requireRunContains ( errors , generate , "--ci-output" ) ;
0 commit comments