Skip to content

Commit 2ba31df

Browse files
committed
fix(showcase): make railway-graphql .com scan guard fail-loud + harden endpoint constant
1 parent 8c603fb commit 2ba31df

2 files changed

Lines changed: 50 additions & 16 deletions

File tree

showcase/scripts/lib/__tests__/railway-graphql.scan.test.ts

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { describe, expect, it } from "vitest";
2-
import { execSync } from "node:child_process";
2+
import { execFileSync } from "node:child_process";
33
import path from "node:path";
44

55
const REPO_ROOT = path.resolve(__dirname, "../../../..");
@@ -8,20 +8,45 @@ describe("Railway GraphQL host unification", () => {
88
it("no source file references backboard.railway.com (must be .app)", () => {
99
// grep across showcase/ and .github/workflows/. Use -F (literal) so
1010
// the dot in the pattern is not regex-interpreted. The test file
11-
// itself contains the forbidden literal; exclude it via --glob.
12-
// Also exclude two files that legitimately reference the deprecated
13-
// host in documentation/negative-assertion form (no functional use):
11+
// itself contains the forbidden literal; exclude it via git pathspec
12+
// `:(exclude)` magic. Also exclude two files that legitimately
13+
// reference the deprecated host in documentation/negative-assertion
14+
// form (no functional use):
1415
// - railway-graphql.ts JSDoc explains the deprecated .com endpoint
1516
// - railway-graphql.test.ts asserts the endpoint is NOT .com
17+
// Use --untracked so a newly-added (not-yet-committed) file that
18+
// reintroduces the forbidden host still trips the guard. Use
19+
// execFileSync with an args array so REPO_ROOT is not shell-parsed.
1620
let out = "";
1721
try {
18-
out = execSync(
19-
`git -C ${REPO_ROOT} grep -nF "backboard.railway.com" -- showcase ':(exclude)showcase/scripts/lib/__tests__/railway-graphql.scan.test.ts' ':(exclude)showcase/scripts/lib/railway-graphql.ts' ':(exclude)showcase/scripts/lib/__tests__/railway-graphql.test.ts' .github/workflows`,
22+
out = execFileSync(
23+
"git",
24+
[
25+
"-C",
26+
REPO_ROOT,
27+
"grep",
28+
"--untracked",
29+
"-nF",
30+
"backboard.railway.com",
31+
"--",
32+
"showcase",
33+
":(exclude)showcase/scripts/lib/__tests__/railway-graphql.scan.test.ts",
34+
":(exclude)showcase/scripts/lib/railway-graphql.ts",
35+
":(exclude)showcase/scripts/lib/__tests__/railway-graphql.test.ts",
36+
".github/workflows",
37+
],
2038
{ encoding: "utf-8" },
2139
);
22-
} catch {
23-
// git grep exits 1 when no matches — that's the success case.
24-
out = "";
40+
} catch (err) {
41+
// git grep exits 1 when no matches — that's the clean-miss success
42+
// case. Any other exit status (git missing, bad cwd, pathspec
43+
// syntax error, etc.) must fail loud rather than silently pass.
44+
const status = (err as { status?: number }).status;
45+
if (status === 1) {
46+
out = "";
47+
} else {
48+
throw err;
49+
}
2550
}
2651
expect(out).toBe("");
2752
});
Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,20 @@
11
/**
22
* railway-graphql.ts — Single source of truth for the Railway GraphQL
3-
* endpoint host. ALL Railway GraphQL callers in this repo (TypeScript
4-
* scripts, workflow inline curls, and Ruby `bin/railway` via its own
5-
* constant) MUST resolve to this exact URL. The historic `.com` host
6-
* (`backboard.railway.com`) is unauthenticated for the public GraphQL
7-
* API and silently returns 401/403 — fixing here in one place prevents
8-
* it from coming back.
3+
* endpoint host for TypeScript importers in this repo. The historic
4+
* `.com` host (`backboard.railway.com`) is unauthenticated for the
5+
* public GraphQL API and silently returns 401/403; the canonical host
6+
* is `backboard.railway.app`.
7+
*
8+
* Note: the Ruby `bin/railway` script and the inline `curl` commands
9+
* embedded in `.github/workflows/*.yml` hold their OWN copies of this
10+
* URL because they cannot import a TypeScript module. Those copies are
11+
* kept in sync by hand and enforced by the regression guard in
12+
* `./__tests__/railway-graphql.scan.test.ts`, which fails the build if
13+
* any source file under `showcase/` or `.github/workflows/` reintroduces
14+
* the `.com` host.
915
*/
1016
export const RAILWAY_GRAPHQL_ENDPOINT =
11-
"https://backboard.railway.app/graphql/v2";
17+
"https://backboard.railway.app/graphql/v2" as const;
18+
19+
// Fail-fast at module load if a hand-edit ever breaks the URL literal.
20+
new URL(RAILWAY_GRAPHQL_ENDPOINT);

0 commit comments

Comments
 (0)