Skip to content

build(forgebox): rebuild base template from LuCLI template so box install boots clean#3196

Merged
bpamiri merged 2 commits into
developfrom
peter/forgebox-template-from-lucli-source
Jun 13, 2026
Merged

build(forgebox): rebuild base template from LuCLI template so box install boots clean#3196
bpamiri merged 2 commits into
developfrom
peter/forgebox-template-from-lucli-source

Conversation

@bpamiri

@bpamiri bpamiri commented Jun 13, 2026

Copy link
Copy Markdown
Collaborator

Summary

KEYSTONE of the ForgeBox/CommandBox path-repair campaign. The published wheels-base-template ForgeBox package was broken end to end: a raw box install produced an app that box server start could not boot, and the artifact had drifted from what wheels new produces.

Per the locked maintainer decision (Peter, 2026-06-12), the base template is now regenerated from cli/lucli/templates/app/ — the single source of truth (the canonical wheels new output) — instead of the repo-root demo app. CommandBox-only build artifacts (server.json, box.json, README.md, the base .gitignore, .mcp.json, .opencode.json) are layered on top; these are the CommandBox equivalents of the LuCLI lucee.json / rewrite.config / _env that wheels new users get.

What changed

  • tools/build/scripts/prepare-base.sh — sources app/config/db/public/tests/vendor from the LuCLI template (auto-drops repo-only demo cruft); substitutes the {{appName}}/{{datasourceName}}/{{reloadPassword}}/{{luceeAdminPassword}} and legacy |appName|/|cfmlEngine|/… placeholders to working defaults at BUILD time (scoped to config/server/env/layout — app/snippets/*.txt code-gen templates ship verbatim); translates _envenv.example; generates the default Main.cfc + app/views/main/index.cfm exactly as wheels new does post-copy.
  • tools/build/base/.gitignore — no longer excludes /db/**; only generated *.sqlite/*.db are ignored so db/ (with db/.keep) ships.
  • tools/build/base/server.json — hardcoded sane defaults (name=Wheels, cfengine=lucee); substitution is now a belt-and-suspenders safety net.
  • tools/build/base/box.json — fixed format script paths for the 4.0 app/ layout, simplified postInstall, de-duped keywords.
  • tools/build/base/README.md — corrected dependency from ^3.1.0 to 4.0.3; documents the box-install path + CLI-first recommendation.
  • Removed tools/build/base/config/{app.cfm,settings.cfm} — these now come from the LuCLI template (so set(useUnderscoreReferenceColumns=true), the env("WHEELS_RELOAD_PASSWORD","") reload pattern, and current guides.wheels.dev doc links all flow from the single source).

Defects fixed

Verification (CommandBox docker, CommandBox 6.3.3 / Lucee 7.0.4.34)

Before (current prepare-base.sh output): placeholders present, box server start → "Invalid slug detected" on |cfmlEngine|; db/ stripped on publish; demo cruft + 5 /cli mappings; no useUnderscoreReferenceColumns; 3.1.0 links.

After (clean pipeline, zero manual edits):

  • box install exit 0 → wheels-core auto-pulled to vendor/wheels/
  • box server start boots Lucee 7.0.4.34, profile Wheels, webroot public
  • GET /200 "Welcome to Wheels" page
  • /wheels/info200, /wheels/routes200 (dev)
  • Clean URLs: dropped a Widgets controller → /widgets and /widgets/index route to the app layout; /nonexistentcontroller → 404 (proves routing is real)
  • db/ present (.keep + .gitignore)
  • tools/ci/smoke-env.sh reload-gate probes PASS (reload-unauthenticated-refused and reload-wrong-password-refused both refused, not 302). The wheels-info-clean-404 and root-no-trace-markers probes note dev-expected behavior (info page + debugbar render only in development).

No cli/ paths modified (the LuCLI template was read-only as the source of truth).

Fixes #3176, #3173, #3174

🤖 Generated with Claude Code

…tall boots clean

The published wheels-base-template ForgeBox package was broken end to end: a
raw `box install` produced an app that `box server start` could not boot, and
the artifact diverged from what `wheels new` produces.

Source the app/config/db/public/tests/vendor scaffold from the single source of
truth (cli/lucli/templates/app/) instead of the repo-root demo app, then layer
the CommandBox-only build artifacts (server.json, box.json, README.md, base
.gitignore, .mcp.json, .opencode.json) on top.

Fixes:
- #3173: substitute placeholders at BUILD TIME to working defaults
  (appName=Wheels, cfengine=lucee, datasourceName=wheels, reloadPassword empty).
  `box install` has no substitution step, so the |cfmlEngine| token previously
  killed `box server start` with "Invalid slug detected". The published artifact
  now carries zero |tokens| / {{tokens}}.
- #3174: the base .gitignore no longer excludes /db/** — db/ (with db/.keep)
  ships so JDBC drivers have a parent dir. Only generated *.sqlite/*.db files
  are ignored.
- #3176: sourcing from the LuCLI template auto-drops repo-only demo cruft
  (app/jobs/ProcessOrdersJob.cfc, public/ApplicationProxy.cfc, public/index.bxm,
  the dev /cli + /modules mappings in public/Application.cfc). The template's
  settings.cfm carries set(useUnderscoreReferenceColumns=true) and the current
  guides.wheels.dev links; README dependency corrected to wheels-core 4.0.3.

Generate the default Main controller + app/views/main/index.cfm in the build
exactly as `wheels new` does post-copy — without them the root route
(main##index) throws Wheels.ViewNotFound on GET /.

Verified end to end in CommandBox docker (CommandBox 6.3.3 / Lucee 7.0.4):
clean `box install` auto-pulls wheels-core to vendor/wheels, `box server start`
boots with zero manual edits, GET / -> 200 welcome page, /wheels/info and
/wheels/routes -> 200 in dev, clean URLs route (dropped Widgets controller
resolves; unknown route -> 404), db/ ships. tools/ci/smoke-env.sh reload-gate
probes pass (reload-unauthenticated and reload-wrong-password both refused);
the info-404 and trace-marker probes note dev-expected behavior (info page +
debugbar render only in development).

Fixes #3176, #3173, #3174

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Peter Amiri <peter@alurium.com>
@bpamiri bpamiri enabled auto-merge (squash) June 13, 2026 03:32
@github-actions github-actions Bot added docs dependencies Pull requests that update a dependency file labels Jun 13, 2026
…-base guard

The ForgeBox base-template rebuild (#3196) made prepare-base.sh
CWD-independent: it derives REPO_ROOT from BASH_SOURCE and reads every
source file by absolute path, including `cp "${REPO_ROOT}/LICENSE"
"${BUILD_DIR}/"`. The three sibling prepare scripts (core/cli/starterApp)
run from the repo root and keep the bare `cp LICENSE "${BUILD_DIR}/"`
form. buildArtifactLicenseSpec only matched the bare form, so the keystone
rebuild failed two assertions even though LICENSE/NOTICE still land in
BUILD_DIR.

Broaden both the LICENSE and NOTICE regexes to accept an optional
`"${REPO_ROOT}/` prefix while staying tight enough that deleting a copy
line still fails the guard (verified red->green: original spec 6 pass /
2 fail, fixed spec 8 pass / 0 fail). prepare-base.sh is left on the robust
absolute-path form on purpose — running it from an unrelated CWD still
produces a complete build (LICENSE, NOTICE, db/, no residual placeholders),
which a bare `cp LICENSE` would break.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Peter Amiri <petera@pai.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file docs enhancement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Align the ForgeBox wheels-base-template with the LuCLI wheels new template (single source of truth)

1 participant