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"]