fix: prefix matching against matrix-expanded job names (#25212)
This commit is contained in:
@@ -77,9 +77,13 @@ runs:
|
|||||||
const rootCauseFailures = jobs.filter(j => {
|
const rootCauseFailures = jobs.filter(j => {
|
||||||
if (j.status !== 'completed' || j.conclusion !== 'failure') return false;
|
if (j.status !== 'completed' || j.conclusion !== 'failure') return false;
|
||||||
// h20 runners are flaky (dirty GPU state from prior runs); their failures
|
// h20 runners are flaky (dirty GPU state from prior runs); their failures
|
||||||
// should not cascade fast-fail to other stages. Exact match avoids
|
// should not cascade fast-fail to other stages. j.name shape from
|
||||||
// accidentally matching the h200 job names.
|
// listJobsForWorkflowRun: "<job-key>" + optional " / <reusable-job>"
|
||||||
if (j.name === 'stage-c-test-8-gpu-h20') {
|
// + optional " (<matrix>)". Split off the base job key before exact
|
||||||
|
// match so we cover both inline + reusable forms without confusing
|
||||||
|
// 'h20' with the 'h200' prefix.
|
||||||
|
const baseName = j.name.split(/[ /]/)[0];
|
||||||
|
if (baseName === 'stage-c-test-8-gpu-h20') {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// If the failing step is the health check, it's a cascade — skip it
|
// If the failing step is the health check, it's a cascade — skip it
|
||||||
|
|||||||
@@ -89,7 +89,11 @@ runs:
|
|||||||
if (spec.exact) {
|
if (spec.exact) {
|
||||||
return jobName === spec.prefix;
|
return jobName === spec.prefix;
|
||||||
}
|
}
|
||||||
return jobName === spec.prefix || jobName.startsWith(spec.prefix + ' (');
|
// Match bare prefix or any GHA-rendered shard suffix. Inline matrix
|
||||||
|
// produces `<prefix> (<shard>)`; reusable-workflow callers produce
|
||||||
|
// `<prefix> / <called-job> (<shard>)`. Both have a space after the
|
||||||
|
// prefix, so a single ' '-delimited check covers both.
|
||||||
|
return jobName === spec.prefix || jobName.startsWith(spec.prefix + ' ');
|
||||||
};
|
};
|
||||||
|
|
||||||
// Use ETag conditional requests to avoid consuming rate limit when nothing changed.
|
// Use ETag conditional requests to avoid consuming rate limit when nothing changed.
|
||||||
@@ -177,13 +181,16 @@ runs:
|
|||||||
|
|
||||||
if (matchingJobs.length < spec.expected_count) {
|
if (matchingJobs.length < spec.expected_count) {
|
||||||
// Job-level `if:` is evaluated before matrix expansion. When it
|
// Job-level `if:` is evaluated before matrix expansion. When it
|
||||||
// evaluates false, GitHub emits exactly one "skipped" entry using
|
// evaluates false, GitHub emits exactly one "skipped" entry
|
||||||
// the un-expanded job name (bare prefix, no " (shard)" suffix)
|
// without a "(shard)" suffix instead of N matrix entries. Two
|
||||||
// instead of N matrix entries. Detect that precise shape so we
|
// shapes are possible:
|
||||||
// don't poll forever — and so we don't mistake a partially
|
// - inline matrix: `<prefix>`
|
||||||
|
// - reusable workflow: `<prefix> / <called-job>`
|
||||||
|
// Both lack the ` (` shard marker. Detect that precise shape so
|
||||||
|
// we don't poll forever — and so we don't mistake a partially
|
||||||
// materialized dynamic/reusable matrix for a skipped one.
|
// materialized dynamic/reusable matrix for a skipped one.
|
||||||
const unexpandedSkip = matchingJobs.length === 1 &&
|
const unexpandedSkip = matchingJobs.length === 1 &&
|
||||||
matchingJobs[0].name === spec.prefix &&
|
!matchingJobs[0].name.includes(' (') &&
|
||||||
matchingJobs[0].status === 'completed' &&
|
matchingJobs[0].status === 'completed' &&
|
||||||
matchingJobs[0].conclusion === 'skipped';
|
matchingJobs[0].conclusion === 'skipped';
|
||||||
if (unexpandedSkip) {
|
if (unexpandedSkip) {
|
||||||
|
|||||||
Reference in New Issue
Block a user