Archilyzer · Source

archilyzer

Archilyzer
git clone https://archilyzer.pages.dev/source/archilyzer.git
Log | Files | Refs | README | LICENSE

commit cf20cd088e4c7bd62d98be311f96e2609857ec1d
parent 67ace2d330967dd2ec7b6ec34df37ee3a39db1a4
Author: I Mean I'm Just Saying <imeanimjustsaying@kiwifarms.st>
Date:   Fri, 25 Sep 2026 16:20:01 -0400

publish: deploy homepage [--preview <branch>] — deployHomepage takes previewBranch the way deployHub does

previewBranchProblem refuses main/production and bad names before the build
check; a preview deploys to its own branch with no --branch main and prints
the previewAliasUrl line. homepageDeployArgs is the pure argv, pinned in
build.test.ts (+2).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

Diffstat:
Mcommon/bin/archilyzer.ts | 13++++++++++---
Mcommon/publish/build.test.ts | 25+++++++++++++++++++++++++
Mcommon/publish/build.ts | 37++++++++++++++++++++++++++++++++-----
3 files changed, 67 insertions(+), 8 deletions(-)

diff --git a/common/bin/archilyzer.ts b/common/bin/archilyzer.ts @@ -158,10 +158,17 @@ export const COMMANDS: Command[] = [ }, { path: ["deploy", "homepage"], - usage: "ship homepage/out to the Pages project archilyzer (production branch main)", - run: async () => { + usage: + "[--preview <branch>] ship homepage/out to the Pages project archilyzer (production branch main)", + flags: { preview: "string" }, + run: async ({ flags }) => { const { deployHomepage } = await import("../publish/build"); - return refusalsExit(() => deployHomepage({ signal: interrupted() })); + return refusalsExit(() => + deployHomepage({ + signal: interrupted(), + previewBranch: typeof flags.preview === "string" ? flags.preview : undefined, + }), + ); }, }, { diff --git a/common/publish/build.test.ts b/common/publish/build.test.ts @@ -6,6 +6,8 @@ import { buildHubSteps, buildSiteSteps, hubProjectProblem, + homepageDeployArgs, + deployHomepage, dockerSiteOutDir, dockerSiteStagingDir, resolveOutDir, @@ -126,3 +128,26 @@ test("hubProjectProblem refuses a missing project and the homepage's", () => { assert.match(hubProjectProblem("archilyzer")!, /homepage's — set the hub's own project/); assert.equal(hubProjectProblem("archilyzer-hub"), null); }); + +test("homepageDeployArgs: production is branch main; a preview is its own branch and never main", () => { + const base = ["wrangler", "pages", "deploy", "/repo/homepage/out", "--project-name", "archilyzer"]; + assert.deepEqual(homepageDeployArgs("/repo/homepage/out"), [...base, "--branch", "main"]); + assert.deepEqual(homepageDeployArgs("/repo/homepage/out", " "), [...base, "--branch", "main"]); + assert.deepEqual(homepageDeployArgs("/repo/homepage/out", " r8-home "), [...base, "--branch", "r8-home"]); +}); + +test("deployHomepage refuses a bad preview branch before it looks for a build", async () => { + const noBuild = { monorepoRoot: "/nonexistent-repo" } as Paths; + await assert.rejects( + deployHomepage({ paths: noBuild, previewBranch: "main" }), + /"main" is the production branch/, + ); + await assert.rejects( + deployHomepage({ paths: noBuild, previewBranch: "Not_Valid" }), + /not a valid preview branch name/, + ); + await assert.rejects( + deployHomepage({ paths: noBuild, previewBranch: "r8-home" }), + /homepage\/out holds no build/, + ); +}); diff --git a/common/publish/build.ts b/common/publish/build.ts @@ -974,21 +974,48 @@ export async function buildHomepage(opts: PublishOpts = {}): Promise<number> { } /** - * Deploy homepage/out to the homepage's constant project, to its production - * branch `main` — exactly what homepage/package.json's hardcoded `deploy` line - * ran. THROWS on failure or when there is no build. + * The wrangler argv (after `pnpm dlx`) for a homepage deploy of `outDir`: the + * production branch `main` — what homepage/package.json's hardcoded `deploy` + * line ran — or, with `previewBranch`, that preview branch and no `main`. + * Pure, so the test pins exactly what deployHomepage runs. */ -export async function deployHomepage(opts: PublishOpts = {}): Promise<void> { +export function homepageDeployArgs(outDir: string, previewBranch?: string): string[] { + const branch = previewBranch?.trim() || undefined; + return [ + ...pagesDeployArgs({ outDir, project: HOMEPAGE_PAGES_PROJECT, previewBranch: branch }), + ...homepageProductionArgs(branch), + ]; +} + +function homepageProductionArgs(previewBranch: string | undefined): string[] { + return previewBranch ? [] : ["--branch", "main"]; +} + +/** + * Deploy homepage/out to the homepage's constant project: production (branch + * `main`), or a PREVIEW with `previewBranch` — the same refusals and alias line + * as deployHub. THROWS on failure or when there is no build. + */ +export async function deployHomepage( + opts: PublishOpts & { previewBranch?: string } = {}, +): Promise<void> { const { paths, onLog, signal } = resolved(opts); + if (opts.previewBranch !== undefined) { + const problem = previewBranchProblem(opts.previewBranch); + if (problem) throw new Error(problem); + } + const branch = opts.previewBranch?.trim() || undefined; const outDir = path.join(homepageDir(paths), "out"); if (!existsSync(path.join(outDir, "index.html"))) { throw new Error("homepage/out holds no build — run archilyzer build homepage first"); } + if (branch) onLog(`=== Deploy homepage (preview "${branch}") ===\n`); const code = await runPagesDeployIntoLog(onLog, signal, { outDir, project: HOMEPAGE_PAGES_PROJECT, cwd: homepageDir(paths), - extraArgs: ["--branch", "main"], + previewBranch: branch, + extraArgs: homepageProductionArgs(branch), }); if (signal.aborted) return; if (code !== 0) throw new Error(`Homepage deploy failed (exit ${code}).`);