Skip to content

Use singular S3 key prefixes for changelog/bundle artifacts#3434

Merged
cotti merged 1 commit into
mainfrom
changelog/singular-bucket-prefix
Jun 1, 2026
Merged

Use singular S3 key prefixes for changelog/bundle artifacts#3434
cotti merged 1 commit into
mainfrom
changelog/singular-bucket-prefix

Conversation

@cotti

@cotti cotti commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

Why

The changelog automation uploads artifacts to S3 under plural folder prefixes ({product}/changelogs/ and {product}/bundles/), but everywhere else in the codebase these entities are singular (ArtifactType.Changelog, ArtifactType.Bundle). This inconsistency is a small mishap worth correcting now, before any consumer reads the published layout from the CDN.

What

Artifacts now upload under {product}/changelog/ and {product}/bundle/, and the scrubber Lambda detects bundles via the /bundle/ path segment. Upload-target and incremental-uploader tests were updated to assert the new keys.

This changes where new objects are written in the elastic-docs-v3-changelog-bundles[-private] buckets. There is no consumer of these prefixes yet, so the only follow-up is housekeeping: optionally migrate/relabel any objects already written under the old plural prefixes (or let them age out). The S3 bucket names and the local :::{changelog} directive folder convention (changelog/bundles/ in a docset) are unchanged.

Companion docs-only PRs update the matching references in docs-infra and docs-actions.

Made with Cursor

Align the S3 object key prefixes with the singular entity naming used
throughout the codebase (ArtifactType.Changelog / ArtifactType.Bundle).

Uploads now land under {product}/changelog/ and {product}/bundle/
instead of the plural {product}/changelogs/ and {product}/bundles/,
and the scrubber Lambda detects bundles via the /bundle/ path segment.

Co-authored-by: Cursor <cursoragent@cursor.com>
@cotti cotti requested a review from a team as a code owner June 1, 2026 13:06
@cotti cotti requested a review from reakaleek June 1, 2026 13:06
@cotti cotti added the bug label Jun 1, 2026
@cotti cotti temporarily deployed to integration-tests June 1, 2026 13:06 — with GitHub Actions Inactive
@coderabbitai

coderabbitai Bot commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: e9717acc-17fe-45f8-b973-e2194aa47e2a

📥 Commits

Reviewing files that changed from the base of the PR and between 4856b14 and 089e3ab.

📒 Files selected for processing (6)
  • src/infra/docs-lambda-changelog-scrubber/Program.cs
  • src/infra/docs-lambda-changelog-scrubber/README.md
  • src/services/Elastic.Changelog/Uploading/ChangelogUploadService.cs
  • tests/Elastic.Changelog.Tests/Changelogs/LinkAllowlistSanitizerTests.cs
  • tests/Elastic.Changelog.Tests/Uploading/ChangelogUploadServiceTests.cs
  • tests/Elastic.Documentation.Integrations.Tests/S3/S3IncrementalUploaderTests.cs

📝 Walkthrough

Walkthrough

This PR renames S3 object key paths for changelog and bundle uploads from plural to singular directory conventions. The ChangelogUploadService now constructs paths using {product}/changelog/ and {product}/bundle/ instead of {product}/changelogs/ and {product}/bundles/. The Lambda scrubber is updated to recognize the new "/bundle/" pattern for routing, with corresponding README documentation updates. Test assertions across unit and integration test suites are updated to verify the new path formats.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and concisely describes the main change: switching S3 key prefixes from plural to singular forms for changelog and bundle artifacts.
Description check ✅ Passed The description clearly explains why the change is needed, what is being changed, and the scope of impact, all directly related to the changeset.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch changelog/singular-bucket-prefix

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@cotti cotti self-assigned this Jun 1, 2026
@cotti cotti merged commit 8d81400 into main Jun 1, 2026
26 checks passed
@cotti cotti deleted the changelog/singular-bucket-prefix branch June 1, 2026 14:51
cotti added a commit that referenced this pull request Jun 1, 2026
Follows #3434, which moved bundle/changelog artifacts from {product}/bundles/
and {product}/changelogs/ to the singular {product}/bundle/ and
{product}/changelog/. The CDN consumer fetched bundles from the old plural
path, so it would 404 against the new layout; this points it at
{product}/bundle/{file} and updates the registry docs/comments/tests to match.
The directive's local-folder convention (changelog/bundles/) is unchanged.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
cotti added a commit that referenced this pull request Jun 19, 2026
)

* changelog: publish per-product registry-index for bundle uploads

Bundle uploads now refresh a per-product registry-index.json so consumers
(the upcoming changelog directive cdn: mode) can enumerate bundles without
an S3 listing. The builder does a read-merge-conditional-PUT
(If-Match/If-None-Match) with bounded retries to stay safe under concurrent
uploads, writes the manifest to the private bucket, and relies on the
scrubber's existing pass-through to mirror it to the public CDN bucket.
Refresh failures are non-fatal: bundle objects are unaffected.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Cursor <cursoragent@cursor.com>

* changelog: add CDN consumer mode to the {changelog} directive

Lets the {changelog} directive load bundles published to the public
S3/CloudFront bucket via :cdn:, with optional :version: filtering, so a
docset can render another product's changelog without the bundle files
living in-repo. Also renames the per-product manifest from
registry-index.json to registry.json, reserving "registry-index" for a
possible future bucket-wide meta-registry.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Cursor <cursoragent@cursor.com>

