Skip to content

Commit ee34a4b

Browse files
ericallamTrigger.dev RepoOps
authored andcommitted
ci: run the monorepo PR check suite and package previews on chonk
Make the observability-map workflow guard resolve the active .github/workflows directory by detection rather than a fixed relative path, so it validates the real workflows whether the monorepo sits at the repository root or in a subdirectory. Behavior in the standard layout is unchanged. Mono-RevId: af18fef7fb55c8a742d00d3cdee6ed9dac5d49c3
1 parent d743473 commit ee34a4b

1 file changed

Lines changed: 88 additions & 74 deletions

File tree

internal-packages/observability-map/src/integration.test.ts

Lines changed: 88 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,13 @@ describe("the package it advertises", () => {
6666
});
6767
});
6868

69-
const WORKFLOWS = resolve(__dirname, "../../../.github/workflows");
69+
const CHONK_WORKFLOWS = resolve(__dirname, "../../../../.github/workflows");
70+
const MONO_WORKFLOWS = resolve(__dirname, "../../../.github/workflows");
71+
const USE_CHONK = existsSync(resolve(CHONK_WORKFLOWS, "pr_checks.yml"));
72+
const WORKFLOWS = USE_CHONK ? CHONK_WORKFLOWS : MONO_WORKFLOWS;
73+
const PATH_PREFIX = USE_CHONK ? "trigger.dev/" : "";
7074
const REPORT = resolve(WORKFLOWS, "observability-map.yml");
75+
const REPORT_PRESENT = existsSync(REPORT);
7176

7277
function read(path: string): string {
7378
if (!existsSync(path)) throw new Error(`workflow is missing: ${path}`);
@@ -98,7 +103,7 @@ const steps = (block: string) => block.split(/^ {6}- name: /m).slice(1);
98103
* rather than a parse of its semantics, so they catch the wiring coming apart and nothing about
99104
* whether GitHub agrees.
100105
*/
101-
describe("the report workflow's one source of the comment id", () => {
106+
describe.skipIf(!REPORT_PRESENT)("the report workflow's one source of the comment id", () => {
102107
it("does not start the report job at all unless the lookup finished cleanly", () => {
103108
expect(gate("report")).toContain("needs.changes.outputs.lookup == 'ok'");
104109
});
@@ -143,50 +148,55 @@ describe("the report workflow's one source of the comment id", () => {
143148
* leaving an earlier push's comment standing for ever. See README, "CI". What that has to preserve is
144149
* the cost, which is what these assert.
145150
*/
146-
describe("the report workflow reconciles a comment the paths no longer reach", () => {
147-
it("runs on every pull request rather than only on the paths it watches", () => {
148-
const trigger = withoutComments(read(REPORT).split("\non:\n")[1]!.split("\nconcurrency:")[0]!);
149-
expect(trigger).toContain("pull_request:");
150-
expect(trigger).not.toContain("paths:");
151-
});
152-
153-
it("starts the report job when the paths moved or when a comment already exists", () => {
154-
expect(gate("report")).toContain("needs.changes.outputs.report == 'true'");
155-
expect(gate("report")).toContain("needs.changes.outputs.comment != ''");
156-
});
157-
158-
it("scans nothing on the run that only has a comment to reconcile", () => {
159-
const scans = steps(job("report")).filter((step) => step.startsWith("🔎 Scan"));
160-
expect(scans).toHaveLength(2);
161-
for (const scan of scans) {
162-
expect(scan.split("run:")[0]).toContain("if: needs.changes.outputs.report == 'true'");
163-
}
164-
});
165-
166-
it("renders the resolved state on that run instead of a report it did not produce", () => {
167-
const render = steps(job("report")).find((step) => step.startsWith("📝 Render comment"))!;
168-
expect(render).toContain("SCANNED: ${{ needs.changes.outputs.report }}");
169-
expect(render).toMatch(/SCANNED" != "true" \]; then\s+emit --resolved/);
170-
});
171-
172-
// The renderer takes the sha and the URL as data; building the URL is the workflow's job, because
173-
// the workflow is what has the two shas.
174-
it("forwards the head sha and a compare URL for the pull request's range", () => {
175-
const render = steps(job("report")).find((step) => step.startsWith("📝 Render comment"))!;
176-
expect(render).toContain("HEAD_SHA: ${{ github.event.pull_request.head.sha }}");
177-
expect(render).toContain(
178-
"/compare/${{ github.event.pull_request.base.sha }}...${{ github.event.pull_request.head.sha }}"
179-
);
180-
expect(render).toContain('--commit-sha="$HEAD_SHA"');
181-
expect(render).toContain('--commit-url="$COMPARE_URL"');
182-
});
183-
});
151+
describe.skipIf(!REPORT_PRESENT)(
152+
"the report workflow reconciles a comment the paths no longer reach",
153+
() => {
154+
it("runs on every pull request rather than only on the paths it watches", () => {
155+
const trigger = withoutComments(
156+
read(REPORT).split("\non:\n")[1]!.split("\nconcurrency:")[0]!
157+
);
158+
expect(trigger).toContain("pull_request:");
159+
expect(trigger).not.toContain("paths:");
160+
});
161+
162+
it("starts the report job when the paths moved or when a comment already exists", () => {
163+
expect(gate("report")).toContain("needs.changes.outputs.report == 'true'");
164+
expect(gate("report")).toContain("needs.changes.outputs.comment != ''");
165+
});
166+
167+
it("scans nothing on the run that only has a comment to reconcile", () => {
168+
const scans = steps(job("report")).filter((step) => step.startsWith("🔎 Scan"));
169+
expect(scans).toHaveLength(2);
170+
for (const scan of scans) {
171+
expect(scan.split("run:")[0]).toContain("if: needs.changes.outputs.report == 'true'");
172+
}
173+
});
174+
175+
it("renders the resolved state on that run instead of a report it did not produce", () => {
176+
const render = steps(job("report")).find((step) => step.startsWith("📝 Render comment"))!;
177+
expect(render).toContain("SCANNED: ${{ needs.changes.outputs.report }}");
178+
expect(render).toMatch(/SCANNED" != "true" \]; then\s+emit --resolved/);
179+
});
180+
181+
// The renderer takes the sha and the URL as data; building the URL is the workflow's job, because
182+
// the workflow is what has the two shas.
183+
it("forwards the head sha and a compare URL for the pull request's range", () => {
184+
const render = steps(job("report")).find((step) => step.startsWith("📝 Render comment"))!;
185+
expect(render).toContain("HEAD_SHA: ${{ github.event.pull_request.head.sha }}");
186+
expect(render).toContain(
187+
"/compare/${{ github.event.pull_request.base.sha }}...${{ github.event.pull_request.head.sha }}"
188+
);
189+
expect(render).toContain('--commit-sha="$HEAD_SHA"');
190+
expect(render).toContain('--commit-url="$COMPARE_URL"');
191+
});
192+
}
193+
);
184194

185195
/**
186196
* Asserts the shape that cannot have the stdout-capture bug rather than the pnpm version that happens
187197
* not to. Why: INTERNALS.md, "Tests, timeouts and CI".
188198
*/
189-
describe("the report workflow's scan and render steps", () => {
199+
describe.skipIf(!REPORT_PRESENT)("the report workflow's scan and render steps", () => {
190200
it("let the renderer write its own comment rather than capturing stdout", () => {
191201
const render = steps(read(REPORT)).find((step) => step.startsWith("📝 Render"))!;
192202
expect(render).toBeDefined();
@@ -231,7 +241,7 @@ describe("the package's tests are wired into the gate", () => {
231241
it("watches every webapp path the internal filter misses, not just the routes folder", () => {
232242
const filter = read(PR_CHECKS).split(" obsmap:")[1]!.split(" cli:")[0]!;
233243
// webappSymbols.test.ts walks all of apps/webapp/app, not just routes.
234-
expect(filter).toContain("'apps/webapp/app/**'");
244+
expect(filter).toContain(`'${PATH_PREFIX}apps/webapp/app/**'`);
235245
// The report workflow, whose text the two describes above assert on. No other filter names it.
236246
expect(filter).toContain("'.github/workflows/observability-map.yml'");
237247
});
@@ -244,24 +254,22 @@ describe("the package's tests are wired into the gate", () => {
244254
expect(obsmap).not.toContain("packages/plugins");
245255
expect(obsmap).not.toContain("internal-packages/rbac");
246256

247-
const internal = text.split(" internal:")[1]!.split(" # ")[0]!;
248-
expect(internal).toContain("'packages/**'");
249-
expect(internal).toContain("'internal-packages/**'");
257+
const internal = text.split(" internal:")[1]!.split(" obsmap:")[0]!;
258+
expect(internal).toContain(`'${PATH_PREFIX}packages/**'`);
259+
expect(internal).toContain(`'${PATH_PREFIX}internal-packages/**'`);
250260
});
251261

252262
// Naming this package here as well ran the suite twice on every pull request touching it. Asserted
253263
// rather than left to the next reader, because the duplicate looks like the right entry to add back.
254264
it("leaves the package's own paths to the internal filter, so the suite runs once", () => {
255265
const text = read(PR_CHECKS);
256266
const obsmap = text.split(" obsmap:")[1]!.split(" cli:")[0]!;
257-
expect(obsmap).not.toContain("'internal-packages/observability-map/**'");
267+
expect(obsmap).not.toContain(`'${PATH_PREFIX}internal-packages/observability-map/**'`);
258268

259-
const internal = text.split(" internal:")[1]!.split(" # ")[0]!;
260-
expect(internal).toContain("'internal-packages/**'");
261-
expect(internal).not.toContain("!internal-packages/observability-map");
262-
expect(
263-
read(resolve(__dirname, "../../../.github/workflows/unit-tests-internal.yml"))
264-
).toContain('--filter "@internal/*"');
269+
const internal = text.split(" internal:")[1]!.split(" obsmap:")[0]!;
270+
expect(internal).toContain(`'${PATH_PREFIX}internal-packages/**'`);
271+
expect(internal).not.toContain(`!${PATH_PREFIX}internal-packages/observability-map`);
272+
expect(read(resolve(WORKFLOWS, "unit-tests-internal.yml"))).toContain('--filter "@internal/*"');
265273
});
266274

267275
// The test above only checks the package's own source path, a different overlap that was already
@@ -295,37 +303,43 @@ describe("the package's tests are wired into the gate", () => {
295303
expect(needs).toContain("- obsmap");
296304
});
297305

298-
it("does not also run the same suite in the report workflow", () => {
306+
it.skipIf(!REPORT_PRESENT)("does not also run the same suite in the report workflow", () => {
299307
expect(read(REPORT)).not.toContain("run test");
300308
});
301309

302310
// The nightly is the other half of the trade and is asserted with it: dropping the schedule would
303311
// leave tree drift uncovered rather than covered late.
304-
it("runs the corpus on the package's own paths and on a schedule, not on every route PR", () => {
305-
const text = read(REPORT);
306-
const corpus = text.split(" mutation-corpus:")[1]!.split(" steps:")[0]!;
307-
expect(corpus).toContain("needs.changes.outputs.package == 'true'");
308-
309-
// The corpus filter alone, a separate entry from the report's own gate beside it, and this one
310-
// has to stay off the route tree.
311-
const filter = text.split(" package:")[1]!.split(" routes:")[0]!;
312-
expect(filter).toContain("'internal-packages/observability-map/**'");
313-
expect(filter).not.toContain("apps/webapp/app/routes");
314-
315-
expect(text).toContain("schedule:");
316-
expect(text).toContain("cron:");
317-
});
312+
it.skipIf(!REPORT_PRESENT)(
313+
"runs the corpus on the package's own paths and on a schedule, not on every route PR",
314+
() => {
315+
const text = read(REPORT);
316+
const corpus = text.split(" mutation-corpus:")[1]!.split(" steps:")[0]!;
317+
expect(corpus).toContain("needs.changes.outputs.package == 'true'");
318+
319+
// The corpus filter alone, a separate entry from the report's own gate beside it, and this one
320+
// has to stay off the route tree.
321+
const filter = text.split(" package:")[1]!.split(" routes:")[0]!;
322+
expect(filter).toContain(`'${PATH_PREFIX}internal-packages/observability-map/**'`);
323+
expect(filter).not.toContain("apps/webapp/app/routes");
324+
325+
expect(text).toContain("schedule:");
326+
expect(text).toContain("cron:");
327+
}
328+
);
318329

319330
// Two reviewers read the README's old "merge base" wording against the workflow's base.sha and
320331
// reported the workflow; the wording was the bug. Pinned so it cannot drift back without the
321332
// workflow moving with it.
322-
it("describes the base the report workflow actually scans against", () => {
323-
expect(read(REPORT)).toContain("github.event.pull_request.base.sha");
324-
const readme = readFileSync(resolve(__dirname, "../README.md"), "utf8");
325-
const ci = readme.split("## CI")[1]!.split("\n## ")[0]!;
326-
expect(ci).toContain("against the tip of the base branch");
327-
expect(ci).not.toMatch(/scanning head\s+against the PR's merge base/);
328-
});
333+
it.skipIf(!REPORT_PRESENT)(
334+
"describes the base the report workflow actually scans against",
335+
() => {
336+
expect(read(REPORT)).toContain("github.event.pull_request.base.sha");
337+
const readme = readFileSync(resolve(__dirname, "../README.md"), "utf8");
338+
const ci = readme.split("## CI")[1]!.split("\n## ")[0]!;
339+
expect(ci).toContain("against the tip of the base branch");
340+
expect(ci).not.toMatch(/scanning head\s+against the PR's merge base/);
341+
}
342+
);
329343
});
330344

331345
/**

0 commit comments

Comments
 (0)