CI/CD for Go Projects: GitHub Actions from A to Z
\n\nIn modern software development, automating the processes of building, testing, and deploying (CI/CD) has become not just a convenience, but a necessity. For Go (Golang) projects, using GitHub Actions is one of the simplest and most effective ways to organize continuous integration and delivery. In this article, we will break down the full cycle of setting up a CI/CD pipeline for Go applications, starting from basic configuration to automatic deployment.
\n\nWhat is GitHub Actions and why is it important for Go?
\n\nGitHub Actions is a built-in platform for automating workflows in GitHub repositories. It allows you to create pipelines that trigger on specific events: push to a branch, creating a pull request, publishing a release, etc.
\n\nFor Go projects, GitHub Actions offers several key advantages:
\n- \n
- Fast compilation — Go compiles very quickly, reducing pipeline execution time. \n
- Static linking — Go binaries do not require external dependencies, simplifying deployment. \n
- Built-in testing — the
go testutility integrates perfectly with CI systems. \n - Cross-platform — easily build binaries for different OS and architectures. \n
Setting up a basic CI pipeline
\n\nLet's start by creating a simple workflow that will run tests and check the code for compliance with Go standards. To do this, create a .github/workflows directory in the root of your repository and a ci.yml file.
Example of a basic configuration:
\n\nname: CI Pipeline for Go\n\non:\n push:\n branches: [ main, develop ]\n pull_request:\n branches: [ main ]\n\njobs:\n build-and-test:\n runs-on: ubuntu-latest\n \n steps:\n - name: Checkout code\n uses: actions/checkout@v4\n\n - name: Setup Go\n uses: actions/setup-go@v5\n with:\n go-version: '1.22'\n\n - name: Cache Go modules\n uses: actions/cache@v4\n with:\n path: ~/go/pkg/mod\n key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}\n restore-keys: |\n ${{ runner.os }}-go-\n\n - name: Download dependencies\n run: go mod download\n\n - name: Run vet\n run: go vet ./...\n\n - name: Run tests\n run: go test -v -race -count=1 ./...\n\n - name: Build\n run: go build -o myapp ./cmd/app\n\nThis workflow performs the following steps:
\n- \n
- Clones the repository. \n
- Installs Go version 1.22. \n
- Caches modules to speed up subsequent runs. \n
- Downloads dependencies via
go mod download. \n - Runs
go vetfor static analysis. \n - Executes tests with the
-raceflag to detect data races. \n - Builds the binary file. \n
Advanced configuration: cross-platform build and linters
\n\nGo makes it easy to build applications for different platforms. Let's add a build matrix and the golangci-lint linter to the pipeline.
Updated ci.yml file:
name: Advanced Go CI/CD\n\non:\n push:\n branches: [ main ]\n pull_request:\n branches: [ main ]\n\njobs:\n lint:\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@v4\n - uses: actions/setup-go@v5\n with:\n go-version: '1.22'\n - name: golangci-lint\n uses: golangci/golangci-lint-action@v4\n with:\n version: latest\n args: --timeout=5m\n\n test:\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@v4\n - uses: actions/setup-go@v5\n with:\n go-version: '1.22'\n - run: go test -v -race -coverprofile=covera