* changelog: align CDN registry paths with singular S3 key prefixes

Follows #3434, which moved bundle/changelog artifacts from {product}/bundles/
and {product}/changelogs/ to the singular {product}/bundle/ and
{product}/changelog/. The CDN consumer fetched bundles from the old plural
path, so it would 404 against the new layout; this points it at
{product}/bundle/{file} and updates the registry docs/comments/tests to match.
The directive's local-folder convention (changelog/bundles/) is unchanged.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Cursor <cursoragent@cursor.com>

* test: update development TOC count for new changelog registry doc

PhysicalDocsetNavigationIncludesNestedTocs snapshots the real docs/development
TOC. Adding changelog-bundle-registry.md introduced a fourth nav item (a file
leaf), so the expected counts are bumped from 3 to 4 (and file leaves 0 to 1).

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Cursor <cursoragent@cursor.com>

* changelog: address PR review feedback for CDN consumer mode

Review fixes:
- CdnChangelogFetcher only memoizes a clean, non-empty fetch so a transient
  CDN/replication failure no longer pins an empty/partial result for the
  process lifetime.
- RegistryBuilder narrows the existing-manifest catch to JsonException, so a
  transient S3/IO read error bubbles to the best-effort refresh handler instead
  of letting an If-Match PUT overwrite a valid manifest with partial data.
- Scrubber README clarifies only registry manifests (RegistryKey.IsRegistry)
  pass through; other .json keys are skipped.
- CDN render test primes the fetcher cache against the default base instead of
  mutating the process-wide DOCS_BUILDER_CHANGELOG_CDN env var.

Feature:
-: cdn: product is now optional and inferred from the repository name when
  omitted (common 1:1 repo/product case); multi-product repos still specify it
  explicitly, and a clear error is emitted when it cannot be inferred.
Co-authored-by: Cursor <cursoragent@cursor.com>

* test: simplify Paths reference to satisfy lint (IDE0002)

Import Elastic.Documentation.Configuration and use the unqualified Paths
reference in the CDN inference test instead of the fully-qualified name.

Co-authored-by: Cursor <cursoragent@cursor.com>

* changelog: address review feedback on CDN registry PR

- Validate :cdn: product before assigning CdnProduct so invalid names are
  never stored on the block (and update the test accordingly).
- Make BundleLoader.MergeBundlesByTarget static and drop the throwaway
  BundleLoader the CDN path constructed just to satisfy the signature.
- Use a process-shared static HttpClient (SocketsHttpHandler with
  PooledConnectionLifetime + a fetch timeout) in CdnChangelogFetcher to stop
  leaking a socket handle per directive; keep a per-instance client for
  injected test handlers and make the fetcher IDisposable.
- Sort registry.json by VersionOrDate (not Ordinal) so the on-disk manifest
  is genuinely newest-first for mixed-width semvers; add a regression test.
- Document the Cancel.None constraint, the single-PUT retry capture, and the
  cache-priming base URL.

Co-authored-by: Cursor <cursoragent@cursor.com>

* docs: clarify :cdn: product is a products.yml id and use a public-repo example

Address review feedback on the {changelog} :cdn: option docs:
- State that the product value is a product id defined in products.yml,
  not just any [a-zA-Z0-9_-]+ string.
- Replace the multi-product `cloud` inference example with the public
  `cloud-serverless`-published-from-`docs-content` example.

Co-authored-by: Cursor <cursoragent@cursor.com>

* changelog: declare CDN release_notes in docset.yml and prefetch at startup

Replace the directive's dynamic, per-page CDN fetching with a declarative model
that mirrors cross_links: products are listed under `release_notes` in docset.yml,
validated against products.yml, and prefetched once at build startup.

- Add product-keyed `release_notes` schema + validation in ConfigurationFile
- Refactor CdnChangelogFetcher into a stateless async fetch engine
- Add FetchedReleaseNotes, IReleaseNotesResolver/Noop, and ReleaseNotesFetcher
  (strict fail-fast: a declared product's registry failure fails the build)
- Thread IReleaseNotesResolver through DocumentationSet/ParserContext and all
  build entry points (isolated, serve, codex, assembler) with a Noop default
- Rework `{changelog}` `:cdn:` into a selector over the prefetched set; infer the
  product from the repository via products.yml (canonical id, not repo name)
- Add ChangelogCdn base-URL helper; update docs and tests

Co-authored-by: Cursor <cursoragent@cursor.com>

* changelog: ConfigureAwait(false) on assembler release-notes fetch

Addresses CodeRabbit review feedback: the FetchAsync call into the
ReleaseNotesFetcher library should not capture the synchronization context,
matching the repo's async guideline and the fetcher's own internals.

Co-authored-by: Cursor <cursoragent@cursor.com>

* changelog: address review — trim private-method docs, typed git availability, version-filter test

- Shorten/remove verbose XML summaries on private methods (FilterByVersion,
  InferCdnProductFromRepository, IsSafeBundleFileName, ResolveInlineEntries,
  RegistryBuilder helpers) to a single line or none.
- Add GitCheckoutInformation.IsAvailable so product inference no longer matches
  the raw "unavailable" sentinel string.
- Document the match-all-on-empty semantic in ChangelogVersionMatch.Matches.
- Add a combined :cdn: + :version: directive test covering CDN-mode filtering.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
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