Files
sanguo_moziplus_v2/docs/research/gitea-actions-research.md
T
2026-06-06 11:26:44 +08:00

20 KiB
Raw Blame History

Gitea Actions 能力调研报告

调研时间:2026-06-06 Gitea 版本:v1.23.4(实例 http://192.168.2.154:3000 已确认) 调研来源:Gitea 官方文档 v1.23、API 规范、v1.23.0 Release Notes、act-runner 文档


调研结论(先给结论)

总体评估: 可行,但有若干注意事项

能力类别 状态 说明
Actions 基础能力 支持 v1.23.4 内置 Actions(自 1.21 默认启用),兼容 GitHub Actions YAML
Workflow 触发器 支持 push/pull_request/workflow_dispatch/schedule 均支持
Job 依赖和条件 ⚠️ 部分支持 needs 支持,if 支持,但 failure() 表达式不受支持(仅 always() 支持)
Secrets/环境变量 支持 多级 Secrets 和 Variables${{ secrets.XXX }} 语法
Status Check 支持 Actions 结果自动作为 commit status,可用于 Branch Protection
Branch Protection 支持 支持 required approvals、status check、merge whitelist 等
CI 内调 Gitea API ⚠️ 需配置 v1.23 无内置 GITEA_TOKENv1.24+ 才有),需用 PAT 或配置 secrets
Webhook 支持 仓库/组织/系统级别,支持 HMAC SHA256 签名验证

确认支持的能力

  1. YAML 语法兼容.gitea/workflows/.github/workflows/ 均可
  2. 触发器push(含分支过滤)、pull_request(含 types 过滤)、workflow_dispatchv1.23 新增)、schedule
  3. Job 间依赖needs 关键字支持
  4. 条件执行if 支持(但表达式有限制)
  5. Secrets & Variables:仓库/组织/用户多级管理,优先级:仓库 > 组织 > 用户
  6. Status Check + Branch ProtectionActions 完成后自动产生 commit status,可配置为 merge 前置条件
  7. Review 要求Branch Protection 支持 required_approvals
  8. Webhook:仓库/组织/系统级别,多事件类型选择,HMAC SHA256 签名
  9. 绝对 URL action:支持从任意 Git 仓库引用 action
  10. Go Actions:支持用 Go 编写 action

不支持或有限制的能力

  1. 表达式函数:仅 always() 支持,failure()success()cancelled() 不支持
  2. permissions 关键字:在 v1.23 中被忽略(v1.24+ 才实现 GITEA_TOKEN 权限控制)
  3. concurrency:不支持(用于限制同时运行同一 workflow)
  4. continue-on-error:不支持
  5. timeout-minutes:不支持
  6. environment:不支持
  7. 复杂 runs-on:仅支持单个 label,不支持表达式
  8. run-name:不支持
  9. Problem Matchers:不支持
  10. GITEA_TOKENv1.23 中无内置 job token(需 v1.24+),需要手动配置 PAT 作为 secret

需要额外配置的事项

  1. act-runner 安装和注册:需要单独部署
  2. 仓库启用 Actions:默认关闭,需手动开启
  3. Branch Protection:需在仓库 Settings 中手动配置或通过 API
  4. PAT Tokenv1.23 需要 PAT 才能在 workflow 中调 Gitea API
  5. 考虑升级到 v1.24+:可获得 GITEA_TOKEN 内置支持、permissions 关键字等

逐项验证结果

1. Actions 基础能力

