Skip to content

docs: document the changelog convention and the release process - #41

Merged
thdurante merged 2 commits into
mainfrom
thiago/document-changelog-and-release-convention
Aug 6, 2026
Merged

docs: document the changelog convention and the release process#41
thdurante merged 2 commits into
mainfrom
thiago/document-changelog-and-release-convention

Conversation

@thdurante

@thdurante thdurante commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Summary

Writes down two things that weren't documented anywhere:

  1. The changelog convention — every PR that changes observable behaviour adds its entry under ## [Unreleased], accumulating. Releasing then means renaming a heading, not reconstructing history from the commit log.
  2. The release process — manual and tag-driven. Merging to main publishes nothing.

CLAUDE.md only, +41 lines. AGENTS.md is a symlink to it, so agents get it too.

Why

The mechanism had to be reverse-engineered from tag objects and workflow config to answer "does merging bump a version?" — it doesn't. And the changelog convention was inconsistent across the only two releases that have one:

Release How the CHANGELOG landed
v0.20.0 via PR #34
v0.20.1 direct push to main

In both cases the whole section was authored at release time — between v0.20.0 and v0.20.1, cfb35ee is the only commit touching the file; feature PRs #35 and #37 never did. The accumulating convention removes that release-time archaeology.

Worth being clear about what this PR is: the convention is already in use on main, adopted ad hoc — #38 and #39 both added entries under ## [Unreleased]. This documents and ratifies that, rather than proposing something new. Which is also why it needs @facundofarias' sign-off: he has cut both prior releases the other way, and he is the one who will follow this runbook.

What it records

  • Releases are manual and tag-driven; release.yml fires on push: tags: ["v*"].
  • The version lives only in the git tag. GoReleaser injects it via -X main.version={{.Version}}; cmd/dhq/main.go defaults to dev. There is no version file to bump.
  • GoReleaser's changelog: block generates the GitHub release notes from commit subjects and never touches CHANGELOG.md. It filters docs:, chore:, test:, ci: — which is why both existing CHANGELOG commits, both docs:, appear in no release notes at all.
  • internal/version/update.go reads /releases/latest — the latest published release, not the tag. The sequence is tag → GoReleaser builds → release published → each CLI notices on its next invocation. Not instant, but not retractable either, so deploy dependent API changes before tagging.
  • skills/ is go:embed-ed, so a reference-doc correction ships to users and warrants a changelog entry — not obvious from the file layout.

Also adds the changelog step to the Adding-a-New-Resource checklist.

Review round

Both findings real, both fixed in b3e7a27; all three threads resolved.

Reviewer Finding Outcome
CodeRabbit (Major) + Codex (P2) The release steps never pushed main — following them literally publishes the tag while origin/main lacks the changelog commit Fixed — step 3 now does git push origin main, explicitly before the tag, with a note on why the order matters
CodeRabbit (Minor) "tagging immediately advertises the upgrade" overstated it Fixedupdate.go:14 reads /releases/latest, so it needs a published release and the CLI's next run

Both were defects in a runbook, which is the worst place for them: the doc exists to be followed literally. The push-main gap was documentation-only — cfb35ee is on main and v0.20.1 points at it, so the step has always happened in practice, it just was never written down.

Test plan

Documentation only — no code paths touched.

  • go build ./cmd/dhq/
  • Every factual claim verified against source rather than asserted:
Claim Verified against
Tag-triggered release .github/workflows/release.yml
Version injected via ldflags .goreleaser.yaml:22
Local builds report dev cmd/dhq/main.go:12
Release notes filter docs:/chore:/test:/ci: .goreleaser.yaml changelog block
Update checker polls releases API internal/version/update.go:14
Skills embedded in the binary skills/embed.go:15
Tags are annotated git cat-file -t v0.20.1tag

🤖 Generated with Claude Code

https://claude.ai/code/session_01Hibw5xsRNGDkYzr1hXsDQz

Summary by CodeRabbit

  • Documentation
    • Added guidance for documenting observable changes in the changelog.
    • Documented the manual release process, version information, release-note generation, and update-checking behavior.

