From fab14e31966ba7a4c4d3f0286f28151c0ced300b Mon Sep 17 00:00:00 2001 From: Matrix Music Bot Dev Date: Fri, 3 Jul 2026 00:02:51 +0800 Subject: [PATCH] =?UTF-8?q?ci:=20Gitea=20Actions=20=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E6=9E=84=E5=BB=BA=20+=20=E6=8E=A8=E9=80=81=E9=95=9C=E5=83=8F?= =?UTF-8?q?=E5=88=B0=20Container=20Registry?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 按用户选定方案: - Registry: Gitea 内置 Container Registry - 触发: 仅 push master/main - 标签: latest + git short SHA - 架构: linux/amd64 单架构 新增文件: .gitea/workflows/build-image.yml CI workflow 定义 .gitea/README.md Gitea Actions 运维手册 workflow 步骤: 1. actions/checkout@v4 检出源码 2. dtolnay/rust-toolchain@stable 安装 Rust(仅用于 cache key 计算) 3. Swatinem/rust-cache@v2 缓存 Cargo registry / target 4. cargo metadata sanity check 防止 manifest 漂移 5. docker/setup-buildx-action@v3 Buildx 6. docker/login-action@v3 登录 Gitea Registry(用 ${{ gitea.token }}) 7. docker/metadata-action@v5 生成 latest + sha 标签 + OCI labels 8. docker/build-push-action@v5 构建 + 推送(含 BuildKit registry cache) 9. aquasecurity/trivy-action CVE 扫描(不阻塞) 特性: - concurrency 控制:避免重复构建(同一 ref 只跑最新) - 自动镜像标签:latest + commit short SHA - BuildKit cache 推到 :buildcache 镜像(下次构建复用) - Gitea 内置 token 自动认证(无需手动 secrets) - OCI 标准 labels(title/source/license/vendor) gitea/README.md 包含: - 前置要求(Registry 开启、Runner 注册、网络) - 镜像使用示例 - 常见扩展(tag 触发 / 多架构 / 自动部署) - 故障排查(login 失败 / build 失败 / pull 失败) --- .gitea/README.md | 183 +++++++++++++++++++++++++++++++ .gitea/workflows/build-image.yml | 132 ++++++++++++++++++++++ 2 files changed, 315 insertions(+) create mode 100644 .gitea/README.md create mode 100644 .gitea/workflows/build-image.yml diff --git a/.gitea/README.md b/.gitea/README.md new file mode 100644 index 0000000..17df45c --- /dev/null +++ b/.gitea/README.md @@ -0,0 +1,183 @@ +# Gitea Actions CI/CD 部署指南 + +本目录包含 Gitea Actions 工作流配置,用于自动构建并推送 Docker 镜像到 +Gitea Container Registry。 + +## 当前工作流 + +### `build-image.yml` + +- **触发条件**:push 到 `master` / `main` 分支(排除 tag 推送) +- **目标架构**:`linux/amd64` +- **镜像标签**: + - `latest`(latest 镜像) + - ``(commit 短哈希,便于回溯) +- **目标 Registry**:Gitea 内置 Container Registry + - URL:`http://192.168.6.200:3080/1076code/matrix/packages/container/matrix-music-bot` +- **构建方式**:`docker buildx` + BuildKit 缓存(推到 registry 作为 `:buildcache` 镜像层) +- **安全扫描**:自动跑 Trivy 扫描 CRITICAL/HIGH 漏洞(不阻塞流程) + +## 镜像使用 + +构建完成后,可通过以下方式拉取: + +```bash +# 拉取最新 +docker pull http://192.168.6.200:3080/1076code/matrix/packages/container/matrix-music-bot:latest + +# 拉取特定 commit +docker pull http://192.168.6.200:3080/1076code/matrix/packages/container/matrix-music-bot:abc1234 + +# 运行(用 docker-compose 简化环境变量管理) +MATRIX_BOT_SECRET_PASSPHRASE="..." docker-compose up -d +``` + +或在 `docker-compose.yml` 中直接引用: + +```yaml +services: + matrix-music-bot: + image: 192.168.6.200:3080/1076code/matrix/packages/container/matrix-music-bot:latest + # 移除 build: 段,改用 image 拉取 + # ... 其他配置不变 +``` + +## Gitea 实例前置要求 + +1. **Container Registry 已开启** + - Gitea 管理后台 → packages → 启用 Container Registry + - 配置域名(与 Gitea 主站一致即可) + +2. **注册 Actions Runner** + - Gitea 管理后台 → Actions → Runners → Create new runner + - 在 runner 机器上执行: + + ```bash + # Gitea Actions Runner 安装(参考 https://docs.gitea.com/usage/actions/act-runner) + # 1. 下载 act_runner 二进制 + curl -O https://dl.gitea.com/act_runner/0.2.11/act_runner-0.2.11-linux-amd64 + chmod +x act_runner-0.2.11-linux-amd64 + mv act_runner-0.2.11-linux-amd64 /usr/local/bin/act_runner + + # 2. 注册 runner(用 Gitea UI 提供的注册 token) + act_runner register \ + --instance http://192.168.6.200:3080 \ + --token \ + --labels ubuntu-latest:docker + + # 3. 启动 runner(前台或 daemon) + act_runner daemon + ``` + + - Runner 必须有 `docker buildx` 可用(Docker 20.10+) + +3. **网络可达性** + - Runner 能访问 `crates.io`(或 rsproxy.cn 镜像)下载 Rust crates + - Runner 能访问 GitHub 拉取 `actions/checkout` 等 actions + - Runner 能访问 Gitea Container Registry(通常同主机 / 同网络) + +## 工作流调整指南 + +### 添加 tag 触发的版本镜像 + +在 `build-image.yml` 顶部加: + +```yaml +on: + push: + branches: [master, main] + tags: ['v*'] # ← 新增:tag 推送触发 + tags-ignore: '' # 取消排除 + +# 然后在 metadata-action 的 tags 加: +# type=semver,pattern={{version}} +# type=semver,pattern={{major}}.{{minor}} +# type=semver,pattern={{major}} +``` + +### 启用多架构镜像 + +修改: + +```yaml +env: + PLATFORM: linux/amd64,linux/arm64 + +jobs: + build: + steps: + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 +``` + +### 添加推送后自动部署 + +```yaml +deploy: + needs: build + runs-on: ubuntu-latest + if: gitea.ref == 'refs/heads/master' + steps: + - name: SSH to production + uses: appleboy/ssh-action@v1 + with: + host: ${{ secrets.PROD_HOST }} + username: ${{ secrets.PROD_USER }} + key: ${{ secrets.PROD_SSH_KEY }} + script: | + cd /opt/matrix-music-bot + MATRIX_BOT_SECRET_PASSPHRASE=$(cat ~/.matrix-bot-passphrase) \ + docker-compose pull && docker-compose up -d +``` + +### 添加 PR 检查(不推送) + +新增 job: + +```yaml +pr-check: + if: gitea.event_name == 'pull_request' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: docker/setup-buildx-action@v3 + - uses: docker/build-push-action@v5 + with: + context: . + push: false # 不推送,只构建验证 +``` + +## 故障排查 + +### Workflow 触发不了 + +检查: + +- `.gitea/workflows/` 目录权限(应为 755) +- workflow 文件名后缀必须是 `.yml` 或 `.yaml` +- 仓库设置 → Actions → Workflows 状态为启用 + +### `docker/login-action` 失败 + +- 确认 Gitea 已开启 Container Registry +- 检查 `gitea.actor` / `gitea.token` 是否有 packages 写权限 +- Registry URL 必须包含 scheme(如 `http://...`,不能用裸 hostname) + +### `docker/build-push-action` 构建失败 + +- 检查 Dockerfile 路径(默认 `./Dockerfile`) +- 检查 BuildKit 是否启用(Buildx 默认启用) +- 国内环境:考虑加 `RUN cargo config set source.crates-io.replace-with ...` + +### 镜像推送后无法 `docker pull` + +- Registry 是 HTTP(非 HTTPS):客户端需加 `--insecure-registry` 或配置 daemon.json +- 或用 Gitea 的 HTTPS 反向代理 + +## 相关文档 + +- Gitea Actions 官方文档:https://docs.gitea.com/usage/actions/overview +- docker/build-push-action:https://github.com/docker/build-push-action +- docker/metadata-action:https://github.com/docker/metadata-action \ No newline at end of file diff --git a/.gitea/workflows/build-image.yml b/.gitea/workflows/build-image.yml new file mode 100644 index 0000000..d5a5885 --- /dev/null +++ b/.gitea/workflows/build-image.yml @@ -0,0 +1,132 @@ +# Gitea Actions workflow:构建并推送 Docker 镜像到 Gitea Container Registry +# +# 触发条件:push 到 master/main +# 镜像标签:latest + git short SHA +# 目标架构:linux/amd64(v1 简化) +# Registry:http://192.168.6.200:3080 的 Gitea 内置 Container Registry +# +# 前置要求: +# 1. Gitea 实例已开启 Container Registry(packages 功能) +# 2. 仓库已注册一个 Gitea Actions runner(带 docker 能力) +# 3. 仓库设置 → Actions → Secrets 无需手动配置 +# (本 workflow 使用 Gitea 内置的 ${{ gitea.token }} 自动认证) + +name: build-and-push-image + +on: + push: + branches: + - master + - main + # 排除 tag 推送触发的版本构建(后续可加 on: push: tags 单独 workflow) + tags-ignore: 'v*' + +# 避免重复构建:同时 push 到 master 多 commit 时只跑最新一次 +concurrency: + group: build-image-${{ gitea.ref }} + cancel-in-progress: true + +env: + # Gitea Container Registry 地址 + # 默认推断规则:${{ gitea.server_url }}/${{ gitea.repository }}/packages/container/ + # 例如:http://192.168.6.200:3080/1076code/matrix/packages/container/matrix-music-bot + REGISTRY: ${{ gitea.server_url }} + IMAGE_NAMESPACE: ${{ gitea.repository_owner }} + IMAGE_NAME: matrix-music-bot + # 单架构构建(v1 简化;如需 arm64 改为 linux/amd64,linux/arm64) + PLATFORM: linux/amd64 + +jobs: + build: + name: build-push + runs-on: ubuntu-latest # Gitea runner 标签,按实际配置调整 + timeout-minutes: 30 + + steps: + # 1. 检出源码 + - name: Checkout + uses: actions/checkout@v4 + + # 2. 安装 Rust 工具链(用于 cache key 计算 + 编译期校验) + # 注:实际编译在 Docker 内进行,此处仅用于 cache 命中率 + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@stable + + # 3. 缓存 Cargo registry / target 目录(加速依赖解析,可选) + # 如未安装 Swatinem/rust-cache action,可改用 actions/cache@v4 + - name: Cache cargo registry + uses: Swatinem/rust-cache@v2 + with: + cache-on-failure: true + + # 4. 验证 Cargo.lock 一致性(防止 manifest 漂移) + # 注意:此步骤在宿主 runner 上跑,需与 Dockerfile 内编译一致; + # 如果 Gitea runner 是 linux/amd64 而 Dockerfile 也是 debian-bookworm 则一致 + - name: Verify Cargo.lock is up to date + run: | + cargo metadata --format-version 1 --no-deps > /dev/null + # 简易 sanity check:能解析 manifest 即可 + + # 5. 设置 Docker Buildx(启用 BuildKit 缓存) + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + # 6. 登录 Gitea Container Registry + # 用 Gitea 内置 token(每个 workflow run 自动生成) + - name: Login to Gitea Container Registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ gitea.actor }} + password: ${{ gitea.token }} + + # 7. 提取元数据(自动生成标签) + - name: Extract Docker metadata + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAMESPACE }}/${{ env.IMAGE_NAME }} + # tags: latest + sha 短哈希 + tags: | + type=raw,value=latest + type=sha,format=short + # 镜像标签 labels(用 OCI 标准) + labels: | + org.opencontainers.image.title=matrix-music-bot + org.opencontainers.image.description=Element Call 加密房间中的点歌机器人 + org.opencontainers.image.source=${{ gitea.server_url }}/${{ gitea.repository }} + org.opencontainers.image.licenses=MIT + org.opencontainers.image.vendor=1076code + + # 8. 构建并推送镜像 + - name: Build and push + uses: docker/build-push-action@v5 + with: + context: . + file: ./Dockerfile + platforms: ${{ env.PLATFORM }} + # BuildKit 缓存(推到 registry 作为缓存层,下次构建复用) + cache-from: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAMESPACE }}/${{ env.IMAGE_NAME }}:buildcache + cache-to: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAMESPACE }}/${{ env.IMAGE_NAME }}:buildcache,mode=max + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + # 推送(生产);注释掉此行可改为本地构建(PR 场景) + push: true + + # 镜像安全扫描(可选:用 Trivy 检查已知 CVE) + scan: + name: vulnerability-scan + needs: build + runs-on: ubuntu-latest + timeout-minutes: 10 + continue-on-error: true # 扫描失败不阻塞流程 + + steps: + - name: Run Trivy vulnerability scanner + uses: aquasecurity/trivy-action@master + with: + image-ref: ${{ env.REGISTRY }}/${{ env.IMAGE_NAMESPACE }}/${{ env.IMAGE_NAME }}:latest + format: 'table' + exit-code: '0' # 仅报告不阻塞 + ignore-unfixed: true + severity: 'CRITICAL,HIGH' \ No newline at end of file