Files
opencode/skill/gitea/rust-quick-reference.md
voson 425ca5b5fd feat(gitea): 添加 Dockerfile 模板和 Rust 支持,优化 runner 网络配置说明
- 新增 Go、Node.js、Rust 服务的 Dockerfile 模板
- 新增 Rust 快速参考指南
- 新增 Rust 后端工作流模板
- 优化 create-runner.md,明确 host 网络模式为缓存必需条件
- 更新 gitea skill 主文档
2026-01-30 10:12:09 +08:00

444 lines
9.4 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 项目 Gitea CI/CD 快速参考
快速设置 Rust 项目的 CI/CD 流程。
## 最小化配置3 步)
### 1. 创建 Dockerfile.ci
在项目根目录创建 `Dockerfile.ci`
```dockerfile
FROM alpine:3.21
RUN apk add --no-cache ca-certificates tzdata curl && \
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
WORKDIR /app
COPY your-binary-name .
ENV TZ=Asia/Shanghai
ENV RUST_LOG=info
EXPOSE 9090
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
CMD curl -sf http://localhost:9090/healthz || exit 1
CMD ["./your-binary-name"]
```
**修改项**
- `your-binary-name` → 你的二进制文件名(通常和 `Cargo.toml` 中的 `name` 一致)
- `9090` → 你的服务端口
### 2. 创建 workflow 文件
创建 `.gitea/workflows/your-service.yml`
```yaml
name: Your Service - Build & Publish
on:
push:
paths:
- '**' # 修改为实际监听路径
tags:
- 'v*' # 修改为实际 tag 格式
env:
SERVICE_PREFIX: your-service # 修改为实际服务名
CARGO_INCREMENTAL: 0
CARGO_NET_RETRY: 10
RUSTUP_DIST_SERVER: https://rsproxy.cn
RUSTUP_UPDATE_ROOT: https://rsproxy.cn/rustup
jobs:
build-and-publish:
runs-on: ubuntu-latest # 修改为你的 Runner 标签
steps:
- uses: actions/checkout@v4
- name: Install Rust
run: |
curl --proto '=https' --tlsv1.2 -sSf https://rsproxy.cn/rustup-init.sh | sh -s -- -y
echo "$HOME/.cargo/bin" >> $GITHUB_PATH
source "$HOME/.cargo/env"
rustup target add x86_64-unknown-linux-musl
- name: Build
run: |
cargo build --release --target x86_64-unknown-linux-musl
cp target/x86_64-unknown-linux-musl/release/your-binary-name .
- name: Docker Login
uses: docker/login-action@v3
with:
registry: ${{ github.server_url }}
username: ${{ vars.REGISTRY_USERNAME }}
password: ${{ secrets.RELEASE_TOKEN }}
- name: Build & Push Image
uses: docker/build-push-action@v6
with:
context: .
file: ./Dockerfile.ci
push: true
tags: |
${{ github.server_url }}/${{ github.repository }}:latest
${{ github.server_url }}/${{ github.repository }}:${{ github.sha }}
```
**修改项**
- `your-service` → 你的服务名
- `your-binary-name` → 你的二进制文件名
- `ubuntu-latest` → 你的 Runner 标签
- `paths` → 触发构建的路径
- `tags` → 触发构建的 tag 格式
### 3. 推送代码并打 tag
```bash
git add .gitea Dockerfile.ci
git commit -m "ci: 添加 CI/CD 配置"
git push
# 触发构建
git tag v0.1.0
git push origin v0.1.0
```
## 进阶配置
### 添加交叉编译支持
如果你的 Runner 是 ARM64但需要构建 x86_64 镜像:
```yaml
- name: Install Zig and cargo-zigbuild
run: |
wget -q https://ziglang.org/download/0.13.0/zig-linux-aarch64-0.13.0.tar.xz
tar -xf zig-linux-aarch64-0.13.0.tar.xz
mv zig-linux-aarch64-0.13.0 /opt/zig
echo "/opt/zig" >> $GITHUB_PATH
cargo install cargo-zigbuild
- name: Build
run: |
cargo zigbuild --release --target x86_64-unknown-linux-musl
```
### 添加 Rust 缓存
```yaml
- name: Cache Rust dependencies
uses: https://github.com/Swatinem/rust-cache@v2
with:
workspaces: . -> target
cache-targets: true
```
### 添加版本号注入
**1. 创建 `build.rs`**
```rust
fn main() {
if let Ok(git_tag) = std::env::var("GIT_TAG") {
println!("cargo:rustc-env=GIT_TAG={}", git_tag);
}
println!("cargo:rerun-if-env-changed=GIT_TAG");
}
```
**2. 在 workflow 中设置环境变量**
```yaml
- name: Build
env:
GIT_TAG: ${{ github.ref_name }}
run: cargo build --release
```
**3. 在代码中使用**
```rust
let version = option_env!("GIT_TAG").unwrap_or("dev");
println!("Version: {}", version);
```
### 添加 Release 创建
```yaml
release:
name: Create Release
runs-on: ubuntu-latest
needs: build-and-publish
if: startsWith(github.ref, 'refs/tags/')
steps:
- name: Create Release
run: |
curl -X POST "${{ github.server_url }}/api/v1/repos/${{ github.repository }}/releases" \
-H "Authorization: token ${{ secrets.RELEASE_TOKEN }}" \
-H "Content-Type: application/json" \
-d "{
\"tag_name\": \"${{ github.ref_name }}\",
\"name\": \"Release ${{ github.ref_name }}\",
\"body\": \"自动构建的 Release\"
}"
```
## 健康检查端点实现
如果你的服务还没有健康检查端点,快速添加:
### 使用 Axum
```rust
use axum::{Router, routing::get};
#[tokio::main]
async fn main() {
let app = Router::new()
.route("/healthz", get(|| async { "OK" }));
let listener = tokio::net::TcpListener::bind("0.0.0.0:9090")
.await
.unwrap();
axum::serve(listener, app).await.unwrap();
}
```
### 使用 Actix-web
```rust
use actix_web::{web, App, HttpServer, HttpResponse};
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new()
.route("/healthz", web::get().to(|| async { HttpResponse::Ok().body("OK") }))
})
.bind("0.0.0.0:9090")?
.run()
.await
}
```
### 使用 Rocket
```rust
#[macro_use] extern crate rocket;
#[get("/healthz")]
fn healthz() -> &'static str {
"OK"
}
#[launch]
fn rocket() -> _ {
rocket::build().mount("/", routes![healthz])
}
```
## Cargo.toml 优化配置
```toml
[profile.release]
opt-level = 3 # 最高优化级别
lto = true # 链接时优化
codegen-units = 1 # 单个代码生成单元
strip = true # 去除符号表
panic = 'abort' # panic 时直接退出
```
## .dockerignore 示例
创建 `.dockerignore` 减小构建上下文:
```
target/
.git/
.gitignore
*.md
tests/
benches/
examples/
.github/
.gitea/workflows/
Dockerfile*
docker-compose.yml
```
## 环境变量配置
### 在 workflow 中
```yaml
env:
RUST_LOG: info # 日志级别
CONFIG_FILE: production.yaml # 配置文件
DATABASE_URL: ${{ secrets.DATABASE_URL }} # 数据库连接
```
### 在 Dockerfile 中
```dockerfile
ENV RUST_LOG=info
ENV CONFIG_FILE=production.yaml
```
### 在运行时
```bash
docker run -e RUST_LOG=debug -e CONFIG_FILE=custom.yaml your-image
```
## 常见 Runner 标签
| 标签 | 说明 |
|------|------|
| `ubuntu-latest` | Ubuntu 最新版本 |
| `darwin-arm64` | macOS ARM64 |
| `darwin-amd64` | macOS x86_64 |
| `linux-amd64` | Linux x86_64 |
| `linux-arm64` | Linux ARM64 |
查看可用 Runner
```bash
/gitea-list-runners
```
## 触发条件参考
### 推送到特定分支
```yaml
on:
push:
branches:
- main
- develop
```
### 推送特定路径
```yaml
on:
push:
paths:
- 'src/**'
- 'Cargo.toml'
- 'Cargo.lock'
```
### 特定 tag 格式
```yaml
on:
push:
tags:
- 'v*' # v1.0.0, v2.1.3
- 'device-rs-*' # device-rs-1.0.0
```
### Pull Request
```yaml
on:
pull_request:
branches:
- main
```
### 定时触发
```yaml
on:
schedule:
- cron: '0 2 * * *' # 每天凌晨 2 点
```
## 调试技巧
### 查看 workflow 日志
在 Gitea 仓库页面:
1. 点击 "Actions"
2. 选择对应的 workflow run
3. 查看每个 step 的日志
### 本地测试构建
```bash
# 测试 Rust 构建
cargo build --release --target x86_64-unknown-linux-musl
# 测试 Docker 构建
docker build -f Dockerfile.ci -t test:latest .
# 测试容器运行
docker run -p 9090:9090 test:latest
```
### 使用 act 本地运行 workflow
```bash
# 安装 act如果使用 Gitea Actions
# 注意act 主要支持 GitHub ActionsGitea Actions 可能有兼容性问题
# 列出可用的 actions
act -l
# 运行特定 job
act -j build-and-publish
```
## 完整配置示例
参考 BMS 项目的 device-rs
- Workflow: [device-rs.yml](https://git.voson.top/tianchu/bms/src/branch/main/.gitea/workflows/device-rs.yml)
- Dockerfile: [Dockerfile.ci](https://git.voson.top/tianchu/bms/src/branch/main/device-rs/Dockerfile.ci)
- 项目结构: [device-rs/](https://git.voson.top/tianchu/bms/src/branch/main/device-rs)
## 故障排查清单
### 构建失败
- [ ] 检查 Rust 版本是否满足要求
- [ ] 检查依赖是否正确(`Cargo.lock` 是否提交)
- [ ] 检查 musl 目标是否安装(`rustup target list --installed`
- [ ] 查看完整构建日志
### Docker 推送失败
- [ ] 检查 Docker Registry 地址是否正确
- [ ] 检查 `REGISTRY_USERNAME` 变量是否设置
- [ ] 检查 `RELEASE_TOKEN` secret 是否正确
- [ ] 检查 Token 权限(需要 packages write 权限)
### 容器启动失败
- [ ] 检查二进制文件名是否正确
- [ ] 检查端口是否正确
- [ ] 检查健康检查端点是否存在
- [ ] 查看容器日志(`docker logs <container>`
### Runner 无法连接
- [ ] 检查 Runner 是否在运行(`/gitea-list-runners`
- [ ] 检查 Runner labels 是否匹配 workflow 中的 `runs-on`
- [ ] 检查网络连接
- [ ] 查看 Runner 日志(`~/.config/gitea/runners/<runner-name>/*.log`
## 更多资源
- [完整 Workflow 模板](./workflow-templates/rust-backend.md)
- [Dockerfile 模板详解](./dockerfile-templates/rust-service.md)
- [Gitea Actions 文档](https://docs.gitea.com/usage/actions/quickstart)
- [Rust CI 最佳实践](https://doc.rust-lang.org/cargo/guide/continuous-integration.html)