Skip to content

Fix flatpack:build after a deploy into a new release directory - #4

Merged
DanielDarrenJones merged 1 commit into
mainfrom
fix-build-after-move
Nov 10, 2026
Merged

DanielDarrenJones merged 1 commit into
mainfrom
fix-build-after-move

Conversation

@DanielDarrenJones

Copy link
Copy Markdown
Contributor

With zero-downtime deploys (Forge's release directories, Envoyer, Deployer), each deploy puts the app at a new path while storage is shared. Flatpack's compiled content lives in storage and holds absolute paths, so it arrives at the new path pointing at the old one.

What went wrong

flatpack:build runs Stache::clear() and then Stache::warm() in one process. Statamic's Keys::clear() forgets each store's saved keys but leaves the keys it already has in memory. Those still pointed at the old path, so during the warm every file was a "duplicate" of itself at its old path. No collections were found, the build threw Call to a member function sites() on null, and the cleared store was written out on shutdown. The result: a failed deploy and a live site with no entries until someone rebuilt from scratch.

Reproduced on Statamic 6.40 with a 9,000-entry site: build, copy the app to a new directory, build again → error, 0 entries. Affects 1.0.0 and 1.1.0.

What changes

  • flatpack:build clears each store's keys in memory after clearing the Stache (plain stores first, since finding a collection's or taxonomy's stores reads those).
  • A build that throws discards everything it buffered, so the last good build stays in place.
  • flatpack:refresh, and Refresh in the Control Panel, build everything when the content was compiled for another path. Before, refresh threw. The path is recorded at build time; for builds from before this change it's worked out from the saved collection paths.
  • flatpack:status shows "built for another path" when that's the case.

Checks

  • The repro above now builds from the new path: all 12,840 entry and term URLs identical, entry paths under the new directory.
  • A build made to fail (an unreadable collection file) leaves the previous build serving everything.
  • The parity suite gains two scenarios: move the app and build; move it again and refresh. Both compare against plain Statamic.
  • bin/parity passes locally on Statamic 6 (latest), 5 (latest) and 5.11.0. One of five local runs on 5.11.0 failed the first new scenario and I couldn't reproduce it in three more, so watch that job.

Also in here

bin/parity now lets Composer update every package when installing a Statamic version. The Statamic 5 skeleton pins laravel/pail to a release that needs Laravel 12, which Statamic 5.11 can't use, so the "Statamic 5 (earliest supported)" job has been failing to install on every branch, main included.

Not covered

A site that deploys to a new path and runs neither flatpack:build nor flatpack:refresh keeps serving the old build, with entry paths pointing at the previous release. Reads work; saves from the Control Panel would write to the old release. The deploy docs already say to run flatpack:build on every deploy.

Until this is released

Deleting the store before building avoids the failure, at the cost of an empty store while the build runs: rm -rf storage/statamic/flatpack && php please flatpack:build.

With zero-downtime deploys the app moves to a new path while storage is
shared, so the compiled content (which holds absolute paths) comes with it.
Stache::clear() forgets each store's saved keys but not the ones it has in
memory, so in flatpack:build every file looked like a duplicate of itself at
its old path, nothing was built, and the cleared store was then persisted.

flatpack:build now clears the keys in memory too, and a build that throws
discards what it buffered, leaving the last good build in place. A refresh
of content built for another path builds everything instead, and
flatpack:status says when that's needed.

The parity suite moves the app and builds, then moves it again and refreshes.

bin/parity lets Composer update every package when installing a Statamic
version: the skeleton pins laravel/pail to a release that needs Laravel 12,
which Statamic 5.11 can't use.
@DanielDarrenJones
DanielDarrenJones merged commit 20d325d into main Nov 10, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant