fix(ci): skip portable report merge when shards are skipped (#2943)
* fix(ci): skip portable report merge when shards are skipped
The portable consumer can still run after an upstream build failure, even though the test-shard matrix is skipped and no Vitest blob artifacts exist. Guard artifact download and both report merge variants on successful shards; retain the required-shard gate so skipped or failed shards remain failures.
This applies the report-consumer condition from ee0256c740 to current pinned main without changing action pins or required gates.
* fix(ci): preserve failed shard diagnostics
* docs: clarify current revision CI policy
This commit is contained in:
1 parent
7a6defab18
commit
2895a18ca9
3 files changed
+26
-8
No files matched your search
@@ -290,14 +290,19 @@ jobs:
|
|||||||
- if: needs.changes.outputs.code == 'true' && success()
|
- if: needs.changes.outputs.code == 'true' && success()
|
||||||
run: npm ci
|
run: npm ci
|
||||||
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
||||||
if: needs.changes.outputs.code == 'true' && success()
|
if: >-
|
||||||
|
!cancelled() && needs.changes.outputs.code == 'true' &&
|
||||||
|
(needs.test-shard.result == 'success' || needs.test-shard.result == 'failure')
|
||||||
with:
|
with:
|
||||||
path: .vitest/blob
|
path: .vitest/blob
|
||||||
pattern: vitest-report-*
|
pattern: vitest-report-*
|
||||||
merge-multiple: true
|
merge-multiple: true
|
||||||
- name: Merge coverage, JUnit, and timing reports
|
- name: Merge coverage, JUnit, and timing reports
|
||||||
id: merge
|
id: merge
|
||||||
if: needs.changes.outputs.code == 'true' && needs.changes.outputs.tier == 'full' && success()
|
if: >-
|
||||||
|
!cancelled() && needs.changes.outputs.code == 'true' &&
|
||||||
|
needs.changes.outputs.tier == 'full' &&
|
||||||
|
(needs.test-shard.result == 'success' || needs.test-shard.result == 'failure')
|
||||||
run: >-
|
run: >-
|
||||||
npm run test:ci:merge --
|
npm run test:ci:merge --
|
||||||
--coverage.reportsDirectory=coverage
|
--coverage.reportsDirectory=coverage
|
||||||
@@ -312,7 +317,10 @@ jobs:
|
|||||||
--outputFile.json=test-results.json
|
--outputFile.json=test-results.json
|
||||||
- name: Merge fast-suite JUnit and timing reports
|
- name: Merge fast-suite JUnit and timing reports
|
||||||
id: merge-fast
|
id: merge-fast
|
||||||
if: needs.changes.outputs.code == 'true' && needs.changes.outputs.tier == 'fast' && success()
|
if: >-
|
||||||
|
!cancelled() && needs.changes.outputs.code == 'true' &&
|
||||||
|
needs.changes.outputs.tier == 'fast' &&
|
||||||
|
(needs.test-shard.result == 'success' || needs.test-shard.result == 'failure')
|
||||||
run: >-
|
run: >-
|
||||||
npm exec -- vitest --merge-reports
|
npm exec -- vitest --merge-reports
|
||||||
--reporter=default
|
--reporter=default
|
||||||
|
|||||||
+1
-2
@@ -182,8 +182,7 @@ The separate GitHub Pages host uses only the manual
|
|||||||
## Development feedback and PR verification
|
## Development feedback and PR verification
|
||||||
|
|
||||||
For routine merges, wait for the required checks to pass for the current PR
|
For routine merges, wait for the required checks to pass for the current PR
|
||||||
revision against the current `main`. Branch protection requires up-to-date
|
revision. Administrators retain an override for deliberate maintainer recovery.
|
||||||
branches; administrators retain an override for deliberate maintainer recovery.
|
|
||||||
If `main` is broken, prioritize a focused repair before updating affected PRs.
|
If `main` is broken, prioritize a focused repair before updating affected PRs.
|
||||||
|
|
||||||
Select checks for the behavior changed. For a source edit:
|
Select checks for the behavior changed. For a source edit:
|
||||||
|
|||||||
@@ -45,23 +45,34 @@ const workflow = async () =>
|
|||||||
),
|
),
|
||||||
).jobs;
|
).jobs;
|
||||||
|
|
||||||
it("collects failed-shard diagnostics before enforcing the shard result", async () => {
|
it("merges available failed-shard diagnostics and skips unavailable shard reports", async () => {
|
||||||
const steps = (await workflow()).test!.steps;
|
const steps = (await workflow()).test!.steps;
|
||||||
|
const download = steps.find(
|
||||||
|
(step) =>
|
||||||
|
step.uses?.includes("actions/download-artifact") &&
|
||||||
|
step.with?.pattern === "vitest-report-*",
|
||||||
|
);
|
||||||
const merge = steps.findIndex((step) => step.run?.includes("test:ci:merge"));
|
const merge = steps.findIndex((step) => step.run?.includes("test:ci:merge"));
|
||||||
const upload = steps.findIndex((step) => step.with?.name === "test-results");
|
const upload = steps.findIndex((step) => step.with?.name === "test-results");
|
||||||
const gate = steps.findIndex(
|
const gate = steps.findIndex(
|
||||||
(step) => step.env?.SHARD_RESULT && step.run?.includes("test "),
|
(step) => step.env?.SHARD_RESULT && step.run?.includes("test "),
|
||||||
);
|
);
|
||||||
expect(merge).toBeGreaterThan(0);
|
expect(merge).toBeGreaterThan(0);
|
||||||
|
expect(download?.if).toContain("!cancelled()");
|
||||||
|
expect(download?.if).toContain("needs.test-shard.result == 'success'");
|
||||||
|
expect(download?.if).toContain("needs.test-shard.result == 'failure'");
|
||||||
expect(upload).toBeGreaterThan(merge);
|
expect(upload).toBeGreaterThan(merge);
|
||||||
expect(gate).toBeGreaterThan(upload);
|
expect(gate).toBeGreaterThan(upload);
|
||||||
expect(steps[merge]?.if).not.toContain("needs.test-shard.result");
|
|
||||||
const merges = steps.filter((step) => step.run?.includes("--reporter=json"));
|
const merges = steps.filter((step) => step.run?.includes("--reporter=json"));
|
||||||
expect(merges).toHaveLength(2);
|
expect(merges).toHaveLength(2);
|
||||||
for (const step of merges)
|
for (const step of merges) {
|
||||||
expect(step.run).toContain(
|
expect(step.run).toContain(
|
||||||
"--reporter=./scripts/ci/test-timing-reporter.mjs",
|
"--reporter=./scripts/ci/test-timing-reporter.mjs",
|
||||||
);
|
);
|
||||||
|
expect(step.if).toContain("!cancelled()");
|
||||||
|
expect(step.if).toContain("needs.test-shard.result == 'success'");
|
||||||
|
expect(step.if).toContain("needs.test-shard.result == 'failure'");
|
||||||
|
}
|
||||||
expect(steps[upload]?.with?.path).toContain("test-timings.json");
|
expect(steps[upload]?.with?.path).toContain("test-timings.json");
|
||||||
expect(steps[upload]?.with).toMatchObject({ "include-hidden-files": true });
|
expect(steps[upload]?.with).toMatchObject({ "include-hidden-files": true });
|
||||||
expect(steps[upload]?.with?.path).toContain(
|
expect(steps[upload]?.with?.path).toContain(
|
||||||
|
|||||||
Reference in new issue
Block a user