[6.x] Partial refresh Stache items from git history - #15354
Open
godismyjudge95 wants to merge 6 commits into
Open
[6.x] Partial refresh Stache items from git history#15354godismyjudge95 wants to merge 6 commits into
godismyjudge95 wants to merge 6 commits into
Conversation
Unmapped files no longer force a full rebuild, so a mixed deploy can still do a targeted --git refresh. Fieldsets, config/statamic, and other blueprints still invalidate the whole stache.
A failed git diff no longer looks like an empty change set, so a bad stored SHA cannot skip content updates. --include-dirty now lists untracked files, copy lines add the new path, and forgetItemByPath matches tidy path variants.
An empty ref file now bootstraps like a missing one, and a full clear+warm writes HEAD when the site is a git repo. Collection, taxonomy, and collection-tree yaml also warm the child store. Targeted --git skips excluded stores, and term yaml updates every locale.
updateItemFromPath and forgetItemByPath call cacheItem, forgetItem, and getKeyFromPath more times than the baseline allowed.
cacheItem, forgetItem, and getKeyFromPath already live there. The new methods belong next to them, not on Store.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR is a solution to a long standing problem for us: whenever we push to deploy we have to avoid doing a
php please stache:refreshlike the plague because it can take larger sites minutes to complete and while it runs it takes the entire site down.My solution here is to add a flag
stache:refresh --gitwhich stores the the current SHA ref each time it is run. Then it simply refreshes only stache items for the content that has been changed since the last time it has been ran. This means you still get to push to deploy content changes, but don't take the entire site down when you need to runstache:refreshto display those changes.I could see a few downsides to this:
storage/statamic/.stache-git-refinstead of a cache item - this is so it survives deploys, but this means it isn't compatible with things like Laravel CloudSince it isn't changing the default behavior I think both of those items are fine?
Let me know what you think.
AI Explanation:
Why
A deploy that changes a few content files should not rebuild every Stache store.
statamic:stache:refresh --gitdiffs from the SHA instorage/statamic/.stache-git-reftoHEAD, maps each path to a store action, then writes the current HEAD SHA.Scope
Adds
--gitand--include-dirtyonstatamic:stache:refresh.--excludefrom 6.x stays.Git::stacheDiff()parsesgit diff --name-status, includingR###renames andC###copies.--include-dirtyalso reads staged files, unstaged tracked files, and untracked files viagit ls-files --others --exclude-standard.GitPathMappermapscontent/,users/, andresources/blueprints/ontoupdate-item,forget-item,warm-store, orfull-refresh. Collection yaml also warmsentries::{handle}. Taxonomy yaml also warmsterms::{handle}. Collection tree yaml also warmsentries::{handle}. Fieldsets,config/statamic/, and other blueprints still map tofull-refresh. Unmapped paths such assrc/, views, andpublic/produce no actions.Store::updateItemFromPath()loads items throughgetItemFromModifiedPath()so a term file updates every locale.Store::forgetItemByPath()tidies the path and tries slash and resolved variants.A missing, empty, or whitespace-only ref file is a first run. A successful full clear and warm writes the ref when the site is a git repo. A failed
git diffexitsFAILUREand does not write the ref.Tradeoffs
Unmapped paths are ignored so a mixed deploy stays targeted. A new store that the mapper does not know will stay stale until you map it or run a full refresh.
GitProcess::diff(),diffDirty(), anddiffStaged()now throw when git writes to stderr or exits non-zero. OnlystacheDiff()calls those methods. A git warning on stderr with exit 0 fails the command.Targeted update is not a full
Stache::warm(). Entry deletes do not rebuild term associations. Asset binaries and form submissions stay unmapped. An id or slug change can leave the old key until a full refresh.Blast Radius
Default
statamic:stache:refreshnow writesstorage/statamic/.stache-git-refwhen the site is a git repo, so the next--gitrun does not replay the whole history.--excludenow skips targetedupdate-item,forget-item, andwarm-storeactions as well as full warm.--exclude=entriesskipsentries::blog.Control Panel git commit and push do not call
diff(). They should be unchanged.Verification
From
/home/daniel/ddev/sites/statamic/cms-worktrees/stache-refresh-gitwith/home/daniel/ddev/sites/server/bin/php vendor/bin/phpunit --configuration phpunit.dist.xml:tests/Stache/GitPathMapperTest.php,tests/Console/Commands/StacheRefreshTest.php,tests/Stache/Stores/EntriesStoreTest.php: 62 passed, 234 assertions, 1 incomplete test that was already inEntriesStoreTest.tests/Git/GitTest.phpandtests/Git/GitProcessTest.phpfiltered to parse, copy, untracked, ref, and stache diff cases: 15 passed, 45 assertions.mago lint -son the changed PHP files: no issues.