commit c8d18beff044d7e1a1a5e228696b00285ffa7371
parent 7491a866aff24236e4a4a3e05c6818d4745ef833
Author: I Mean I'm Just Saying <imeanimjustsaying@kiwifarms.st>
Date: Mon, 28 Sep 2026 01:38:21 -0400
ops: /api/ops/build-homepage {deploy?, preview?} and /api/ops/deploy-homepage {preview?} → previewUrl, and the pnpm ops verbs
The hub's routes' twins, adapters over homepageDeployActions: a preview
without deploy is a 400 on build-homepage; deploy-homepage's previewUrl is
previewAliasUrl(HOMEPAGE_PAGES_PROJECT, preview). archilyzer-ops.mjs lists
build-homepage and deploy-homepage and says what they do in the usage
(+1 test).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Diffstat:
4 files changed, 94 insertions(+), 0 deletions(-)
diff --git a/editor/app/api/ops/build-homepage/route.ts b/editor/app/api/ops/build-homepage/route.ts
@@ -0,0 +1,33 @@
+import { NextResponse } from "next/server";
+import {
+ buildAndDeployHomepageAction,
+ buildHomepageAction,
+} from "../../../sites/lib/homepageDeployActions";
+import { jobResponse, ops, optBool, optPreviewBranch, OpsInputError } from "../_lib";
+
+export const dynamic = "force-dynamic";
+
+// POST { deploy?: boolean, preview? } -> { ok: true, jobId }
+//
+// Builds the HOMEPAGE (the `homepage` package, Archilyzer's own site) into
+// homepage/out. `deploy: true` makes it the one-job build-then-deploy (`/sites`
+// → Homepage, "Deploy after build") to the Pages project `archilyzer`, which
+// deploys only when the build exits 0; `preview` needs `deploy`.
+export async function POST(request: Request) {
+ return ops(request, ["deploy", "preview"], async (body) => {
+ const deploy = optBool(body, "deploy") === true;
+ const preview = optPreviewBranch(body);
+ if (preview !== undefined && !deploy) {
+ throw new OpsInputError('"preview" needs "deploy": true — a build alone deploys nothing');
+ }
+ return jobResponse(
+ deploy
+ ? await buildAndDeployHomepageAction(preview ? { previewBranch: preview } : undefined)
+ : await buildHomepageAction(),
+ );
+ });
+}
+
+export function GET() {
+ return NextResponse.json({ ok: false, error: "POST only" }, { status: 405 });
+}
diff --git a/editor/app/api/ops/deploy-homepage/route.ts b/editor/app/api/ops/deploy-homepage/route.ts
@@ -0,0 +1,32 @@
+import { NextResponse } from "next/server";
+import { previewAliasUrl } from "yt-dlp-transcript-common/lib/pagesDeploy";
+import { HOMEPAGE_PAGES_PROJECT } from "yt-dlp-transcript-common/publish/build";
+import { deployHomepageAction } from "../../../sites/lib/homepageDeployActions";
+import { jobResponse, ops, optPreviewBranch } from "../_lib";
+
+export const dynamic = "force-dynamic";
+
+// POST { preview? } -> { ok: true, jobId, previewUrl? }
+//
+// DEPLOY ONLY — the homepage already built in homepage/out, to its constant
+// Pages project `archilyzer`: production (branch `main`), or with `preview` a
+// branch alias, knowable before the job runs. Refused before any job when the
+// preview name is bad or homepage/out holds no build.
+export async function POST(request: Request) {
+ return ops(request, ["preview"], async (body) => {
+ const preview = optPreviewBranch(body);
+ const res = jobResponse(
+ await deployHomepageAction(preview ? { previewBranch: preview } : undefined),
+ );
+ if (!preview || res.status !== 200) return res;
+ const payload = (await res.json()) as Record<string, unknown>;
+ return NextResponse.json({
+ ...payload,
+ previewUrl: previewAliasUrl(HOMEPAGE_PAGES_PROJECT, preview),
+ });
+ });
+}
+
+export function GET() {
+ return NextResponse.json({ ok: false, error: "POST only" }, { status: 405 });
+}
diff --git a/scripts/archilyzer-ops.mjs b/scripts/archilyzer-ops.mjs
@@ -37,6 +37,8 @@
// pnpm ops build-hub --wait
// pnpm ops build-hub --json '{"deploy":true}' --wait
// pnpm ops deploy-hub --wait
+// pnpm ops build-homepage --json '{"deploy":true}' --wait
+// pnpm ops deploy-homepage --json '{"preview":"refresh"}' --wait
// pnpm ops get channel the-quartering
// pnpm ops tags --json '{"op":"define","tag":{"id":"eva-collab","label":"Collab"}}'
// pnpm ops tag-videos --file ids.json
@@ -106,6 +108,10 @@ const ACTIONS = [
// build uses) and its deploy to homepage.json's Pages project.
"build-hub",
"deploy-hub",
+ // The HOMEPAGE (the `homepage` package, Archilyzer's own site, into
+ // homepage/out) and its deploy to the constant Pages project `archilyzer`.
+ "build-homepage",
+ "deploy-homepage",
"relocate",
"relocate-back",
"evict-clips",
@@ -309,6 +315,12 @@ export function usage() {
' after, and deploy-hub ships the one already built. Both deploy to the',
" Pages project set on /sites under Hub, and take \"preview\" too.",
"",
+ 'build-homepage builds the homepage package into homepage/out;',
+ ' {"deploy": true} deploys it after (only if the build succeeded), and',
+ " deploy-homepage ships the one already built. Both deploy to the Pages",
+ " project archilyzer (https://archilyzer.pages.dev), production unless",
+ ' "preview" is given.',
+ "",
'cut-release turns a changelog\'s [Unreleased] into "## [<version>] - <date>":',
' {"workspace": "editor" | "export" | "all",',
' "version": "X.Y.Z" | "next" | "next-minor",',
diff --git a/scripts/archilyzer-ops.test.mjs b/scripts/archilyzer-ops.test.mjs
@@ -361,3 +361,20 @@ test("build-hub and deploy-hub are POSTs to their own routes, named in the usage
assert.match(usage(), /Actions:.*build-hub, deploy-hub/);
assert.match(usage(), /build-hub builds the hub into export\/out/);
});
+
+// The homepage's pair (release 11 slice O4), the hub's twins: a POST each, the
+// body passed through untouched — the routes judge it.
+test("build-homepage and deploy-homepage are POSTs to their own routes, named in the usage", () => {
+ const build = parseArgs(["build-homepage", "--json", '{"deploy":true}', "--wait"]);
+ assert.equal(build.method, "POST");
+ assert.equal(build.path, "/api/ops/build-homepage");
+ assert.deepEqual(build.body, { deploy: true });
+ assert.equal(build.wait, true);
+ const deploy = parseArgs(["deploy-homepage", "--json", '{"preview":"refresh"}']);
+ assert.equal(deploy.method, "POST");
+ assert.equal(deploy.path, "/api/ops/deploy-homepage");
+ assert.deepEqual(deploy.body, { preview: "refresh" });
+ assert.match(usage(), /Actions:.*build-homepage, deploy-homepage/);
+ assert.match(usage(), /build-homepage builds the homepage package into homepage\/out/);
+ assert.match(usage(), /project archilyzer \(https:\/\/archilyzer\.pages\.dev\)/);
+});