Command Palette

Search for a command to run...

Hectal
PHASE 8Advanced ~7 min· topic 3 of 4

Topic 8.3

Release Automation: Versions, Changelogs & Release Trains

In one line

Releasing should be a button (or nothing at all). Conventional commits and tools like semantic-release or release-please compute the next version, generate changelogs, tag, and publish, whether you ship continuously or on a release train.

0/4 · 0%

Think of it like this

A newspaper press. Articles (commits) are written all day; at press time the paper is assembled, numbered, and printed automatically with a table of contents (changelog). Nobody hand-writes the index at midnight.

Key ideas

  1. 01

    CONVENTIONAL COMMITS: feat: add wishlist (minor), fix: rounding in totals (patch), feat!: remove v1 API or a BREAKING CHANGE: footer (major), chore:/docs: (no release). Enforce with a commit-msg hook or PR-title check (Git course, commit messages).

  2. 02

    RELEASE TOOLS read the commits since the last tag: SEMANTIC-RELEASE (fully automatic on merge to main: compute version, tag, changelog, GitHub release, publish packages), RELEASE-PLEASE (opens a 'release PR' with the next version and changelog that you merge when ready), and Changesets (for JS monorepos). The version and notes stop depending on someone remembering.

  3. 03

    For deployable services, the immutable artifact identifier (Git SHA image tag) is what's promoted between environments (Phase 5, versioning and promotion); a human-friendly SemVer tag or date version can be added for release notes. For libraries and APIs consumed by others, SemVer is essential (DevOps guide, twelve-factor).

  4. 04

    RELEASE CADENCES: continuous deployment (every merge ships, possibly behind feature flags), scheduled release TRAINS (e.g. weekly cut from main to a release branch, stabilise, ship; common for mobile apps and regulated environments), and hotfix paths (branch from the release tag, fix, cherry-pick back to main: Git course, cherry-pick).

Code & diagrams

release-please on GitHub Actionsyaml
name: release
on:
  push: { branches: [main] }
permissions: { contents: write, pull-requests: write }
jobs:
  release:
    runs-on: ubuntu-latest
    steps:
      - uses: googleapis/release-please-action@v4
        id: rp
        with: { release-type: maven }
      - if: ${{ steps.rp.outputs.release_created }}
        run: echo "Released ${{ steps.rp.outputs.tag_name }}"   # build + publish the tagged artifact here
commits → versiontext
v1.4.2 (last tag)
  fix: handle empty cart totals        → patch
  feat: add wishlist endpoint          → minor
  docs: update README                  → no release
=> next version v1.5.0, changelog grouped by Features / Bug Fixes

Explain it without notes

01

Why generate versions from commit messages instead of choosing them manually?

Practice

01

A mobile team wants predictable weekly releases while developers merge continuously. Design the flow.

Trade-offs

  • ↔

    Fully automatic releases maximise flow but need strong tests and flags; release PRs or trains add a human checkpoint and predictability at the cost of latency.

Done when you can

  • I can set up automated versioning and changelogs

  • I can choose between continuous releases and release trains