$ cd ..

How to automate GitHub releases using GitHub Actions

📅 2021-11-02

⌛ 1137 days ago

Problem

At Vume, the majority of our backend is written in Clojure. As new commits are pushed, we needed a way to automatically build JAR binaries but at the same time, avoid having to manually tag a release. The developers define the current version in the base project.clj file present on the root of every repository as:

(defproject mprgs "0.12.12-SNAPSHOT"
    :min-lein-version "2.0.0"
    :java-source-paths ["src/java"]
    :source-paths ["src/clj"]
...

I needed a way to automatically grab that version number and push a release to GitHub whenever a PR was merged to the master branch.

Solution

Since all our code is already present on GitHub, I choose to simply use GitHub Actions for building the JAR binaries. Native integration with GitHub features (access to repository secrets, access tokens to push a new release) made it all the more easier.

Grabbing the version number from the root project.clj was trivial by using a simple bash command:

- name: Get Version
    run: |
    echo "MPRGS_VERSION=$(grep -oP -m 1 '(?<=")(?:\\.|[^"\\])*(?=")' project.clj)" >> $GITHUB_ENV

Here, the -m 1 argument instructs grep to only consider the first match in the entire body. The regex itself captures the first string encoded in double quotes[1].

If the build succeeds, then marvinpinto/action-automatic-releases is invoked with the following parameters:

- uses: "marvinpinto/action-automatic-releases@latest"
    with:
    repo_token: "${{ secrets.GITHUB_TOKEN }}"
    automatic_release_tag: "${{ env.MPRGS_VERSION }}"
    prerelease: false
    title: "v${{ env.MPRGS_VERSION }}"
    files: |
        LICENSE
        ./target/*.jar

Which simply uploads all the assets we describe as a part of the GitHub release. I had some issues with grabbing the environment variable (set-env is now deprecated due to a security vulnerability).

And finally:

Automated Release
Automated Release

And as a bonus, the Action also creates a changelog with the commits that were part of the newest build.