TheSkillz

Changelog on Tag

Every git tag writes its own CHANGELOG.md section, automatically

TheSkillz Team TheSkillz Team No reviews yet4 human installs0 agent installsv1.0.0
Scan passed · 100/100Human reviewedOfficial · TheSkillz
☆ Star 0

Installs a git hook and a GitHub Actions workflow so that creating a release tag writes that version's section into CHANGELOG.md, built from the commits in the tag's range. Keeps Keep-a-Changelog structure and compare links correct, replaces a section instead of duplicating it on a re-run, and carries the entry rules that keep the file short and specific.

SKILL.md

Changelog on Tag

A tag is created; CHANGELOG.md gains a section for it, built from the commits between the previous tag and this one. Nothing else changes. The commits are raw material, not the output — an entry names what changed for the person using the software.

What this skill does and does not do

Does: resolve a tag's commit range, group the commits, write or replace that version's section in CHANGELOG.md, keep the compare links correct, and install the automation that runs it on every future tag.

Does not: decide version numbers, bump manifests, create tags, publish GitHub Releases, or push anything. Those belong to a release process.

Set up the automation (one time per repository)

scripts/install-tag-hook.sh --hook --ci

--hook writes .git/hooks/reference-transaction, which fires the moment a tag ref is created locally. --ci copies a workflow to .github/workflows/changelog-on-tag.yml, which runs on push: tags so a tag pushed from any machine is still covered.

Install both. The hook gives the person tagging an immediate, reviewable diff; CI is the backstop for tags created elsewhere or through the GitHub UI. Running both on the same tag is safe — the writer replaces a version's section rather than appending a second one.

Before running the installer, confirm with the user:

  • The tag pattern that counts as a release (default v*, semver only).
  • Whether the CI job may commit to the default branch. If that branch is protected, use --ci-mode pr so the workflow opens a pull request instead.
  • The changelog path, if it is not CHANGELOG.md.

Check what already exists first. If the repository uses git-cliff, changesets, release-please or semantic-release, say so and stop: two tools writing the same file will fight. This skill is for repositories with no changelog automation.

Write a tag's section

1. Read the range

scripts/tag-range.sh v2.4.0

Prints the previous tag, the commit range, the tag date, and one record per commit with subject, body and author. With no argument it uses the most recent tag reachable from HEAD.

2. Draft the entries

Read references/entry-rules.md before writing a line. It carries the grouping, the phrasing rules and the exclusion list.

The short version: one entry per user-visible change, in the present tense, naming the effect rather than the commit. Merge commits, formatting, CI config, dependency bumps with no behaviour change and internal refactors do not get entries. If a tag range contains nothing user-visible, say so and write a one-line section rather than padding it.

3. Write the section

Pipe the drafted markdown into the writer:

scripts/changelog-write.py --tag v2.4.0 --stdin <<'EOF'
### Breaking
- The `/v1/users` endpoint is removed. Use `/v2/users`; the response shape is unchanged.

### Added
- Refunds can be issued for part of a payment.

### Fixed
- Sessions no longer end early when the access token rotates.
EOF

The writer inserts the section in version order, creates CHANGELOG.md with a Keep a Changelog header if it is missing, replaces an existing section for the same tag instead of duplicating it, and maintains the [2.4.0]: …/compare/… link definitions at the foot of the file.

--from-commits skips the drafting step and groups commit subjects mechanically by Conventional Commit type. That is what the hook and CI use unattended. It produces a correct file, not a well-written one — when a person is in the loop, draft the entries yourself.

4. Verify

scripts/changelog-write.py --tag v2.4.0 --check
git diff CHANGELOG.md

--check exits non-zero if the section is missing or the compare links are broken. Read the diff before committing: confirm exactly one section changed and that no earlier release was rewritten.

Backfilling

For a repository with tags but no changelog:

for tag in $(git tag --sort=version:refname); do
  scripts/changelog-write.py --tag "$tag" --from-commits
done

Then rewrite the entries for the last two or three releases by hand. Older sections can stay mechanical; nobody reads them, and a wrong summary is worse than a commit subject.

Rules

  • Never rewrite a section for an already-released version except to correct a factual error, and never in the same commit as a new release's section.
  • The changelog commit lands after the tag, so its content is not inside the tag. This is the accepted trade-off for tag-triggered generation. If a release artifact must contain its own changelog, write the section against HEAD before tagging: scripts/changelog-write.py --tag v2.4.0 --range v2.3.1..HEAD.
  • Do not commit or push from the hook. It edits the file and prints one line. The person tagging decides what to commit.
  • Do not invent entries for commits you cannot explain. Ask, or quote the commit subject unchanged.
  • A tag that only moves (git tag -f) is not a release. The hook ignores it.

Output

Report the tag, the previous tag, the commit count in the range, how many became entries, and the path written. Name anything you dropped and why, and anything you could not classify. Do not claim the changelog is updated without having seen git diff output in this run.

Reviews

Sign in to leave a review.

  • Be the first to review this skill.

More in devops