CI/CD for Go Projects: GitHub Actions from A to Z

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

CI/CD for Go Projects with GitHub Actions: Complete Guide



Automating build, testing, and deployment processes is an essential part of modern Go (Golang) development. GitHub Actions provides a powerful and flexible toolkit for building CI/CD pipelines directly in your repository. In this article, we will cover how to set up a full continuous integration and delivery cycle for a Go project, from simple testing to automatic deployment.



What is CI/CD and Why is it Important for Go?



CI (Continuous Integration) is the practice of frequently merging code into the main branch with automated building and testing. CD (Continuous Delivery/Deployment) is the automatic deployment of the finished application.

For Go projects, CI/CD is especially useful because:

  • Go compiles into a static binary, simplifying deployment
  • Fast testing thanks to Go's native speed
  • Automatic checking with linters and formatters (gofmt, golangci-lint)
  • Possibility of multi-platform builds (Linux, macOS, Windows)


GitHub Actions Basics for Go



GitHub Actions uses YAML files in the .github/workflows directory. Each file describes one or more workflows (pipelines).



Let's look at a basic workflow for a Go project:



name: Go CI

on: push: branches: [ main, develop ] pull_request: branches: [ main ]

jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up Go uses: actions/setup-go@v5 with: go-version: '1.22' - name: Cache Go modules uses: actions/cache@v4 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: Run tests run: go test -v -race -coverprofile=coverage.out ./... - name: Upload coverage uses: actions/upload-artifact@v4 with: name: coverage path: coverage.out


This workflow runs on pushes to main/develop and on pull requests. It sets up Go, caches dependencies, runs tests with the -race flag (race detector) and -coverprofile flag (code coverage).



Advanced Settings: Linters and Multi-Platform Builds



To maintain code quality, let's add a linter check. golangci-lint is the de facto standard for Go.



  lint:    runs-on: ubuntu-latest    steps:    - uses: actions/checkout@v4    - name: Set up Go      uses: actions/setup-go@v5      with:        go-version: '1.22'    - name: golangci-lint      uses: golangci/golangci-lint-action@v6      with:        version: latest        args: --timeout=5m ./...


Multi-platform builds are useful if your application needs to run on different operating systems:



  build:    needs: [test, lint]    strategy:      matrix:        os: [ubuntu-latest, macos-latest, windows-latest]        goarch: [amd64, arm64]        runs-on: ${{ matrix.os }}        steps:    - uses: actions/checkout@v4    - name: Set up Go      uses: actions/setup-go@v5      with:        go-version: '1.22'    - name: Build      run: |        GOARCH=${{ matrix.goarch }} go build -v -o myapp-${{ matrix.os }}-${{ matrix.goarch }} ./cmd/app


Note: For Windows, you will need to adjust the output file name (add .exe). Use if runner.os == 'Windows' or set the name via variables.



Automatic Deployment of a Go Application



For deployment, let's consider two popular scenarios: publishing a Docker image and uploading a binary to a server.



Blogs

Book Recommendations