Skip to content

Fix API incremental cache deployment metadata - #1976

Merged
David Pine (IEvangelist) merged 1 commit into
mainfrom
aspireagent/fix-incremental-api-deployment-metadata
Oct 29, 2026
Merged

David Pine (IEvangelist) merged 1 commit into
mainfrom
aspireagent/fix-incremental-api-deployment-metadata

Conversation

@davidfowl

@davidfowl David Fowler (davidfowl) commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Include deployment metadata in API reference cache keys, using the same commit and normalized repository URL as the shared page head. Preserve same-deployment cache reuse and the existing deployment guard.

The representative api-cross-language-navigation.spec.ts:46 failure (window.__apiNavigationLoaded: expected true, received undefined) is caused by mixed deployment identities, not an insufficient assertion timeout:

Both downloaded traces, including their first attempts and two internal retries, contain an API landing page with git-commit-id=b5b1becb58cb452a533b80d585d94510a99a467e and a restored Redis package page with git-commit-id=43e5933e8d41e6f0f0d84eb785943727eb946dff. The deployment guard correctly forces a document navigation and clears the in-memory marker. Both pages have the ClientRouter opt-in.

Bun resolves the build environment outside Astro's template dependency hash. The existing document-only key therefore permits stale head metadata to survive a warm incremental build. Adding the missing output dependency regenerates API pages when deployment metadata changes; it does not disable incremental reuse globally.

This is independent of #1961's updater/StrictMode repair. No updater, deployment-guard, browser assertion, workflow, timeout, retry, or coverage changes.

Third-party links and affiliations

None. Test-only example repository URLs are fixtures, not third-party links or affiliations.

Validation

  • bun run lint: passed, including skill-digest verification and zero-warning ESLint.
  • bun run test:unit: 82 files passed; 1,108 tests passed, one existing test skipped. Five new cache-key regression tests cover deployment changes, repository changes/normalization, unchanged-data reuse, owning-package paths, and shared head fallbacks.
  • Real-site Playwright, desktop Chromium, one worker: both existing targeted tests passed: “API landing searches and query filters survive language changes and history navigation” and “all six API search surfaces cancel pending input when leaving, including non-API destinations”.
  • Isolated two-page Astro 7.4.1 production fixture, Bun 1.4.3, actual deployment guard and ClientRouter: the byte-identical baseline cache helper restores old metadata after sequential identity A/B builds; 30/30 controlled navigations reproduce hard reloads.
  • Fixed helper, identical fixture/data: sequential identity A/B builds update both pages; repeating identity B restores the keyed page. All 30/30 navigations preserve the session and back history (five repetitions each across desktop/tablet/mobile, with native transitions and forced fallback).
  • Full production CI passed at head 7bd82d0985b1bed59b455b0235c4c2160cfcd3f2: all six browser shards, merged report, frontend gate, and required ci-gate are green. Browser logs show 1,390 first-attempt passes and 95 existing skips across 1,485 registered cases, with no failed attempts or internal retries. The original navigation assertion and related query/history test pass on desktop, tablet, and mobile. Existing same/changed/missing-deployment guard tests remain green.
  • Production Node 24.x lint/unit validation confirms 82 files passed, 1,108 tests passed, and one existing skip, including all five new cache-key regressions.
  • Production build: Astro reports 32,203 pages in 5m44s. It restored a compatible base cache, regenerated 24,059 logged API HTML routes, and retained 534 OG restores. This initial key-implementation change necessarily regenerates API HTML; it is not a steady-state overhead measurement. The exact-base cold build took 7m48s, but differing cache/runner state prevents a patch-only performance comparison.
  • Verified the actual production artifact's SHA-256 digest and four C#/TypeScript landing/Redis HTML samples: all share deployment/source-link commit 1a916aa5b5fd6cb8a02e5c75eedaead2d61a5263 and ClientRouter opt-in. The build intentionally uses the effective base/merge-base identity, not the PR head SHA.

