Stream of Consciousness

Mark Eschbach's random writings on various topics.

Automatic release of a Go library

Categories: programming tech

Tags: golang continuous-deployment

github.com/meschbach/go-junk-bucket has gotten to the point it would be awesome to increment versions every merge. This would allow easier migration between versions and updated changes.

My goal is:

  • Increment the version number. This should be merged based on the following rules as indicated by a commit message within the merging branch:
    • By default a patch tag should be created.
    • If the text of a commit contains some tag for major or minor then those should be chosen instead.
    • If multiple major/minors exist then it should only increment once with the largest one.
  • Incremented version number should tag the repository and create a Github release.

First look at existing work

There are many Github Actions out there. Here is a survey of the top 3 I found while searching for version bump.
These look great but not exactly what I was looking for. All three top actions just produce a version number, not the actual tags or releases.

reecetech/version-increment

Benefits:

  • Version bumps based on keywords in commit messages.
  • Highly configurable for how version numbers are chosen.
  • Tag based: Can be configured to pull tags from Github via the API or from the local source.

Drawbacks:

  • Documentation is not very clear.
  • Only calculates the next version number, does not create commits or releases.
  • Has a lot of extra features such as several version styles.

MCKanpolat/auto-semver-action

Benefits:

  • Version bumps based on keywords in commit messages.
  • Relatively simple Typescript release.
  • Can bump a lot of elements via commit messages.
  • Tag based: Can be configured to pull tags from Github via the API or from the local source.

Drawbacks:

  • Only calculates the next version number, does not create commits or releases.

IgorGov/auto-inc-ver

Benefits:

  • Version bumps based on keywords in commit messages.
  • Relatively simple Typescript release.
  • Can bump a lot of elements via commit messages.
  • Tag based: Can be configured to pull tags from Github via the API or from the local source.

Drawbacks:

  • Python based, which means yet another runtime for my Go projects.
  • Only calculates the next version number, does not create commits or releases.

Another Search

In attempting to find an out of the box solution, I quickly found myself at anothrNick/github-tag-action which looks most promising. This gives a quick example of how to increment the version and flush it back to Github using the following:

name: Bump version
on:
  pull_request:
    types:
      - closed
    branches:
      - master

jobs:
  build:
    if: github.event.pull_request.merged == true
    runs-on: ubuntu-22.04
    permissions:
      contents: write
    steps:
    - uses: actions/checkout@v4
      with:
        ref: ${{ github.event.pull_request.merge_commit_sha }}
        fetch-depth: '0'

    - name: Bump version and push tag
      uses: anothrNick/github-tag-action@v1 # Don't use @master or @v1 unless you're happy to test the latest version
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # if you don't want to set write permissions use a PAT token
        WITH_V: true
        PRERELEASE: true

This looks similar to what I want to do!

Giving it a whirl!

So in the end I need to level up my Github Action knowledge to work on dependent jobs and merge actions. I opted for the simplest integration which was to add the following to my current pipeline.

name: Go

on: [push]

jobs:
  maybe_release:
    if: "${{ contains(github.ref, 'main') }}"
    needs:
    - build_test
    runs-on: ubuntu-latest

    permissions:
      contents: write
    steps:
    - uses: actions/checkout@v4
      with:
        ref: ${{ github.event.pull_request.merge_commit_sha }}
        fetch-depth: '0'

    - name: Bump version and push tag
      uses: anothrNick/github-tag-action@v1 # Don't use @master or @v1 unless you're happy to test the latest version
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # if you don't want to set write permissions use a PAT token
        WITH_V: true
        DEFAULT_BUMP: patch

This works and catches both PR and pushes onto main . If the project continues to get interest I will look into a better paved road for my projects.