Upgrading: move an app to a newer GoFastr release

Two things version independently: the Go module dependency your app builds against, and the gofastr CLI installed with go install. Updating go.mod does NOT update the CLI binary; keep them on the same release. Every command below uses vX.Y.Z as a placeholder; substitute the release you're upgrading to.

Crossing v0.87.0? Read What changed in v0.87.0 first. That release reskinned the default theme, added entity screens (framework/entityui) and rebuilt the admin on them, and the page lists every breaking change with what replaces it.

Crossing v0.86.0? Read What changed in v0.86.0 first. That release rebuilt the UI layer, and the page lists every breaking change with what replaces it.

The guided path: gofastr upgrade

The CLI embeds a migration registry: one entry per release that carried breaking or migration-relevant changes, maintained alongside the changelog. gofastr upgrade reads your go.mod, resolves the target release, and shows exactly what you'll cross on the way:

8 lines
# Install the TARGET release's CLI first; an older binary's registry
# can't know about releases that came after it:
go install github.com/DonaldMurillo/gofastr/cmd/gofastr@vX.Y.Z

gofastr upgrade                # plan against the newest tagged release
gofastr upgrade --to vX.Y.Z    # plan against a specific release
gofastr upgrade --apply        # also run go get / tidy / build / test
gofastr upgrade --from vA.B.C  # go.mod already bumped: name the old release

The plan lists each in-between release's notes (BREAKING entries called out clearly), and where a change has a known code signature, the report points at the affected file:line in your project: the same guided style as gofastr audit a11y. --apply then runs the mechanical steps and stops at the first failure so you fix with the notes in hand. An app that vendors its dependencies (vendor/modules.txt) gets a go mod vendor step after go mod tidy; without it every later go command refuses the stale vendor/. A release candidate target (--to v0.96.0-rc.1) shows the notes of the release it precedes.

The scan lists unreadable source, stylesheet, text and settings files as Unscanned, including symlinks that escape the project root. Review these entries before treating a report with no matches as a clean scan. A missing optional gofastr.yml is not an unreadable-file warning. Stylesheet, text and settings reads are capped at 8 MiB per file; larger files appear as Unscanned instead of being read in full. A Go constraint naming more than eight distinct free build tags appears as Unscanned with constraint names more than 8 tags: the bounded search did not decide whether that file can build. This is different from no satisfiable build configuration, which means no supported platform and tag assignment satisfies the constraint. Review tag-limit files separately. Retired HTML attributes in Go string values and attribute maps match ASCII-case-insensitively, including names ending in - that identify an attribute family. Unicode lookalikes remain distinct. Retired CSS selectors match escaped identifier spellings too, including hexadecimal escapes, while reporting the original source position. Escaped punctuation stays part of its identifier, never a combinator, class boundary or pseudo-class function; longer names remain distinct. Retired classes also match [class=…] and [class~=…] selectors. Quoted values follow CSS string escapes: an escaped LF, CR, CRLF or form feed continues the value without adding whitespace before class-token matching. A module without a go directive is checked as Go 1.16, the Go tool's default, rather than bypassing minimum-version notes. An invalid go.mod either prevents scan startup or appears as Unscanned when the directive matcher encounters it after loading. Module directives are inspected before package loading can add or upgrade them, including nested modules.

The manual workflow

  1. List the available releases:
1 lines
   go list -m -versions github.com/DonaldMurillo/gofastr
  1. Read the release notes for the release you chose; breaking changes, migrations, and deprecations are called out per release: <https://github.com/DonaldMurillo/gofastr/releases> (the same content ships in CHANGELOG.md). Do this before touching go.mod.
  1. Update the module dependency:
1 lines
   go get github.com/DonaldMurillo/gofastr@vX.Y.Z
  1. Update the standalone CLI to the same release (if you use it):
1 lines
   go install github.com/DonaldMurillo/gofastr/cmd/gofastr@vX.Y.Z
  1. Clean the module files:
1 lines
   go mod tidy
  1. Build and test:
2 lines
   go build ./...
   go test ./...
  1. Confirm which version Go actually selected (MVS can pick a higher version than you asked for if another dependency requires it):
1 lines
   go list -m github.com/DonaldMurillo/gofastr
  1. Review the go.mod / go.sum diff before committing.

For the CLI, gofastr --help is the smoke test that the new binary is on your PATH. Don't treat gofastr version as proof of the installed tag: go install builds don't always carry injected version metadata.

Common mistakes

  • Upgrading go.mod but not the CLI. go get changes what your app builds against; the gofastr binary on your PATH stays whatever you last installed. Generators, gofastr build's gates, and the embedded docs then disagree with your framework version. Step 4 is not optional if you use the CLI.
  • Running gofastr upgrade with the OLD binary. The migration registry ships inside the CLI, so a binary older than the target can't know the target's notes (it warns when this happens). Install the target CLI first, then plan the upgrade.
  • Running go get before gofastr upgrade. The plan starts at the version in go.mod, so a bumped go.mod hides every note in between ("Already on the target release"). Pass --from with the release the code was written for, and the scan points at the same lines, through the compile errors when the app no longer type-checks.
  • Skipping the release notes on a multi-release jump. Breaking changes are per-release; jumping vA→vD means reading B, C, and D. gofastr upgrade collects all of them for exactly this case.
  • Trusting go get over go list -m. Another dependency can pull a newer GoFastr than you requested (minimal version selection). Step 7 tells you what you're actually running.
  • Committing go.sum churn blind. The diff should contain the gofastr bump and its transitive updates; anything else deserves a look before it lands.