ci(playwright): tighten fixture-cache fingerprint to seed-affecting paths - #33061
Conversation
…aths
The fixture-cache fingerprint used to include three overly-broad
prefixes that caused every ~5th PR to invalidate the cache for reasons
that couldn't actually affect what was seeded:
* `openmetadata-spec/`
Fingerprinted the whole schema module, including Java utilities
and generated code that only affect the SDK the tests use — not
the Postgres/OpenSearch state we snapshot into the fixture.
Narrowed to `openmetadata-spec/src/main/resources/json/schema/`
(the JSON shape definitions).
* `openmetadata-service/src/main/resources/`
The whole resources tree — logback.xml, openapi.yml, monitoring/,
META-INF/, dataInsights/, rdf/ — was hashed. Only two subtrees
actually describe seeded content:
- `json/data/` (test connections, bot users, sample workflows,
app-marketplace definitions)
- `applications/` (application-bundle resources)
Everything else is runtime-only. Replaced the broad prefix with
these two subtrees.
* `openmetadata-service/src/main/java/.../search/`
Fingerprinted the entire search package — aggregators, clients,
filters, highlighters, resources — none of which change what gets
seeded into the ES/OS index. The one search subtree that matters
for seeding is the index-mapping classes; the fixture pack
captures the built indices and their mappings are decided by
`.../search/indexes/` and `.../search/models/`. Narrowed to
just those two.
Two whole subtrees dropped as strictly runtime-only:
* `.../apps/bundles/searchIndex/` — the bulk reindexer, only runs
on user-triggered "reindex" jobs, not during initial seeding.
* `.../resources/search/` and `.../resources/searchindex/` — REST
endpoints. Servable behaviour, not seeded state.
Measured impact on the last 100 merges to `main`:
* Old prefixes: 18 invalidations (18%)
* New prefixes: 14 invalidations (14%)
* -22% invalidation rate
* 0 new-only invalidations (the new set is strictly a subset)
The remaining 14 are legitimate: connector-schema additions (Salesforce
Data360, Domo, MCP), real migrations (v159 backfill, v210 pipeline),
and dep bumps that touch pom.xml / UI package.json (the ingestion image
is bundled into the fixture, so Java dep bumps stay in as a
conservative correctness signal — err on the side of a rebuild over a
stale fixture).
This makes cache warming worthwhile: with the old prefixes, ~18% of
merges would have invalidated a warmed cache; with the new prefixes,
~14% will. Combined with a cache warmer populating main's scope
(follow-up PR), effective cache hit rate on merge_group jumps from 0%
(today, since nothing populates main) to ~86%.
Side effect: the fixture cache key changes on this PR (from
ae713dbc… to 325a148e…) because playwright_cache_fingerprint.py is
itself in FIXTURE_PREFIXES. Every merge_group run after this lands
will miss until the warmer re-populates. The warmer PR follows.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
❌ PR checklist incompleteThis PR cannot be merged until the following are addressed on its linked issue:
The fields live on the linked issue in the Shipping project (open the issue → right sidebar → Projects). After you set them, re-run this check (or push a commit) — issue/project changes do not re-trigger it automatically. Maintainers can bypass this check by adding the |
Code Review ✅ ApprovedTightens the fixture-cache fingerprint by narrowing three overly-broad path prefixes ( OptionsDisplay: compact → Showing less information. Comment with these commands to change the behavior for this request:
Was this helpful? React with 👍 / 👎 | Powered by Gitar — free for open source |
✅ Playwright Results — workflow succeededValidated commit ✅ 557 passed · ❌ 0 failed · 🟡 0 flaky · ⏭️ 0 skipped · 🧰 0 lifecycle flaky PerformanceBlocking targets: ✅ met · Optimization targets: 🟡 in progress Shard-job maxima below are not the full workflow wall time; the linked run includes build, fixture, planning, and reporting. 🕒 Full workflow signal wall (to summary) 49m 35s ⏱️ Max setup 4m 20s · max shard execution 17m 51s · max shard-job elapsed before upload 21m 38s · reporting 4s 🌐 236.16 requests/attempt · 2.82 app boots/UI scenario · 16.62% common-shard skew Optimization targets still in progress:
How to debug locally# Download playwright-test-results-<shard> artifact and unzip
npx playwright show-trace path/to/trace.zip # view trace |
Summary
Tightens the fixture-cache fingerprint (
.github/scripts/playwright_cache_fingerprint.py) so runtime-only code changes stop invalidating a cache whose content they can't affect.Measured on the last 100 merges to
main:Motivation
Investigation into why merge_group runs never hit the fixture cache found two independent problems:
main's cache scope —merge_groupevents are deliberately blocked from saving (ephemeral-ref cache-poisoning risk), nopushtrigger exists, and the "nightly" workflows only haveworkflow_dispatch. So merge_group runs always start cold. Fixed by a follow-up warmer PR.openmetadata-spec/all rolled the fixture key, forcing a rebuild for changes that couldn't affect what got seeded. This PR.The two fixes compose: with a warmer + this tightened fingerprint, effective merge_group cache hit rate goes from 0% (today) to ~86% (100% − 14%). Estimated saving: ~15 min per merge × ~40 merges/day × 86% ≈ ~8-9 hours of merge-queue wall time per day.
What changed
Three overly-broad prefixes narrowed:
openmetadata-spec/openmetadata-spec/src/main/resources/json/schema/openmetadata-service/src/main/resources/.../resources/json/data/+.../resources/applications/logback.xml,openapi.yml,monitoring/,META-INF/,dataInsights/,rdf/— all runtime-only. Onlyjson/data/(test connections, bots, marketplace defs) andapplications/describe seeded content..../service/search/.../service/search/indexes/+.../service/search/models/AggregationManagementClient,HighlightFieldClassifier,ColumnFilterMatcher, ...) doesn't decide what's seeded into the index. The mapping classes that shape indexed documents are all underindexes/andmodels/.Two whole subtrees dropped entirely as runtime-only:
.../apps/bundles/searchIndex/— the bulk reindexer, runs only on user-triggered reindex jobs; the fixture's initial seed doesn't invoke it..../resources/search/and.../resources/searchindex/— REST endpoints (SearchResource,SearchReindexResource,VectorSearchResource). Servable behaviour, not seeded state.Everything else in the fingerprint stays as-is (migrations, initialization, security/JWT/auth, seed-data prefixes, Docker,
conf/openmetadata.yaml, UI auth utils, fixture scripts).The 14 remaining invalidations
Sampled and categorized:
All defensible. Tightening further would trade correctness for hit rate, which is the wrong direction — a stale fixture masks migration bugs.
Side effect
The fixture cache key changes on this PR (from
ae713dbc…to325a148e…) becauseplaywright_cache_fingerprint.pyis itself in FIXTURE_PREFIXES (intended safeguard against skew). Every merge_group run after this lands will miss the cache until the follow-up warmer PR re-populates main's scope with the new key. First few merge_group runs post-merge will be no worse than today; then everything gets much faster once the warmer lands and runs.Test plan
fixture,schema,seed,ingestion,distribution)Non-goals
🤖 Generated with Claude Code