GitHub Actions Release Workflow Builder

Automate GitHub releases with changelogs and asset uploads

Generate a GitHub Actions release workflow that triggers on version tags, builds your artifacts, auto-generates release notes from commit history, and uploads build assets to the GitHub Release — using the built-in GITHUB_TOKEN, no extra secrets. It runs free in your browser on Gera Tools, with nothing uploaded.

Last updated Source: Gera Tools

What triggers this workflow?

It triggers on pushing a Git tag that matches your pattern, such as v1.2.0. Pushing the tag with `git push origin v1.2.0` starts the run, builds artifacts, and publishes a GitHub Release for that tag.

When you tag a version, you usually want the same things to happen every time: build the artifacts, attach them, and publish notes. This generator builds a GitHub Actions workflow that fires on a version tag, runs your build, auto-generates release notes from commit history, and uploads your assets to a GitHub Release.

How it works

The workflow listens on a push event filtered to tags matching your pattern. On a match it:

  1. Checks out the full history so the changelog action can diff against the previous tag.
  2. Runs your build command to produce the release artifacts.
  3. Calls softprops/action-gh-release, which creates the release for the pushed tag, sets generate_release_notes: true, and uploads every file matching your asset globs.

It needs only the built-in GITHUB_TOKEN with contents: write permission — no personal access token.

Full workflow skeleton

name: Release

on:
  push:
    tags:
      - "v*"  # fires on v1.0.0, v2.3.1-rc1, etc.

permissions:
  contents: write  # needed to create releases and upload assets

jobs:
  release:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0  # full history so release notes diff against the previous tag

      - name: Build artifacts
        run: make dist  # replace with your actual build command

      - name: Publish release
        uses: softprops/action-gh-release@v2
        with:
          generate_release_notes: true  # GitHub builds notes from merged PRs since the last tag
          prerelease: false
          files: |
            dist/*.tar.gz
            dist/*.zip

How auto-generated release notes work

When generate_release_notes: true is set, GitHub queries the merged pull requests between the previous tag and the current one and formats them into a changelog. The result groups PRs by label (features, bug fixes, and so on) if you have configured a .github/release.yml categorisation file.

The quality of auto-generated notes depends directly on your PR titles. A PR titled “fix login bug” produces a vague changelog entry; a PR titled fix: handle expired session token on refresh produces a useful one. If your team uses Conventional Commits, the titles translate naturally.

Choosing your tag pattern

Use v* to match all semver-style tags (v1.0.0, v2.1.0-beta.1). For projects releasing multiple artifacts from one repo, consider a prefix like api/v* or cli/v* and separate workflows per prefix. Avoid tagging the default branch directly for releases — always push the tag explicitly after finalising the commit.

Pre-releases and release candidates

Enable the pre-release toggle and the workflow sets prerelease: true on the GitHub Release, which marks it clearly as non-stable and excludes it from the “latest release” pointer. This is the correct approach for tags like v2.0.0-rc1 or v3.0.0-beta.2 — package registries and tools that watch the latest release tag will not pick these up accidentally.

Tips and notes

  • Use a tag pattern like v* so only version tags publish releases, not every tag.
  • Generated notes summarize merged pull requests since the last tag; write clear PR titles for clean changelogs.
  • Provide multiple asset globs (one per line) to attach binaries for several platforms in a single release.
  • For signed or checksummed assets, add a step before the release that produces the .sha256 files and include them in the globs.
  • fetch-depth: 0 is essential — without full history, the notes generator cannot find the previous tag to diff against.