1.1 Gitea v1.23.4 是否内置 Actions

  • 。自 Gitea 1.19 引入 Actions1.21 起默认启用([actions] ENABLED=true
  • 我们的实例确认版本为 v1.23.4
  • 证据curl http://192.168.2.154:3000/api/v1/version{"version":"1.23.4"}
  • 证据:官方文档 "Starting with Gitea 1.19, Gitea Actions are available as a built-in CI/CD solution"

1.2 是否兼容 GitHub Actions YAML 语法?

  • 。workflow 文件放在 .gitea/workflows/.github/workflows/ 目录
  • 设计上以 GitHub Actions 兼容为目标
  • 可直接使用 actions/checkout@v4 等 GitHub Actions(默认从 GitHub 下载)
  • 配置 [actions].DEFAULT_ACTIONS_URL 可设为 github(默认)或 self
  • 注意v1.21.0 前默认从 gitea.com 下载,v1.21.0+ 默认从 github.com 下载

1.3 act-runner 如何安装和注册?

  • 详见下方 "act-runner 部署指南"
  • 支持二进制安装和 Docker 安装
  • 注册需要 registration token(从 Web UI 或 CLI 获取)
  • 支持 macOS LaunchDaemon 作为守护进程

2. Workflow 触发器

2.1 on: pushon: pull_request 是否支持?

  • 支持
  • 示例:
    on: [push, pull_request]
    
  • 完整触发器列表:pushpull_requestworkflow_dispatchschedulereleaseissues

2.2 on: push 能否限制分支?

  • 支持
  • 语法与 GitHub Actions 一致:
    on:
      push:
        branches: [main]
    
  • 支持 branchesbranches-ignoretagstags-ignorepathspaths-ignore

2.3 on: pull_request 是否支持 types

  • 支持
  • 语法:
    on:
      pull_request:
        types: [opened, synchronize]
    

2.4 其他触发器

  • workflow_dispatch:v1.23.0 新增!支持手动触发,支持输入参数(含 choice、boolean、number、environment 类型)
  • schedule:支持标准 cron 语法 + 非标准语法 @yearly/@monthly/@weekly/@daily/@hourly
    • ⚠️ 注意:v1.23 起 schedule 默认使用 UTC 时区

3. Job 依赖和条件

3.1 needs 关键字是否支持?

  • 支持
  • 与 GitHub Actions 语法一致:
    jobs:
      test:
        runs-on: ubuntu-latest
        steps: [...]
      deploy:
        needs: test
        runs-on: ubuntu-latest
        steps: [...]
    

3.2 if: failure() 条件是否支持?

  • ⚠️ 有限制
  • if 关键字本身支持
  • 表达式函数仅 always() 支持failure()success()cancelled() 不支持
  • 影响:无法直接实现 "前序 job 失败时执行" 的逻辑
  • 变通方案:使用 job output 传递状态,或拆分为多个 workflow

3.3 环境变量和 Secrets 是否支持?

  • 支持
  • Secrets${{ secrets.MY_SECRET }},支持仓库/组织/用户三级
  • Variables${{ vars.MY_VAR }},同样支持三级
  • 内置环境变量GITHUB_*GITEA_* 前缀的变量均有
    • gitea.actorgitea.event_namegitea.refgitea.repository
  • Secret 命名规则
    • 仅含 [a-z], [A-Z], [0-9], _
    • 不能以 GITHUB_GITEA_ 开头
    • 不能以数字开头
    • 不区分大小写

4. Status Check 和 Branch Protection

4.1 Actions 跑完后是否自动显示 Status Check

  • Actions 运行完成后,结果会作为 commit status 自动显示在 PR 页面
  • API 端点:GET /repos/{owner}/{repo}/commits/{ref}/status
  • API 端点:GET /repos/{owner}/{repo}/commits/{ref}/statuses
  • 可通过 gitea-actions badge 在其他地方展示状态

4.2 Branch Protection 能否设置"必须 CI 通过才能 merge"

  • 支持
  • Branch Protection API 中有 enable_status_checkstatus_check_contexts 字段
  • 通过 Web UI:仓库 Settings → Branches → Add Branch Protection Rule
  • 通过 API
    POST /api/v1/repos/{owner}/{repo}/branch_protections
    {
      "branch_name": "main",
      "enable_status_check": true,
      "status_check_contexts": ["ci/test"]
    }
    

4.3 能否设置"必须至少 1 人 Review 才能 merge"

  • 支持
  • Branch Protection 中的 required_approvals 字段
  • 通过 API
    POST /api/v1/repos/{owner}/{repo}/branch_protections
    {
      "branch_name": "main",
      "required_approvals": 1
    }
    
  • v1.23 新增:Protected branch 支持 priority 设置

5. CI 内调 Gitea API

5.1 workflow 里能否用 curl 调 Gitea API

  • 可以,但需要认证 token
  • Gitea API 完全兼容 RESTfulcurl 直接调用即可

5.2 Token 怎么获取?

  • ⚠️ v1.23 的限制v1.23 没有内置 GITEA_TOKEN(这是 v1.24+ 才引入的功能)
  • v1.24+ 方案${{ secrets.GITEA_TOKEN }} 自动注入,带有可配置的权限范围
  • v1.23 变通方案
    1. 创建 Personal Access TokenPAT),存为仓库 Secret
    2. 在 workflow 中使用 ${{ secrets.GITEA_TOKEN }}(手动配置的同名 secret
    3. 或使用 ${{ secrets.MY_PAT }} 自定义名称
  • 调用示例
    - name: Comment on PR
      run: |
        curl -X POST \
          "http://192.168.2.154:3000/api/v1/repos/${{ gitea.repository }}/issues/${{ github.event.pull_request.number }}/comments" \
          -H "Authorization: token ${{ secrets.GITEA_TOKEN }}" \
          -H "Content-Type: application/json" \
          -d '{"body": "CI passed ✅"}'
    

建议:考虑升级 Gitea 到 v1.24+ 以获得内置 GITEA_TOKEN 支持,这是最显著的改进之一。

6. Webhook 配置

6.1 在哪里配置 Webhook

  • 三级配置
    1. 仓库级别/{owner}/{repo}/settings/hooks
    2. 组织级别:组织 Settings → Webhooks
    3. 系统级别:管理员配置
  • API 端点
    • GET /api/v1/repos/{owner}/{repo}/hooks — 列出 hooks
    • POST /api/v1/repos/{owner}/{repo}/hooks — 创建 hook

6.2 能否选择特定事件类型?

  • 支持
  • 可选事件类型包括:
    • Push events
    • Pull request events
    • Tag create/delete events
    • Branch create/delete events
    • Issue events
    • Release events
    • 等等

6.3 Secret 签名验证是否支持?

  • 支持
  • 使用 HMAC SHA256 签名
  • 请求头 X-Gitea-Signature 包含签名
  • 验证方式:
    $payload_signature = hash_hmac('sha256', $payload, $secret_key, false);
    if ($header_signature !== $payload_signature) { /* reject */ }
    
  • ⚠️ 注意:payload 中的 secret 字段已在 v1.13.0 废弃,应使用 header 签名验证
  • v1.19+ 还支持配置 Authorization header

6.4 Webhook 支持的类型

  • Giteanative)、Gogs、Slack、Discord、Dingtalk、Telegram、Microsoft Teams、Feishu(飞书)、Wechatwork、Packagist

