Skip to content

No CLI to unpublish a changelog note from a shipped bundle #4072

Open

Description

@lcawl

What happened?

Authors can publish a changelog note (changelog note + changelog upload --artifact-type changelog) and, if the release bundle already shipped, the scrubber adds it to {parent}.amend-notes.yaml so it appears in published docs.

There is no docs-builder command that reverses that. changelog remove only deletes local YAML and does not change published bundles or the CDN pool. changelog upload only writes objects (PutObject). changelog bundle-amend --remove writes a numbered sidecar, but if the note YAML is still in the pool the scrubber can treat it as a late note and put it back in .amend-notes.

Authors are not assumed to have S3 console access. Expected: an author who can upload can also take a note off a shipped release without hand-deleting bucket objects.

How can we reproduce it?

  1. Create and upload a note-*.yml after the product version’s bundle is already on the CDN (changelog note, then changelog upload --artifact-type changelog). Confirm the scrubber wrote {parent}.amend-notes.yaml and the note renders.
  2. Run changelog remove on the local file (and/or changelog bundle-amend --remove + upload amend-N).
  3. Observe: the pool object is still published; a later scrubber reconcile can restore the note via .amend-notes. There is no changelog subcommand whose documented effect is deleting changelog/{org}/{repo}/{branch}/{file} from the private bucket so the Lambda can drop the public copy.

Version or commit

1.56.0+1da7c32f8561d7cbc1fc5ff1aa2dd52ebb34bb9c

Activity

  1. lcawl commented on Sep 11, 2026

    @lcawl
    ContributorAuthor

    Here's some additional AI analysis of the gap and possible solutions...

    Current gap

    • changelog upload writes changelog/{org}/{repo}/{branch}/{file} to the private bucket (PutObject / ETag skip). Same AWS credential chain authors already use in CI (OIDC) or locally.
    • changelog remove deletes local files only ([CommandIntent(Destructive | RequiresConfirmation)], [MutationScope(Directory)]). Docs already say this does not change bundles.
    • The scrubber copies private → public on ObjectCreated and deletes the public copy on ObjectRemoved. .amend-notes and notes-{version}.json are rebuilt from remaining pool notes. There is no CLI that emits that delete.
    • bundle-amend --remove only writes a numbered sidecar. If the pool object still exists, NoteAmendReconciler can treat the note as late and put it back in .amend-notes.

    Any author-facing unpublish path should delete (or tombstone) the private object and let the Lambda update public state. Authors should use the same auth story as upload, not the AWS console.

    Option A — New changelog unpublish

    New subcommand that mirrors upload keying: --artifact-type changelog (and optionally bundle / amend), --target s3, --s3-bucket-name, --owner / --repo / --branch, explicit --files (or positional paths). DeleteObject on the private key. --dry-run. Tag [CommandIntent(Destructive | RequiresConfirmation)], [MutationScope(Global)], [RequiresAuth] if that is how other remote mutators are marked.

    • Pros: Clear verb; hard to confuse with local remove or with upload; can refuse .amend-notes and notes-*.json.
    • Cons: Third command in the publish/unpublish story; must regenerate docs/cli-schema.json; IAM docs need s3:DeleteObject on changelog/* (and bundle/* if bundles are in scope).

    Option B — changelog upload --delete (or --unpublish)

    Same service and flags as upload; flag switches Put to Delete for the discovered files (or a --files list).

    • Pros: One place for remote I/O and key layout; small surface.
    • Cons: upload meaning “delete” is easy to misuse; skip-ETag / incremental-put logic does not map cleanly to delete; confirmation must be very loud.

    Option C — Extend changelog remove with --remote

    Keep default = local disk. --remote (plus the same S3 flags as upload) also DeleteObject for each matched file’s pool key. --dry-run already exists.

    • Pros: Authors already think “remove this changelog”; one filter language (--files, products, profiles).
    • Cons: Easy to assume historical remove unpublished (it never did); mixing directory mutation and global S3 mutation in one command; MutationScope is currently Directory.

    Option D — CI / docs-actions on file deletion

    No new interactive CLI. Deleting note-*.yml in git and merging triggers the existing upload OIDC role to delete the corresponding private key (or a dedicated workflow).

    • Pros: Authors never handle AWS locally; matches “repo is source of truth.”
    • Cons: Slow; easy to miss if the file was never committed; does not help one-off CDN-only notes; workflow must not delete unrelated pool objects.

    Option E — Upload directory as exact remote mirror

    changelog upload deletes remote keys under the authoring prefix that are not in the local folder.

    • Pros: Unpublish falls out of “sync.”
    • Cons: Accidental empty/wrong --directory wipes the pool. Unacceptable as a default; only list as a rejected or heavily gated design (--prune + confirmation + prefix allowlist).

    Option F — Change the Lambda so --remove is enough (no pool delete)

    Teach NoteAmendReconciler to treat numbered exclude-entries as intentional removal: do not classify those leaves as late, do not put them in .amend-notes.

    • Pros: Parent-embedded notes can be taken off published docs with commands authors already have (bundle-amend --remove + upload amend-N). No new S3 delete permission.
    • Cons: The YAML remains in the pool, so a future changelog bundle / CDN note auto-merge can pull it back in. Late notes that never entered the parent still need either a numbered exclude the reconciler honors and a stable checksum/name match, or a real unpublish. Does not replace pool delete for “this file should not exist.”

    Option G — Tombstone / withdrawn note

    Authors upload a marker (flag on the note YAML, or a sidecar) the notes reconciler interprets as “drop from indexes and .amend-notes.” No DeleteObject.

    • Pros: Same Put-only IAM as today.
    • Cons: New schema; pool still stores content; must define who may remove a tombstone; easy to get wrong vs real delete.

    Option H — Docs-only / wait

    Document the gap (the companion docs plan) and leave unpublish to operators who already run upload CI.

    • Pros: No destructive CLI risk.
    • Cons: Authors still cannot finish “remove this known issue from 9.3.0” without an unpublished process.

    Shared constraints (any implementable option except H)

    • Delete or tombstone private objects only; never instruct clients to write public .amend-notes or notes-*.json.
    • --dry-run and confirmation for any remote delete.
    • Refuse Lambda-owned names (.amend-notes, notes-*.json).
    • Tests in tests/Elastic.Changelog.Tests/ (upload/unpublish + reconciler if option F).
    • After CLI changes: dotnet run --project src/tooling/docs-builder -- __schema > docs/cli-schema.json and CLI markdown.
    • Elastic upload IAM must allow s3:DeleteObject if the path uses delete (A–E). That is a docs-infra / OIDC role change, not only this repo.
  2. lcawl commented on Sep 16, 2026

    @lcawl
    ContributorAuthor

    NOTE: There is some overlap with #4122 but per AI analysis, after that PR is merged, authors still have no CLI to delete the private object. The review comments addressed in #4122 only stop the Lambda from leaving a published sidecar/registry when that object is gone.

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions