15 March 2020

Publishing a Go module: getting up and running

There’s a certain joy from writing a library or package which you can reuse across multiple projects. Want to know what is even more satisfying? Other people consuming your code!

In this post I’ll share a few tips & tricks to make it easier when publishing a Golang module.

What is a Go module?

Before we get going, let’s take a look at what exactly is a module in Golang:

A module is a collection of Go packages stored in a file tree with a go.mod file at its root.

So if you want to publish a module, make sure it contains at least one package and a `go.mod file.

Example: parsing training schemes

As an amateur athlete, I train as part of a Track & Field club. Our trainer gives us an interval training program right after the warming up phase.

I want to be able to calculate the total distance per training. The perfect opportunity to write a reusable Go module.

The interval notation is written using the International Association of Athletics Federations (IAAF) Standard Representation of Running Training.

That’s a lot of words. Let’s take a look at some examples:

10 x 400 (72”) [2’]`

This means: 10 repetitions of 400m , with each repetition run at 72 seconds and two minutes recovery between the repetitions.

3x4x300(3000)[100mr/o &5’]

This means: 3 sets of 4 repetitions of 300m, with each repetition run at 3,000m pace, 100m active, roll-on recovery between the repetitions and 5 minutes between the sets.

In general, the notation is written in the form of:

sets x repetitions x distance (intensity/pace) [ recovery between reps, then recovery between sets]

To parse this notation and allow working with the data, I’ve created the go-iaaf-intervals module. It is based on the work of bwind who created the same module in Python. For me, this was the perfect opportunity to figure out how to publish a Go module.

3, 2, 1… Go!

Making the code public

The first thing you need to do is publish the code of your package so it’s publicly available.

I’ve published the go-iaaf-intervals module on GitHub, because that’s where most of my public work is stored. Other popular alternatives are GitLab and Bitbucket.

To provide clarity for people who want to consume your module, it really helps to add a license and provide a README file.

Marketing

Go Report Card

Promote your work and provide a shiny Go Report Card badge.

Go Report Card is a web application that generates a report on the quality of an open source go project. It uses several measures, including gofmt, go vet, go lint and gocyclo.

For the go-iaaf-go codebase, I’ve added it the the README. GitLab has a dedicated place for project badges.

If you don’t have an A+ rating yet, go and improve your code!

Continuous Integration with Travis

Another way to show people you’re serious about your module, is to configure automated tests and display the latest test result.

I’ve used Travis CI and added another badge with the status of the build for the last commit on the master branch.

Configuring Travis is straightforward. The configuration below will perform the tests for Golang v1.8, the latest version in the v1.x range and once agains the master branch of Golang.

.travis.yml

language: go
go:
  - 1.8
  - 1.x
  - master

script:
  - go test

matrix:
  allow_failures:
    - go: master

For more details, please refer to the Travis documentation on Building a Go Project.

Initial release

Add a Git-tag once your code is published. You can use the v0.x to indicate it’s an initial, unstable version.

Please note that you should use semantic versioning for modules. More about this on the Go blog.

After some time, if you are introducing breaking changes, it’s time for a v2.x release. There’s certain rules to follow in order to make it easier for consumers to migrate. These are documented in the post Go Modules: v2 and Beyond.

It does help to keep the API as small as possible initially. By doing so, you prevent the amount of possible breaking changes later on. In terms of documentation and releases, it’s easier to convert a private member into a public one that the other way around.

The initial release of the go-iaaf-intervals module

The initial release of the go-iaaf-intervals package.

pkg.go.dev

Now that all of the above is setup, it’s time to add your module to the https://pkg.go.dev website. It’s a centralised directory for Go modules.

To add a package or module, it should be fetched from proxy.golang.org. This can be achieved by using go get <module name>.

go get github.com/Voles/go-iaaf-intervals

After some time, your module will automatically be added to the directory.

The detail page provides a nice overview about the module:

  • the automatically generated documentation
  • an overview of the available versions
  • consumers of the module
  • modules that are being used by this module

https://pkg.go.dev/github.com/Voles/go-iaaf-intervals

Fin

Now you know the basics of publishing a module, nothing should stop you from publishing your beloved pet projects!

Credits

Cover photo by Kira auf der Heide on Unsplash