act-runner 部署指南

方式一:二进制安装(推荐用于 Mac mini)

# 1. 下载 act_runnerarm64 版本)
curl -L -o act_runner https://gitea.com/gitea/act_runner/releases/latest/download/act_runner-darwin-arm64
chmod +x act_runner
./act_runner --version

# 2. 生成配置文件(可选)
./act_runner generate-config > config.yaml

# 3. 获取 registration token
# 方式 A:从 Web UI
#   - 实例级:http://192.168.2.154:3000/-/admin/actions/runners
#   - 组织级:http://192.168.2.154:3000/<org>/settings/actions/runners
#   - 仓库级:http://192.168.2.154:3000/<owner>/<repo>/settings/actions/runners
# 方式 B:从 Gitea CLI(需要服务器访问权限)
#   gitea --config /etc/gitea/app.ini actions generate-runner-token

# 4. 注册 runner
./act_runner register \
  --no-interactive \
  --instance http://192.168.2.154:3000 \
  --token <registration_token> \
  --name mac-mini-runner \
  --labels ubuntu-latest:host,macos:host

# 5. 启动 runner
./act_runner daemon

# 6. 设置为 macOS LaunchDaemon(开机自启)

LaunchDaemon 配置

创建 /Library/LaunchDaemons/com.gitea.act_runner.plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.gitea.act_runner</string>
    <key>ProgramArguments</key>
    <array>
        <string>/usr/local/bin/act_runner</string>
        <string>daemon</string>
        <string>--config</string>
        <string>/etc/act_runner/config.yaml</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>KeepAlive</key>
    <true/>
    <key>WorkingDirectory</key>
    <string>/var/lib/act_runner</string>
    <key>StandardOutPath</key>
    <string>/var/lib/act_runner/act_runner.log</string>
    <key>StandardErrorPath</key>
    <string>/var/lib/act_runner/act_runner.err</string>
    <key>EnvironmentVariables</key>
    <dict>
        <key>PATH</key>
        <string>/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
        <key>HOME</key>
        <string>/var/lib/act_runner</string>
    </dict>