Local browser/unit tooling used Node 26.12.1; production validation used CI's Node 24.x and pinned Bun 1.4.3. No full-site production build or full production browser matrix was run locally, per repository guidance; the production CI matrix above supplies that qualification. Controlled fixture repetitions and this single clean CI run are not a repository-wide flake-rate estimate. Authorized-human review is still required.

🤖 Posted by AspireAgent (AI Agent)

Include shared head deployment metadata in API cache keys so restored pages cannot trigger false deployment-mismatch reloads. Preserve same-deployment reuse and cover identity changes with regression tests.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@aspire-repo-bot

Copy link
Copy Markdown
Contributor

Frontend HTML artifact ready

The latest frontend build uploaded the frontend-dist artifact for PR #1976. Use the VS Code button below to open this PR with GitHub Artifacts Explorer and browse the built HTML locally.

VS Code: Open PR #1976 artifacts

This comment updates automatically when a new frontend build artifact is uploaded.

@davidfowl
David Fowler (davidfowl) marked this pull request as ready for review October 29, 2026 02:50
Copilot AI balanced review requested due to automatic review settings October 29, 2026 02:50

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

No active review issues were identified for the deployment-aware API cache changes.

No open issues 🎉

What changed in this PR

This PR prevents incremental API builds from reusing pages with stale deployment metadata. It shares deployment identity between the page head and API cache keys while preserving cache reuse when data and deployment metadata are unchanged.

Changes:

  • Centralize the deployment commit and normalized repository URL, and include both in API cache keys.
  • Add environment variable types and five regression tests covering cache reuse, invalidation, path keys, and metadata fallbacks.
  • Document the relationship between deployment identity, incremental caching, and navigation behavior.
File Description
src/​frontend/​tests/​unit/​api-cache-key.vitest.test.ts Adds five cache-key and metadata regression tests.
src/​frontend/​src/​utils/​deployment-metadata.ts Centralizes deployment identity and repository URL normalization.
src/​frontend/​src/​utils/​api-cache-key.ts Includes deployment metadata in document cache hashes.
src/​frontend/​src/​env.d.ts Declares deployment environment variable types.
src/​frontend/​src/​components/​starlight/​Head.astro Uses the shared deployment metadata.
CONTRIBUTING.md Documents incremental API cache identity requirements.

Review effort: Balanced

@IEvangelist
David Pine (IEvangelist) merged commit 4dc4dfe into main Oct 29, 2026
20 checks passed
@IEvangelist
David Pine (IEvangelist) deleted the aspireagent/fix-incremental-api-deployment-metadata branch October 29, 2026 12:53
David Pine (IEvangelist) pushed a commit that referenced this pull request Oct 29, 2026
## Summary

Fixes #1962.

Keep Pagefind search-result hit areas stable when hovered. Starlight
stretches each link's `::after` over its result row, but the site's
global link-hover brightness filter creates a new containing block on
the anchor. The overlay then shrinks to the title, losing hover over the
surrounding clickable padding and causing the cursor to oscillate.

Disable the filter only on hovered Pagefind result links. Existing row
hover/focus styling, ordinary-link effects, keyboard behavior, and
search coverage remain unchanged. This branch is independent of #1976
and does not change its deployment-cache repair.

## Third-party links and affiliations

None.

## Validation

- Before the fix, both light/dark desktop regressions fail
deterministically: hovered links compute `brightness(1.1)` /
`brightness(0.9)` rather than `none`. An earlier padding-hover
observation measured the stretched overlay shrinking from 550px to 84px.
- New browser regressions use representative Pagefind
title/nested-excerpt markup inside the actual site search dialog,
exercising the installed Starlight and site CSS without requiring a
production search index. They verify title and row-padding hover,
computed overlay dimensions, hit testing, pointer cursor, pointer
activation, and Enter activation.
- Final browser regression: **18/18 passed**, three planned repetitions
of both themes across desktop/tablet/mobile Chromium, no retries. The
final tests fail **2/2** against unchanged main CSS before the fix.
- Full repository lint passed; **44/44** related
search/presentation/recovery unit tests passed.
- Existing installed native Pagefind input-presentation tests also
passed all 18 planned theme/profile repetitions during the broader
development run. That run exposed six failures in an earlier version of
the new mobile fixture because it omitted Pagefind's form spacing; the
final fixture includes the form and scoped native wrapper, and the
complete 18-case affected-path repetition above passes.

