mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-10-30 09:16:55 +00:00
ci: run cli tests in their own job so runtime tests stop timing out (#6326)
* ci: run cli tests in their own job so runtime tests stop timing out * ci: format the test aggregator needs list * ci: keep the test aggregator needs on one line for the reachability check * ci(reachability): read wrapped and block needs lists instead of rejecting them
This commit is contained in:
@@ -575,7 +575,29 @@ jobs:
|
||||
- run: bun run --filter '@hyperframes/{parsers,lint,studio-server}' build
|
||||
- run: bun run --cwd packages/core build
|
||||
- run: bun run --cwd packages/core build:hyperframes-runtime
|
||||
- run: bun run --filter '@hyperframes/{cli,core,engine}' test
|
||||
- run: bun run --filter '@hyperframes/{core,engine}' test
|
||||
|
||||
test-cli:
|
||||
name: Test (cli)
|
||||
needs: changes
|
||||
if: needs.changes.outputs.code == 'true'
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
steps:
|
||||
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
|
||||
with:
|
||||
lfs: true
|
||||
- uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2
|
||||
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
||||
with:
|
||||
node-version: 22
|
||||
- uses: ./.github/actions/install-ffmpeg-linux
|
||||
- uses: ./.github/actions/prepare-ffmpeg-bin
|
||||
- run: bash scripts/ci/install-workspace-dependencies.sh
|
||||
- run: bun run --filter '@hyperframes/{parsers,lint,studio-server}' build
|
||||
- run: bun run --cwd packages/core build
|
||||
- run: bun run --cwd packages/core build:hyperframes-runtime
|
||||
- run: bun run --filter '@hyperframes/cli' test
|
||||
|
||||
test-support:
|
||||
name: Test (support)
|
||||
@@ -612,7 +634,16 @@ jobs:
|
||||
|
||||
test:
|
||||
name: Test
|
||||
needs: [changes, producer-source-tests, test-studio, test-runtime, test-support, test-skills]
|
||||
needs:
|
||||
[
|
||||
changes,
|
||||
producer-source-tests,
|
||||
test-studio,
|
||||
test-runtime,
|
||||
test-cli,
|
||||
test-support,
|
||||
test-skills,
|
||||
]
|
||||
# Keep the existing required `Test` context authoritative for producer
|
||||
# failures too. It also fails closed if any package shard fails or is cancelled.
|
||||
if: always() && (needs.changes.result != 'success' || needs.changes.outputs.code == 'true' || needs.changes.outputs.skills == 'true')
|
||||
@@ -630,10 +661,10 @@ jobs:
|
||||
echo "::error::Producer unit/integration tests did not succeed."
|
||||
exit 1
|
||||
- name: Require package test shards
|
||||
if: needs.changes.outputs.code == 'true' && (needs.test-studio.result != 'success' || needs.test-runtime.result != 'success' || needs.test-support.result != 'success')
|
||||
if: needs.changes.outputs.code == 'true' && (needs.test-studio.result != 'success' || needs.test-runtime.result != 'success' || needs.test-cli.result != 'success' || needs.test-support.result != 'success')
|
||||
run: |
|
||||
echo "::error::A package test shard did not succeed."
|
||||
echo "studio=${{ needs.test-studio.result }} runtime=${{ needs.test-runtime.result }} support=${{ needs.test-support.result }}"
|
||||
echo "studio=${{ needs.test-studio.result }} runtime=${{ needs.test-runtime.result }} cli=${{ needs.test-cli.result }} support=${{ needs.test-support.result }}"
|
||||
exit 1
|
||||
- name: Require skills tests
|
||||
if: needs.changes.outputs.skills == 'true' && needs.test-skills.result != 'success'
|
||||
|
||||
@@ -58,24 +58,29 @@ function jobField(body, key) {
|
||||
return body.match(new RegExp(`^ ${key}: (.*)$`, "m"))?.[1] ?? "";
|
||||
}
|
||||
|
||||
// `needs` as a one-line list, a multi-line list or a block list, whichever the formatter wrote.
|
||||
function jobNeeds(body) {
|
||||
const value = body.match(/^ needs:(.*(?:\n(?: .*| *))*)/m)?.[1] ?? "";
|
||||
return value
|
||||
.replace(/#.*$/gm, "")
|
||||
.replace(/^\s*- /gm, "")
|
||||
.split(/[\s,[\]]+/)
|
||||
.filter(Boolean);
|
||||
}
|
||||
|
||||
function readJob(block) {
|
||||
const name = block.match(/^ ([\w-]+):/)[1];
|
||||
const body = block.slice(block.indexOf("\n") + 1);
|
||||
const condition = jobField(body, "if");
|
||||
const needs = jobField(body, "needs");
|
||||
return {
|
||||
name,
|
||||
body,
|
||||
condition,
|
||||
needs: needs.replace(/[[\]]/g, "").split(/,\s*/).filter(Boolean),
|
||||
};
|
||||
const needs = jobNeeds(body);
|
||||
return { name, body, condition, needs };
|
||||
}
|
||||
|
||||
// Reject unsupported control syntax instead of treating it as an unconditional job.
|
||||
export function readWorkflow(source) {
|
||||
if (/^\s+(?:paths|paths-ignore|branches-ignore):/m.test(source.split("jobs:\n")[0]))
|
||||
throw new Error("Workflow trigger restrictions need an explicit reachability model");
|
||||
if (/^ (?:needs|if):\s*$/m.test(source))
|
||||
if (/^ if:\s*$/m.test(source) || /^ needs:\s*\n (?![-[])/m.test(source))
|
||||
throw new Error("Block job conditions and dependencies need an explicit reachability model");
|
||||
if (/^\s+(?:- )?working-directory:/m.test(source))
|
||||
throw new Error("Working-directory overrides need an explicit reachability model");
|
||||
|
||||
@@ -137,11 +137,21 @@ test("conditions in the first step key are never credited", () => {
|
||||
assert.match(check(tree)["scripts/parity.test.mjs"][0], /no CI runner/);
|
||||
});
|
||||
|
||||
test("block dependency syntax fails closed instead of losing the dependency", () => {
|
||||
test("block and wrapped dependency lists gate a job like the one-line list", () => {
|
||||
for (const needs of ["\n - disabled", "\n [\n disabled,\n ]"]) {
|
||||
const tree = fixture("node --test scripts/parity.test.mjs", '"**"');
|
||||
tree[".github/workflows/ci.yml"] =
|
||||
tree[".github/workflows/ci.yml"].replace(" needs: changes", ` needs:${needs}`) +
|
||||
" disabled:\n if: false\n steps: []\n";
|
||||
assert.match(check(tree)["scripts/parity.test.mjs"].join("\n"), /CI filters exclude/);
|
||||
}
|
||||
});
|
||||
|
||||
test("a dependency mapping fails closed instead of losing the dependency", () => {
|
||||
const tree = fixture();
|
||||
tree[".github/workflows/ci.yml"] = tree[".github/workflows/ci.yml"].replace(
|
||||
"needs: changes",
|
||||
"needs:\n - disabled",
|
||||
"needs:\n disabled: x",
|
||||
);
|
||||
assert.throws(() => check(tree), /Block job/);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user