CLI command
changelog
A product's changelog: the https address of its Keep a Changelog file, read on request into one entry per released version, each entry drafted into release notes with publishing and announcing held for approval.
Invocation#
echo-cli changelog set --product <id> --url <https-url> --by <name>
echo-cli changelog sync --product <id>
echo-cli changelog entries --product <id>
echo-cli changelog draft --entry <entry-id> --by <name>
echo-cli changelog drafts --product <id>Inputs and output#
set writes the source: product_id, source_url, set_by and set_at. sync writes source_url, read (how many released versions the file holds) and added (the entries not read before, each with id, product_id, version, released_on, body and read_at). entries writes source (or null) and entries, newest read first. draft writes draft (id, entry_id, post_id, post_request_id, announcement_request_id, route, drafted_by, drafted_at) and post, the draft blog post with its surface_slug, slug, title, description, body_markdown, reading_minutes and keywords. drafts writes a product's drafts, newest first.
State effect#
Every verb calls Echo Web's authenticated /api/analytics/changelog, /api/analytics/changelog/sync or /api/analytics/changelog/drafts with ECHO_INTERNAL_BEARER at ECHO_WEB_BASE_URL; the Release announcements section of the tracking screen calls the same operations, Echo Desktop's Changelog section on the GEO screen sets the source, syncs it and lists the entries, and echo-mcp reads the source and entries (echo_changelog_entries) and the drafts (echo_release_drafts). sync fetches the source now and reads every "## [version] - date" heading as one release (the brackets and the date may be absent), its body the text up to the next heading; the Unreleased section is never a release, and an entry already read keeps its first reading, so editing a released section later changes nothing stored. Setting the source again replaces the address and keeps the entries. draft asks the model route in Echo Web's ECHO_RELEASE_DRAFT_ROUTE, through Brama, for release notes that use only the entry's text and name its version in the title and the body; notes that do not are the error and nothing is written. The notes become a draft post, slug release-<version>, in the one blog surface linked to the product (echo-cli glossary surface links it), and two requests wait in the approval queue (see approvals): publish_blog_post for that post and publish_announcement for the entry. Nothing is published or emailed until a reviewer approves each. An entry is drafted once. Echo Web also syncs every product's source by itself every three hours (/api/cron/changelog-sync) and drafts, as "scheduled changelog sync", each entry that reading adds; the first reading of a source only stores its entries, so setting a source does not draft its history, and a product whose reading or drafting fails is answered with why without stopping the others.
Refusals#
- A wrong invocation is refused before anything is sent: "changelog takes <every usage, separated by semicolons>; got <word>", "changelog <verb> does not take <flag>; it takes …", "<flag> needs a value" and "changelog <verb> needs <flag>" for each flag the verb needs.
- Echo Web answers a bad request with "product_id is required: …", "source_url must be the https address of the product's Keep a Changelog file; got <value>", "set_by is required: an internal caller has no signed-in user, so it names who is acting" (and drafted_by), "entry_id is required: …", "product <name> has <n> blog surfaces linked (<slugs>), so which blog its release notes belong in is not one answer; link only one" or "the changelog at <url> holds no release heading (\"## [version] - date\"); it is not a Keep a Changelog file"; not found with "no product has id <id>; echo-cli products lists the ones that exist", "product <id> has no changelog source; echo-cli changelog set --product <id> --url <https-url> sets one", "no changelog entry has id <id>; echo-cli changelog entries --product <id> lists them" or "product <name> has no blog surface linked to it, so its release notes have no blog to be drafted in; echo-cli glossary surface --surface <slug> --product <id> links one"; a conflict with "changelog entry <id> was already drafted at <time>, as post <post id>". A source that cannot be fetched, or answers other than success, fails with "the changelog at <url> could not be read: <cause>"; drafting on a deployment without ECHO_RELEASE_DRAFT_ROUTE is refused naming that setting, and a route whose notes miss a field or the version fails naming the route and what it gave.