9.1 KiB
9.1 KiB
Go 后端服务 Workflow 模板
适用于 Go 后端 API 服务、微服务、CLI 工具的 CI/CD workflow。
适用场景
- Go HTTP API 服务
- gRPC 微服务
- CLI 工具
- 需要构建 Docker 镜像的 Go 项目
环境要求
| 依赖 | Runner 要求 |
|---|---|
| Go 1.21+ | Runner 主机已安装 |
| Docker | Runner 主机已安装 |
Workflow 骨架模板
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 模板
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"]
缓存配置
缓存路径
path: |
~/go/pkg/mod # Go 模块缓存
~/.cache/go-build # Go 构建缓存
Key 计算
HASH=$(sha256sum go.mod go.sum | sha256sum | awk '{print $1}' | head -c 16)
构建参数说明
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 ./... |
使用步骤
- 复制上方 workflow 模板到
.gitea/workflows/your-service.yml - 修改
SERVICE_PREFIX和SERVICE_DIR为实际值 - 修改
paths和tags触发条件 - 根据项目需求填充 "用户自定义构建步骤" 部分
- 创建
Dockerfile.ci文件 - 配置 Secrets
- 推送代码触发 workflow
版本发布
# 创建并推送 tag
git tag your-service-1.0.0
git push origin your-service-1.0.0