# Go 后端服务 Workflow 模板 适用于 Go 后端 API 服务、微服务、CLI 工具的 CI/CD workflow。 ## 适用场景 - Go HTTP API 服务 - gRPC 微服务 - CLI 工具 - 需要构建 Docker 镜像的 Go 项目 ## 环境要求 | 依赖 | Runner 要求 | |------|------------| | Go 1.21+ | Runner 主机已安装 | | Docker | Runner 主机已安装 | ## Workflow 骨架模板 ```yaml name: Go Backend - Build & Publish on: push: paths: - 'your-service/**' # 修改为实际目录 - '.gitea/workflows/your-service.yml' tags: - 'your-service-*' # 修改为实际 tag 前缀 concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true env: SERVICE_PREFIX: your-service # 修改为实际服务名 SERVICE_DIR: your-service # 修改为实际目录名 GOPROXY: https://goproxy.cn,direct jobs: build-and-publish: name: Build & Publish runs-on: darwin-arm64 permissions: contents: read packages: write outputs: binary_name: ${{ steps.vars.outputs.binary_name }} git_tag: ${{ steps.vars.outputs.git_tag }} steps: - name: Checkout uses: actions/checkout@v4 with: fetch-depth: 0 - name: Verify Go environment run: | go version echo "GOPATH=$(go env GOPATH)" - name: Get go-hashfiles id: hash-go working-directory: ${{ env.SERVICE_DIR }} run: | HASH=$(sha256sum go.mod go.sum | sha256sum | awk '{print $1}' | head -c 16) echo "hash=${HASH}" >> "$GITHUB_OUTPUT" - name: Cache Go modules uses: https://github.com/actions/cache@v3 with: path: | ~/go/pkg/mod ~/.cache/go-build key: go-${{ env.SERVICE_PREFIX }}-${{ steps.hash-go.outputs.hash }} restore-keys: go-${{ env.SERVICE_PREFIX }}- - name: Set variables id: vars run: | git_tag=$(git describe --tags --abbrev=0 --always) registry=$(echo ${{ github.server_url }} | cut -d '/' -f 3) binary_name="${{ github.event.repository.name }}-${{ env.SERVICE_PREFIX }}" image_repo="${{ github.event.repository.name }}" { echo "git_tag=${git_tag}" echo "registry=${registry}" echo "binary_name=${binary_name}" echo "image_repo=${image_repo}" echo "latest_tag=${{ env.SERVICE_PREFIX }}-latest" } >> $GITHUB_ENV echo "binary_name=${binary_name}" >> $GITHUB_OUTPUT echo "git_tag=${git_tag}" >> $GITHUB_OUTPUT - name: Build working-directory: ${{ env.SERVICE_DIR }} env: CGO_ENABLED: 0 GOOS: linux GOARCH: amd64 run: | # ============================================ # 用户自定义构建步骤(按项目需求修改) # ============================================ # 代码生成(按需启用) # go generate ./... # go tool ent generate ./schema # go tool wire ./... # go tool oapi-codegen -config oapi.yaml api.yaml # go tool stringer -type=MyType ./... # 测试(按需启用) # go test ./... # go vet ./... # 构建(必须) go build -o ${{ env.binary_name }} \ -ldflags '-s -w -X main.GitTag=${{ env.git_tag }}' chmod +x ${{ env.binary_name }} - name: Upload artifact uses: actions/upload-artifact@v3 with: name: ${{ env.SERVICE_PREFIX }}-binary-linux-amd64 path: ${{ env.SERVICE_DIR }}/${{ env.binary_name }} - name: Docker - Login uses: docker/login-action@v3 with: registry: ${{ env.registry }} username: ${{ vars.REGISTRY_USERNAME }} password: ${{ secrets.REGISTRY_PASSWORD }} - name: Docker - Setup Buildx uses: docker/setup-buildx-action@v3 - name: Docker - Build & Push uses: docker/build-push-action@v6 with: context: ${{ env.SERVICE_DIR }} file: ./${{ env.SERVICE_DIR }}/Dockerfile.ci push: true platforms: linux/amd64 tags: | ${{ env.registry }}/${{ github.repository_owner }}/${{ env.image_repo }}:${{ env.latest_tag }} ${{ env.registry }}/${{ github.repository_owner }}/${{ env.image_repo }}:${{ env.git_tag }} cache-from: type=registry,ref=${{ env.registry }}/${{ github.repository_owner }}/${{ env.image_repo }}:buildcache cache-to: type=registry,ref=${{ env.registry }}/${{ github.repository_owner }}/${{ env.image_repo }}:buildcache,mode=max - name: Notify if: always() continue-on-error: true env: WEBHOOK_URL: ${{ vars.WEBHOOK_URL }} run: | status="${{ job.status }}" [ "$status" = "success" ] && status_text="Build Success" || status_text="Build Failed" curl -s -H "Content-Type: application/json" -X POST -d \ "{\"msg_type\":\"text\",\"content\":{\"text\":\"${{ env.binary_name }} ${status_text}\"}}" \ "$WEBHOOK_URL" || true release: name: Create Release runs-on: darwin-arm64 needs: build-and-publish if: startsWith(github.ref, 'refs/tags/') steps: - name: Checkout uses: actions/checkout@v4 with: fetch-depth: 0 - name: Download artifact uses: actions/download-artifact@v3 with: name: ${{ env.SERVICE_PREFIX }}-binary-linux-amd64 path: dist - name: Create Release env: GITEA_TOKEN: ${{ secrets.RELEASE_TOKEN }} BINARY_NAME: ${{ needs.build-and-publish.outputs.binary_name }} run: | git_tag=$(git describe --tags --abbrev=0) api_url="${{ github.server_url }}/api/v1" repo="${{ github.repository }}" # 生成校验和 cd dist sha256sum "${BINARY_NAME}" > "${BINARY_NAME}.sha256" cd .. # 创建 Release release_id=$(curl -s -X POST \ -H "Authorization: token $GITEA_TOKEN" \ -H "Content-Type: application/json" \ -d "{\"tag_name\":\"${git_tag}\",\"name\":\"Release ${git_tag}\"}" \ "${api_url}/repos/${repo}/releases" | jq -r '.id') # 上传二进制文件 curl -s -X POST \ -H "Authorization: token $GITEA_TOKEN" \ -F "attachment=@dist/${BINARY_NAME}" \ "${api_url}/repos/${repo}/releases/${release_id}/assets" # 上传校验和 curl -s -X POST \ -H "Authorization: token $GITEA_TOKEN" \ -F "attachment=@dist/${BINARY_NAME}.sha256" \ "${api_url}/repos/${repo}/releases/${release_id}/assets" ``` --- ## Dockerfile.ci 模板 ```dockerfile FROM alpine:latest # 安装时区数据和证书 RUN apk add --no-cache tzdata ca-certificates # 设置时区 ENV TZ=Asia/Shanghai # 复制构建好的二进制文件 # 注意:需要在 docker build 时通过 --build-arg 传递 BINARY_NAME # 或者直接写死二进制文件名 ARG BINARY_NAME=server COPY ${BINARY_NAME} /app/server WORKDIR /app # 健康检查(按需修改端口和路径) HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ CMD wget --no-verbose --tries=1 --spider http://localhost:8080/health || exit 1 EXPOSE 8080 ENTRYPOINT ["/app/server"] ``` --- ## 缓存配置 ### 缓存路径 ```yaml path: | ~/go/pkg/mod # Go 模块缓存 ~/.cache/go-build # Go 构建缓存 ``` ### Key 计算 ```bash HASH=$(sha256sum go.mod go.sum | sha256sum | awk '{print $1}' | head -c 16) ``` --- ## 构建参数说明 ```bash CGO_ENABLED=0 # 禁用 CGO,生成静态链接二进制 GOOS=linux # 目标操作系统 GOARCH=amd64 # 目标架构 -ldflags '-s -w' # 去除符号表和调试信息,减小体积 -X main.GitTag=... # 注入版本信息 ``` --- ## Secrets 配置 | Secret | 用途 | |--------|------| | `REGISTRY_PASSWORD` | Docker Registry 密码 | | `RELEASE_TOKEN` | Gitea API 令牌(创建 Release) | --- ## 常见代码生成工具 根据项目使用的框架,在 Build 步骤中添加相应的生成命令: | 框架/工具 | 命令 | |----------|------| | Ent (ORM) | `go tool ent generate ./schema` | | Wire (DI) | `go tool wire ./...` | | oapi-codegen | `go tool oapi-codegen -config oapi.yaml api.yaml` | | Stringer | `go tool stringer -type=MyType ./...` | | Protobuf | `protoc --go_out=. --go-grpc_out=. *.proto` | | go generate | `go generate ./...` | --- ## 使用步骤 1. 复制上方 workflow 模板到 `.gitea/workflows/your-service.yml` 2. 修改 `SERVICE_PREFIX` 和 `SERVICE_DIR` 为实际值 3. 修改 `paths` 和 `tags` 触发条件 4. 根据项目需求填充 "用户自定义构建步骤" 部分 5. 创建 `Dockerfile.ci` 文件 6. 配置 Secrets 7. 推送代码触发 workflow --- ## 版本发布 ```bash # 创建并推送 tag git tag your-service-1.0.0 git push origin your-service-1.0.0 ```