Save 500+ Hours of Maintenance Work With These 3 GitHub Actions
Tags: github, opensource, buildinpublic, githubactions
Published: 2023-12-03 13:32:54

GitHub Actions are awesome.

They help you ship high-quality software more quickly, without spending a lot of time and effort in the process. 

In this article, I’m sharing 3 GitHub Actions we use at [Flipt](https://github.com/flipt-io/flipt) that saved us more than 500 developer hours.

You can use these battle-tested actions and automate your GitHub workflow right away.

Let’s get rolling! 🚀

---
## TL;DR

- [GA #1: bufbuild actions](#ga--1--bufbuild-actions)
- [GA #2: devcontainers/ci](#ga--2--devcontainers-ci)
- [GA #3: goreleaser/goreleaser-action](#ga--3--goreleaser-goreleaser-action)

---

## [GA #1: bufbuild actions](https://github.com/bufbuild)

![bufbuild actions repo](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/duq365bhqabduuuw20sj.png)

For background, we at Flipt are heavy users of protocol buffers and GRPC. We offer both a GRPC and REST API for communication between Flipt and our user’s services. 

In the early days, working with GRPC and Protocol Buffers was a pain. You had to:

1. Make sure that you have the right versions of protoc (the protobuf compiler) 
2. Correct GRPC extensions to generate code for your language of choice. 
3. Be extremely careful about adding, updating, and deleting fields or messages in your GRPC protobuf files. Because doing something incorrectly would break backward compatibility for your users. 

Now, [Buf](https://buf.build/) allows us to automate all of this toil by:
- Generating code for our GRPC SDKs 
- Linting to make sure we don't break backward compatibility.

Here’s how we use Buf in our GitHub Actions:

1. We push new proto changes to the Buf Schema Registry after linting and running breaking changes checks.
2. After each release of Flipt, we trigger workflows for all of our GRPC SDKs to pull the latest changes from the BSR (above).
3. Then generate and publish new versions of our GRPC SDKs. (e.g. C# GRPC SDK)

[Link to full code](https://github.com/flipt-io/flipt/blob/40dff044341fe6aa0161bcdf7b592935bc75f9fe/.github/workflows/proto-push.yml)

This action automates the process of linting, publishing, and code generation saving hours if not days of manual work. 

## [GA #2: devcontainers/ci](https://github.com/devcontainers/ci)

![devcontainers/ci repo](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yev9n1xruk8pwpng360h.png)

Every maintainer wants a consistent environment for contributors to develop and test their code.
 
But setting up & provisioning devcontainers can be a challenge when done manually. And that’s where devcontainers action comes in. 

It creates and manages devcontainers for GitHub repositories. With this action, you can run commands for:

- CI
- Testing
- Building, etc

We love [devcontainers](https://containers.dev/) and GitHub Codespaces at Flipt. 

They are an easy way to standardize a development environment for contributors. Using codespaces, contributors can get a running developing Flipt right from the GitHub UI. 

If a contributor doesn’t want to use or pay for Codespaces, they can also run our devcontainer locally using VSCode + Docker. 

**There’s one challenge with devcontainers though.**

Keeping a devcontainer configuration up to date. Especially for a constantly changing project like Flipt. 

We solved this by leaning on the devcontainers/ci action to [build our devcontainer each day](https://github.com/flipt-io/flipt/blob/40dff044341fe6aa0161bcdf7b592935bc75f9fe/.github/workflows/devcontainer.yml). Now we can quickly resolve any issues with the build.

Trust me, using this action is a no-brainer.

## [GA #3: goreleaser/goreleaser-action](https://github.com/goreleaser/goreleaser-action)

![Go Releaser Action Repo](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/czjw8d200wcq4r0x0yrj.png)

[Goreleaser](https://goreleaser.com/) action makes it too easy to build, package, and publish Go binaries.

Additionally, you can:

- Cross-compile your Go project for multiple architectures
- Release to GitHub, GitLab and Gitea 
- Create nightly builds
- Push to Homebrew, DockerHub, Snap packages
- Create announcements for new releases on Twitter, Discord, Slack, etc

**Goreleaser saves us so much time and effort it’s unreal.**
 
Flipt binaries are published for 3 different architectures — amd64, x86_64, and arm64. 

Also, to keep the MacOS Gatekeeper process happy, we need to sign and notarize the binary of our MacOS (arm64) builds.

We leverage GoReleaser (Pro) to:

- First run two build workflows in parallel (one for Linux and one for MacOS) 
- And then merge the two results into a single job for publishing to GitHub Releases and DockerHub/GHCR/Homebrew.

If you’re interested, we have documented our entire release process [here](https://github.com/flipt-io/flipt/blob/main/RELEASE.md).

If you’re maintaining a Go project, always, always, use Goreleaser and spend saved time on more productive tasks.

## Wrapping Up

That’s it!

Hope you found the list useful.
Leave a ⭐ to support our work at [Flipt](https://github.com/flipt-io/flipt).

If you liked this post, follow us for more of open source related articles 🙂