mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-10-30 09:16:55 +00:00
ci: one regression shard writes the test image cache (#6729)
* ci: one regression shard writes the test image cache, so it stops evicting the rest * test(ci): each image cache has one writer, shard 0 of a main push
This commit is contained in:
@@ -46,8 +46,8 @@ jobs:
|
||||
file: Dockerfile.test
|
||||
load: true
|
||||
tags: hyperframes-producer:test
|
||||
# regression.yml owns this cache's writes.
|
||||
cache-from: type=gha,scope=regression-test-image
|
||||
cache-to: type=gha,mode=max,scope=regression-test-image
|
||||
|
||||
- name: Validate fast-capture video (drawElement + BeginFrame)
|
||||
run: |
|
||||
|
||||
@@ -156,10 +156,9 @@ jobs:
|
||||
load: true
|
||||
tags: hyperframes-producer:test
|
||||
cache-from: type=gha,scope=regression-test-image
|
||||
# PR matrices can fan out across many stacked branches at once. Let
|
||||
# them consume the shared cache, but keep a single writer on main so
|
||||
# concurrent exports cannot exhaust the Actions cache service.
|
||||
cache-to: ${{ github.event_name == 'push' && 'type=gha,mode=max,scope=regression-test-image' || '' }}
|
||||
# One writer: the first shard of a main push. Every shard rebuilds the same layers with
|
||||
# different digests, so each export added ~1.3 GB and evicted the rest of the 10 GB cache.
|
||||
cache-to: ${{ github.event_name == 'push' && strategy.job-index == 0 && 'type=gha,mode=max,scope=regression-test-image' || '' }}
|
||||
|
||||
- name: "Run regression shard: ${{ matrix.shard }} (${{ matrix.mode }})"
|
||||
run: |
|
||||
|
||||
@@ -10,29 +10,28 @@ const load = (path) => parse(readFileSync(path, "utf8"));
|
||||
const workflows = readdirSync(workflowsDir)
|
||||
.filter((file) => /\.ya?ml$/.test(file))
|
||||
.map((file) => ({ file, doc: load(join(workflowsDir, file)) }));
|
||||
const events = (on) =>
|
||||
typeof on === "string" ? [on] : Array.isArray(on) ? on : Object.keys(on ?? {});
|
||||
const cacheWrites = (list) =>
|
||||
list.flatMap(({ file, doc }) =>
|
||||
Object.entries(doc.jobs ?? {}).flatMap(([name, job]) =>
|
||||
(job.steps ?? [])
|
||||
.map((step) => String(step.with?.["cache-to"] ?? ""))
|
||||
.filter((to) => to.includes("type=gha"))
|
||||
.map((to) => ({ id: `${file} ${name}`, to, matrix: Boolean(job.strategy?.matrix) })),
|
||||
),
|
||||
);
|
||||
|
||||
const dispatchOnly = ["fast-video-validation.yml"];
|
||||
const ungatedCacheWrites = (list) =>
|
||||
list
|
||||
.filter(({ file }) => !dispatchOnly.includes(file))
|
||||
.flatMap(({ file, doc }) =>
|
||||
Object.entries(doc.jobs ?? {}).flatMap(([name, job]) =>
|
||||
(job.steps ?? [])
|
||||
.map((step) => String(step.with?.["cache-to"] ?? ""))
|
||||
.filter((to) => to.includes("type=gha") && !to.includes("github.event_name == 'push'"))
|
||||
.map(() => `${file} ${name}`),
|
||||
),
|
||||
);
|
||||
|
||||
// The Actions cache holds 10 GB; per-PR image exports evict the bun cache and leave installs cold.
|
||||
test("only pushes to main write image layers to the Actions cache", () => {
|
||||
for (const file of dispatchOnly) {
|
||||
const { doc } = workflows.find((w) => w.file === file);
|
||||
assert.deepEqual(events(doc.on), ["workflow_dispatch"], `${file} must stay dispatch-only`);
|
||||
}
|
||||
assert.deepEqual(ungatedCacheWrites(workflows), []);
|
||||
// The Actions cache holds 10 GB. Per-PR exports evicted the bun cache; every shard of a main push
|
||||
// exporting its own copy of the same layers evicted the release's prebuilt ffmpeg.
|
||||
test("one job of a push to main writes each image cache", () => {
|
||||
const writes = cacheWrites(workflows);
|
||||
const ids = (list) => list.map((w) => w.id);
|
||||
assert.deepEqual(ids(writes.filter((w) => !w.to.includes("github.event_name == 'push'"))), []);
|
||||
assert.deepEqual(
|
||||
ids(writes.filter((w) => w.matrix && !w.to.includes("strategy.job-index == 0"))),
|
||||
[],
|
||||
);
|
||||
const scopes = writes.map((w) => w.to.match(/scope=([\w-]+)/)?.[1]);
|
||||
assert.deepEqual(scopes, [...new Set(scopes)]);
|
||||
});
|
||||
|
||||
test("preflight installs without downloading ffmpeg or Chrome", () => {
|
||||
|
||||
Reference in New Issue
Block a user