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

541 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 骨架模板
```yaml
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 模板
### 多阶段构建(推荐)
```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"]
```
### 简单构建
```dockerfile
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"]
```
---
## 构建参数说明
### 编译优化
```bash
# 交叉编译目标
x86_64-unknown-linux-gnu # 标准 Linux (glibc)
x86_64-unknown-linux-musl # 静态链接 Linux
# 编译标志
--release # 发布模式优化
--target <target> # 指定目标平台
# 二进制优化
strip <binary> # 去除符号表,减小体积
```
### 缓存策略
```yaml
# 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_` 开头
---
## 触发条件
### 标准触发
```yaml
on:
push:
branches: [main] # 仅 main 分支
tags: ['v*'] # 版本标签
pull_request:
branches: [main] # PR 到 main
```
### 路径过滤(单体仓库)
```yaml
on:
push:
branches: [main]
paths:
- 'services/api-hub/**' # 仅特定服务目录变更
- 'shared/**' # 共享代码变更
- 'Cargo.toml' # 根依赖变更
```
---
## 发布流程
### Release 创建
- **触发**:推送 `v*` 格式的 tag`v1.0.0`
- **构建物**
- `{SERVICE_NAME}-{version}-x86_64-linux-gnu.tar.gz`
- `{SERVICE_NAME}-{version}-x86_64-linux-musl.tar.gz`
- **Changelog**: 自动从 `CHANGELOG.md` 提取或生成默认内容
### 版本发布操作
```bash
# 创建并推送版本标签
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
```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
---
## 高级功能
### 多平台构建
```yaml
- 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
```
### 集成测试
```yaml
- name: 集成测试
run: |
# 启动依赖服务数据库、Redis 等)
docker compose up -d postgres redis
# 等待服务就绪
sleep 5
# 运行集成测试
cargo test --test integration_tests
# 清理
docker compose down
```
### 安全扫描
```yaml
- name: 安全审计
run: |
cargo install cargo-audit
cargo audit
```
---
## 版本
- **模板版本**: 1.0
- **最后更新**: 2026-01-29
- **基于项目**: API Hub
- **优化重点**: 变量命名规范、简化配置、增强 Release 功能