C.W.K.
Stream
Lesson 08 of 13 · published

Release Creation

~11 min · releases, tags, changelog

Level 0Apprentice
0 XP0/101 lessons0/10 achievements
0/120 XP to next level120 XP to go0% complete

Tag-driven release pipeline

The standard release shape: push a tag like v1.4.2, a workflow fires on tag push, builds release artifacts, publishes to GitHub Releases / npm / PyPI / ghcr, and posts the changelog.

Components

  1. Tag — created locally with git tag v1.4.2 && git push --tags or via GitHub UI.
  2. Release workflow — listens on on: push: tags: ['v*.*.*'].
  3. Build — produces release artifacts.
  4. Changelog — auto-generated (release-please, changesets, conventional-changelog) or human-written.
  5. GitHub Release — created via softprops/action-gh-release or the gh release create CLI.
  6. Distribution publish — npm, PyPI, ghcr.io, etc., from the same workflow.

Automation level

Choose your spot on the spectrum:

  • Manual taggit tag by hand. Simplest.
  • release-please (Google) — auto-PRs a 'release' commit; merging the PR creates the tag.
  • changesets (npm-centric) — contributors write changeset files; CI aggregates and tags.
  • semantic-release — fully automatic from conventional commits.

Code

Release workflow on tag push·yaml
name: release
on:
  push:
    tags: ['v*.*.*']
permissions:
  contents: write   # to create the GitHub Release
  id-token: write   # for trusted publishing to PyPI

jobs:
  release:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with: { fetch-depth: 0 }
      - uses: astral-sh/setup-uv@v3
      - run: uv build
      - name: Generate changelog
        id: changelog
        run: |
          # Crude: list commits since the previous tag
          previous=$(git tag --sort=-creatordate | sed -n 2p)
          {
            echo 'log<<EOF'
            git log --pretty='- %s (%h)' "$previous"..HEAD
            echo 'EOF'
          } >> $GITHUB_OUTPUT
      - uses: softprops/action-gh-release@v2
        with:
          files: dist/*
          body: '${{ steps.changelog.outputs.log }}'
      - name: Publish to PyPI (trusted)
        uses: pypa/gh-action-pypi-publish@release/v1

External links

Exercise

Set up a release workflow on a sandbox repo: tag v0.1.0 locally, push, and watch the workflow create a GitHub Release with the tag's commit log. Then bump to v0.1.1 and verify the changelog narrows to just the new commits.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.