Skip to content

Fix redirects not written or deployed for isolated builds - #3746

Open
cotti wants to merge 3 commits into
mainfrom
worktree-fix-isolated-build-redirects
Open

Fix redirects not written or deployed for isolated builds#3746
cotti wants to merge 3 commits into
mainfrom
worktree-fix-isolated-build-redirects

Conversation

@cotti

@cotti cotti commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Why

Redirects defined in _redirects.yml for docs-builder's own docs (and any other isolated/per-docset build) were silently discarded. IsolatedBuildService.Build called GenerateAll with the discard operator (_ = await), so the GenerationResult.Redirects map was thrown away and redirects.json was never written to disk. And even if it had been written, no workflow step ever pushed it to the redirect store the preview environment already serves from.

What

  • IsolatedBuildService.Build: captures the GenerateAll result and writes redirects.json to the output directory, resolving each redirect's relative file paths to absolute URL paths using the configured --path-prefix
  • assembler deploy update-redirects: gains a --no-delete flag that skips the KVS reconciliation delete pass — only PUTs the new entries. This is required for per-docset deploys, which only know about their own redirects and must not wipe other repos' entries from a shared KVS
  • docs-preview-local.yml: adds a "Deploy redirects to CloudFront KVS" step after the S3 upload, running on pushes to main only, that invokes assembler deploy update-redirects --no-delete preview

How

The URL resolution in IsolatedBuildService.ToAbsoluteUrl mirrors FileNavigationLeaf.DetermineUrl: strips .md, strips trailing /index, and treats a bare index path as the path-prefix root. Cross-repo redirects (containing ://) are skipped since the isolated build has no cross-link resolver to follow them.

Known limitation: with --no-delete there is no reconciliation, so redirects removed from _redirects.yml will linger in the KVS. A scoped reconciliation (deleting only keys under this docset's path prefix) is a reasonable follow-up.

Isolated builds (e.g. docs-builder's own docs) were discarding the
GenerationResult from GenerateAll with `_ = await`, so redirects.json
was never produced and redirects defined in _redirects.yml had no effect.

- Capture GenerateAll result in IsolatedBuildService.Build and write
  redirects.json with path-prefix-resolved absolute URLs
- Add --no-delete flag to `assembler deploy update-redirects` so
  per-docset deploys only PUT new entries without wiping other repos'
  KVS redirects
- Add Deploy redirects step in docs-preview-local.yml to push
  docs-builder's redirects.json to the CloudFront KVS on push to main

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
@reakaleek

Copy link
Copy Markdown
Member

Do we have redirects in our preview environment?

The preview environment does not serve redirects from a CloudFront KVS,
so deploying redirects.json there has no effect. The build-side changes
(writing redirects.json, --no-delete flag) remain as groundwork for when
a deploy target exists.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
@cotti

cotti commented Aug 3, 2026

Copy link
Copy Markdown
Contributor Author

Good question — I went and checked the infra to be sure. The preview environment does already have the full redirect-serving setup:

  • The redirects key-value store for the preview environment exists (verified it's live), it's just empty — nothing has ever populated it.
  • The CloudFront function that does the KVS lookup and issues the 301s is already associated with the default cache behavior of the preview distribution.
  • The OIDC deployer role this repo's workflows assume already has write permission on that store.

So the only missing piece was exactly what this PR adds: producing redirects.json from the isolated build and pushing it. The key format also lines up — on push to main the build runs with the /​elastic/docs-builder/tree/main path prefix, which matches the URIs the CloudFront function looks up.

One known limitation worth flagging: since the deploy uses --no-delete (to avoid touching other repos' entries in the shared store), redirects removed from _redirects.yml will linger in the store. A scoped reconciliation — deleting only keys under this docset's path prefix — would be a reasonable follow-up.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants