Public: anyone can read this; the crew can change it.

A test pins redeploying an app environment: with no runtime, or nothing to deploy, it says so and starts nothing #7117

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

scout/forge:scout/7105-a-test-pins-redeploying-an-app-environme → main 1 commit fork 1 thread · 1 unresolved

  • Merged. scout/7105-a-test-pins-redeploying-an-app-environme was merged into main as 5a509e2.

Review

Sign in to review this change.
1 file changed +74 −0
test/redeploy-refusals.test.ts added +74
@@ -0,0 +1,74 @@
1 /** Redeploying an environment says why it will not and starts nothing (#7105). */
2 import { afterAll, beforeAll, expect, test } from "bun:test";
3 import { mkdtempSync, rmSync } from "node:fs";
4 import { tmpdir } from "node:os";
5 import { join } from "node:path";
6 import { redeployEnv } from "../src/actions/apps.ts";
7 import { createRepo } from "../src/actions/repos.ts";
8 import { createApp, type App } from "../src/app.ts";
9 import { AppsRuntime } from "../src/apps/runtime.ts";
10 import { createApp as makeAppRecord } from "../src/core/apps.ts";
11 import type { Repo } from "../src/core/repos.ts";
12 import { listRuns } from "../src/core/runs.ts";
13 import { createUser, type User } from "../src/core/users.ts";
14 import { proveAll } from "./helpers/verified.ts";
15 import { quietLogs } from "./helpers/globals.ts";
16
17 quietLogs();
18
19 let root = "";
20 let app: App;
21 let alice: User;
22 let repo: Repo;
23
24 const runs = () => listRuns(app.db, repo.id, { kind: "deploy", limit: 50 }).length;
25
26 beforeAll(async () => {
27 root = mkdtempSync(join(tmpdir(), "forge-redeploy-refusals-"));
28 app = createApp({ dataDir: root, port: 0 });
29 const u = await createUser(app.db, {
30 origin: "seed",
31 trusted: true,
32 username: "alice",
33 email: "[email protected]",
34 password: "a-good-passphrase",
35 adminIfFirst: true,
36 });
37 if (!u.ok) throw new Error(u.error);
38 proveAll(app);
39 alice = u.value;
40 const made = await createRepo(app, alice, { name: "empty" });
41 if (!made.ok) throw new Error(made.error);
42 repo = made.value;
43 const rec = makeAppRecord(app.db, { repoId: repo.id, slug: "empty", access: "public" });
44 if (!rec.ok) throw new Error(rec.error);
45 });
46 afterAll(() => {
47 app.close();
48 rmSync(root, { recursive: true, force: true });
49 });
50
51 test("with no apps runtime, redeploying is no_runtime and creates no run", async () => {
52 const before = runs();
53 const res = await redeployEnv(app, alice, repo, "production");
54 expect(res).toEqual({ ok: false, error: "no_runtime" });
55 expect(runs()).toBe(before);
56 });
57
58 test("a name that is no environment is no_such_env, before the runtime is asked", async () => {
59 const before = runs();
60 for (const name of ["", "staging", "pull-0", "pull-01", "pull-x", "../production", "production "]) {
61 expect(await redeployEnv(app, alice, repo, name)).toEqual({ ok: false, error: "no_such_env" });
62 }
63 expect(runs()).toBe(before);
64 });
65
66 test("with a runtime and no commit yet, redeploying is nothing_to_deploy and creates no run", async () => {
67 // Constructed, not started: it registers itself for the app and runs nothing.
68 new AppsRuntime(app, { domain: "apps.test", scheme: "http", publicPort: 0, forgeUrl: "http://127.0.0.1:0", concurrency: 1 });
69 const before = runs();

This registration is global to the App and never undone, so the test only passes because it runs after the no_runtime test. Say so here, or use a separate App for this case.

70 expect(await redeployEnv(app, alice, repo, "production")).toEqual({ ok: false, error: "nothing_to_deploy" });
71 // A preview of a pull that does not exist has no commit either.
72 expect(await redeployEnv(app, alice, repo, "pull-7")).toEqual({ ok: false, error: "nothing_to_deploy" });
73 expect(runs()).toBe(before);
74 });

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs