A GitHub Action for creating GitHub Releases on Linux, Windows, and macOS virtual environments
Typically usage of this action involves adding a step to a build that
is gated pushes to git tags. You may find step.if
field helpful in accomplishing this
as it maximizes the reuse value of your workflow for non-tag pushes.
Below is a simple example of step.if
tag gating
name: Main
on: push
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Release
uses: softprops/action-gh-release@v2
if: startsWith(github.ref, 'refs/tags/')
You can also use push config tag filter
name: Main
on:
push:
tags:
- "v*.*.*"
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Release
uses: softprops/action-gh-release@v2
You can configure a number of options for your GitHub release and all are optional.
A common case for GitHub releases is to upload your binary after its been validated and packaged.
Use the with.files
input to declare a newline-delimited list of glob expressions matching the files
you wish to upload to GitHub releases. If you'd like you can just list the files by name directly.
If a tag already has a GitHub release, the existing release will be updated with the release assets.
Below is an example of uploading a single asset named Release.txt
name: Main
on: push
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Build
run: echo ${{ github.sha }} > Release.txt
- name: Test
run: cat Release.txt
- name: Release
uses: softprops/action-gh-release@v2
if: startsWith(github.ref, 'refs/tags/')
with:
files: Release.txt
Below is an example of uploading more than one asset with a GitHub release
name: Main
on: push
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Build
run: echo ${{ github.sha }} > Release.txt
- name: Test
run: cat Release.txt
- name: Release
uses: softprops/action-gh-release@v2
if: startsWith(github.ref, 'refs/tags/')
with:
files: |
Release.txt
LICENSE
⚠️ Note: Notice the
|
in the yaml syntax above ☝️. That lets you effectively declare a multi-line yaml string. You can learn more about multi-line yaml syntax here⚠️ Note for Windows: Paths must use
/
as a separator, not\
, as\
is used to escape characters with special meaning in the pattern; for example, instead of specifyingD:\Foo.txt
, you must specifyD:/Foo.txt
. If you're using PowerShell, you can do this with$Path = $Path -replace '\\','/'
Many systems exist that can help generate release notes for you. This action supports loading release notes from a path in your repository's build to allow for the flexibility of using any changelog generator for your releases, including a human 👩💻
name: Main
on: push
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Generate Changelog
run: echo "# Good things have arrived" > ${{ github.workspace }}-CHANGELOG.txt
- name: Release
uses: softprops/action-gh-release@v2
if: startsWith(github.ref, 'refs/tags/')
with:
body_path: ${{ github.workspace }}-CHANGELOG.txt
repository: my_gh_org/my_gh_repo
# note you'll typically need to create a personal access token
# with permissions to create releases in the other repo
token: ${{ secrets.CUSTOM_GITHUB_TOKEN }}
The following are optional as step.with
keys
Name | Type | Description |
---|---|---|
body |
String | Text communicating notable changes in this release |
body_path |
String | Path to load text communicating notable changes in this release |
draft |
Boolean | Indicator of whether or not this release is a draft |
prerelease |
Boolean | Indicator of whether or not is a prerelease |
preserve_order |
Boolean | Indicator of whether order of files should be preserved when uploading assets |
files |
String | Newline-delimited globs of paths to assets to upload for release |
name |
String | Name of the release. defaults to tag name |
tag_name |
String | Name of a tag. defaults to github.ref |
fail_on_unmatched_files |
Boolean | Indicator of whether to fail if any of the files globs match nothing |
repository |
String | Name of a target repository in <owner>/<repo> format. Defaults to GITHUB_REPOSITORY env variable |
target_commitish |
String | Commitish value that determines where the Git tag is created from. Can be any branch or commit SHA. Defaults to repository default branch. |
token |
String | Secret GitHub Personal Access Token. Defaults to ${{ github.token }} |
discussion_category_name |
String | If specified, a discussion of the specified category is created and linked to the release. The value must be a category that already exists in the repository. For more information, see "Managing categories for discussions in your repository." |
generate_release_notes |
Boolean | Whether to automatically generate the name and body for this release. If name is specified, the specified name will be used; otherwise, a name will be automatically generated. If body is specified, the body will be pre-pended to the automatically generated notes. See the GitHub docs for this feature for more information |
append_body |
Boolean | Append to existing body instead of overwriting it |
make_latest |
String | Specifies whether this release should be set as the latest release for the repository. Drafts and prereleases cannot be set as latest. Can be true , false , or legacy . Uses GitHub api defaults if not provided |
💡 When providing a body
and body_path
at the same time, body_path
will be
attempted first, then falling back on body
if the path can not be read from.
💡 When the release info keys (such as name
, body
, draft
, prerelease
, etc.)
are not explicitly set and there is already an existing release for the tag, the
release will retain its original info.
The following outputs can be accessed via ${{ steps.<step-id>.outputs }}
from this action
Name | Type | Description |
---|---|---|
url |
String | Github.com URL for the release |
id |
String | Release ID |
upload_url |
String | URL for uploading assets to the release |
assets |
String | JSON array containing information about each uploaded asset, in the format given here (minus the uploader field) |
As an example, you can use ${{ fromJSON(steps.<step-id>.outputs.assets)[0].browser_download_url }}
to get the download URL of the first asset.
The following step.env
keys are allowed as a fallback but deprecated in favor of using inputs.
Name | Description |
---|---|
GITHUB_TOKEN |
GITHUB_TOKEN as provided by secrets |
GITHUB_REPOSITORY |
Name of a target repository in <owner>/<repo> format. defaults to the current repository |
⚠️ Note: This action was previously implemented as a Docker container, limiting its use to GitHub Actions Linux virtual environments only. With recent releases, we now support cross platform usage. You'll need to remove the
docker://
prefix in these versions
This Action requires the following permissions on the GitHub integration token:
permissions:
contents: write
When used with discussion_category_name
, additional permission is needed:
permissions:
contents: write
discussions: write
GitHub token permissions can be set for an individual job, workflow, or for Actions as a whole.
Note that if you intend to run workflows on the release event (on: { release: { types: [published] } }
), you need to use
a personal access token for this action, as the default secrets.GITHUB_TOKEN
does not trigger another workflow.
Doug Tangren (softprops) 2019