DEV Community

Cover image for 🚀 GitHub Action for release your Go projects as fast and easily as possible
Vic Shóstak
Vic Shóstak

Posted on • Updated on

🚀 GitHub Action for release your Go projects as fast and easily as possible

Introduction

Hello, DEV World! 😉 Continuing the series of articles on automating routine using the excellent CI/CD tool — GitHub Actions.

It's time to automate the releases of your applications written on Go!

📝 Table of contents

🤔 What will we automate?

If you've ever faced the challenge of releasing a project written on Go for different platforms/OS, you already know what kind of problems you may come across. If not, I will bring some of them:

  • You need to constantly monitor the features of each OS (for example, specific slashes in the paths).
  • You need to create archives manually and upload them to the release page on GitHub.
  • You need to look at all the commits to make CHANGELOG for a new version.
  • ...and many more!

So, what if I told you that there is a tool that will allow you to do all this (and more) automatically after creating a tag in your repository?

I'm not kidding, it allows you to do all this with GoReleaser GitHub action 👇

GitHub logo goreleaser / goreleaser-action

GitHub Action for GoReleaser

GoReleaser Logo

GoReleaser Action

GitHub Action for GoReleaser

GitHub release GitHub marketplace Test workflow Codecov


GoRelease Action

Usage

GoReleaser Action runs goreleaser, please follow its docs for more information about how to customize what GoReleaser do.

Workflow

name: goreleaser

on:
  pull_request:
  push:

permissions:
  contents: write

jobs:
  goreleaser:
    runs-on: ubuntu-latest
    steps:
      -
        name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0
      -
        name: Set up Go
        uses: actions/setup-go@v4
      -
        name: Run GoReleaser
        uses: goreleaser/goreleaser-action@v5
        with:
          # either 'goreleaser' (default) or 'goreleaser-pro'
          distribution: goreleaser
          version: latest
          args: release --clean
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          # Your GoReleaser Pro key, if you are using the 'goreleaser-pro' distribution
          # GORELEASER_KEY: ${{ secrets.GORELEASER_KEY }}
Enter fullscreen mode Exit fullscreen mode

IMPORTANT: note the fetch-depth: 0 input in Checkout step…

↑ Table of contents

👀 Repository structure

For a short, project will be contain very simple function:

package main

import "fmt"

func main() {
    fmt.Println("Hi, DEV World! 😉")
}
Enter fullscreen mode Exit fullscreen mode

And the repository structure will be as simple as that:

.
├── .github
│   └── workflows
│       └── release_build.yml  # <-- GitHub Action
└── main.go                    # <-- main function
Enter fullscreen mode Exit fullscreen mode

↑ Table of contents

🤖 Configure GitHub Action

Let's move on to the main character of our story. Look at the listing of the file release_build.yml, which already has a lot of familiar elements (if you did read my previous articles about GitHub Action 😏):

name: Release Go project

on:
  push:
    tags:
      - "*" # triggers only if push new tag version, like `0.8.4` or else

jobs:
  build:
    name: GoReleaser build
    runs-on: ubuntu-latest

    steps:
      - name: Check out code into the Go module directory
        uses: actions/checkout@v2
        with:
          fetch-depth: 0 # See: https://goreleaser.com/ci/actions/

      - name: Set up Go 1.14
        uses: actions/setup-go@v2
        with:
          go-version: 1.14
        id: go

      - name: Run GoReleaser
        uses: goreleaser/goreleaser-action@master
        with:
          version: latest
          args: release --rm-dist
        env:
          GITHUB_TOKEN: ${{ secrets.GO_RELEASER_GITHUB_TOKEN }}
Enter fullscreen mode Exit fullscreen mode

Yes, GitHub automatically creates a GITHUB_TOKEN secret to use in your workflow, but I recommend to create your own token with repo scopes here:

GITHUB_TOKEN

And now, create new GitHub secret (GO_RELEASER_GITHUB_TOKEN in my case):

GitHub secret

↑ Table of contents

✅ Troubleshooting

If your file with main() function is not in the root directory of your repository, GoReleaser will generate an error. Therefore, you will need to specify the correct directory in the step settings, for example like this:

# ...

    steps:

      # ...

      - name: Run GoReleaser
        uses: goreleaser/goreleaser-action@master
        with:
          version: latest
          args: release --rm-dist
          workdir: ./cmd/myapp # <-- path to directory with main() func
        env:
          GITHUB_TOKEN: ${{ secrets.GO_RELEASER_GITHUB_TOKEN }}
Enter fullscreen mode Exit fullscreen mode

↑ Table of contents

🚀 Time to release!

