diff --git a/infra/package.json b/infra/package.json index 0ad762a12fc..1d1844a487e 100644 --- a/infra/package.json +++ b/infra/package.json @@ -1,10 +1,13 @@ { "name": "@cap/infra", + "type": "module", "devDependencies": { - "sst": "3.17.14" + "sst": "3.17.14", + "vitest": "~2.1.9" }, "scripts": { - "sst": "sst" + "sst": "sst", + "test": "vitest run" }, "dependencies": { "@pulumi/github": "^6.7.0", diff --git a/infra/sst.config.ts b/infra/sst.config.ts index c148670f801..3f2c044a971 100644 --- a/infra/sst.config.ts +++ b/infra/sst.config.ts @@ -1,5 +1,7 @@ /// +import { parseStageName } from "./stage"; + const GITHUB_ORG = "CapSoftware"; const _GITHUB_REPO = "Cap"; const _GITHUB_APP_ID = "1196731"; @@ -12,16 +14,7 @@ const _CLOUDFLARE_ACCOUNT_ID = "3de2dd633194481d80f68f55257bdbaa"; const AXIOM_API_TOKEN = "xaat-c0704be6-e942-4935-b068-3b491d7cc00f"; const AXIOM_DATASET = "cap-otel"; -const parsedStage = () => { - if ($app.stage === "staging") return { variant: "staging" } as const; - if ($app.stage === "production") return { variant: "production" } as const; - if ($app.stage.startsWith("git-branch-")) - return { - variant: "git-branch", - branch: $app.stage.slice("git-branch-".length), - } as const; - throw new Error("Unsupported stage"); -}; +const parsedStage = () => parseStageName($app.stage); export default $config({ app(input) { diff --git a/infra/stage.test.ts b/infra/stage.test.ts new file mode 100644 index 00000000000..ceb1e63f45d --- /dev/null +++ b/infra/stage.test.ts @@ -0,0 +1,21 @@ +import { describe, expect, it } from "vitest"; +import { parseStageName } from "./stage"; + +describe("parseStageName", () => { + it("recognizes fixed deployment stages", () => { + expect(parseStageName("staging")).toEqual({ variant: "staging" }); + expect(parseStageName("production")).toEqual({ variant: "production" }); + }); + + it("extracts branch names from git branch preview stages", () => { + expect(parseStageName("git-branch-add-infra-tests")).toEqual({ + variant: "git-branch", + branch: "add-infra-tests", + }); + }); + + it("rejects unsupported stages", () => { + expect(() => parseStageName("preview")).toThrow("Unsupported stage"); + expect(() => parseStageName("git-branch-")).toThrow("Unsupported stage"); + }); +}); diff --git a/infra/stage.ts b/infra/stage.ts new file mode 100644 index 00000000000..e0766f5fc48 --- /dev/null +++ b/infra/stage.ts @@ -0,0 +1,15 @@ +export type ParsedStage = + | { variant: "staging" } + | { variant: "production" } + | { variant: "git-branch"; branch: string }; + +export function parseStageName(stage: string): ParsedStage { + if (stage === "staging") return { variant: "staging" }; + if (stage === "production") return { variant: "production" }; + if (stage.startsWith("git-branch-")) { + const branch = stage.slice("git-branch-".length); + if (!branch) throw new Error("Unsupported stage"); + return { variant: "git-branch", branch }; + } + throw new Error("Unsupported stage"); +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2810356dc57..3991e7810d1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -918,6 +918,9 @@ importers: sst: specifier: 3.17.14 version: 3.17.14 + vitest: + specifier: ~2.1.9 + version: 2.1.9(@types/node@22.15.17)(jsdom@26.1.0)(lightningcss@1.32.0)(terser@5.44.0) packages/config: dependencies: