Skip to content

v1.6.57 - #240

Merged
roncodes merged 2 commits into
mainfrom
dev-v1.6.57
Aug 17, 2026
Merged

v1.6.57#240
roncodes merged 2 commits into
mainfrom
dev-v1.6.57

Conversation

@roncodes

Copy link
Copy Markdown
Member

Ready for immediate release: version bumped, RELEASE.md written, so merging this tags v1.6.57 and 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.' . $key using the key exactly as the caller passed itconfigureSystem('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:

writes/reads:  system_settings.platform_api.token_hash
event forgot:  system_settings.system.platform_api.token_hash   ← nothing ever writes this

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 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 redis it passes, which is why it never reproduced locally.

Also fixed

clearCacheByPattern() resolved a Redis connection unguarded, and the saved event calls through it — so on an install with no Redis configured, an ordinary Setting::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 on main.

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

roncodes and others added 2 commits August 17, 2026 14:40
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

codecov Bot commented Aug 17, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (b85c27f) to head (f067bf8).

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     
Flag Coverage Δ
backend 100.00% <100.00%> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@roncodes
roncodes merged commit 0408548 into main Aug 17, 2026
10 checks passed
@roncodes
roncodes deleted the dev-v1.6.57 branch August 17, 2026 07:08
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