Go is a popular programming language developed by Google for building efficient and reliable software. One of the key features of Go is its built-in support for modules, which allow developers to organize their code and share it with others.

Go modules are a great way to share code with others, but there will be times when you want to keep your code private. This is where private Go modules come in.

Go does not have a central package server like other languages and instead, Go relies on the repository of where the package is distributed. You may see Go module names such as github.com/author/repo, meaning this is hosted on GitHub. The same can be applied for a private Go module.

Private Go modules allow developers to store their code under a private repository, such as GitHub, and still use it in their projects without having to make the code public.

In this article we’ll look at how to set up a private Go module in a few scenarios.

Go Get Module

To include a public package in the Go application, run the command go get:

go get github.com/author/go-module

As long as this module is publicly accessible, Go will include a reference to this in the project’s go.mod file and download the package.

Private Modules

When a Go package is behind a private repository, the go get command will fail as it won’t have the ability to fetch the package without some sort of authentication. The following sections will show you how to configure your project to pull private Go modules locally, in a GitHub Action and in a Dockerfile.

Private Modules in Localhost

GitHub Personal Access Token

In order for Go to access the private repository, a Personal Access Token from GitHub will be needed. You can create an access token from the GitHub settings: https://github.com/settings/tokens. Give the token a description and select the “repo” scope.

Configure Go with Personal Access Token

Once you have your access token, you’ll need to configure Go to use it when trying to access the private repository. You can do this by setting the GOPRIVATE environment variable to the hostname of the repository, and GONOPROXY variable to localhost. Finally set the global git config to use the token.

export GOPRIVATE=github.com/<username>/<reponame>
export GONOPROXY=localhost
export GITHUB_ACCESS_TOKEN=<your-token>

git config --global url."https://$GITHUB_ACCESS_TOKEN:[email protected]/".insteadOf "https://github.com/"

Use private modules

You can now use the private Go module by importing them into your project like any other Go module.

import "github.com/<username>/<reponame>/<module>"

Private Modules in GitHub Actions

Setting up private Go modules within GitHub Actions is similar to configuring this locally.

GitHub Secrets

Once a Personal Access Token is created from the steps above it will need to be added to the project’s GitHub Secrets where the GitHub Action will run.

Navigate to the GitHub repository settings and select “Secrets” from the sidebar. Here you can create a new secret and give it a name, such as GITHUB_ACCESS_TOKEN.

GitHub Action

Next, you’ll need to create the Go Build GitHub action.

Here’s an example of a basic GitHub Action that sets the environment variables from the Secrets and runs a Go script:

name: Go Build

on:
  push:
    branches:
      - main

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v2

      # Use the GitHub token for downloading private modules
      - name: Configure private token
        env:
          GH_ACCESS_TOKEN: ${{ secrets.GITHUB_ACCESS_TOKEN }}
        run: |
          git config --global url."https://${GH_ACCESS_TOKEN}:[email protected]/".insteadOf "https://github.com/"          

      # Run the application tests
      - name: Run tests
        run: go test

      # Build the Docker image by creating an .env file
      # and loading it in the Dockerfile in the next step.
      - name: Build Docker image
        run: |
          echo ${{ secrets.GITHUB_ACCESS_TOKEN }} > /.env
          docker build -t <your-image-name> .          

Private Module in Dockerfile

From the last step of the GitHub action, we run the docker build command and pass the GITHUB_ACCESS_TOKEN in a Docker Secrets .env file.

This command can also be run locally with the same arguments:

docker build -t <your-image-name> .

Example Dockerfile:

FROM golang:latest

COPY . .

# Read the GITHUB_ACCESS_TOKEN from the .env file
RUN --mount=type=secret,id=_env,dst=/.env

# Run the same git config command to use the token.
RUN git config --global url."https://${GITHUB_ACCESS_TOKEN}:[email protected]/".insteadOf "https://github.com/"

# go mod downlod now has access to private modules.
RUN go mod download

RUN go build

CMD ["./your-go-application"]

Related articles: