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

Archive, part 3b: Wake restarts an archived app's production from the default branch on the same data #2477

Merged opened this

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

Merged

scout/forge:scout/2457-archive-part-3b-wake-restarts-an-archive → main 1 commit fork 1 thread · 1 unresolved

  • Merged. scout/2457-archive-part-3b-wake-restarts-an-archive was merged into main as 16f8bfd.

Review

Sign in to review this change.
2 files changed +26 −2
src/actions/repos.ts +9
@@ -8,6 +8,7 @@ import { requireVerified } from "./verify.ts";
88 import { requireAbility } from "./roles.ts";
99 import type { App } from "../app.ts";
1010 import { appsRuntime } from "../apps/runtime.ts";
11 import { getAppByRepo } from "../core/apps.ts";
1112 import { canSeeSealed } from "../core/sealed.ts";
1213 import { capacityValue } from "../core/capacity.ts";
1314 import { NEW_FOR_MS } from "./accounts.ts";
@@ -317,6 +318,14 @@ export async function updateRepoSettings(
317318 const runtime = appsRuntime(app);
318319 if (runtime !== undefined) await runtime.stopRepo(repo.id);
319320 }
321 // Waking brings production back from the default branch on the same data
322 // directory; a preview returns on its pull's next push.
323 if (updated.archivedAt === null && repo.archivedAt !== null) {
324 const runtime = appsRuntime(app);

Fine as written. Wake goes through the same admin and agent gate as Archive. Consider asserting in a test that an agent cannot wake, since that path is now live.

325 const record = getAppByRepo(app.db, repo.id);
326 if (runtime !== undefined && record !== undefined)
327 await runtime.reconcileApp(record, updated, "wake", "production");
328 }
320329 const changed: string[] = (
321330 [
322331 "visibility",
test/apps.test.ts +17 −2
@@ -11,7 +11,7 @@
1111 */
1212
1313 import { afterAll, beforeAll, describe, expect, test } from "bun:test";
14 import { existsSync, writeFileSync } from "node:fs";
14 import { existsSync, readFileSync, writeFileSync } from "node:fs";
1515 import { mkdtemp, rm } from "node:fs/promises";
1616 import { tmpdir } from "node:os";
1717 import { join } from "node:path";
@@ -460,7 +460,22 @@ describe("apps: production, previews, data, gates", () => {
460460 // A visit does not wake it.
461461 expect((await viaHost(`hello.${DOMAIN}`)).status).toBe(503);
462462 expect(runtime.envStatus(record, "production")?.state).not.toBe("running");
463 }, 60_000);
463
464 // Waking restarts production on the same data directory.
465 const woke = await updateRepoSettings(app, alice, repo, {
466 archived: false,
467 });
468 expect(woke.ok).toBe(true);
469 for (
470 let i = 0;
471 i < 600 && runtime.envStatus(record, "production")?.state !== "running";
472 i++
473 )
474 await Bun.sleep(100);
475 expect(runtime.envStatus(record, "production")?.state).toBe("running");
476 expect(readFileSync(join(data, "archive-marker"), "utf8")).toBe("kept");
477 expect((await viaHost(`hello.${DOMAIN}`)).status).toBe(200);
478 }, 120_000);
464479 });
465480
466481 describe("a preview whose copied data the build cannot read starts fresh (issue #36)", () => {

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs