From 00faa6c2afd45a3de1484950dc626710b5a464b2 Mon Sep 17 00:00:00 2001 From: Peter Amiri Date: Sun, 5 Jul 2026 21:52:43 -0700 Subject: [PATCH 1/3] fix(cli): repoint 15 dead v4-0-0-snapshot and 3.1.0 guide URLs at live v4 pages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The pre-GA v4-0-0-snapshot docs slug was retired at GA, killing every templated guide URL still carrying it — including working-with-wheels/* paths that only ever existed in the v3 tree. Freshly scaffolded apps shipped comments and READMEs linking 404s, and two runtime CLI messages (Module.cfc install pointer, Doctor.cfc remediation) printed dead links. Repointed at live guides.wheels.dev/v4-0-0/ pages (every target curl-verified 200 before the swap): - scaffold config/settings.cfm + environment.cfm -> core-concepts/environments-and-configuration/ - scaffold config/routes.cfm + both ConfigRoutes.txt templates -> basics/routing/ - mailers/jobs/plugins template READMEs -> digging-deeper/sending-email/, background-jobs/, packages/ (also fixes the bare wheels.dev domain that should be guides.wheels.dev) - Module.cfc + Doctor.cfc runtime messages -> start-here/installing/ - cli/README.md -> command-line-tools/ - cli/src analyze/code.cfc report footer (wheels.dev/3.1.0 era) -> command-line-tools/wheels-commands/code-quality/ - demo app config/settings.cfm + environment.cfm (wheels.dev/3.1.0 era) -> core-concepts/environments-and-configuration/ ConfigRoutesStaleDocUrlSpec updated: its 'canonical' routing URL was itself the dead snapshot slug; now pins basics/routing/ and gains a structural guard that scans cli/lucli/templates/ plus the known runtime-message files for any reintroduction of retired URL shapes (v4-0-0-snapshot, wheels.dev/3.1.0, cfwheels.org-era hosts). Verified: wheels.tests.specs.cli suite passes locally on Lucee 7 + SQLite (127 specs) including the rewritten guard. Signed-off-by: Peter Amiri --- cli/README.md | 4 +- cli/lucli/Module.cfc | 2 +- cli/lucli/services/Doctor.cfc | 2 +- cli/lucli/templates/app/app/jobs/README.md | 2 +- cli/lucli/templates/app/app/mailers/README.md | 2 +- cli/lucli/templates/app/app/plugins/README.md | 2 +- .../app/app/snippets/ConfigRoutes.txt | 2 +- .../templates/app/config/environment.cfm | 2 +- cli/lucli/templates/app/config/routes.cfm | 2 +- cli/lucli/templates/app/config/settings.cfm | 2 +- cli/src/commands/wheels/analyze/code.cfc | 2 +- cli/src/templates/ConfigRoutes.txt | 2 +- config/environment.cfm | 2 +- config/settings.cfm | 2 +- .../specs/cli/ConfigRoutesStaleDocUrlSpec.cfc | 94 ++++++++++++++----- 15 files changed, 85 insertions(+), 39 deletions(-) diff --git a/cli/README.md b/cli/README.md index f47e993565..bab58fd7c9 100644 --- a/cli/README.md +++ b/cli/README.md @@ -23,7 +23,7 @@ Both installers depend only on Java 21, which is pulled in automatically. ## Commands -See [the CLI command guides](https://guides.wheels.dev/v4-0-0-snapshot/command-line-tools/) or run `wheels --help` in your terminal. +See [the CLI command guides](https://guides.wheels.dev/v4-0-0/command-line-tools/) or run `wheels --help` in your terminal. ## Template Customization @@ -40,4 +40,4 @@ To customize a template: 2. Modify it to match your needs 3. The CLI will automatically use your custom template -See the [Template System Guide](https://guides.wheels.dev/v4-0-0-snapshot/command-line-tools/) for detailed documentation. +See the [Template System Guide](https://guides.wheels.dev/v4-0-0/command-line-tools/) for detailed documentation. diff --git a/cli/lucli/Module.cfc b/cli/lucli/Module.cfc index 359c329c60..25704db14b 100644 --- a/cli/lucli/Module.cfc +++ b/cli/lucli/Module.cfc @@ -6429,7 +6429,7 @@ component extends="modules.BaseModule" { out(" unzip wheels-core-.zip -d ~/.wheels/modules/wheels/vendor/"); out(" wheels new #appName#"); out(""); - out("See: https://guides.wheels.dev/v4-0-0-snapshot/start-here/installing/"); + out("See: https://guides.wheels.dev/v4-0-0/start-here/installing/"); throw( type="Wheels.FrameworkNotFound", diff --git a/cli/lucli/services/Doctor.cfc b/cli/lucli/services/Doctor.cfc index 46875fb5c2..135d110b24 100644 --- a/cli/lucli/services/Doctor.cfc +++ b/cli/lucli/services/Doctor.cfc @@ -660,7 +660,7 @@ component { recs, "Install or reinstall the Wheels CLI with a complete distribution, " & "or set WHEELS_FRAMEWORK_PATH to a vendor/wheels/ directory. " - & "See: https://guides.wheels.dev/v4-0-0-snapshot/start-here/installing/" + & "See: https://guides.wheels.dev/v4-0-0/start-here/installing/" ); } else if (findNoCase("Missing required directory", combined)) { arrayAppend(recs, "Run 'wheels new' to scaffold a complete project structure"); diff --git a/cli/lucli/templates/app/app/jobs/README.md b/cli/lucli/templates/app/app/jobs/README.md index 69e3c522b9..39ba8ac7e3 100644 --- a/cli/lucli/templates/app/app/jobs/README.md +++ b/cli/lucli/templates/app/app/jobs/README.md @@ -48,4 +48,4 @@ wheels generate migration create_wheels_jobs_table wheels migrate latest ``` -See [Background Jobs](https://wheels.dev/v4-0-0-snapshot/digging-deeper/) in the guides for retries, backoff, priority queues, and the monitoring dashboard. +See [Background Jobs](https://guides.wheels.dev/v4-0-0/digging-deeper/background-jobs/) in the guides for retries, backoff, priority queues, and the monitoring dashboard. diff --git a/cli/lucli/templates/app/app/mailers/README.md b/cli/lucli/templates/app/app/mailers/README.md index 82c52e0bd8..d1bc4c6b07 100644 --- a/cli/lucli/templates/app/app/mailers/README.md +++ b/cli/lucli/templates/app/app/mailers/README.md @@ -31,4 +31,4 @@ set(mailerSettings = { }); ``` -See [Sending Email](https://wheels.dev/v4-0-0-snapshot/digging-deeper/sending-email/) in the guides for the full walkthrough. +See [Sending Email](https://guides.wheels.dev/v4-0-0/digging-deeper/sending-email/) in the guides for the full walkthrough. diff --git a/cli/lucli/templates/app/app/plugins/README.md b/cli/lucli/templates/app/app/plugins/README.md index e158020221..f2183fccae 100644 --- a/cli/lucli/templates/app/app/plugins/README.md +++ b/cli/lucli/templates/app/app/plugins/README.md @@ -17,7 +17,7 @@ wheels stop && wheels start Note: the install verb is `add`, not `install`. -See [Packages](https://wheels.dev/v4-0-0-snapshot/digging-deeper/) in the guides for details. +See [Packages](https://guides.wheels.dev/v4-0-0/digging-deeper/packages/) in the guides for details. ## Migrating from a 3.x plugin diff --git a/cli/lucli/templates/app/app/snippets/ConfigRoutes.txt b/cli/lucli/templates/app/app/snippets/ConfigRoutes.txt index 4522a53d28..7220374991 100644 --- a/cli/lucli/templates/app/app/snippets/ConfigRoutes.txt +++ b/cli/lucli/templates/app/app/snippets/ConfigRoutes.txt @@ -2,7 +2,7 @@ // Use this file to add routes to your application and point the root route to a controller action. // Don't forget to issue a reload request (e.g. reload=true) after making changes. - // See https://guides.wheels.dev/v4-0-0-snapshot/handling-requests-with-controllers/routing for more info. + // See https://guides.wheels.dev/v4-0-0/basics/routing/ for more info. mapper() // CLI-Appends-Here diff --git a/cli/lucli/templates/app/config/environment.cfm b/cli/lucli/templates/app/config/environment.cfm index 222ae78a50..df4174e63b 100644 --- a/cli/lucli/templates/app/config/environment.cfm +++ b/cli/lucli/templates/app/config/environment.cfm @@ -2,7 +2,7 @@ // Use this file to set the current environment for your application. // You can set it to "development", "testing", "maintenance" or "production". // Don't forget to issue a reload request (e.g. reload=true) after making changes. -// See https://guides.wheels.dev/v4-0-0-snapshot/working-with-wheels/switching-environments for more info. +// See https://guides.wheels.dev/v4-0-0/core-concepts/environments-and-configuration/ for more info. // Below, we have set it to "development" for you since that is convenient when you are building your application. // We recommend that you change this to "production" when you're running your application live. diff --git a/cli/lucli/templates/app/config/routes.cfm b/cli/lucli/templates/app/config/routes.cfm index 283b3af077..a55cb64bf5 100644 --- a/cli/lucli/templates/app/config/routes.cfm +++ b/cli/lucli/templates/app/config/routes.cfm @@ -2,7 +2,7 @@ // Use this file to add routes to your application and point the root route to a controller action. // Don't forget to issue a reload request (e.g. reload=true) after making changes. - // See https://guides.wheels.dev/v4-0-0-snapshot/handling-requests-with-controllers/routing for more info. + // See https://guides.wheels.dev/v4-0-0/basics/routing/ for more info. mapper() // CLI-Appends-Here diff --git a/cli/lucli/templates/app/config/settings.cfm b/cli/lucli/templates/app/config/settings.cfm index c13d1d528f..27124f6d5a 100644 --- a/cli/lucli/templates/app/config/settings.cfm +++ b/cli/lucli/templates/app/config/settings.cfm @@ -3,7 +3,7 @@ Use this file to configure your application. You can also use the environment specific files (e.g. /config/production/settings.cfm) to override settings set here. Don't forget to issue a reload request (e.g. reload=true) after making changes. - See https://guides.wheels.dev/v4-0-0-snapshot/working-with-wheels/configuration-and-defaults for more info. + See https://guides.wheels.dev/v4-0-0/core-concepts/environments-and-configuration/ for more info. */ /* diff --git a/cli/src/commands/wheels/analyze/code.cfc b/cli/src/commands/wheels/analyze/code.cfc index 9a09a8a030..cd59f95a91 100644 --- a/cli/src/commands/wheels/analyze/code.cfc +++ b/cli/src/commands/wheels/analyze/code.cfc @@ -661,7 +661,7 @@ component extends="../base" { html &= ' diff --git a/cli/src/templates/ConfigRoutes.txt b/cli/src/templates/ConfigRoutes.txt index 4522a53d28..7220374991 100644 --- a/cli/src/templates/ConfigRoutes.txt +++ b/cli/src/templates/ConfigRoutes.txt @@ -2,7 +2,7 @@ // Use this file to add routes to your application and point the root route to a controller action. // Don't forget to issue a reload request (e.g. reload=true) after making changes. - // See https://guides.wheels.dev/v4-0-0-snapshot/handling-requests-with-controllers/routing for more info. + // See https://guides.wheels.dev/v4-0-0/basics/routing/ for more info. mapper() // CLI-Appends-Here diff --git a/config/environment.cfm b/config/environment.cfm index b1d7e5e97f..cc8cd3d1a0 100644 --- a/config/environment.cfm +++ b/config/environment.cfm @@ -2,7 +2,7 @@ // Use this file to set the current environment for your application. // You can set it to "development", "testing", "maintenance" or "production". // Don't forget to issue a reload request (e.g. reload=true) after making changes. -// See https://wheels.dev/3.1.0/guides/working-with-wheels/switching-environments for more info. +// See https://guides.wheels.dev/v4-0-0/core-concepts/environments-and-configuration/ for more info. // Below, we have set it to "development" for you since that is convenient when you are building your application. // We recommend that you change this to "production" when you're running your application live. diff --git a/config/settings.cfm b/config/settings.cfm index cf7ecb547f..0b3d81020a 100644 --- a/config/settings.cfm +++ b/config/settings.cfm @@ -3,7 +3,7 @@ Use this file to configure your application. You can also use the environment specific files (e.g. /config/production/settings.cfm) to override settings set here. Don't forget to issue a reload request (e.g. reload=true) after making changes. - See https://wheels.dev/3.1.0/guides/working-with-wheels/configuration-and-defaults for more info. + See https://guides.wheels.dev/v4-0-0/core-concepts/environments-and-configuration/ for more info. */ /* diff --git a/vendor/wheels/tests/specs/cli/ConfigRoutesStaleDocUrlSpec.cfc b/vendor/wheels/tests/specs/cli/ConfigRoutesStaleDocUrlSpec.cfc index 9c10d570fc..d9fa867f28 100644 --- a/vendor/wheels/tests/specs/cli/ConfigRoutesStaleDocUrlSpec.cfc +++ b/vendor/wheels/tests/specs/cli/ConfigRoutesStaleDocUrlSpec.cfc @@ -1,21 +1,22 @@ /** - * Regression: scaffolded config/routes.cfm shipped a `// See https://...` doc - * URL pointing at `https://guides.wheels.dev/docs/routing` — a path that - * doesn't exist on the current docs site. The lucli scaffolder's active - * `config/routes.cfm` template was already updated to the canonical - * `/v4-0-0-snapshot/handling-requests-with-controllers/routing` URL, but two - * sibling templates that produce the same comment for older code paths still - * had the broken link: + * Regression: scaffolded files shipped `See https://...` doc URLs pointing at + * guide paths that no longer exist on the docs site. * - * - cli/src/templates/ConfigRoutes.txt - * - cli/lucli/templates/app/app/snippets/ConfigRoutes.txt + * Round 1 (issue ##2635): config/routes.cfm templates pointed at the retired + * `guides.wheels.dev/docs/routing` path. * - * Both are user-facing on freshly scaffolded apps. Issue ##2635. + * Round 2 (2026-07): the pre-GA `v4-0-0-snapshot` slug was retired when the + * 4.0 docs consolidated onto `v4-0-0`, which killed every templated URL still + * carrying it — including the `working-with-wheels/*` paths that only ever + * existed in the v3 tree. The scaffolded settings.cfm/routes.cfm/environment.cfm, + * three template READMEs, two runtime CLI messages (Module.cfc, Doctor.cfc), + * and the demo app's config all linked 404s. All were repointed at live + * `guides.wheels.dev/v4-0-0/...` pages. * - * Also guards against any reintroduction of `cfwheels.org`, `cfwheels.com`, - * or `docs.cfwheels.org` URLs in these template files, since those domains - * were retired at the 3.0 rebrand and only `wheels.dev` / `guides.wheels.dev` - * remain canonical. + * This spec pins the canonical routing URL in the routes templates AND scans + * the scaffold template tree plus the known runtime-message files for any + * reintroduction of retired URL shapes: `v4-0-0-snapshot`, `wheels.dev/3.1.0`, + * and the rebrand-retired cfwheels.org / cfwheels.com / docs.cfwheels.org hosts. */ component extends="wheels.WheelsTest" { @@ -31,7 +32,7 @@ component extends="wheels.WheelsTest" { "cli/lucli/templates/app/app/snippets/ConfigRoutes.txt", "cli/lucli/templates/app/config/routes.cfm" ]; - var canonical = "https://guides.wheels.dev/v4-0-0-snapshot/handling-requests-with-controllers/routing"; + var canonical = "https://guides.wheels.dev/v4-0-0/basics/routing/"; for (var rel in targets) { // Capture the loop variable so the closure body binds the @@ -45,26 +46,71 @@ component extends="wheels.WheelsTest" { expect(content contains canonical).toBeTrue( relPath & " should reference " & canonical - & " — the same URL used by cli/lucli/templates/app/config/routes.cfm." + & " — the live v4 routing guide." ); expect(content contains "guides.wheels.dev/docs/routing").toBeFalse( relPath & " still references the stale /docs/routing path on guides.wheels.dev." ); - - expect(content contains "docs.cfwheels.org").toBeFalse( - relPath & " still references the retired docs.cfwheels.org host." - ); - - expect(reFindNoCase("cfwheels\.(org|com)", content) > 0).toBeFalse( - relPath & " still references a retired cfwheels.org / cfwheels.com URL." - ); }); })(rel); } }); + describe("Retired guide URL shapes", () => { + + var repoRoot = expandPath("/wheels/../.."); + + // Files outside the template tree that print or ship guide URLs. + var extraFiles = [ + "cli/README.md", + "cli/lucli/Module.cfc", + "cli/lucli/services/Doctor.cfc", + "cli/src/templates/ConfigRoutes.txt", + "cli/src/commands/wheels/analyze/code.cfc", + "config/settings.cfm", + "config/environment.cfm" + ]; + + it("no retired guide URLs under cli/lucli/templates/ or the known runtime-message files", () => { + var scanned = []; + var templateRoot = repoRoot & "/cli/lucli/templates"; + var templateFiles = directoryList(templateRoot, true, "path"); + for (var path in templateFiles) { + if (reFindNoCase("\.(cfm|cfc|txt|md|json)$", path)) { + arrayAppend(scanned, path); + } + } + for (var rel in extraFiles) { + arrayAppend(scanned, repoRoot & "/" & rel); + } + + var offenders = []; + for (var path in scanned) { + if (!fileExists(path)) { + continue; + } + var content = fileRead(path); + if ( + findNoCase("v4-0-0-snapshot", content) + || findNoCase("wheels.dev/3.1.0", content) + || findNoCase("docs.cfwheels.org", content) + || reFindNoCase("cfwheels\.(org|com)", content) + ) { + arrayAppend(offenders, path); + } + } + + expect(arrayLen(offenders) == 0).toBeTrue( + "Retired guide URL shape (v4-0-0-snapshot, wheels.dev/3.1.0, or a cfwheels.org-era host) found in: " + & arrayToList(offenders, "; ") + & ". Point these at live guides.wheels.dev/v4-0-0/ pages instead." + ); + }); + + }); + } } From ea73beed929d091b9c9ef3b60a60944f5228f96a Mon Sep 17 00:00:00 2001 From: Peter Amiri Date: Sun, 5 Jul 2026 22:33:04 -0700 Subject: [PATCH 2/3] ci: install git before checkout in the CommandBox smoke container MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The commandbox-install-smoke job has failed with exit 127 on every run since it was added: the ortussolutions/commandbox image ships without git, so actions/checkout falls back to the REST-API tarball — which honors .gitattributes export-ignore, and this repo export-ignores tools/ and cli/. The workspace therefore never contained the build scripts and templates the job exists to test. Install git before checkout so it performs a real clone, and assert post-checkout that tools/build/scripts/prepare-base.sh is present so any future fallback is named precisely instead of failing as a missing-file error three steps later. Signed-off-by: Peter Amiri --- .../workflows/commandbox-install-smoke.yml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/.github/workflows/commandbox-install-smoke.yml b/.github/workflows/commandbox-install-smoke.yml index df78ec3430..ac8703a268 100644 --- a/.github/workflows/commandbox-install-smoke.yml +++ b/.github/workflows/commandbox-install-smoke.yml @@ -80,8 +80,27 @@ jobs: # Pin the version the prepare scripts stamp into the artifacts. PKG_VERSION: "0.0.0-cismoke" steps: + # The CommandBox image ships without git, and actions/checkout without git + # falls back to the REST-API tarball — which honors .gitattributes + # export-ignore, and this repo export-ignores tools/ and cli/. That left + # this job's workspace without the very build scripts and templates it + # exists to test (prepare-base.sh: No such file or directory, exit 127, + # on every run since the job was added). Install git BEFORE checkout so + # it performs a real clone. + - name: Ensure git is available (checkout must not fall back to the export-ignored tarball) + run: | + command -v git >/dev/null 2>&1 || { + apt-get update -y && apt-get install -y --no-install-recommends git ca-certificates + } + git --version + - uses: actions/checkout@v5 + - name: Assert the export-ignored paths actually checked out + run: | + test -f tools/build/scripts/prepare-base.sh || { + echo "::error::tools/ missing from workspace — checkout fell back to the export-ignored tarball again"; exit 1; } + # curl + jq are the only host tools the probes need; the CommandBox image # is Debian-based but minimal. Install defensively (no-op if present). - name: Ensure curl is available From 315ad18220fd0de40deff2e9c7d9551b5803d092 Mon Sep 17 00:00:00 2001 From: Peter Amiri Date: Sun, 5 Jul 2026 22:55:36 -0700 Subject: [PATCH 3/3] fix: repoint the demo app routes.cfm guide URL and cover it in the guard MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Addresses the wheels-bot review finding: config/routes.cfm:4 still shipped a retired wheels.dev/3.1.0 URL — the one file its two same-directory siblings' fix missed — and the new structural guard's extraFiles list didn't cover it, so the guard passed green while a dead link shipped. Repointed to guides.wheels.dev/v4-0-0/basics/routing/ (matching the scaffold template) and added config/routes.cfm to the guard's extraFiles. Also adds the changelog fragment the review noted was missing for this user-facing fix. Signed-off-by: Peter Amiri --- changelog.d/fix-dead-guide-urls.fixed.md | 1 + config/routes.cfm | 2 +- vendor/wheels/tests/specs/cli/ConfigRoutesStaleDocUrlSpec.cfc | 3 ++- 3 files changed, 4 insertions(+), 2 deletions(-) create mode 100644 changelog.d/fix-dead-guide-urls.fixed.md diff --git a/changelog.d/fix-dead-guide-urls.fixed.md b/changelog.d/fix-dead-guide-urls.fixed.md new file mode 100644 index 0000000000..6ec8a6507e --- /dev/null +++ b/changelog.d/fix-dead-guide-urls.fixed.md @@ -0,0 +1 @@ +- Repointed 16 dead `v4-0-0-snapshot`- and `3.1.0`-era guide URLs at live `guides.wheels.dev/v4-0-0/` pages: the scaffolded app's `config/settings.cfm`/`routes.cfm`/`environment.cfm` comments, three template READMEs (mailers/jobs/plugins), both `ConfigRoutes.txt` templates, two runtime CLI messages (`Module.cfc` install pointer, `Doctor.cfc` remediation), `cli/README.md`, the analyze report footer, and the demo app's config. `ConfigRoutesStaleDocUrlSpec` now structurally guards the template tree and known runtime-message files against reintroducing retired URL shapes. diff --git a/config/routes.cfm b/config/routes.cfm index 193361273b..fd7b7faa36 100755 --- a/config/routes.cfm +++ b/config/routes.cfm @@ -1,7 +1,7 @@ // Use this file to add routes to your application and point the root route to a controller action. // Don't forget to issue a reload request (e.g. reload=true) after making changes. -// See https://wheels.dev/3.1.0/guides/handling-requests-with-controllers/routing for more info. +// See https://guides.wheels.dev/v4-0-0/basics/routing/ for more info. mapper() // CLI-Appends-Here diff --git a/vendor/wheels/tests/specs/cli/ConfigRoutesStaleDocUrlSpec.cfc b/vendor/wheels/tests/specs/cli/ConfigRoutesStaleDocUrlSpec.cfc index d9fa867f28..b226dcc05d 100644 --- a/vendor/wheels/tests/specs/cli/ConfigRoutesStaleDocUrlSpec.cfc +++ b/vendor/wheels/tests/specs/cli/ConfigRoutesStaleDocUrlSpec.cfc @@ -70,7 +70,8 @@ component extends="wheels.WheelsTest" { "cli/src/templates/ConfigRoutes.txt", "cli/src/commands/wheels/analyze/code.cfc", "config/settings.cfm", - "config/environment.cfm" + "config/environment.cfm", + "config/routes.cfm" ]; it("no retired guide URLs under cli/lucli/templates/ or the known runtime-message files", () => {