Create new release with tag (in my case, it's 0.8.4) and go to Actions page in order to follow up on the job:

go releaser job

After successfully completing the job, go to release page to see awesome result: CHANGELOG with all of your commits (between two versions), checksums.txt file and uploaded archives with compiled apps for all platforms!

release page

That's it! Just like that! 🎉

↑ Table of contents

🎯 Real-life example

If the screenshots above are not enough, I invite you to look at the one of my projects, where I use GoReleaser action in real-life:

GitHub logo create-go-app / cli

✨ A complete and self-contained solution for developers of any qualification to create a production-ready project with backend (Go), frontend (JavaScript, TypeScript) and deploy automation (Ansible, Docker) by running only one CLI command.

Create Go App

Create Go App CLI

Go version Go report Code coverage Wiki License

Create a new production-ready project with backend (Golang) frontend (JavaScript, TypeScript) and deploy automation (Ansible Docker) by running only one CLI command.

Focus on writing your code and thinking of the business-logic! The CLI will take care of the rest.

⚡️ Quick start

First, download and install Go. Version 1.20 or higher is required.

❗️ Note: If you're looking for the Create Go App CLI for other Go versions: 1.16, 1.17.

Installation is done by using the go install command:

go install github.com/create-go-app/cli/v4/cmd/cgapp@latest
Enter fullscreen mode Exit fullscreen mode

Or see the repository's Release page, if you want to download a ready-made deb, rpm, apk or Arch Linux package.

Also, GNU/Linux and macOS users available way to install via Homebrew:

# Tap a new formula:
brew tap create-go-app/tap

# Installation:
brew install create-go-app/tap/cgapp
Enter fullscreen mode Exit fullscreen mode

Let's create a new project via interactive console UI (or CUI

↑ Table of contents

💬 Questions for better understanding

  1. Which parameter in the GitHub Actions config is triggering job?
  2. Why we need to define fetch-depth: 0 for actions/checkout action?
  3. What does the -rm-dist argument mean in Run GoReleaser step?

↑ Table of contents

✏️ Exercises for independent execution

  • Repeat everything you have seen in the article, but with your own Golang project. Please, write about your result & link to your shorter website in the comments below!
  • Change the triggering value so that it only works for major versions. Please, read more about software versioning here.

↑ Table of contents

Photos/Images by

  • GoReleaser Action repository & website (links: 1, 2)
  • GitHub repository settings (link)

P.S.

If you want more articles (like this) on this blog, then post a comment below and subscribe to me. Thanks! 😻

And of course, you can help me make developers' lives even better! Just connect to one of my projects as a contributor. It's easy!

My projects that need your help (and stars) 👇

  • 🔥 gowebly: A next-generation CLI tool for easily build amazing web applications with Go on the backend, using htmx & hyperscript and the most popular atomic/utility-first CSS frameworks on the frontend.
  • create-go-app: Create a new production-ready project with Go backend, frontend and deploy automation by running one CLI command.
  • 🏃 yatr: Yet Another Task Runner allows you to organize and automate your routine operations that you normally do in Makefile (or else) for each project.
  • 📚 gosl: The Go Snippet Library provides snippets collection for working with routine operations in your Go programs with a super user-friendly API and the most efficient performance.
  • 🏄‍♂️ csv2api: The parser reads the CSV file with the raw data, filters the records, identifies fields to be changed, and sends a request to update the data to the specified endpoint of your REST API.
  • 🚴 json2csv: The parser can read given folder with JSON files, filtering and qualifying input data with intent & stop words dictionaries and save results to CSV files by given chunk size.

Top comments (5)

Collapse
 
arnested profile image
Arne Jørgensen

[...] GitHub automatically creates a GITHUB_TOKEN secret to use in your workflow, but I recommend to create your own token [...]

I'm curious why you recommend that?

Collapse
 
koddr profile image
Vic Shóstak

Hi! Thank you for asking.

Now I've reread this place in my article and I don't really understand either :)

Usually, I use several secret variables for various manipulations of the repository. So, I am already used to making a new key.

If you don't need it, you may not follow my recommendation, but I wrote this "as for myself from the past" :D

Collapse
 
bryanbraun profile image
Bryan Braun

I was looking into this and I noticed that the README for goreleaser-action says that you may need to generate your own token if you want to publish to an external repo (which you'd need to do if you are publishing your project to homebrew, for example).

Collapse
 
mariusty profile image
mariusty

Just awesome detailed instructions, love them
I wish you had this blog when i was studying in uni :D

Collapse
 
koddr profile image
Vic Shóstak

Wow! Glad to hear it. 😘