</dict>
</plist>
sudo launchctl load /Library/LaunchDaemons/com.gitea.act_runner.plist

方式二:Docker 安装

docker run \
  -e GITEA_INSTANCE_URL=http://192.168.2.154:3000 \
  -e GITEA_RUNNER_REGISTRATION_TOKEN=<token> \
  -e GITEA_RUNNER_NAME=docker-runner \
  --name gitea-runner \
  -d docker.io/gitea/act_runner:latest

Runner Labels 说明

Labels 决定 job 如何运行:

  • ubuntu-latest:docker://node:16-bullseye — 在 Docker 容器中运行
  • ubuntu-latest:hostubuntu-latest — 直接在宿主机运行
  • macos:host — 自定义 label,在宿主机运行

建议Mac mini 上使用 host 模式(不需要 Docker),labels 设置为:

ubuntu-latest:host,macos-arm64:host

启用仓库 Actions

⚠️ 重要:即使实例启用了 Actions,每个仓库也需要手动启用

  • 仓库 Settings → 勾选 "Enable Repository Actions"
  • 或通过 APIPATCH /api/v1/repos/{owner}/{repo}{"has_actions": true}

Branch Protection 配置指南

Web UI 方式

  1. 进入仓库 → Settings → Branches
  2. 点击 "Add Branch Protection Rule" 或编辑默认分支
  3. 配置项:
    • Branch name pattern:如 main
    • Enable push:控制谁能 push
    • Enable merge whitelist:控制谁能 merge PR
    • Required approvals:设置最少 review 人数
    • Enable status check:勾选并输入 CI workflow 名称
    • 其他:signed commits、protected file patterns 等

API 方式

# 创建 Branch Protection
curl -X POST \
  "http://192.168.2.154:3000/api/v1/repos/{owner}/{repo}/branch_protections" \
  -H "Authorization: token <PAT>" \
  -H "Content-Type: application/json" \
  -d '{
    "branch_name": "main",
    "enable_push": false,
    "enable_merge_whitelist": true,
    "merge_whitelist_usernames": ["chufeng"],
    "enable_status_check": true,
    "status_check_contexts": ["ci/test", "ci/lint"],
    "required_approvals": 1,
    "enable_approvals_whitelist": true,
    "approvals_whitelist_usernames": ["chufeng"]
  }'

# 列出所有 Branch Protection
curl "http://192.168.2.154:3000/api/v1/repos/{owner}/{repo}/branch_protections" \
  -H "Authorization: token <PAT>"

# 编辑 Branch Protection
curl -X PATCH \
  "http://192.168.2.154:3000/api/v1/repos/{owner}/{repo}/branch_protections/{id}" \
  -H "Authorization: token <PAT>" \
  -H "Content-Type: application/json" \
  -d '{"required_approvals": 2}'

推荐配置(适合我们的场景)

{
  "branch_name": "main",
  "enable_push": false,
  "enable_merge_whitelist": true,
  "enable_status_check": true,
  "status_check_contexts": ["CI"],
  "required_approvals": 1,
  "require_signed_commits": false
}

Webhook 配置指南

Web UI 方式

  1. 仓库 → Settings → Webhooks → Add Webhook → 选择 "Gitea"
  2. 配置:
    • Target URL:接收 webhook 的服务地址
    • HTTP MethodPOST
    • POST Content Typeapplication/json
    • Secret:用于 HMAC SHA256 签名验证
    • Trigger On:选择事件类型
    • Active:勾选

API 方式

