Skip to content

Changelog Workflow โ€‹

Date: 2026-04-30 Status: โœ… Active

Overview โ€‹

Lantern records changes at two layers:

  1. Per-push dev narrative โ€” daily files in docs/changelogs/dev/, AI-generated by .github/workflows/ai-changelog.yml on every push to dev
  2. Per-release prod summary โ€” GitHub Releases (the Releases tab on github.com), auto-generated by .github/workflows/release-prod.yml on each tagged release

There is no prod-*.md file in the repo โ€” release notes live on github.com only. See PR_WORKFLOW.md for the broader release pipeline design (issue #298).

Directory structure โ€‹

docs/changelogs/
โ”œโ”€โ”€ dev/         # Daily AI-generated narrative entries
โ””โ”€โ”€ archived/    # Historical (pre-2026-04-30 layout)

Pre-2026-04-30 layouts also had prod/ (consolidated production releases) and used a _merged suffix marker. That structure is retired โ€” see Migration history below.

/dev โ€” Development changelogs โ€‹

One file per date during active development on the dev branch.

Naming: dev-MM.DD.YYYY-v{version}.md

Examples:

  • dev-04.30.2026-v0.1.0.md
  • dev-04.27.2026-v0.1.0.md

Lifecycle:

  • Created by the AI changelog workflow on first push of the day
  • Subsequent pushes append a timestamped ## Update - YYYY-MM-DD HH:MM UTC section
  • Files accumulate forever (no archival flow currently). If they ever become unwieldy, consider moving older years into dev/archive/YYYY/.

/archived โ€” Historical changelogs โ€‹

Old changelogs from before the dev/prod split was retired, preserved for audit trail.

Daily development workflow โ€‹

Automated AI generation (default path) โ€‹

The AI Changelog Generator runs automatically on every push to dev:

  • No manual action required โ€” file is created and committed automatically with [skip ci]
  • Multiple pushes per day โ€” subsequent pushes append a timestamped ## Update section
  • Skip-aware โ€” pushes by bots, with [skip ci] / [skip changelog] in the subject line, or with no bumping commits โ†’ no file change
  • Empty-AI guard โ€” if the AI returns no entries (e.g. all chore/docs work), no file write happens
  • Dry-run โ€” trigger manually via Actions tab with dry_run: true to preview output

Manual entry (rare) โ€‹

If the AI fails or you want to record something manually:

  1. Create or open docs/changelogs/dev/dev-MM.DD.YYYY-v{version}.md
  2. Use the template below
  3. Commit with the related work (no separate "changelog commit" needed)
markdown
# Changelog - Dev - MM.DD.YYYY

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

---

## [Unreleased] - YYYY-MM-DD

### Added
- **Feature title** โ€” Brief description. ([#NNN](https://github.com/cattreedev/lantern_app/pull/NNN)) `enhancement`

### Fixed
- **Bug title** โ€” What was wrong and why it matters. ([#NNN](...)) `bug`

Format rules โ€‹

  • Keep a Changelog format
  • Present tense imperative ("Add feature" not "Added feature")
  • Categories: Added, Changed, Deprecated, Removed, Fixed, Security
  • Entries describe what changed and why it matters
  • AI-enriched entries include PR link + label badges; manual entries can be one-liners

Production releases โ€‹

How it works โ€‹

When dev is merged to main and CI passes, release-prod.yml fires:

  1. Reads the last v* git tag
  2. Fetches PRs merged since that tag and inspects their labels
  3. Computes the next version per the bump priority below
  4. Creates a tag and a GitHub Release with auto-generated notes (grouped by label per .github/release.yml)

The release notes live in the GitHub Releases tab. There is no prod-*.md file in the repo.

Versioning โ€‹

Follows SemVer 2.0 with stage suffixes:

vMAJOR.MINOR.PATCH-stage.N
StageMeaning
prototypeEarly development; pilot mode, narrow audience
alphaFirst prod cut, contracts still moving
betaFeature-complete, hardening
(no suffix)Stable โ€” public API committed

The counter (.N) increments monotonically within a stage and resets only on stage transition. Stage transitions are manual via workflow_dispatch on release-prod.yml.

Bump priority โ€‹

Pre-1.0:

Label on any PR in batchBump
breaking-changeMINOR
enhancementPATCH
bug / securityPATCH
chore / documentation / dependencies / devops only(no release cut)

Post-1.0 (when base major โ‰ฅ 1) shifts up: breaking-change โ†’ MAJOR, enhancement โ†’ MINOR, etc.

The label set is enforced by lint-pr-labels.yml โ€” every PR must have โ‰ฅ1 type label before merge.

Manual stage transitions โ€‹

To cut the first alpha release after prototype:

bash
gh workflow run release-prod.yml --ref main \
  -f stage_transition=alpha

This bumps the base version (PATCH minimum), resets the counter to 0, and tags the result with -alpha.0 suffix.

Dry-run preview โ€‹

Before any real tag, preview what would happen:

bash
gh workflow run release-prod.yml --ref main \
  -f dry_run=true

The job posts the computed version + auto-generated notes to its run summary without writing tags or publishing.

Common tasks โ€‹

See the latest dev changelog โ€‹

bash
ls docs/changelogs/dev/ | tail -1
cat "docs/changelogs/dev/$(ls docs/changelogs/dev/ | tail -1)"

See the latest release โ€‹

bash
git describe --tags --abbrev=0 --match 'v*'
gh release view "$(git describe --tags --abbrev=0 --match 'v*')"

List all releases โ€‹

bash
gh release list --limit 20

See PRs that landed in a specific release โ€‹

bash
PREV=$(git tag --sort=-creatordate --list 'v*' | sed -n '2p')
CUR=$(git tag --sort=-creatordate --list 'v*' | sed -n '1p')
gh api "repos/cattreedev/lantern_app/compare/${PREV}...${CUR}" \
  --jq '.commits[].commit.message' | grep -oE '#[0-9]+' | sort -u

References โ€‹

Migration history โ€‹

2026-04-30 (#298): Retired prod/*.md consolidation flow. Release notes now live in GitHub Releases only. Removed:

  • tooling/scripts/consolidate-changelog.mjs
  • npm run changelog:consolidate
  • "Check for unconsolidated DEV changelog entries" warn step in deploy-prod.yml
  • _merged suffix convention
  • prod/ directory writes (existing files preserved as-is)

Rationale: GitHub Releases (auto-generated from PR titles + grouped by labels via .github/release.yml) replace the in-repo prod artifact, eliminating duplication and removing the need for a GH_PAT to commit back to protected branches.

2026-01-22: Migrated from monolithic docs/CHANGELOG.md to structured docs/changelogs/ directory.

Built with VitePress