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

A pure module picks the pill's other side: production for a preview, the newest open preview for production #6082

Merged opened this

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

Merged

scout/forge:scout/6075-a-pure-module-picks-the-pill-s-other-sid → main 1 commit fork 1 thread · 1 unresolved

  • Merged. scout/6075-a-pure-module-picks-the-pill-s-other-sid was merged into main as a267180.

Review

Sign in to review this change.
2 files changed +65 −0
src/apps/side.ts added +33
@@ -0,0 +1,33 @@
1 /**
2 * The pill's other side: from a preview, production; from production, the
3 * newest preview worth opening. Plain data in, plain data out. Every address
4 * is the one the forge recorded for the app, never read from a request.
5 */
6
7 export interface SideApp {
8 /** The forge's record of production's address. */
9 readonly url: string;
10 }
11
12 export interface SidePreview {
13 readonly number: number;
14 readonly title: string;
15 readonly state: string;
16 /** The forge's record of this preview's address. */
17 readonly url: string;
18 }
19
20 export interface Side {
21 readonly label: string;
22 readonly url: string;
23 }
24
25 /** A preview someone can open: up now, or waking on request. */
26 const OPENABLE = new Set(["running", "asleep"]);
27
28 export function sideOf(app: SideApp, environment: string, previews: readonly SidePreview[]): Side | null {
29 if (environment !== "production") return { label: "Open on production", url: app.url };
30 let newest: SidePreview | undefined;
31 for (const p of previews) if (OPENABLE.has(p.state) && (newest === undefined || p.number > newest.number)) newest = p;
32 return newest === undefined ? null : { label: `Newest preview: #${newest.number} ${newest.title}`, url: newest.url };

The label interpolates the pull title unescaped and uncapped. That is fine for a pure module, but the caller must escape it and truncate it. Consider returning the title and number separately so the renderer owns the wording.

33 }
test/apps-side.test.ts added +32
@@ -0,0 +1,32 @@
1 import { expect, test } from "bun:test";
2 import { sideOf, type SidePreview } from "../src/apps/side.ts";
3
4 const app = { url: "https://lab--forge.example" };
5 const p = (number: number, state: string, title = `t${number}`): SidePreview => ({
6 number,
7 title,
8 state,
9 url: `https://lab--${number}--forge.example`,
10 });
11
12 test("a preview points at production's recorded address", () => {
13 expect(sideOf(app, "pull-7", [p(7, "running")])).toEqual({ label: "Open on production", url: app.url });
14 });
15
16 test("production points at the highest running or asleep preview", () => {
17 expect(sideOf(app, "production", [p(3, "running"), p(9, "asleep", "Nine"), p(5, "running")])).toEqual({
18 label: "Newest preview: #9 Nine",
19 url: "https://lab--9--forge.example",
20 });
21 });
22
23 test("production with no previews has no other side", () => {
24 expect(sideOf(app, "production", [])).toBeNull();
25 });
26
27 test("stopped, failed and deploying previews are skipped", () => {
28 expect(sideOf(app, "production", [p(4, "running"), p(8, "stopped"), p(9, "failed"), p(10, "deploying")])?.url).toBe(
29 "https://lab--4--forge.example",
30 );
31 expect(sideOf(app, "production", [p(8, "stopped")])).toBeNull();
32 });

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs