Files
opencode/skill/gitea/workflow-templates/rust-backend.md
Voson f36b0159bd feat(gitea): 新增 Rust 后端工作流模板并更新现有模板
- 添加完整的 Rust 后端 CI/CD 工作流模板
- 更新 Android、Go、Node.js、微信小程序工作流模板
- 优化工作流生成器配置
- 更新 Gitea skill 主文档
2026-01-29 22:52:32 +08:00

14 KiB
Raw Blame History

Rust 后端服务 Workflow 模板

适用于 Rust 后端 API 服务、微服务、CLI 工具的 CI/CD workflow。

适用场景

  • Rust HTTP API 服务Axum、Actix-Web、Warp
  • gRPC 微服务
  • CLI 工具
  • 需要构建 Docker 镜像的 Rust 项目
  • 跨平台编译需求

环境要求

依赖 Runner 要求
Rust 1.75+ Runner 主机已安装
Docker Runner 主机已安装
Cross 编译工具 可选,用于多平台构建

Workflow 骨架模板

name: API Hub CI/CD

on:
  push:
    branches: [main]
    tags: ['v*']
  pull_request:
    branches: [main]

env:
  CARGO_TERM_COLOR: always
  SERVICE_NAME: api-hub

jobs:
  test:
    name: 测试
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: 安装 Rust
        uses: actions-rust-lang/setup-rust-toolchain@v1
        with:
          toolchain: stable
          components: rustfmt, clippy

      - name: 缓存 Cargo 依赖
        uses: actions/cache@v4
        with:
          path: |
            ~/.cargo/bin/
            ~/.cargo/registry/index/
            ~/.cargo/registry/cache/
            ~/.cargo/git/db/
            target/
          key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}

      - name: 检查代码格式
        run: cargo fmt -- --check

      - name: 运行 Clippy 检查
        run: cargo clippy -- -D warnings

      - name: 运行测试
        run: cargo test --verbose

      - name: 构建
        run: cargo build --release --verbose

  build-docker:
    name: 构建 Docker 镜像
    needs: test
    if: github.event_name == 'push' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v'))
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: 设置 Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: 登录容器仓库
        uses: docker/login-action@v3
        with:
          registry: ${{ env.registry }}
          username: ${{ github.actor }}
          password: ${{ secrets.REGISTRY_TOKEN }}

      - name: 提取元数据
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: ${{ env.registry }}/${{ github.repository }}/${{ env.SERVICE_NAME }}
          tags: |
            type=ref,event=branch
            type=semver,pattern={{version}}
            type=semver,pattern={{major}}.{{minor}}
            type=sha,prefix=,suffix=,format=short

      - name: 构建并推送镜像
        uses: docker/build-push-action@v5
        with:
          context: .
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
          cache-from: type=gha
          cache-to: type=gha,mode=max

  health-check:
    name: 健康检查
    needs: build-docker
    if: github.event_name == 'push' && github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: 运行健康检查测试
        run: |
          # 启动服务
          docker run -d --name api-hub-test -p 8080:8080 ${{ env.registry }}/${{ github.repository }}/${{ env.SERVICE_NAME }}:main
          
          # 等待服务启动
          sleep 10
          
          # 健康检查
          echo "检查健康端点..."
          curl -f http://localhost:8080/health || exit 1
          
          # 就绪检查
          echo "检查就绪端点..."
          curl -f http://localhost:8080/ready || exit 1
          
          # 存活检查
          echo "检查存活端点..."
          curl -f http://localhost:8080/live || exit 1
          
          echo "所有健康检查通过!"
          
          # 清理
          docker stop api-hub-test
          docker rm api-hub-test

  release:
    name: 创建发布
    needs: test
    if: startsWith(github.ref, 'refs/tags/v')
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: 安装 Rust
        uses: actions-rust-lang/setup-rust-toolchain@v1
        with:
          toolchain: stable
          targets: x86_64-unknown-linux-gnu, x86_64-unknown-linux-musl

      - name: 构建 Release 二进制文件
        run: |
          # Linux GNU 版本
          cargo build --release --target x86_64-unknown-linux-gnu
          strip target/x86_64-unknown-linux-gnu/release/${{ env.SERVICE_NAME }}
          tar czf ${{ env.SERVICE_NAME }}-${{ github.ref_name }}-x86_64-linux-gnu.tar.gz \
            -C target/x86_64-unknown-linux-gnu/release ${{ env.SERVICE_NAME }}
          
          # Linux MUSL 版本 (静态链接)
          cargo build --release --target x86_64-unknown-linux-musl
          strip target/x86_64-unknown-linux-musl/release/${{ env.SERVICE_NAME }}
          tar czf ${{ env.SERVICE_NAME }}-${{ github.ref_name }}-x86_64-linux-musl.tar.gz \
            -C target/x86_64-unknown-linux-musl/release ${{ env.SERVICE_NAME }}

      - name: 生成 Changelog
        id: changelog
        run: |
          echo "CHANGELOG<<EOF" >> $GITHUB_OUTPUT
          if [ -f CHANGELOG.md ]; then
            # 提取当前版本的变更日志
            awk '/^## \[${{ github.ref_name }}\]/{flag=1;next} /^## \[/{flag=0} flag' CHANGELOG.md || echo "查看完整变更日志CHANGELOG.md"
          else
            echo "## ${{ github.ref_name }}"
            echo ""
            echo "### 变更内容"
            echo "- 发布版本 ${{ github.ref_name }}"
            echo ""
            echo "### 下载"
            echo "- \`${{ env.SERVICE_NAME }}-${{ github.ref_name }}-x86_64-linux-gnu.tar.gz\`: 标准 Linux 版本"
            echo "- \`${{ env.SERVICE_NAME }}-${{ github.ref_name }}-x86_64-linux-musl.tar.gz\`: 静态链接版本(推荐用于容器)"
            echo ""
            echo "### 部署"
            echo "\`\`\`bash"
            echo "# 下载并解压"
            echo "wget ${{ github.server_url }}/${{ github.repository }}/releases/download/${{ github.ref_name }}/${{ env.SERVICE_NAME }}-${{ github.ref_name }}-x86_64-linux-musl.tar.gz"
            echo "tar xzf ${{ env.SERVICE_NAME }}-${{ github.ref_name }}-x86_64-linux-musl.tar.gz"
            echo ""
            echo "# 运行服务"
            echo "./${{ env.SERVICE_NAME }}"
            echo "\`\`\`"
          fi
          EOF

      - name: 创建 Release
        uses: softprops/action-gh-release@v1
        with:
          name: ${{ env.SERVICE_NAME }} ${{ github.ref_name }}
          body: ${{ steps.changelog.outputs.CHANGELOG }}
          files: |
            ${{ env.SERVICE_NAME }}-${{ github.ref_name }}-x86_64-linux-gnu.tar.gz
            ${{ env.SERVICE_NAME }}-${{ github.ref_name }}-x86_64-linux-musl.tar.gz
          draft: false
          prerelease: ${{ contains(github.ref_name, '-') }}

  notify:
    name: 发送通知
    needs: [test, build-docker, release]
    if: always()
    runs-on: ubuntu-latest
    steps:
      - name: 发送构建通知
        run: |
          TEST_STATUS="${{ needs.test.result }}"
          BUILD_STATUS="${{ needs.build-docker.result }}"
          RELEASE_STATUS="${{ needs.release.result }}"
          
          if [[ "$TEST_STATUS" == "success" && ("$BUILD_STATUS" == "success" || "$BUILD_STATUS" == "skipped") && ("$RELEASE_STATUS" == "success" || "$RELEASE_STATUS" == "skipped") ]]; then
            STATUS="成功"
          else
            STATUS="失败"
          fi
          
          curl -X POST ${{ vars.WEBHOOK_URL }} \
            -H "Content-Type: application/json" \
            -d '{
              "repository": "${{ github.repository }}",
              "ref": "${{ github.ref }}",
              "commit": "${{ github.sha }}",
              "status": "'"$STATUS"'",
              "workflow": "${{ github.workflow }}",
              "actor": "${{ github.actor }}",
              "test_result": "'"$TEST_STATUS"'",
              "build_result": "'"$BUILD_STATUS"'",
              "release_result": "'"$RELEASE_STATUS"'"
            }' || true

