GitHub Releases provide an easy to access method for end users to download versioned software binaries. You can create them manually, but it’s much easier to let GitHub Actions build them automatically using release tags created in your repository.

Using Tagged Releases

Tags are an existing feature in Git, with extended support offered by GitHub with Releases, which offer a place to host binaries with associated changelogs.

You can create a tag much like you’d make a branch, except it’s a fixed point that doesn’t move and always points to a specific commit. This is useful for creating versioned releases, and most people will create tags using semantic versioning format (Major.Minor.Patch).

Tags can be pushed to GitHub where they can be used in other automation workflows. In this case, we will be setting up a GitHub Actions script that will listen for commits containing tagged releases and automatically publish the build artifacts to a release.

Setting Up GitHub Actions

First, you’ll want to make sure you have a working GitHub Actions build, and that your build scripts are functioning properly. The exact setup for your workflow will depend on what kind of project you’re building, but generally, you don’t want to be debugging two problems at once, so you should add the release publishing once you already have working artifacts. You can read our guide to setting up a GitHub Actions build to learn more.

The first thing to do is edit the “on” section of your Actions script to also run when Tags are created. By default, you probably have the “push” event to track releases or the master branch. You’ll need to add tags, and set a filter. For all tags, simply use a wildcard:

At the end of the workflow, after everything is built, we will create the Release entry. This is a two part step—first, we will need to create a new Release object with all the metadata, and then we can use the outputted publish URL for this to upload the artifacts. You can create multiple upload steps if you have multiple artifacts.

In either case, we will want to only run these steps if the workflow is running because of a tag. We can do this with a simple if check, and check if the github.ref object is a tag, which stores the ref name of the branch or tag that triggered the workflow.

The first step is to create a Release object, which can be done with the following step. The GitHub token doesn’t need to be created manually—it’s a special token that can always be referenced from Actions scripts.

     - name: Create Release
      if: startsWith(github.ref, 'refs/tags/')
      uses: actions/create-release@v1
      id: create_release
        draft: false
        prerelease: false
        release_name: ${{ github.ref }}
        tag_name: ${{ github.ref }}
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Note here that the changelog for the release is stored at, which must exist for the workflow to run properly. You can edit this with each tag to change the markdown displayed by GitHub on the release page. There are tools to generate this automatically with commit messages, but most teams will have their own method of managing this anyway.

Next, you can start uploading artifacts. This uses the upload URL from the previous step, and you’ll need to define a path where it can be found along with the display name for the asset.

     - name: Upload Release
      if: startsWith(github.ref, 'refs/tags/')
      uses: actions/upload-release-asset@v1
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        upload_url: ${{ steps.create_release.outputs.upload_url }}
        asset_path: Oxide.Ext.Sanctuary/bin/Release/net48/Oxide.Ext.Sanctuary.dll
        asset_name: Oxide.Ext.Sanctuary.dll
        asset_content_type: application/octet-stream

Note here that the content type is set to octet-stream, which is typical for binary data like executables and DLLs. If you’re publishing a ZIP or some other kind of file, you will want to change this, though it only affects the visuals on the release page.

Now, you can commit the changes to the Actions workflow, and then create a new tag and push it to GitHub. You should see a new workflow run being created, except instead of running off the master branch, it’s running because of the tag:

Once it’s finished, you’ll see the release in the GitHub sidebar.

Leave a Reply

Your email address will not be published. Required fields are marked *