# 创建仓库级 Webhook
curl -X POST \
  "http://192.168.2.154:3000/api/v1/repos/{owner}/{repo}/hooks" \
  -H "Authorization: token <PAT>" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "gitea",
    "config": {
      "url": "http://your-service/webhook",
      "content_type": "json",
      "secret": "your-webhook-secret"
    },
    "events": ["push", "pull_request"],
    "active": true
  }'

# 列出 hooks
curl "http://192.168.2.154:3000/api/v1/repos/{owner}/{repo}/hooks" \
  -H "Authorization: token <PAT>"

# 测试 hook
curl -X POST \
  "http://192.168.2.154:3000/api/v1/repos/{owner}/{repo}/hooks/{id}/tests" \
  -H "Authorization: token <PAT>"

Webhook 事件类型列表

事件 说明
push Git push(含 branch 和 tag
pull_request PR 创建/更新/关闭/merge
pull_request_assign PR 分配 reviewer
pull_request_label PR 标签变更
pull_request_milestone PR 里程碑变更
pull_request_comment PR 评论
pull_request_review_approved PR Review 通过
pull_request_review_rejected PR Review 拒绝
pull_request_review_comment PR Review 评论
issue Issue 相关
release Release 发布
create Branch/Tag 创建
delete Branch/Tag 删除
fork 仓库 fork
repository 仓库创建/删除

风险和限制

1. 已知功能限制

限制项 影响 变通方案
failure() 表达式不支持 无法实现 "失败时通知" job 拆分为独立 workflow + webhook
concurrency 不支持 同一 workflow 可能并行运行 在 workflow 脚本中加锁机制
continue-on-error 不支持 job 失败即终止 将错误处理逻辑放在 step 内
timeout-minutes 不支持 job 可能无限运行 act-runner 配置全局超时
GITEA_TOKEN 不内置(v1.23 CI 中调 API 需手动配置 PAT 创建 PAT 存为 secret
permissions 关键字被忽略 无法精细控制 job token 权限 v1.23 不适用,需升级

2. 兼容性注意事项

  • 数据库 charset:使用 MySQL 时需确保 charset 为 utf8mb4,否则 emoji 会报错
  • SHA256 仓库:某些 action(如 actions/checkout)在 SHA256 仓库中可能无法正常工作
  • Subpath 部署:如果 Gitea 运行在子路径下,某些 action 可能有问题
  • Schedule 时区:v1.23 起默认使用 UTC,需注意时区转换

3. 安全注意事项

  • act-runner 有潜在安全风险:运行 job 可访问 runner 所在机器
  • 内部使用的 Gitea 实例风险较低(官方明确说明)
  • 不建议为不信任的仓库/组织提供 runner
  • v1.23 的 fork PR workflow 自动限制为只读权限(安全特性)

4. 升级建议

强烈建议升级到 Gitea v1.24+,主要获益:

  1. 内置 GITEA_TOKEN:不再需要手动配置 PAT
  2. permissions 关键字支持:可精细控制 job 权限
  3. 更多表达式函数failure() 等可能得到支持
  4. 更多 bug 修复和性能改进

当前 v1.23.4 的替代方案仍然可行,只是需要更多手动配置。

5. 不支持 GitHub Actions 的功能清单

以下 GitHub Actions 特性在 Gitea Actions 中不可用

  • Problem Matchers
  • Create error annotation
  • Pre/Post steps 在 UI 中不单独展示
  • Services steps 在 UI 中不单独展示
  • Package repository authorization
  • Complex runs-on 表达式

示例 Workflow(验证可用)

name: CI
on:
  push:
    branches: [main]
  pull_request:
    types: [opened, synchronize]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Run tests
        run: |
          echo "Running tests..."
          # pytest / go test / etc.

  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Run lint
        run: |
          echo "Running lint..."
          # flake8 / eslint / etc.

  deploy:
    needs: [test, lint]
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'
    steps:
      - uses: actions/checkout@v4
      - name: Deploy
        run: |
          echo "Deploying..."
          # deploy script
        env:
          DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }}

注意if: github.ref == 'refs/heads/main' 可用,但 if: failure() 不可用。deploy job 仅在 main 分支且 test+lint 通过时执行。


参考资料