Introduction: Why CI/CD is Important for Go Projects
Modern Go (Golang) development requires not only writing clean and efficient code but also setting up processes that automate testing, building, and delivery of applications. CI/CD (Continuous Integration / Continuous Delivery) is a set of practices that allows you to quickly and safely deliver changes to production. For Go developers, GitHub Actions has become one of the most popular tools due to its tight integration with repositories and ease of setup.
In this article, we will break down how to create a full CI/CD pipeline for a Go project using GitHub Actions. You will learn how to automate testing, building binary files, and deploying to a server. All examples will be in Go (Golang) with practical steps.
1. Basics of GitHub Actions for Go
GitHub Actions is a built-in workflow automation system. Each workflow is a YAML file that describes the steps for building, testing, and deploying. For Go projects, a minimal pipeline includes:
- Setting up Go
- Caching dependencies
- Running tests
- Building the application
Workflow File Structure
Create a directory .github/workflows/ in the root of your repository and a file ci.yml. Here is the basic configuration for Go:
name: CI for Go project
on: push: branches: [ main, develop ] pull_request: branches: [ main ]
jobs: build-and-test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4
- name: Setup Go uses: actions/setup-go@v5 with: go-version: '1.22'
- name: Cache modules uses: actions/cache@v3 with: path: ~/go/pkg/mod key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} restore-keys: | ${{ runner.os }}-go-
- name: Download dependencies run: go mod download
- name: Lint code run: go vet ./...
- name: Run tests run: go test -v -race -coverprofile=coverage.out ./...
- name: Build binary file run: go build -o myapp ./cmd/main.goThis workflow runs on pushes to main or develop, as well as on pull requests. It checks the code for errors, runs tests with the race flag (data race detector), and builds the binary.
2. Advanced Pipeline: Testing and Code Quality
Basic checks are good, but for a serious Go project, you need more. Let's add static analysis and code coverage checks.
Adding golangci-lint
golangci-lint is a linter aggregator that includes go vet, errcheck, staticcheck, and others. Let's add it to the workflow:
- name: Setup golangci-lint uses: golangci/golangci-lint-action@v4 with: version: latest
- name: Run linter run: golangci-lint run ./...Code Coverage Report
Test coverage is an important quality metric. GitHub Actions can generate reports and even block PRs with low coverage:
- name: Generate coverage report run: go test -coverprofile=coverage.out -covermode=atomic ./...
- name: Check minimum coverage run: | go tool cover -func=coverage.out | grep total | awk '{print $3}' | sed 's/%//' > coverage.txt if [ $(cat coverage.txt) -lt 70 ]; then echo "Code coverage is less than 70%" exit 1 fiNow the workflow will fail if test coverage drops below 70%. This is an excellent practice for maintaining the quality of a Go project.
3. Building and Publishing a Docker Image
Go applications are often deployed as Docker containers. GitHub Actions allows you to aut