g1t/services/deployments/src/moves.test.ts

79 lines3,274 bytesCodeBlame

Pick any line to see why it is the way it is: the commit, the pull request and issue it came from, and what the agent was thinking.

status.g1t.sh with incident management, invites that land you in the workspace, settings as pages, usage without quotas1import assert from "node:assert/strict";
2import { test } from "node:test";
3
4import { moveTargets, ownerOf, rebuildOutcome, retryDue, type MovedApp } from "./moves.ts";
5
6const app = (over: Partial<MovedApp>): MovedApp => ({
7 script: "lab-api-syntaqx",
8 project_id: "prj_api",
9 kind: "production",
10 branch: null,
11 number: null,
12 commit_sha: "aaa",
13 deployed_at: "2026-10-05T00:26:29Z",
14 ...over,
15});
16
17test("each stale app is one target, paused or not, with the names it replaces", () => {
18 const targets = moveTargets([
19 app({}),
20 app({ script: "lab-api-git-v2-syntaqx", kind: "preview", branch: "v2", number: 1, commit_sha: "bbb" }),
21 app({ script: "automation-lab-syntaqx", project_id: "prj_lab", commit_sha: "ccc" }),
22 ]);
23 assert.deepEqual(
24 targets.map((t) => [t.projectId, t.kind, t.branch, t.number, t.commit, t.from]),
25 [
26 ["prj_api", "production", null, null, "aaa", ["lab-api-syntaqx"]],
27 ["prj_api", "preview", "v2", 1, "bbb", ["lab-api-git-v2-syntaqx"]],
28 ["prj_lab", "production", null, null, "ccc", ["automation-lab-syntaqx"]],
29 ],
30 );
31});
32
33test("an app under two old names (moved twice) is built once, replacing both", () => {
34 const targets = moveTargets([
35 app({ script: "lab-api-acme", deployed_at: "2026-10-01T00:00:00Z", commit_sha: "old" }),
36 app({ script: "lab-api-syntaqx", deployed_at: "2026-10-05T00:00:00Z", commit_sha: "new" }),
37 ]);
38 assert.equal(targets.length, 1);
39 assert.equal(targets[0].commit, "new");
40 assert.deepEqual(targets[0].from.sort(), ["lab-api-acme", "lab-api-syntaqx"]);
41});
42
43test("a build a move dropped is built again, at its newer commit", () => {
44 const targets = moveTargets(
45 [app({})],
46 [
47 { project_id: "prj_api", kind: "production", branch: null, number: null, commit_sha: "newer", created_at: "2026-10-06T01:00:00Z" },
48 { project_id: "prj_web", kind: "preview", branch: "x", number: 4, commit_sha: "w", created_at: "2026-10-06T01:00:00Z" },
49 ],
50 );
51 assert.deepEqual(
52 targets.map((t) => [t.projectId, t.commit, t.from]),
53 [
54 ["prj_api", "newer", ["lab-api-syntaqx"]],
55 ["prj_web", "w", []],
56 ],
57 );
58});
59
60test("only a queued build counts as rebuilt; refusals and errors are tried again", () => {
61 assert.equal(rebuildOutcome({ ok: true, value: { status: "queued" } }), "queued");
62 assert.equal(rebuildOutcome({ ok: true, value: { status: "skipped" } }), "failed");
63 assert.equal(rebuildOutcome({ ok: true, value: { status: "failed" } }), "failed");
64 assert.equal(rebuildOutcome({ ok: false }), "failed");
65 assert.equal(rebuildOutcome(null), "none");
66});
67
68test("a rebuild that could not start waits before it is tried again", () => {
69 const now = Date.parse("2026-10-06T02:00:00Z");
70 assert.equal(retryDue(null, now, 3600_000), true);
71 assert.equal(retryDue("2026-10-06T01:30:00Z", now, 3600_000), false);
72 assert.equal(retryDue("2026-10-06T01:00:00Z", now, 3600_000), true);
73});
74
75test("an app is its project's current workspace's, not the one its row names", () => {
76 const owners = new Map([["prj_api", "flagon-io"]]);
77 assert.equal(ownerOf({ project_id: "prj_api", workspace: "syntaqx" }, owners), "flagon-io");
78 assert.equal(ownerOf({ project_id: "prj_gone", workspace: "syntaqx" }, owners), "syntaqx");
79});