Language Guide: Go
CircleCI supports building Go projects using any version of Go that can be installed in a Docker image. If you’re in a rush, just copy the sample configuration below into a .circleci/config.yml
in your project’s root directory and start building.
Quickstart: Demo Go reference project
We maintain a reference Go project to show how to build on CircleCI:
In the project you will find a commented CircleCI configuration file .circleci/config.yml
. This file shows best practice for using CircleCI with Go projects.
Sample configuration
version: 2
jobs: # basic units of work in a run
build: # runs not using Workflows must have a `build` job as entry point
docker: # run the steps with Docker
# CircleCI Go images available at: https://hub.docker.com/r/circleci/golang/
- image: cimg/go:1.16
auth:
username: mydockerhub-user
password: $DOCKERHUB_PASSWORD # context / project UI env-var reference
# CircleCI PostgreSQL images available at: https://hub.docker.com/r/circleci/postgres/
- image: cimg/postgres:9.6
auth:
username: mydockerhub-user
password: $DOCKERHUB_PASSWORD # context / project UI env-var reference
environment: # environment variables for primary container
POSTGRES_USER: circleci-demo-go
POSTGRES_DB: circle_test
parallelism: 2
environment: # environment variables for the build itself
TEST_RESULTS: /tmp/test-results # path to where test results will be saved
steps: # steps that comprise the `build` job
- checkout # check out source code to working directory
- run: mkdir -p $TEST_RESULTS # create the test results directory
- restore_cache: # restores saved cache if no changes are detected since last run
keys:
- go-mod-v4-{{ checksum "go.sum" }}
# Wait for Postgres to be ready before proceeding
- run:
name: Waiting for Postgres to be ready
command: dockerize -wait tcp://localhost:5432 -timeout 1m
- run:
name: Run unit tests
environment: # environment variables for the database url and path to migration files
CONTACTS_DB_URL: "postgres://circleci-demo-go@localhost:5432/circle_test?sslmode=disable"
CONTACTS_DB_MIGRATIONS: /home/circleci/project/db/migrations
# store the results of our tests in the $TEST_RESULTS directory
command: |
PACKAGE_NAMES=$(go list ./... | circleci tests split --split-by=timings --timings-type=classname)
gotestsum --junitfile ${TEST_RESULTS}/gotestsum-report.xml -- $PACKAGE_NAMES
- run: make # pull and build dependencies for the project
- save_cache:
key: go-mod-v4-{{ checksum "go.sum" }}
paths:
- "/go/pkg/mod"
- run:
name: Start service
environment:
CONTACTS_DB_URL: "postgres://circleci-demo-go@localhost:5432/circle_test?sslmode=disable"
CONTACTS_DB_MIGRATIONS: /home/circleci/project/db/migrations
command: ./workdir/contacts
background: true # keep service running and proceed to next step
- run:
name: Validate service is working
command: |
sleep 5
curl --retry 10 --retry-delay 1 -X POST --header "Content-Type: application/json" -d '{"email":"test@example.com","name":"Test User"}' http://localhost:8080/contacts
- store_artifacts: # upload test summary for display in Artifacts
path: /tmp/test-results
destination: raw-test-output
- store_test_results: # upload test results for display in Test Summary
path: /tmp/test-results
workflows:
version: 2
build-workflow:
jobs:
- build
Pre-built CircleCI Docker images
We recommend using a CircleCI pre-built image that comes pre-installed with tools that are useful in a CI environment. You can select the version you need from Docker Hub: https://hub.docker.com/r/circleci/golang/. The demo project uses an official CircleCI image.
Build the demo project yourself
A good way to start using CircleCI is to build a project yourself. Here’s how to build the Demo Go Project with your own account:
- Fork the Demo Go Project on GitHub to your own account
- Go to the Projects dashboard in the CircleCI app and click the Follow Project button next to the project you just forked.
- To make changes you can edit the
.circleci/config.yml
file and make a commit. When you push a commit to GitHub, CircleCI will build and test the project.
If you want to test your changes locally, use our CLI tool and run circleci build
.
Config walkthrough
This section explains the commands in .circleci/config.yml
Every config.yml
starts with the version
key. This key is used to issue warnings about breaking changes.
version: 2
Next, we have a jobs
key. If we do not use workflows and have only one job, it must be named build
. Below, our job specifies to use the docker
executor as well as the CircleCI created docker-image for golang 1.12. Next, we use a secondary image so that our job can also make use of Postgres. Finally, we use the environment
key to specify environment variables for the Postgres container.
jobs: # basic units of work in a run
build: # runs not using Workflows must have a `build` job as entry point
docker: # run the steps with Docker
# CircleCI Go images available at: https://hub.docker.com/r/circleci/golang/
- image: cimg/go:1.16
auth:
username: mydockerhub-user
password: $DOCKERHUB_PASSWORD # context / project UI env-var reference
# CircleCI PostgreSQL images available at: https://hub.docker.com/r/circleci/postgres/
- image: cimg/postgres:9.6
auth:
username: mydockerhub-user
password: $DOCKERHUB_PASSWORD # context / project UI env-var reference
environment: # environment variables for primary container
POSTGRES_USER: circleci-demo-go
POSTGRES_DB: circle_test
After setting up Docker we will set an environment variable to store the path to our test results. Note, this environment variable is set for the entirety of the job whereas the environment variables set for POSTGRES_USER
and POSTGRES_DB
are specifically for the Postgres container.
environment:
TEST_RESULTS: /tmp/test-results
Now we need to add several steps
within the build
job. Steps make up the bulk of a job.
Use the checkout
step to check out source code.
steps:
- checkout
Next we create a directory for collecting test results
- run: mkdir -p $TEST_RESULTS
Then we pull down the cache (if present). If this is your first run, this won’t do anything.
- restore_cache: # restores saved cache if no changes are detected since last run
keys:
- go-mod-v4-{{ checksum "go.sum" }}
And install the Go implementation of the JUnit reporting tool and other dependencies for our application. These are good candidates to be pre-installed in primary container.
Both containers (primary and postgres) start simultaneously. Postgres, however, may require some time to get ready. If our tests start before Postgres is available, the job will fail. It is good practice to wait until dependent services are ready; in this example Postgres is the only dependent service.
- run:
name: Waiting for Postgres to be ready
command: dockerize -wait tcp://localhost:5432 -timeout 1m
Now we run our tests. To do that, we need to set an environment variable for our database’s URL and path to the DB migrations files. This step has some additional commands, we’ll explain them below.
- run:
name: Run unit tests
environment:
CONTACTS_DB_URL: "postgres://rot@localhost:5432/circle_test?sslmode=disable"
CONTACTS_DB_MIGRATIONS: /home/circleci/project/db/migrations
command: |
PACKAGE_NAMES=$(go list ./... | circleci tests split --split-by=timings --timings-type=classname)
gotestsum --junitfile ${TEST_RESULTS}/gotestsum-report.xml -- $PACKAGE_NAMES
The command for running unit tests is more complicated than some of our other steps. Here we are using test splitting to allocate resources across parallel containers. Test splitting can help speed up your pipeline if your project has a large test suite.
Next we run our actual build command using make
- the Go sample project uses make to run build commands. If this build happens to pull in new dependencies, we will cache them in the save_cache
step.
- run: make
- save_cache:
key: v1-pkg-cache
paths:
- ~/.cache/go-build
Now we will start the Postgres dependent service, using curl
to ping it to validate that the service is up and running.
- run:
name: Start service
environment:
CONTACTS_DB_URL: "postgres://circleci-demo-go@localhost:5432/circle_test?sslmode=disable"
CONTACTS_DB_MIGRATIONS: /home/circleci/project/db/migrations
command: ./workdir/contacts
background: true # keep service running and proceed to next step
- run:
name: Validate service is working
command: |
sleep 5
curl --retry 10 --retry-delay 1 -X POST --header "Content-Type: application/json" -d '{"email":"test@example.com","name":"Test User"}' http://localhost:8080/contacts
If all went well, the service ran and successfully responded to the post request at localhost:8080
.
Finally, let’s specify a path to store the results of the tests. The store_test_results
step allows you to leverage insights to view how your test results are doing over time, while using the store_artifacts
step allows you to upload any type of file; in this case, also the test logs if one would like to inspect them manually.
- store_artifacts: # upload test summary for display in Artifacts
path: /tmp/test-results
destination: raw-test-output
- store_test_results: # upload test results for display in Test Summary
path: /tmp/test-results
Finally, we specify the workflow block. This is not mandatory (as we only have one job to sequence) but it is recommended.
workflows:
version: 2
build-workflow: # the name of our workflow
jobs: # the jobs that we are sequencing.
- build
Success! You just set up CircleCI for a Go app. Check out our Job page to see how this looks when building on CircleCI.
See also
See the Deploy document for example deploy target configurations.
How to use workflows, which are particularly useful for optimizing your pipelines and orchestrating more complex projects.
Refer to the Caching Dependencies document for more caching strategies.
Help make this document better
This guide, as well as the rest of our docs, are open source and available on GitHub. We welcome your contributions.
- Suggest an edit to this page (please read the contributing guide first).
- To report a problem in the documentation, or to submit feedback and comments, please open an issue on GitHub.
- CircleCI is always seeking ways to improve your experience with our platform. If you would like to share feedback, please join our research community.
Need support?
Our support engineers are available to help with service issues, billing, or account related questions, and can help troubleshoot build configurations. Contact our support engineers by opening a ticket.
You can also visit our support site to find support articles, community forums, and training resources.
CircleCI Documentation by CircleCI is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.