📦 :octocat:

action gh-release

A GitHub Action for creating GitHub Releases on Linux, Windows, and macOS virtual environments


- [🤸 Usage](#-usage) - [🚥 Limit releases to pushes to tags](#-limit-releases-to-pushes-to-tags) - [⬆️ Uploading release assets](#️-uploading-release-assets) - [📝 External release notes](#-external-release-notes) - [💅 Customizing](#-customizing) - [inputs](#inputs) - [outputs](#outputs) - [environment variables](#environment-variables) - [Permissions](#permissions) ## 🤸 Usage ### 🚥 Limit releases to pushes to tags 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 ```yaml 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 ```yaml 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 ``` ### ⬆️ Uploading release assets 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` ```yaml 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 ```yaml 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](https://yaml-multiline.info) > **⚠️ 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 specifying `D:\Foo.txt`, you must specify `D:/Foo.txt`. If you're using PowerShell, you can do this with `$Path = $Path -replace '\\','/'` ### 📝 External release notes 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 👩‍💻 ```yaml 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 }} ``` ### 💅 Customizing #### inputs 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 `/` 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."](https://docs.github.com/en/discussions/managing-discussions-for-your-community/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](https://docs.github.com/en/repositories/releasing-projects-on-github/automatically-generated-release-notes) 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. #### outputs The following outputs can be accessed via `${{ steps..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](https://docs.github.com/en/rest/releases/assets#get-a-release-asset) (minus the `uploader` field) | As an example, you can use `${{ fromJSON(steps..outputs.assets)[0].browser_download_url }}` to get the download URL of the first asset. #### environment variables 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 `/` 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 ### Permissions This Action requires the following permissions on the GitHub integration token: ```yaml permissions: contents: write ``` When used with `discussion_category_name`, additional permission is needed: ```yaml permissions: contents: write discussions: write ``` [GitHub token permissions](https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token) 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](https://github.com/actions/create-release/issues/71). Doug Tangren (softprops) 2019