diff --git a/web/sites/guides/src/content/docs/v4-1-0/command-line-tools/wheels-commands/upgrade.mdx b/web/sites/guides/src/content/docs/v4-1-0/command-line-tools/wheels-commands/upgrade.mdx index ea5aaaf480..6fc5c9e79b 100644 --- a/web/sites/guides/src/content/docs/v4-1-0/command-line-tools/wheels-commands/upgrade.mdx +++ b/web/sites/guides/src/content/docs/v4-1-0/command-line-tools/wheels-commands/upgrade.mdx @@ -33,7 +33,7 @@ Calling `wheels upgrade` with no subcommand prints concise usage listing both ve 1. **Reads the current version** from `vendor/wheels/box.json`. If the file is missing or malformed, the version is reported as `unknown` and the comparison below is skipped. 2. **Resolves the target version.** If you pass `--to=`, that wins. Otherwise the command hits the GitHub releases API (`api.github.com/repos/wheels-dev/wheels/releases/latest`) and strips the leading `v` from the tag name. If the network call fails, the command prints a yellow notice and exits — it will not invent a target. 3. **Compares major versions.** If current and target share the same major, the command notes "Same major version — no known breaking changes" for the major-transition checks, then still runs its advisory scan for the same-major patterns below. -4. **Runs breaking-change checks.** Each check is either a directory existence test or a regex grep across a sub-tree of the project. Major-version transitions add their own checks on top of the advisory scan. Hits are printed as issues (yellow); absences are printed as passed checks (green). +4. **Runs breaking-change checks.** Each check is either a directory existence test or a regex grep across a sub-tree of the project. Major-version transitions add their own checks on top of the advisory scan. Every run, whatever the versions, also includes the app template drift advisory described below. Hits are printed as issues (yellow); absences are printed as passed checks (green). **Exit status:** when breaking findings exist the command throws `Wheels.UpgradeCheckFailed` after the report flushes, exiting non-zero so it can gate CI. Without `--strict`, advisory findings never affect the exit code. With `--strict`, advisory findings escalate to the same hard-fail path — useful for CI pipelines that want to gate on opt-in convention changes, not just breaking ones. With `--format=json` the human report is replaced by a single JSON document (`currentVersion`, `targetVersion`, `success`, `strict`, `breaking`, `advisories`, `passed`, `guide`) — the non-zero exit on breaking or strict-mode advisory findings still applies. The document's `success` field tracks the exit code precisely: it is `false` whenever the process exits non-zero, including the `--strict` + advisory-only case, and the `strict` field is echoed back so consumers can tell `success: false` with empty `breaking[]` apart from a data inconsistency. @@ -120,6 +120,10 @@ The checks are hard-coded in the CLI and keyed by the major-version transition: - *(advisory)* `new wheels.middleware.SecurityHeaders` in `config/` — HSTS defaults on in production in 4.0; pass `hsts=false` if your load balancer already sets it (#2081). - *(advisory)* `protectsFromForgery` under `app/` — the CSRF cookie now sets `SameSite`; cross-site POSTs from third-party frames will break (#2035). +**Every run (any version)** + +- *(advisory)* App template drift (added in 4.1.0, #3379) — `public/Application.cfc` and `public/index.cfm` are compared byte-for-byte against the CLI's bundled app template (the one `wheels new` scaffolds from). A file that differs, or is missing, is reported by name only; no diff is printed. These files are app-owned, so a `vendor/wheels/` swap never updates them, and drift can mean the app is missing framework-side hardening such as the Adobe teardown guards in `onError`/`onSessionEnd`. Customized apps legitimately drift — diff the files yourself and reconcile, keeping your local changes. + Each grep scan covers the file types relevant to that check (`.cfc` and `.cfm` for config and view checks; `Makefile`, `package.json`, `.yml`, `.yaml`, and `.sh` for the `wheels snippets` check) and reports `path:lineNumber` for every hit. Directory checks report only the top-level path when the directory exists and is non-empty. + + ## The 3.x → 4.0 upgrade The mechanics are the same swap, but 4.0 changes framework behavior and some app-side files, so there's required reading and a few extra steps: diff --git a/web/sites/guides/src/content/docs/v4-1-0/upgrading/performance-notes.mdx b/web/sites/guides/src/content/docs/v4-1-0/upgrading/performance-notes.mdx index 93cbf57bd4..f438f0fb5d 100644 --- a/web/sites/guides/src/content/docs/v4-1-0/upgrading/performance-notes.mdx +++ b/web/sites/guides/src/content/docs/v4-1-0/upgrading/performance-notes.mdx @@ -43,7 +43,7 @@ Measured on Lucee 7 + SQLite: The framework suite is only partly instance-creation, so its delta understates the win for an instance-heavy app suite like the one in the original report. ## Where 4.0 stands after the fix @@ -58,16 +58,18 @@ The practical takeaway for benchmarking your upgraded app: warm the app first (t ## How to get the fix -The fix merged to `develop` on 2026-06-20 — one day **after** v4.0.5 was tagged, so it is not in any stable release yet. It ships with **v4.0.6**. Until then it is available on the bleeding-edge channel, which tracks `develop`: +All of this work is in stable releases — no channel switch is needed: + +- **4.0.6** — the per-application mixin-plan cache described above ([#3236](https://github.com/wheels-dev/wheels/pull/3236)). +- **4.1.0** — the model mixin surface moved to compile-time includes, so instances inherit the full model API instead of copying ~270 method references each ([#3462](https://github.com/wheels-dev/wheels/pull/3462)), and model instances are created with a direct constructor call instead of the DI container's resolve/auto-wire path plus a reflective invoke ([#3464](https://github.com/wheels-dev/wheels/pull/3464)). Together with request-scope caching of the integration plan ([#3461](https://github.com/wheels-dev/wheels/pull/3461)), this took 3,000 × `model().new()` from ~1,290 ms on 4.0.3 to ~508 ms on the [#3213](https://github.com/wheels-dev/wheels/issues/3213) benchmark rig (Lucee 7, warmed), narrowing the gap to 2.5 on that workload from ~4.9× to ~1.9×. If a model overrides a mixin and delegates through `variables.super`, see the 4.1.0 caution in [Upgrading Without the CLI](/v4-1-0/upgrading/manual-upgrades/). +- **4.1.1** — flash locking is scoped to where the data lives: session-stored flash takes a per-session lock instead of one application-wide lock, and cookie-stored flash is no longer locked at all ([#3656](https://github.com/wheels-dev/wheels/pull/3656), by @zspitzer). Under a 128-user load test this lifted throughput 10–14%. + +Upgrade the CLI through your package manager, then swap the framework into your app: ```bash -# install the bleeding-edge CLI (brew/apt/yum/scoop all have a -be channel; -# see the Release Channels guide for your platform's exact package) wheels upgrade check # preview what would change -wheels upgrade apply # swap your app's vendor/wheels to the BE framework +wheels upgrade apply # swap your app's vendor/wheels to the CLI's bundled framework wheels server start ``` -`wheels upgrade apply` swaps `vendor/wheels/` in place — do it on a branch or a copy of the app so it's easy to roll back. Once v4.0.6 is out, the stable channel carries the fix and no channel switch is needed. - -→ [Release Channels](/v4-1-0/start-here/release-channels/) covers switching between stable and bleeding-edge (and back) per platform. +`wheels upgrade apply` swaps `vendor/wheels/` in place — do it on a branch or a copy of the app so it's easy to roll back.