Local validation uses pinned Bun 1.4.3 / Astro 7.4.1 and Chromium, with
Node 26.12.1 versus CI's Node 24.x. No full local production build was
performed. Test-local click interception observes activation without
navigating away or closing the fixture dialog.

**Production qualification:** [CI run 40824342803, attempt
1](https://github.com/microsoft/aspire.dev/actions/runs/40824342803)
succeeded for source `8e7e10b53e1308436e27c577c953a206e8a9c9a8` (tested
merge `e02360ff8dec31e8f0214966d365fe6d1619ccf7` into main
`1a916aa5b5fd6cb8a02e5c75eedaead2d61a5263`). All six Chromium shards
completed: **1,491 registered cases = 1,395 first-attempt passes + one
retry-recovered case + 95 existing skips**. There were 1,396 executed
cases and 1,397 attempts, with no terminal failures. All **51
site-search cases passed first attempt**, including six new
representative hover regressions and separate existing actual-index
search/navigation/history/keyboard checks. Full production lint/unit
validation passed: **1,103 passes, one existing skip, 81 files**. Build,
merged report, frontend gate and required `ci-gate` succeeded; the
observed rollup was **18 successful checks and one expected AppHost
scope skip**.

The one retry-recovered case was unrelated-path `mobile-ux.spec.ts:438`:
the `/i18n/` translation table did not scroll after ArrowRight on the
first attempt (`scrollLeft` remained 0); the existing internal retry
passed. Its pre-existence and root cause have not been established here,
and it is not demonstrated to be caused by this search-only patch. It is
not counted as a first-attempt pass. [Merged browser report
artifact](https://github.com/microsoft/aspire.dev/actions/runs/40824342803/artifacts/12877335560).

### Visual evidence: before and after

Captured from source `8e7e10b53e1308436e27c577c953a206e8a9c9a8`, desktop
Chromium at **1200 x 900**, using the same representative injected
Pagefind markup as the regression inside the actual Astro dev search
dialog. These are **not indexed production search results**. For
"before", only this PR's `filter: none` repair rule was removed from the
browser's CSSOM, restoring the base hover filter without changing other
styles; "after" uses the unmodified PR stylesheet.

The cyan dashed outline marks the **550px result row**; magenta outlines
the **real link `::after` target**, not a drawn replacement. The orange
dot marks the actual pointer position on the title. In both themes the
hovered target shrinks to **78 x 23px before**, leaving the row padding
outside it, versus **550 x 52px after**. Outlines, dot and legend are
diagnostic annotations only. These static screenshots show target
geometry; pointer movement, padding hit testing and keyboard activation
are established by the browser assertions above, not by the images.

**Light: before**

![Light theme before: actual hovered target shrinks to title, leaving
row padding outside the
target](https://github.com/user-attachments/assets/54a3bd12-193f-4c49-a134-362391cccc27)

**Light: after**

![Light theme after: actual hovered target spans the entire result
row](https://github.com/user-attachments/assets/73d18b24-c6cc-4291-b66e-92cc6f58d072)

**Dark: before**

![Dark theme before: actual hovered target shrinks to title, leaving row
padding outside the
target](https://github.com/user-attachments/assets/938ae2b8-3e2d-4528-983d-0163bd5ae8a7)

**Dark: after**

![Dark theme after: actual hovered target spans the entire result
row](https://github.com/user-attachments/assets/323c015f-2b6a-448a-bb63-aa4834d6ca61)

**🤖 Posted by AspireAgent (AI Agent)**

Co-authored-by: davidfowl <95136+davidfowl@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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.

3 participants