v1.6.57 - #240
Merged
Merged
Conversation
Writing a system setting did not clear the cache entry Setting::system() reads, so
the old value kept being served until the cache was cleared by hand.
system() caches under 'system_settings.' . $key using the key EXACTLY as the caller
passed it — configureSystem('platform_api.token_hash') reads back
'system_settings.platform_api.token_hash'. The row, though, is stored as
'system.platform_api.token_hash', and the saved/deleted events built the cache key
from the row: 'system_settings.system.platform_api.token_hash', which nothing ever
writes. Both spellings are now forgotten.
clearSystemCache() looked like it covered the gap, but it pattern-clears through
Redis and api/.env.example ships CACHE_DRIVER=file — so on a default install neither
path invalidated anything.
How it showed up: the API contract run's minted platform token was rejected with
"Invalid platform API token." The seed rotated the token and wrote the new hash, and
every request kept validating against the previously cached one. Reproduced by forcing
the file driver on a live stack; with redis it passes, which is why local testing
never caught it.
Also: clearCacheByPattern() resolved a Redis connection unguarded, and the saved event
calls through it — so on an install with no Redis configured, an ordinary
configureSystem() write raised a binding exception. Pattern clearing is inherently
Redis-only; without Redis there is nothing to enumerate, so it skips rather than fails.
The regression test asserts the behaviour, not the implementation: write, read, write
again, read again. Verified it fails against the old event handler and passes with the
fix. Full suite: 1418 passed, 0 failures.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
PHP CI was red on the coverage gate, not the tests: Setting.php came in at 104/105 against an enforced 100%, and the uncovered line was the `!is_string($key) || $key === ''` early return I had added. It is unreachable. forgetCachedSetting() is only ever called from the saved and deleted events with $setting->key, which is always a non-empty string on a persisted row — so the branch could not be exercised without contriving a row that cannot exist. Cast instead: forgetting 'system_settings.' costs nothing on the off chance, and there is no longer a branch that no test can honestly reach. Verified with the repo's own gate rather than by eye: Setting.php 104/104, Utils.php 909/909, `php scripts/coverage-summary.php` exits 0 with every enforced metric at 100%, full suite green. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #240 +/- ##
===========================================
Coverage 100.00% 100.00%
- Complexity 6727 6730 +3
===========================================
Files 397 397
Lines 22442 22447 +5
===========================================
+ Hits 22442 22447 +5
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
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.
Ready for immediate release: version bumped,
RELEASE.mdwritten, so merging this tagsv1.6.57and publishes automatically.The bug
Writing a system setting did not clear the cache entry
Setting::system()reads, so the old value kept being served until the cache was cleared by hand.system()caches under'system_settings.' . $keyusing the key exactly as the caller passed it —configureSystem('platform_api.token_hash')reads backsystem_settings.platform_api.token_hash. The row, though, is stored assystem.platform_api.token_hash, and thesaved/deletedevents built the cache key from the row:clearSystemCache()looked like it covered the gap, but it pattern-clears through Redis andapi/.env.exampleshipsCACHE_DRIVER=file— so on a default install neither path invalidated anything.How it surfaced
The API contract run's minted platform token was rejected with
{"errors":["Invalid platform API token."]}. The seed rotated the token and wrote the new hash; every request kept validating against the previously cached one. It is the only failing assertion in fleetops#295's otherwise-clean run, and nothing in that PR caused it.I reproduced it by forcing the file driver on a live stack — with
redisit passes, which is why it never reproduced locally.Also fixed
clearCacheByPattern()resolved a Redis connection unguarded, and thesavedevent calls through it — so on an install with no Redis configured, an ordinarySetting::configureSystem()write raised a binding exception. Pattern clearing is inherently Redis-only; without Redis there is nothing to enumerate, so it now skips rather than fails.Verification
The regression test asserts behaviour, not implementation — write, read, write again, read again. I checked it fails against the old event handler and passes with the fix, so it is a real guard rather than a passing test.
Full suite: 1418 passed, 0 failures. That includes
SettingControllerExternalProbesTest, the Sentry DSN test that was red onmain.Known limitation, stated rather than hidden
Utils::clearCacheByPattern()still only clears entries on Redis. That no longer matters for settings, which now invalidate their own keys directly, but a caller relying on pattern clearing for something else will not see it work on another driver.🤖 Generated with Claude Code