Skip to content

About

💿 Opinionated, plug-and-play release workflows as a GitHub Action.

Resources

Stars

4 stars

Watchers

0 watching

Forks

Use this GitHub action with your project
Add this Action to an existing workflow or create a new one
View on Marketplace

Latest commit

 

History

35 Commits

Folders and files

Repository files navigation

simple-release

Opinionated, customizable GitHub Action to publish releases out of pushed v* tags.

This is a generalization that collects patterns from the workflows used in Quarkdown and other personal projects from my past decade in OSS.

What it does

Each feature is opt-in.

  • Tagged release: publishes the release with a composed body and artifacts.

  • Version-file bump: writes the tag into a file like version.txt readable by downstream tools, such as build scripts or --version flags.

  • Version replacement: swaps the previous release version for the new one in any file, such as installation snippets in a README.md.

  • Changelog update and extraction: extracts the [Unreleased] section in a keep-a-changelog file, turns it into a dated release section, and uses it to compose the release body.

  • Release notes extraction: extracts the notes for the current tag from the changelog.

  • Devbuild prerelease: moves a rolling tag to the current commit and publishes a prerelease with attached artifacts as a nightly build.

  • Release from a button: bumps the version, commits it, and tags that commit in one atomic push, starting a release without pushing a tag by hand.

  • Major-version tag alias: extracts and pushes the major from the tag (v2.3.4 → v2), ideal for pinning versions in GitHub Actions (dogfooded in this very action).

Quick start

Publish a release when a tag is pushed

name: Release
on:
  push:
    tags: ['v*']

permissions:
  contents: write

