使用 GitHub Actions 为 Go 项目实现 CI/CD:完整指南
自动化构建、测试和部署流程是现代 Go (Golang) 开发的重要组成部分。GitHub Actions 提供了一套强大且灵活的工具包,可直接在您的仓库中构建 CI/CD 管道。在本文中,我们将介绍如何为 Go 项目设置完整的持续集成和交付周期,从简单的测试到自动部署。
什么是 CI/CD,为什么它对 Go 很重要?
CI(持续集成)是指频繁地将代码合并到主分支,并进行自动构建和测试。CD(持续交付/部署)则是指自动部署已完成的应用程序。
对于 Go 项目,CI/CD 尤其有用,因为:
- Go 可编译为静态二进制文件,简化了部署过程
- 得益于 Go 原生的速度,测试速度很快
- 使用 linter 和格式化工具(
gofmt、golangci-lint)进行自动检查 - 支持多平台构建(Linux、macOS、Windows)
Go 项目的 GitHub Actions 基础
GitHub Actions 使用 .github/workflows 目录下的 YAML 文件。每个文件描述一个或多个工作流(管道)。
让我们看一个 Go 项目的基本工作流:
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此工作流在推送到 main/develop 分支以及拉取请求时运行。它会设置 Go 环境、缓存依赖项、使用 -race 标志(竞态检测器)和 -coverprofile 标志(代码覆盖率)运行测试。
高级设置:Linter 和多平台构建
为了保持代码质量,我们添加一个 linter 检查。对于 Go 来说,golangci-lint 是事实上的标准。
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 ./...如果您的应用程序需要在不同的操作系统上运行,那么多平台构建会非常有用:
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注意:对于 Windows,您需要调整输出文件名(添加 .exe)。可以使用 if runner.os == 'Windows' 或通过变量设置名称。
Go 应用程序的自动部署
对于部署,让我们考虑两种常见场景:发布 Docker 镜像和将二进制文件上传到服务器。