Neither was written down. The release mechanism had to be reverse-engineered
from tag objects and workflow config to answer "does merging bump a version?"
(it does not), and the changelog convention was inconsistent across the only two
releases that have one: v0.20.0 came in via a PR, v0.20.1 via a direct push to
main, and in both cases the whole section was authored at release time rather
than accumulated.

Establishes the accumulating convention: every PR that changes observable
behaviour adds its entry under `## [Unreleased]`, so releasing is renaming a
heading rather than reconstructing history from the log. Calls out that `skills/`
is go:embed-ed, so a reference-doc correction ships to users and warrants an
entry — that is not obvious from the file layout.

Also records the parts that are easy to get wrong:

- Releases are manual and tag-driven; merging to main publishes nothing.
- The version lives only in the git tag. GoReleaser injects it via ldflags and
  local builds report `dev`, so there is no version file to bump.
- GoReleaser's `changelog:` block generates the GitHub release notes from commit
  subjects and never touches CHANGELOG.md. It also filters out `docs:`, `chore:`,
  `test:` and `ci:` — which is why the two existing CHANGELOG commits, both
  `docs:`, do not appear in any release notes.
- `internal/version/update.go` polls the releases API, so tagging immediately
  advertises the upgrade to every installed CLI. Deploy dependent API changes
  before tagging, not after.

Adds the changelog step to the Adding-a-New-Resource checklist. AGENTS.md is a
symlink to this file, so agents pick it up too.

Every claim verified against .goreleaser.yaml, .github/workflows/release.yml,
cmd/dhq/main.go, internal/version/update.go, skills/embed.go and the annotated
tag objects.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Hibw5xsRNGDkYzr1hXsDQz
@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

Changes

Release Documentation

Layer / File(s) Summary
Release process documentation
CLAUDE.md
Documents required unreleased changelog entries, manual version tagging, GoReleaser releases, injected versioning, GitHub release-note generation, and update-checker timing.

Estimated code review effort: 1 (Trivial) | ~2 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the documentation changes to the changelog convention and release process.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch thiago/document-changelog-and-release-convention

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@CLAUDE.md`:
- Around line 125-127: Update the release-order guidance in CLAUDE.md to clarify
that internal/version/update.go detects only the latest published GitHub
release, after GoReleaser publication and on the next checker invocation.
Replace the claim that tagging immediately advertises the upgrade while
preserving the instruction to deploy the backend before publishing a dependent
release.
- Around line 106-111: Update the release instructions around Step 4 to push the
release commit to origin/main before pushing the vX.Y.Z tag. Add the explicit
main-branch push while preserving the existing tag creation and push commands.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: db356719-ddf4-459d-9fcc-e618a550c772

📥 Commits

Reviewing files that changed from the base of the PR and between 8bb020d and acdf460.

📒 Files selected for processing (1)
  • CLAUDE.md

Comment thread CLAUDE.md
Comment thread CLAUDE.md Outdated
@thdurante thdurante self-assigned this Aug 6, 2026
@thdurante

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: acdf460132

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread CLAUDE.md
Review follow-up on #41. Two defects in the runbook, both of which matter
because the whole point of the doc is that someone follows it literally.

The release steps committed the changelog on main and then pushed only the tag.
Pushing a tag sends the reachable objects but does not move refs/heads/main, so
following the sequence verbatim would publish a release containing the changelog
while origin/main still lacked it. Adds the explicit `git push origin main`,
before the tag, with a note on why the order matters.

The update-checker note claimed tagging "immediately advertises the upgrade to
every installed CLI". internal/version/update.go:14 reads /releases/latest — the
latest *published* release, not the tag — and Check() runs per CLI invocation.
The real sequence is tag, GoReleaser builds, release published, then each CLI
notices on its next run. The practical advice is unchanged (deploy dependent API
changes before tagging) but the stated mechanism now matches the code.

Caught by CodeRabbit and Codex on #41.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Hibw5xsRNGDkYzr1hXsDQz

@facundofarias facundofarias 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.

👍🏼

@thdurante
thdurante merged commit f2071b5 into main Aug 6, 2026
18 checks passed
@thdurante
thdurante deleted the thiago/document-changelog-and-release-convention branch August 6, 2026 09:10
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