jobs:
  release:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: iamgio/simple-release@v1
        with:
          version-file: version.txt
          changelog-file: CHANGELOG.md
          commit: 'true'
          release-files: |
            build/dist/*.zip
            build/dist/*.tar.gz
Note
The pushed tag points at the commit before the version bump, so checking out the tag shows the previous version in version.txt and CHANGELOG.md. To have the tag carry the release version, start releases with push-tag instead (see below).

Start a release from a button

Run the workflow from the Actions tab, or with gh workflow run release.yml -f version=1.2.3. It bumps the version and changelog on main, commits them, and tags that commit as v1.2.3. The commit and the tag are pushed together: if the tag already exists, or the version is already released, nothing is pushed.

name: Release
on:
  workflow_dispatch:
    inputs:
      version:
        description: Version to release (e.g. 1.2.3)
        required: true

permissions:
  contents: write

jobs:
  release:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          ref: main
          fetch-depth: 0
      - uses: iamgio/simple-release@v1
        with:
          tag: ${{ inputs.version }}
          committer-token: ${{ secrets.COMMITTER_TOKEN }}
          version-file: version.txt
          changelog-file: CHANGELOG.md
          commit: 'true'
          push-tag: 'true'
          release: 'false'

The tag push then triggers your tag-based workflow (such as the one above, without commit), which builds and publishes the release. This requires committer-token to be a PAT: GitHub doesn’t trigger workflows from pushes made with github.token.

Publish a rolling devbuild on every main push

name: Devbuild
on:
  push:
    branches: [main]

permissions:
  contents: write

jobs:
  devbuild:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: iamgio/simple-release@v1
        with:
          devbuild-tag: latest
          devbuild-files: build/dist/*.zip

Release a reusable GitHub Action (major-tag alias)

The following lets a push of a v2.3.4 tag publish a release and force-move the v2 tag to the same commit:

name: Release
on:
  push:
    tags: ['v*.*.*']

permissions:
  contents: write

jobs:
  release:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: iamgio/simple-release@v1
        with:
          release: 'true'
          major-tag: 'true'

Inputs

Core

Input Default Description

tag

github.ref_name

Tag for the release.

token

github.token

Token used to create the releases.

committer-token

Checkout credentials

Token for pushing commits and tags, taking precedence over the credentials persisted by actions/checkout. When empty, pushes use the checkout credentials, or token if checkout persisted none. Use a PAT to push to protected branches, or to let the pushes trigger other workflows.

Version file

Input Default Description

version-file

''

Path to a file to overwrite with the version. Leave empty to skip. Not for JSON manifests: the file is replaced wholesale, so use bump-package-json for those.

keep-v-prefix

false

When true, writes the tag verbatim. Otherwise strips the leading v. Does not apply to bump-package-json.

bump-package-json

false

When true, sets the version field of the root package.json, leaving the rest of the manifest byte-for-byte intact. The leading v is always stripped, as npm requires plain semver.

replace-version-in-files

''

Newline- or comma-separated list of files (e.g. README.md) in which every occurrence of the previous release version is replaced with the new one, as literal text. The previous version is the highest v-prefixed tag below the current one in version order, so check out with fetch-depth: 0. Both 1.2.3 and v1.2.3 occurrences are updated.

Changelog

Input Default Description

changelog-file

''

Path to a keep-a-changelog file. Leave empty to skip.

update-changelog

true

Turn [Unreleased] into a dated release section.

extract-release-notes

true when changelog set and releasing

Extract release notes for the tag from the changelog into the release-notes output.

Extra body section

Input Default Description

body-append-file

''

If set and the file exists, its content is appended after the release notes in the release body.

Release-notes spacers

Input Default Description

insert-changelog-spacers

false

When true, inserts a   spacer line before every H2 and H3 heading in the extracted release notes.

Commit back

Input Default Description

commit

false

Commit the modified version-file, changelog-file, package.json and replace-version-in-files files back to a branch.

commit-message

chore: release {tag}

{tag} is substituted with the tag.

commit-user-name

github-actions

Name used for the auto-commit author.

commit-user-email

github-actions[bot]@users.noreply.github.com

Email used for the auto-commit author.

commit-branch

main

Branch to push the commit to.

push-tag

false

When true, tags the release commit with tag and pushes the commit and the tag atomically. The leading v of tag is optional and always added, and the version must be semver. Requires commit: 'true'. Fails when there is nothing to commit or the tag already exists.

Devbuild

Input Default Description

devbuild-tag

''

Name of the rolling tag to force-move to this commit (e.g. latest). Leave empty to skip.

devbuild-name

Development build

Display name for the prerelease.

devbuild-files

''

Newline- or comma-separated glob patterns of files to attach.

Tagged release

Input Default Description

release

auto

auto = create when ref is a tag. Use true/false to force behavior.

release-name

Tag name

Release display name.

release-body

Composed

Literal Markdown body. If empty, composed from release notes and the append file.

release-files

''

Newline- or comma-separated glob patterns of files to attach.

release-draft

false

Whether the release should be created as a draft.

release-prerelease

false

Whether the release should be marked as a prerelease. Ignored when auto-detect-prerelease is true.

auto-detect-prerelease

false

When true, derive the prerelease flag from the tag: the release is marked as a prerelease when the tag’s semver pre-release segment (parsed by madhead/semver-utils, e.g. rc.1 in v1.2.3-rc.1) matches any prerelease-keywords. Fully overrides release-prerelease.

prerelease-keywords

alpha,beta,rc,pre,preview,snapshot,nightly,dev

Comma-separated, case-insensitive keywords matched as substrings against the tag’s pre-release segment. Only used when auto-detect-prerelease is true.

Major-version tag alias

Input Default Description

major-tag

false

When true, extracts the major from the tag (e.g. v2 from v2.3.4) and force-pushes it to the current commit.

Outputs

Output Description

version

The computed version (tag with leading v optionally stripped).

is-tag

Whether the workflow ref is a tag.

release-notes

Extracted release notes for the tag, if the changelog step ran.

release-url

URL of the created release, if any.

devbuild-url

URL of the created devbuild release, if any.

Permissions

The calling workflow needs contents: write for any step that pushes tags, commits, or creates releases. Pushes authenticate with committer-token when set, and with the credentials persisted by actions/checkout otherwise. Pass a PAT as committer-token (or to actions/checkout) when pushing to a protected branch, or when the pushed commit or tag should trigger other workflows.

Versioning

This action follows semver via v{major}.{minor}.{patch} tags.

About

💿 Opinionated, plug-and-play release workflows as a GitHub Action.

Resources

Stars

4 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages