From 0e5e19551943fbc3d67dddc168edf028e58f53ed Mon Sep 17 00:00:00 2001 From: Rafa Martins <146174365+rafacpti23@users.noreply.github.com> Date: Tue, 1 Sep 2026 00:48:57 -0300 Subject: [PATCH] build: add contributor fast profile (#12192) --- CONTRIBUTING.md | 8 ++++++++ package.json | 1 + scripts/build/backendOnlyPages.mjs | 8 ++++++-- tests/unit/build/backend-only-smoke-workflows.test.ts | 9 +++++++++ 4 files changed, 24 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e3d3d47ea0..40f7cb39ec 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -73,6 +73,9 @@ npm run dev npm run build # next build → .build/next/ then assembleStandalone → dist/ npm run start +# Fast backend/API-only build for contributor changes +npm run build:contributor + # Release build (clean rebuild + HEAD sentinel — required for deploy) npm run build:release # rm -rf .build dist && build + writes dist/BUILD_SHA @@ -100,6 +103,11 @@ npm run build `npm run build:release` additionally cleans both directories first and writes `dist/BUILD_SHA` (= `git rev-parse --short HEAD`) as a deploy integrity sentinel. +`npm run build:contributor` uses the backend-only build profile. It temporarily stubs +dashboard UI files while building, keeps API route handlers, and restores the original files +after the build. Use `npm run build` for changes that affect the dashboard UI or for full +release validation; the contributor profile is not a replacement for the release build. + > **VPS deploy note:** the remote image directory `/usr/lib/node_modules/omniroute/app/` > is unchanged. The deploy skills rsync the contents of `dist/` into it. > Only the in-repo build output path moved (`app/` → `dist/`). diff --git a/package.json b/package.json index dd8d5e61c6..c10860b4c8 100644 --- a/package.json +++ b/package.json @@ -102,6 +102,7 @@ "build": "node scripts/build/build-next-isolated.mjs", "build:secure": "OMNIROUTE_BUILD_PROFILE=minimal node scripts/build/build-next-isolated.mjs", "build:backend": "cross-env OMNIROUTE_BUILD_BACKEND_ONLY=1 node scripts/build/build-next-isolated.mjs", + "build:contributor": "cross-env OMNIROUTE_BUILD_PROFILE=contributor node scripts/build/build-next-isolated.mjs", "build:cli": "node --import tsx scripts/build/prepublish.ts", "omniroute:verify": "node scripts/check/omniroute-verify.mjs", "build:release": "rm -rf .build dist && OMNIROUTE_BUILD_SHA=$(git rev-parse --short HEAD) npm run build && npm run build:cli && node scripts/build/write-build-sha.mjs", diff --git a/scripts/build/backendOnlyPages.mjs b/scripts/build/backendOnlyPages.mjs index 9719e8918e..a06dcefcda 100644 --- a/scripts/build/backendOnlyPages.mjs +++ b/scripts/build/backendOnlyPages.mjs @@ -2,7 +2,7 @@ /** * Backend-only build helper. * - * When `OMNIROUTE_BUILD_BACKEND_ONLY=1` (or `OMNIROUTE_BUILD_PROFILE=backend`) is set, + * When `OMNIROUTE_BUILD_BACKEND_ONLY=1` (or `OMNIROUTE_BUILD_PROFILE=backend|contributor`) is set, * `build-next-isolated.mjs` calls `stubDashboardPages()` BEFORE `next build` and * `restoreDashboardPages()` in a `finally` afterward. * @@ -83,7 +83,11 @@ function stripLeadingUseServer(src) { /** True when the current build should skip the dashboard frontend. */ export function isBackendOnlyBuild(env = process.env) { - return env.OMNIROUTE_BUILD_BACKEND_ONLY === "1" || env.OMNIROUTE_BUILD_PROFILE === "backend"; + return ( + env.OMNIROUTE_BUILD_BACKEND_ONLY === "1" || + env.OMNIROUTE_BUILD_PROFILE === "backend" || + env.OMNIROUTE_BUILD_PROFILE === "contributor" + ); } function walkFiles(dir, out = []) { diff --git a/tests/unit/build/backend-only-smoke-workflows.test.ts b/tests/unit/build/backend-only-smoke-workflows.test.ts index c7975c17b6..d6de517357 100644 --- a/tests/unit/build/backend-only-smoke-workflows.test.ts +++ b/tests/unit/build/backend-only-smoke-workflows.test.ts @@ -12,6 +12,7 @@ import assert from "node:assert/strict"; import fs from "node:fs"; import path from "node:path"; import * as yaml from "js-yaml"; +import { isBackendOnlyBuild } from "../../../scripts/build/backendOnlyPages.mjs"; interface WorkflowStep { name?: string; @@ -42,6 +43,14 @@ function isBackendOnly(step: WorkflowStep): boolean { return env.OMNIROUTE_BUILD_BACKEND_ONLY === "1" || env.OMNIROUTE_BUILD_PROFILE === "backend"; } +test("contributor build profile enables backend-only mode", () => { + assert.equal(isBackendOnlyBuild({ OMNIROUTE_BUILD_PROFILE: "contributor" }), true); +}); + +test("full build remains the default when no backend-only profile is set", () => { + assert.equal(isBackendOnlyBuild({}), false); +}); + // jobName: null selector means "any job" — used when a file has exactly one // "Build CLI bundle" step but we don't want to hardcode/duplicate the job key. interface Target {