Skip to main content

How to Create and Publish a Go Package (Golang)

This article covers how to create and publish a Go (Golang) package.

These instructions were written for a Mac. But they should easily translate to instructions for Linux or Windows.

Step 1. Install Go

If you need to install Go first:

  • Browse to https://go.dev/doc/install
  • Run the installer
  • Open up a terminal or command window to get to the command line
  • Run this command (exclude the $, which is meant to represent the command line prompt):
    • $ go version

Step 2. Install a code editor

I prefer to edit Go projects in Visual Studio Code. If you don’t have that IDE (Integrated Development Environment) installed, but would like to give it a try: 

  • Browse to: https://code.visualstudio.com/
  • Download and run the installer
  • To open it up on a Mac:
    • From the command line, browse to the root folder of a project
    • Run this command (exclude the $, include the period (.) at the end):
    • $ code .

Step 3. Add Go support to Visual Studio Code

If you are using Visual Studio Code, be sure to add Go support:

Step 4. Create a github account

To share your package with the world you need an account on a service where you can share git repos in the cloud. I prefer to use github, but any similar service will do.

If you do not have an account and you would like to set one up on github:

Step 5. Create a new project folder

At the command line create and/or browse to a folder where you keep your projects:

  • Add a new project folder
  • On a Mac I do it like this:
    • mkdir go-lib
    • cd go-lib

Step 6: Initialize a Go project

On the command line, adjust this command for your git service and username:

  • $ go mod init github.com/mitchallen/go-lib

You should see a response similar to this:

go: creating new go.mod: module github.com/mitchallen/go-lib

On a Mac you can verify the file was created doing this:

  • ls -ls
  • cat go.mod

You should see something like this:

module github.com/mitchallen/go-lib

go 1.18

Step 7. Create the library files

You need to create some empty files to update in later steps: 

On a Mac you can do it like this:

  • touch README.md
  • touch LICENSE
  • touch init.go
  • touch go-lib.go
  • touch go-lib_test.go

Notice that the test file ends with underscore (_) test (_test.go).  

This is how the default test tool knows that the file contains tests.

Step 8. Edit init.go

Paste this code into init.go and save it:

/**
* Author: Mitch Allen
* File: init.go
*/

package lib

import (
"fmt"
)

func init() {
fmt.Println("[go-lib] initializing ...")
}

Code Description

The code above includes an init function. The init function in Go is a special (and optional) function that is called when the package that it is in is imported. In this case I’m just using it to log a message. But you could use it for things like initializing a random seed, etc.

Step 9. Edit go-lib.go

Paste this code into go-lib.go and save it:

/**
* Author: Mitch Allen
* File: go-lib.go
*/

package lib

// Returns the sum of two numbers
func Add(a int, b int) int {
return a + b
}

// Returns the difference between two numbers
func Subtract(a int, b int) int {
return a - b
}

Code Description

The code above contains a few simple functions to add and subtract numbers.

The names of the functions begin with a capital letter so that they can be exported for use by other packages and programs.

If you want to keep a function private, start the function name with a lower case.

Step 10. Edit go-lib_test.go

Paste this code into go-lib_test.go and save it:

/**
* Author: Mitch Allen
* File: go-lib_test.go
*/

package lib

import (
"testing"
)

func TestAdd(t *testing.T) {
a := 1
b := 2
expected := a + b

if got := Add(a, b); got != expected {
t.Errorf("Add(%d, %d) = %d, didn't return %d", a, b, got, expected)
}
}

func TestSubtract(t *testing.T) {
a := 1
b := 2
expected := a - b

if got := Subtract(a, b); got != expected {
t.Errorf("Subtract(%d, %d) = %d, didn't return %d", a, b, got, expected)
}
}

Code Description

By default Go comes with rudimentary test capabilities that looks for files ending with “_test.go“.

The code above illustrates how to create basic tests for the package functions.

Step 11. Run the tests

You can run the tests using the following command:

  • go test

If everything passed, tidy up a bit by running:

  • go mod tidy

Then run the tests again, just to be sure:

  • go test

For more verbose output try this:

  • go test -v

Sometimes test results are cached. To make sure they are not, use this command:

  • go test -count 1
  • go test -v -count 1

For more information on testing, run this command:

  • go help testflag

Step 12. Update the README file

Fill in the README.md file with this, adjusting for your git repo path and username:

github.com/mitchallen/go-lib

Usage

Initialize your module

go mod init example.com/my-golib-demo

Get the go-lib module

Note that you need to include the v in the version tag.

go get github.com/mitchallen/[email protected]
package main

import (
"fmt"

"github.com/mitchallen/go-lib"
)

func main() {
fmt.Println(golib.Add(2,3))
fmt.Println(golib.Subtract(2,3))
}

Testing

Tagging

git tag v0.1.0
git push origin --tags

Step 13. Fill in the license file

Without the license file pkg.go.dev won’t display your documentation.

I use the MIT License. You can copy this text and adjust the copyright info line for yourself:

MIT License

Copyright 2022 Mitch Allen

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

Step 14. Publish the repo

  • Initialize the project for git:
    • git init
  • Add the files to git:
    • Note that you need to include the period at the end of this command:
    • git add .
  • Commit the files
    • git commit -m “init commit”
  • Create the repo
    • Go to your git cloud provider (like github) and create a new repo
    • Follow the instructions of your provider for creating the new repo

Example

Here is an example of how I created a repo for my package using github:

Next github prints out some instructions.

I followed the …or push an existing repository from the command line instructions.

Those instruction will be adjusted for your username:

Step 15. Tag the repo

To publish different versions of your package you need to tag it like this:

  • git tag v0.1.0
  • git push origin –tags

You need to update the tags after pushing or merging everything to the main branch.

Step 16. Publish the package

Technically when you create a public repo with your package you have already published it where Go can find it. Unlike other packager managers you don’t need to upload it anywhere. The repo is where Go will retrieve your package from.

But if you want to list it as part of a catalog, you can use the go list command.

See the instructions here:

To publish so others can find it, adjust this command for the path of your repo:

Every time you tag a new build you should run this command, adjusting for the new tag.

Verify the package was published by adjusting this browser search query for your git service username:

It can take a while for package listings to update, so don’t worry if you don’t see it right away.

Step 17. Test the package

To test the package, import it into a demo program.

  • Create a new project folder:
    • mkdir go-lib-demo 
    • cd go-lib-demo
  • Initialize the demo:
    • go mod init example.com/my-golib-demo
  • Get the package:
  • Create a test file:
    • touch demo.go
  • Edit demo.go
  • Paste in this code, adjust for your git repo username and save it:
package main

import (
"fmt"

"github.com/mitchallen/go-lib"
)

func main() {
fmt.Println(lib.Add(2, 3))
fmt.Println(lib.Subtract(2, 3))
}
  • Run the file:
    • go run demo.go

Conclusion

In this article you learned how to:

  • Create a Go (Golang) package
  • Test the package
  • Publish the package
  • List the package in a directory
  • Test the package by installing it in another project

References

  • Go Install – [1]
  • Visual Studio Code Install – [2]
  • Go with Visual Studio Code – [3]
  • GitHub – [4]
  • Publishing a Module – [5]
  • pkg.go.dev – [6]
  • pkg.go.dev/cmd/go/internal/test – [7]