Dockerfile 模板

多阶段构建(推荐)

# 构建阶段
FROM rust:1.75-slim as builder

# 安装构建依赖
RUN apt-get update && apt-get install -y \
    pkg-config \
    libssl-dev \
    && rm -rf /var/lib/apt/lists/*

WORKDIR /app

# 复制依赖文件,利用 Docker 缓存
COPY Cargo.toml Cargo.lock ./

# 创建虚拟源文件用于编译依赖
RUN mkdir src && echo "fn main() {}" > src/main.rs
RUN cargo build --release && rm -rf src

# 复制实际源码并重新编译
COPY src ./src
RUN touch src/main.rs && cargo build --release

# 运行阶段
FROM debian:bookworm-slim

# 安装运行时依赖
RUN apt-get update && apt-get install -y \
    ca-certificates \
    curl \
    && rm -rf /var/lib/apt/lists/*

WORKDIR /app

# 复制二进制文件
COPY --from=builder /app/target/release/api-hub /app/api-hub

# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \
  CMD curl --fail http://localhost:8080/health || exit 1

EXPOSE 8080

ENTRYPOINT ["/app/api-hub"]

简单构建

FROM alpine:latest

# 安装运行时依赖
RUN apk add --no-cache ca-certificates curl tzdata

# 设置时区
ENV TZ=Asia/Shanghai

WORKDIR /app

# 复制预编译的二进制文件
COPY api-hub /app/api-hub
RUN chmod +x /app/api-hub

# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \
  CMD curl --fail http://localhost:8080/health || exit 1

EXPOSE 8080

ENTRYPOINT ["/app/api-hub"]

构建参数说明

编译优化

# 交叉编译目标
x86_64-unknown-linux-gnu    # 标准 Linux (glibc)
x86_64-unknown-linux-musl   # 静态链接 Linux

# 编译标志
--release                   # 发布模式优化
--target <target>          # 指定目标平台

# 二进制优化
strip <binary>             # 去除符号表,减小体积

缓存策略

# Cargo 缓存路径
~/.cargo/bin/              # 已安装的 cargo 工具
~/.cargo/registry/index/   # 注册表索引
~/.cargo/registry/cache/   # 下载的 crate 缓存
~/.cargo/git/db/          # Git 依赖缓存
target/                   # 编译输出缓存

# 缓存 Key 计算
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}

Variables 和 Secrets 配置

Required Variables

Variable 说明 示例
WEBHOOK_URL 构建通知 Webhook https://api.example.com/webhook

Required Secrets

Secret 说明
REGISTRY_TOKEN Container Registry 访问令牌

Optional Secrets

Secret 说明
基础模板无额外 secrets

注意Gitea Actions 不允许变量和密钥名称以 GITEA_GITHUB_ 开头


触发条件

标准触发

on:
  push:
    branches: [main]           # 仅 main 分支
    tags: ['v*']              # 版本标签
  pull_request:
    branches: [main]          # PR 到 main

路径过滤(单体仓库)

on:
  push:
    branches: [main]
    paths:
      - 'services/api-hub/**'   # 仅特定服务目录变更
      - 'shared/**'             # 共享代码变更
      - 'Cargo.toml'            # 根依赖变更

发布流程

Release 创建

  • 触发:推送 v* 格式的 tagv1.0.0
  • 构建物
    • {SERVICE_NAME}-{version}-x86_64-linux-gnu.tar.gz
    • {SERVICE_NAME}-{version}-x86_64-linux-musl.tar.gz
  • Changelog: 自动从 CHANGELOG.md 提取或生成默认内容

版本发布操作

# 创建并推送版本标签
git tag v1.0.0
git push origin v1.0.0

# 预发布版本(标记为 prerelease
git tag v1.0.0-beta.1
git push origin v1.0.0-beta.1

常见构建工具集成

根据项目使用的工具,在构建步骤中添加相应命令:

框架/工具 命令
SeaORM sea-orm-cli generate entity -o src/entity
Diesel diesel migration run && diesel print-schema > src/schema.rs
tonic (gRPC) cargo build (build.rs 自动处理)
utoipa (OpenAPI) 代码生成,无需额外命令
cargo-make cargo make ci

Dockerfile.ci 模板(可选)

如果需要在 CI 中使用自定义 Dockerfile

# 用于 CI 的轻量构建
FROM rust:1.75-alpine as builder

RUN apk add --no-cache musl-dev openssl-dev

WORKDIR /app
COPY . .
RUN cargo build --release --target x86_64-unknown-linux-musl

# 运行时镜像
FROM alpine:latest
RUN apk add --no-cache ca-certificates curl
WORKDIR /app
COPY --from=builder /app/target/x86_64-unknown-linux-musl/release/api-hub .
EXPOSE 8080
HEALTHCHECK CMD curl --fail http://localhost:8080/health || exit 1
ENTRYPOINT ["./api-hub"]

使用步骤

  1. 复制模板.gitea/workflows/{service}.yml
  2. 修改变量
    • SERVICE_NAME: 服务名称
    • 触发条件中的分支和标签模式
  3. 配置 Secrets
    • REGISTRY_TOKEN: Container registry 访问令牌
  4. 可选配置
    • 健康检查端点和端口
    • 构建目标平台
    • Webhook 通知 URL
  5. 推送代码触发 workflow

高级功能

多平台构建

- name: 安装交叉编译工具
  run: |
    rustup target add x86_64-unknown-linux-musl
    rustup target add aarch64-unknown-linux-musl
    # cargo install cross

- name: 构建多平台二进制
  run: |
    # x86_64 GNU
    cargo build --release --target x86_64-unknown-linux-gnu
    
    # x86_64 MUSL
    cargo build --release --target x86_64-unknown-linux-musl
    
    # ARM64 MUSL (使用 cross)
    # cross build --release --target aarch64-unknown-linux-musl

集成测试

- name: 集成测试
  run: |
    # 启动依赖服务数据库、Redis 等)
    docker compose up -d postgres redis
    
    # 等待服务就绪
    sleep 5
    
    # 运行集成测试
    cargo test --test integration_tests
    
    # 清理
    docker compose down

安全扫描

- name: 安全审计
  run: |
    cargo install cargo-audit
    cargo audit

版本

  • 模板版本: 1.0
  • 最后更新: 2026-01-29
  • 基于项目: API Hub
  • 优化重点: 变量命名规范、简化配置、增强 Release 功能