@@ -12,18 +12,24 @@ permissions:
1212# Regular comments get a unique group (run_id) so they don't cancel in-progress test runs
1313#
1414# Logic:
15- # - Regular comments (not /ok-to-test or / retest): unique group prevents cancellation of real tests
16- # - Valid triggers: group 'e2e-openshift-{pr_number}' (can cancel previous runs for same PR)
15+ # - Regular comments (not /ok-to-test, /retest, /ok-to-test-v2, / retest-v2 ): unique group prevents cancellation of real tests
16+ # - Valid triggers: group 'e2e-openshift-{pr_number}' or 'e2e-openshift-v2-{pr_number}' (can cancel previous runs for same PR)
1717# - Fallback chain for ID: pull_request.number -> issue.number -> run_id
1818#
19- # NOTE: Valid command list (/ok-to-test, /retest) must stay in sync with gate job validation (line ~125)
19+ # NOTE: Valid command list must stay in sync with gate job validation
20+ # /ok-to-test and /retest trigger both V1 and V2
2021concurrency :
2122 group : >-
2223 ${{
2324 github.event_name == 'issue_comment' &&
2425 !contains(github.event.comment.body, '/ok-to-test') &&
2526 !contains(github.event.comment.body, '/retest')
2627 && format('comment-isolated-{0}', github.run_id)
28+ || contains(github.event.comment.body, '-v2')
29+ && format('e2e-openshift-v2-{0}',
30+ github.event.pull_request.number
31+ || github.event.issue.number
32+ || github.run_id)
2733 || format('e2e-openshift-{0}',
2834 github.event.pull_request.number
2935 || github.event.issue.number
5763 description : ' Number of prompts'
5864 required : false
5965 default : ' 3000'
66+ analyzer_name :
67+ description : ' Scaling analyzer: empty for V1 (default), "saturation" for V2'
68+ required : false
69+ default : ' '
6070 skip_cleanup :
6171 description : ' Skip cleanup after tests'
6272 required : false
@@ -124,6 +134,7 @@ jobs:
124134 pr_number : ${{ steps.check.outputs.pr_number }}
125135 pr_head_sha : ${{ steps.check.outputs.pr_head_sha }}
126136 is_fork_pr : ${{ steps.check.outputs.is_fork_pr }}
137+ analyzer_name : ${{ steps.check.outputs.analyzer_name }}
127138 steps :
128139 - name : Check permissions and OpenShift E2E triggers (/ok-to-test, /retest)
129140 id : check
@@ -148,10 +159,13 @@ jobs:
148159
149160 // Always run for workflow_dispatch
150161 if (context.eventName === 'workflow_dispatch') {
162+ const inputAnalyzer = '${{ github.event.inputs.analyzer_name }}' || '';
151163 core.setOutput('should_run', 'true');
152164 core.setOutput('pr_number', '');
153165 core.setOutput('pr_head_sha', context.sha);
154166 core.setOutput('is_fork_pr', 'false');
167+ core.setOutput('analyzer_name', inputAnalyzer);
168+ if (inputAnalyzer) console.log(`V2 engine mode: analyzerName=${inputAnalyzer}`);
155169 return;
156170 }
157171
@@ -167,14 +181,18 @@ jobs:
167181 return;
168182 }
169183
170- // NOTE: This list must stay in sync with concurrency group logic (lines 23-25)
171- const validCommands = ['/ok-to-test', '/retest'];
184+ // NOTE: This list must stay in sync with concurrency group logic
185+ const validCommands = ['/ok-to-test', '/retest', '/ok-to-test-v2', '/retest-v2' ];
172186 if (!validCommands.includes(comment)) {
173187 console.log(`Comment "${comment}" is not a valid trigger command, skipping`);
174188 core.setOutput('should_run', 'false');
175189 return;
176190 }
177191
192+ // Determine if this is a V2-only trigger
193+ const isV2 = comment.endsWith('-v2');
194+ const analyzerName = isV2 ? 'saturation' : '';
195+
178196 // Check if commenter has write access
179197 const commenter = context.payload.comment.user.login;
180198 const hasAccess = await hasWriteAccess(commenter);
@@ -199,10 +217,12 @@ jobs:
199217 console.log(`${comment} approved by ${commenter} for PR #${issue.number}`);
200218 console.log(`PR head SHA: ${pr.head.sha}`);
201219 console.log(`Is fork PR: ${isFork} (head: ${headRepo}, base: ${baseRepo})`);
220+ if (isV2) console.log(`V2 engine mode: analyzerName=saturation`);
202221 core.setOutput('should_run', 'true');
203222 core.setOutput('pr_number', issue.number.toString());
204223 core.setOutput('pr_head_sha', pr.head.sha);
205224 core.setOutput('is_fork_pr', isFork ? 'true' : 'false');
225+ core.setOutput('analyzer_name', analyzerName);
206226
207227 // Add reaction to acknowledge
208228 await github.rest.reactions.createForIssueComment({
@@ -214,12 +234,14 @@ jobs:
214234
215235 // Post comment with link to the e2e workflow run
216236 const runUrl = `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`;
217- const cmdDesc = comment === '/ok-to-test' ? 'approve and run' : 're-run';
237+ const baseCmd = comment.replace('-v2', '');
238+ const cmdDesc = baseCmd === '/ok-to-test' ? 'approve and run' : 're-run';
239+ const engineLabel = isV2 ? ' (V2 saturation engine)' : '';
218240 await github.rest.issues.createComment({
219241 owner: context.repo.owner,
220242 repo: context.repo.repo,
221243 issue_number: issue.number,
222- body: `🚀 **OpenShift E2E** — ${cmdDesc} (\`${comment}\`)\n\n[View the OpenShift E2E workflow run](${runUrl})`
244+ body: `🚀 **OpenShift E2E${engineLabel} ** — ${cmdDesc} (\`${comment}\`)\n\n[View the OpenShift E2E workflow run](${runUrl})`
223245 });
224246 return;
225247 }
@@ -273,6 +295,9 @@ jobs:
273295 }
274296 }
275297
298+ // pull_request events always use V1 (default engine)
299+ core.setOutput('analyzer_name', '');
300+
276301 if (isPrivileged) {
277302 // For maintainer/admin fork PRs, we need to trigger via /ok-to-test
278303 // because fork PRs don't have access to secrets on pull_request event
@@ -303,7 +328,7 @@ jobs:
303328 core.setOutput('should_run', 'false');
304329
305330 if (!botComment) {
306- const posted = await tryPostComment(`👋 Thanks for your contribution!\n\nThis PR is from a fork, so **OpenShift E2E** (GPU) tests require approval to run.\n\n**For maintainers/admins:** Comment \`/ok-to-test\` to approve and trigger **OpenShift E2E** on this PR, or \`/retest\` to re-run OpenShift E2E (e.g. after a failure or new commits).\n\n**For contributors:** Please wait for a maintainer or admin to approve running the tests.`);
331+ const posted = await tryPostComment(`👋 Thanks for your contribution!\n\nThis PR is from a fork, so **OpenShift E2E** (GPU) tests require approval to run.\n\n**For maintainers/admins:** Comment \`/ok-to-test\` to approve and trigger **OpenShift E2E** on this PR, or \`/retest\` to re-run OpenShift E2E (e.g. after a failure or new commits).\n\nFor V2 engine testing, use \`/ok-to-test-v2\` or \`/retest-v2\`.\n\ n**For contributors:** Please wait for a maintainer or admin to approve running the tests.`);
307332 if (!posted) {
308333 console.log('Note: Could not post instructions comment on fork PR');
309334 }
@@ -692,6 +717,8 @@ jobs:
692717 # Pass PR-specific namespaces to install script
693718 LLMD_NS : ${{ env.LLMD_NAMESPACE }}
694719 WVA_NS : ${{ env.WVA_NAMESPACE }}
720+ # V2 engine: set to "saturation" for V2 capacity-constraint analyzer
721+ ANALYZER_NAME : ${{ needs.gate.outputs.analyzer_name }}
695722 # Controller instance label for multi-controller isolation in parallel e2e tests
696723 CONTROLLER_INSTANCE : ${{ env.WVA_NAMESPACE }}
697724 # Skip infra VA/HPA — the smoke test creates its own VA+HPA targeting
@@ -733,6 +760,7 @@ jobs:
733760 echo " DECODE_REPLICAS: $DECODE_REPLICAS"
734761 echo " KV_SPARE_TRIGGER: ${KV_SPARE_TRIGGER:-<default>}"
735762 echo " QUEUE_SPARE_TRIGGER: ${QUEUE_SPARE_TRIGGER:-<default>}"
763+ echo " ANALYZER_NAME: ${ANALYZER_NAME:-<default V1>}"
736764 echo " HF token configuration: ✓"
737765 ./deploy/install.sh --model "$MODEL_ID" --accelerator "$ACCELERATOR_TYPE" --release-name "$WVA_RELEASE_NAME" --environment openshift
738766
@@ -1185,23 +1213,30 @@ jobs:
11851213 script : |
11861214 const prHeadSha = '${{ needs.gate.outputs.pr_head_sha }}';
11871215 const e2eResult = '${{ needs.e2e-openshift.result }}';
1216+ const analyzerName = '${{ needs.gate.outputs.analyzer_name }}';
1217+ const isV2 = analyzerName === 'saturation';
11881218
11891219 // Map job result to commit status
11901220 let state, description;
1221+ const engineLabel = isV2 ? ' (V2)' : '';
11911222 if (e2eResult === 'success') {
11921223 state = 'success';
1193- description = ' E2E tests passed' ;
1224+ description = ` E2E tests passed${engineLabel}` ;
11941225 } else if (e2eResult === 'skipped') {
11951226 state = 'pending';
1196- description = ' E2E tests skipped' ;
1227+ description = ` E2E tests skipped${engineLabel}` ;
11971228 } else if (e2eResult === 'cancelled') {
11981229 state = 'failure';
1199- description = ' E2E tests cancelled' ;
1230+ description = ` E2E tests cancelled${engineLabel}` ;
12001231 } else {
12011232 state = 'failure';
1202- description = ' E2E tests failed' ;
1233+ description = ` E2E tests failed${engineLabel}` ;
12031234 }
12041235
1236+ const statusContext = isV2
1237+ ? '${{ github.workflow }} / e2e-v2 (comment trigger)'
1238+ : '${{ github.workflow }} / e2e (comment trigger)';
1239+
12051240 console.log(`Reporting status to PR commit ${prHeadSha}: ${state} - ${description}`);
12061241
12071242 await github.rest.repos.createCommitStatus({
@@ -1211,7 +1246,7 @@ jobs:
12111246 state: state,
12121247 target_url: `https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`,
12131248 description: description,
1214- context: '${{ github.workflow }} / e2e (comment trigger)'
1249+ context: statusContext
12151250 });
12161251
12171252 console.log('Status reported successfully');
0 commit comments