Skip to content

Commit 52809dc

Browse files
committed
Merge remote-tracking branch 'origin/develop' into claude/pedantic-mirzakhani-27b839
# Conflicts: # CHANGELOG.md
2 parents 0a73584 + 584fc44 commit 52809dc

4 files changed

Lines changed: 42 additions & 8 deletions

File tree

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ All historical references to "CFWheels" in this changelog have been preserved fo
104104
### Changed
105105

106106
- **Breaking:** CORS middleware default changed from wildcard `*` to deny-all. Apps must explicitly configure `allowOrigins` or set an explicit wildcard. (#2039)
107+
- **Breaking:** `viteStrictManifest` defaults to `true` — a missing Vite manifest entry now throws `Wheels.ViteAssetNotFound` in production instead of silently falling back (3.x behavior). Rebuild Vite assets during the upgrade window; to retain 3.x silent behavior, `set(viteStrictManifest=false)`. (#2133)
107108
- **Breaking:** `allowEnvironmentSwitchViaUrl` defaults to `false` in production (#2076)
108109
- **Breaking:** Reload password must be non-empty for environment switching in production (#2082)
109110
- **Breaking:** HSTS header defaults on in production (#2081)
@@ -130,6 +131,7 @@ All historical references to "CFWheels" in this changelog have been preserved fo
130131
- RocketUnit test style for new tests — BDD syntax (via WheelsTest) is required going forward. Existing RocketUnit specs continue to run. (#1925)
131132
- `wheels.Test` test base class — extend `wheels.WheelsTest` instead (#1889)
132133
- In-dev-server HTTP MCP endpoint at `/wheels/mcp` — superseded by the LuCLI stdio MCP server (`wheels mcp wheels`). Emits a deprecation warning to the `wheels_mcp` log on first request and advertises `deprecated: true` in the `serverInfo` handshake. Scheduled for removal in a future release. Migrate existing projects with `wheels mcp setup --force`.
134+
- Legacy CommandBox `wheels-cli` module (`wheels g app`, `wheels new` via the CommandBox wizard) — superseded by LuCLI's canonical `wheels new`. Emits a deprecation banner on every invocation. Scheduled for removal in v5.0. (#2227)
133135

134136
### Removed
135137

@@ -142,6 +144,7 @@ All historical references to "CFWheels" in this changelog have been preserved fo
142144
### Fixed
143145

144146
- `wheels routes`, `reload`, `test`, `console`, `migrate`, `seed`, `db status`, `db version`, and `generate admin` now exit non-zero when no Wheels dev server is running. Previously these commands printed a red diagnostic but returned `""`, producing exit 0 — MCP clients and shell automation couldn't distinguish "succeeded with no output" from "server down, nothing ran". A shared `$requireRunningServer()` helper now throws a typed `Wheels.ServerNotRunning` exception that LuCLI's `ExecutionExceptionHandler` maps to exit 1. (#2229)
147+
- Legacy CommandBox `wheels g app` now scaffolds a 4.0 app by default — the `wheels-base-template` default was pinned at `@^3.1.0`, so `box install wheels-cli && wheels g app myapp` produced a 3.x scaffold at 4.0 GA. Updated default (and the `WheelsBaseTemplate` shortcut + wizard default selection) to `@^4.0.0`, fixed the stale "Default is Bleeding Edge" docstring, and added a deprecation banner pointing users at LuCLI's `wheels new`. (#2227)
145148
- `changeColumn` on SQLite now works by implementing the SQLite-standard recreate-table pattern in `SQLiteMigrator`. Previously, SQLite migrations inherited MySQL's `ALTER TABLE ... CHANGE` syntax from `Abstract.cfc` and failed with `near "CHANGE": syntax error`. The migrator's `$execute` now accepts an array of statements so adapters can return multi-step DDL. v1 limitations: foreign-key constraints declared inline on `CREATE TABLE` and triggers are not preserved across the recreate. (#2207)
146149
- Framework-internal browser-test fixture controllers, views, and the `/_browser/*` routes no longer leak into application-level files. Moved from `app/controllers/BrowserTest*.cfc`, `app/views/browsertest*/`, and `config/routes.cfm` into `vendor/wheels/public/browser-fixtures/`, auto-mounted by `$lockedLoadRoutes` when environment is `testing` or `development` and the new opt-in setting `loadBrowserTestFixtures=true` is set. Apps upgrading from a 4.0 snapshot that had custom `/_browser/*` routes must opt in explicitly or re-declare them in `config/routes.cfm`. (#2135, #2138)
147150
- Stray `app/mailers/UserNotificationsMailer.cfc` demo removed from the framework repo root (byte-identical copies remain in the example apps under `examples/tweet/` and `examples/starter-app/`). (#2138)

cli/src/commands/wheels/generate/app-wizard.cfc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ component aliases="wheels g app-wizard, wheels new" extends="../base" {
156156

157157
var template = multiselect( 'Which Wheels Template shall we use? ' )
158158
.options( [
159-
{value: 'wheels-base-template@^3.1.0', display: '3.1 - Wheels Base Template - Stable', selected: true},
159+
{value: 'wheels-base-template@^4.0.0', display: '4.0 - Wheels Base Template - Stable', selected: true},
160160
{value: 'wheels-base-template@BE', display: 'Bleeding Edge - Wheels Base Template'},
161161
{value: 'wheels-template-htmx-alpine-simple', display: 'Wheels Template - HTMX - Alpine.js - Simple.css'},
162162
{value: 'wheels-starter-app', display: 'Wheels Starter App'},

cli/src/commands/wheels/generate/app.cfc

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* {code}
1515
*
1616
* Here are the basic templates that are available for you that come from ForgeBox
17-
* - Wheels Base Template - 3.0 Stable (default)
17+
* - Wheels Base Template - 4.0 Stable (default)
1818
* - Wheels Base Template - Bleeding Edge
1919
* - Wheels Template - HelloWorld
2020
* - Wheels Template - HelloDynamic
@@ -43,7 +43,7 @@ component aliases="wheels g app" extends="../base" {
4343

4444
// Map these shortcut names to the actual ForgeBox slugs
4545
variables.templateMap = {
46-
'WheelsBaseTemplate' : 'wheels-base-template@^3.1.0',
46+
'WheelsBaseTemplate' : 'wheels-base-template@^4.0.0',
4747
'BleedingEdge' : 'wheels-base-template@BE',
4848
'WheelsTemplateHTMX' : 'wheels-template-htmx-alpine-simple',
4949
'WheelsStarterApp' : 'wheels-starter-app',
@@ -55,7 +55,7 @@ component aliases="wheels g app" extends="../base" {
5555

5656
/**
5757
* @name The name of the app you want to create
58-
* @template The name of the app template to generate (or an endpoint ID like a forgebox slug). Default is Bleeding Edge
58+
* @template The name of the app template to generate (or an endpoint ID like a forgebox slug). Default is the stable Wheels Base Template (4.0).
5959
* @directory The directory to create the app in
6060
* @reloadPassword The reload passwrod to set for the app
6161
* @datasourceName The datasource name to set for the app
@@ -68,7 +68,7 @@ component aliases="wheels g app" extends="../base" {
6868
**/
6969
function run(
7070
name = 'MyApp',
71-
template = 'wheels-base-template@^3.1.0',
71+
template = 'wheels-base-template@^4.0.0',
7272
directory,
7373
reloadPassword = '',
7474
datasourceName,
@@ -86,6 +86,14 @@ component aliases="wheels g app" extends="../base" {
8686
// Initialize detail service
8787
var details = application.wirebox.getInstance("DetailOutputService@wheels-cli");
8888

89+
// Deprecation notice — legacy CommandBox surface is scheduled for removal in Wheels v5.0.
90+
// Canonical 4.0+ CLI is LuCLI's `wheels new` (https://github.com/bpamiri/LuCLI).
91+
details.getPrint().yellowBoldLine( "[DEPRECATED] 'wheels g app' (CommandBox wheels-cli) is deprecated." );
92+
details.getPrint().yellowLine( " Use LuCLI 'wheels new' instead — the canonical Wheels 4.0+ CLI." );
93+
details.getPrint().yellowLine( " Install: brew install lucli (or see https://github.com/bpamiri/LuCLI)" );
94+
details.getPrint().yellowLine( " This command will be removed in Wheels v5.0." );
95+
details.line();
96+
8997
// set defaults based on app name
9098
if ( !len( arguments.directory ) ) {
9199
arguments.directory = '#getCWD()##arguments.name#';

web/sites/guides/src/content/docs/v4-0-0-snapshot/upgrading/3x-to-4x.mdx

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ sidebar:
88

99
import { Aside, CardGrid, LinkCard, Steps } from '@astrojs/starlight/components';
1010

11-
This guide walks every breaking change between Wheels 3.x and 4.0, with before/after code for each. Most 3.x apps upgrade in an afternoon. The pressure points are CORS defaults, the test base class rename, the `plugins/``packages/` split, and the `wheels` CLI command renames. Everything else is either additive or continues to work with a deprecation warning.
11+
This guide walks every breaking change between Wheels 3.x and 4.0, with before/after code for each. Most 3.x apps upgrade in an afternoon. The pressure points are CORS defaults, the test base class rename, the `plugins/``packages/` split, the `wheels` CLI command renames, and Vite manifest strictness (production now throws on missing entries — rebuild assets during the upgrade window). Everything else is either additive or continues to work with a deprecation warning.
1212

1313
**You'll learn:**
1414

@@ -37,7 +37,7 @@ This guide walks every breaking change between Wheels 3.x and 4.0, with before/a
3737

3838
</Steps>
3939

40-
## The ten breaking changes
40+
## The eleven breaking changes
4141

4242
Each item cites its `CHANGELOG.md` "Changed" or "Removed" entry. Where the skeleton blog post calls out a two-path upgrade, Path A (fix directly) is documented here; Path B (the Legacy Compatibility Adapter, #2015) is covered at the end.
4343

@@ -169,6 +169,28 @@ var svc = service("emailService");
169169

170170
`service()` is the new global helper (#1933); prefer it over reaching into the container.
171171

172+
### 11. Vite manifest strictness — missing entries throw in production
173+
174+
**CHANGELOG:** `Breaking: viteStrictManifest defaults to true` (#2133).
175+
176+
In 3.x, a missing entry in `public/assets/.vite/manifest.json` silently fell back to the raw source path. In 4.0, the default flips: `viteScriptTag()`, `viteStyleTag()`, and `vitePreloadTag()` throw `Wheels.ViteAssetNotFound` in production when the manifest doesn't contain the requested entrypoint. This catches stale-build deploys at first request instead of letting them ship broken `<script>` tags to the browser.
177+
178+
The most common failure mode is a deploy that pushes new CFML code without rebuilding the Vite bundle — the manifest on the server is older than the entrypoint referenced in a view.
179+
180+
**Recommended fix — rebuild assets as part of the deploy:**
181+
182+
```bash title="your shell (or CI/CD deploy step)"
183+
npm run build # produces public/assets/.vite/manifest.json
184+
```
185+
186+
**Escape hatch — restore 3.x silent-fallback behavior:**
187+
188+
```cfm {test:compile} title="config/settings.cfm"
189+
set(viteStrictManifest = false);
190+
```
191+
192+
Use the escape hatch only if you can't rebuild assets during the upgrade window — then flip it back on once your deploy pipeline emits the manifest reliably.
193+
172194
## Deprecations you should plan to address
173195

174196
### Plugins → packages
@@ -270,7 +292,7 @@ The `/_browser/home`, `/_browser/login`, `/_browser/dashboard`, `/_browser/login
270292

271293
**CHANGELOG:** `Legacy compatibility adapter for 3.x → 4.0 migration soft-landing` (#2015), shipped as `packages/legacyadapter/`.
272294

273-
When you can't fix all ten breaking items in one sprint, activate the adapter, ship the upgrade, and modernize incrementally:
295+
When you can't fix all eleven breaking items in one sprint, activate the adapter, ship the upgrade, and modernize incrementally:
274296

275297
```bash title="your shell"
276298
cp -r packages/legacyadapter vendor/legacyadapter
@@ -322,6 +344,7 @@ These are additive in 4.0 and worth adopting during the upgrade window:
322344
- **Test runner can't find specs.** Check for `tests/specs/functions/` — rename to `functional/`. See #1872.
323345
- **Plugin warning at startup.** Port to `packages/` (see above) or accept the warning until you do.
324346
- **JWT tokens reject as invalid after upgrade.** Algorithm validation is on. Confirm your issuer sets `alg` to a supported value and the signature verification path uses constant-time comparison. See #2079, #2086.
347+
- **`Wheels.ViteAssetNotFound` thrown on first request after deploy.** The deploy shipped code referencing a Vite entrypoint that isn't in the manifest. Rebuild Vite assets (`npm run build`) before deploy, or temporarily `set(viteStrictManifest=false)` to restore 3.x silent fallback. See #2133.
325348

326349
## Related guides
327350

0 commit comments

Comments
 (0)