Introduction to CI/CD for Go Projects
Modern Go (Golang) development requires not only high-quality code but also reliable automation of build, testing, and deployment processes. CI/CD (Continuous Integration / Continuous Deployment) is an approach that allows you to automatically verify every code change, run tests, and deliver the finished application to users. In this article, we will thoroughly examine how to set up a CI/CD pipeline for Go projects using GitHub Actions.
GitHub Actions is a built-in CI/CD system that allows you to create workflows directly in your GitHub repository. This is especially convenient for Go developers, as it does not require configuring external services and integrates easily with existing infrastructure.
Why GitHub Actions for Go?
- Free for public repositories — up to 2000 build minutes per month for free
- Built-in Go support — official actions for setting up the environment
- Flexibility — can run on Ubuntu, Windows, macOS
- Caching — faster builds thanks to Go modules cache
- Matrix testing — parallel execution on different Go versions
Creating a Basic CI/CD Pipeline
Let's start by creating a simple workflow that will run on every push to the repository. To do this, you need to create a file .github/workflows/go.yml in the root of your project.
Basic workflow example
name: Go CI/CD
on: push: branches: [ main, develop ] pull_request: branches: [ main ]
jobs: build: runs-on: ubuntu-latest strategy: matrix: go-version: [ '1.21', '1.22' ]
steps: - uses: actions/checkout@v4
- name: Setup Go uses: actions/setup-go@v5 with: go-version: ${{ matrix.go-version }}
- name: Cache Go modules uses: actions/cache@v3 with: path: ~/go/pkg/mod key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} restore-keys: | ${{ runner.os }}-go-
- name: Install dependencies run: go mod download
- name: Build run: go build -v ./...
- name: Test run: go test -v -race -coverprofile=coverage.txt ./...
- name: Upload coverage uses: codecov/codecov-action@v3 with: file: ./coverage.txt flags: unittestsThis workflow does the following:
- Triggers on push to main/develop or when a pull request is created
- Tests on two Go versions (1.21 and 1.22)
- Caches modules to speed up subsequent builds
- Builds the project and runs tests with the
-raceflag (race detector) and-coverflag (code coverage) - Uploads the coverage report to Codecov
Advanced Settings: Linting and Security
For a professional Go project, simply building and testing the code is not enough. Let's add static analysis and security checks.
Adding linting with golangci-lint
- name: Lint uses: golangci/golangci-lint-action@v3 with: version: latest args: --timeout=5m --out-format=colored-line-number skip-pkg-cache: truegolangci-lint combines dozens of linters (govet, staticcheck, errcheck, and others) and produces a single report. This helps find potential errors, unused code, and style issues.
Security check with govulncheck
- name: Check vulnerabilities run: | go install golang.org/x/vuln/cmd/govulncheck@latest govulncheck ./...The govulncheck utility analyzes project dependencies for known vulnerabilities from the Go Vulnerability Database. This is critical