disclaimer : This is not a tutorial. It’s just a story how I released a project within minutes.

Intro.

Let me set the context first. While working on my day job, I ran into a simple need: converting a UUID to base64. I searched for online tools, but none of them did exactly what I wanted.

Note: Yeah, I know now—you can just use a simple terminal command:

But at the time, I needed a quick solution. So, I wrote a small Go script to convert a UUID to base64:

package main

import (
	"encoding/base64"
	"fmt"
	"os"
	"github.com/gofrs/uuid"
)

func main() {
	uuidString := os.Args[1]

	uuidVal,err := uuid.FromString(uuidString)
	if err != nil {
		fmt.Println(err.Error())
		return
	}

	b64 := base64.StdEncoding.EncodeToString(uuidVal.Bytes())
	fmt.Printf("base64: %s",b64)
}

output: output

Then it hit me, “What not turn this into a TUI app?". At the time, I was exploring bubbletea for a side project.

The project was done in 24 hours—it didn’t take much effort. Here’s the project: ub2.

Since I needed it on my work laptop and it’s a terminal app, using go install was the better choice.

And that brought me to the real question: “How do I release this properly?”

Goreleaser.

I did a quick google search, and goreleaser popped up.

It’s pretty interesting: A cli app that helps you to release your Go,Zig,Rust,Python andTypescript projects.

How to start ?

After installing the goreleaser, cd into your project directly and use the following command : init

A .goreleaser.yaml file is created in the root directory.

# This is an example .goreleaser.yml file with some sensible defaults.
# Make sure to check the documentation at https://goreleaser.com

# The lines below are called `modelines`. See `:help modeline`
# Feel free to remove those if you don't want/need to use them.
# yaml-language-server: $schema=https://goreleaser.com/static/schema.json
# vim: set ts=2 sw=2 tw=0 fo=cnqoj

version: 2

before:
  hooks:
    # You may remove this if you don't use go modules.
    - go mod tidy
    # you may remove this if you don't need go generate
    - go generate ./...

builds:
  - env:
      - CGO_ENABLED=0
    goos:
      - linux
      - windows
      - darwin

archives:
  - formats: [tar.gz]
    # this name template makes the OS and Arch compatible with the results of `uname`.
    name_template: >-
      {{ .ProjectName }}_
      {{- title .Os }}_
      {{- if eq .Arch "amd64" }}x86_64
      {{- else if eq .Arch "386" }}i386
      {{- else }}{{ .Arch }}{{ end }}
      {{- if .Arm }}v{{ .Arm }}{{ end }}
    # use zip for windows archives
    format_overrides:
      - goos: windows
        formats: [zip]

changelog:
  sort: asc
  filters:
    exclude:
      - "^docs:"
      - "^test:"

release:
  footer: >-

    ---

    Released by [GoReleaser](https://github.com/goreleaser/goreleaser).

This file is enough for the release if the goal is simply install the project using go install.

Now we need GITHUB_TOKEN and tag.

Github Token:

For generating token from github, you can refer this guide.

Step 1: Store the Token
Create a .env.sh file to store the token using this format:

export GITHUB_TOKEN="<github.token>"

Note : Treat the token like a password – Do not share it!
If.env.sh is in the root directory, make sure to add it to .gitignore to avoid accidentally committing it.

Step 2: Using the Token
You can use this github token two ways:

  1. Source the .env.sh file.
source .env.sh

This makes the token available as an environment variable in the current terminal session. Any program running in this session can access it via $GITHUB_TOKEN.

  1. Add env_file in .goreleaser.yaml` file.

Add this line to your .goreleaser.yaml

env_files:
  github_token: ./.env.sh

Tags:

Adding tag is pretty straight forward. After the first commit pushed to the remote ( here it is github).

Step 1:Create Tag

git tag -a v0.1.0 -m "message"

Definition:
For versioning, we normally uses this format :- vx.y.z
x : Major version ( For breaking changes )
y : Minor version ( For backwards compatible changes )
z : Patch version ( For bug fixes )

Step 2:Push Tag to Remote

git push origin v0.1.0

Once everything is set up, it all comes down to a single command.

goreleaser release --clean

That’s it! Your software is now out in the world!

Note: --clean is used to delete the dist directory, where the builds exists. You can skip the flag for the first release.

You can find the released zip files in the Releases section in the your github repo screen. releases

Installing using go :

Now you can install the app using go by simpling using the command:

go install github.com/Abhishekkarunakaran/ub2@latest

goreleaser even helped me set up a Homebrew tap so the tool can now be installed via brew—but that’s a story for another post.

Conclusion.

If you’re building CLI tools in Go, goreleaser is a no-brainer. It turns your local script into a downloadable, installable project with almost zero overhead.