Files
ai-proj-helper/skills-dev/gitea-plugin/skills/SKILL.md
John Qiu 712063071c refactor: 通用技能按类别拆分为独立目录
skills/ → skills-dev(9), skills-req(10), skills-ops(4),
skills-integration(8), skills-biz(4), skills-workflow(7)

generate-marketplace.py 改为自动扫描所有 skills-* 目录。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 11:31:58 +10:30

282 lines
8.8 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.
---
name: gitea
description: Gitea 代码托管与 CI/CD 管理。用于 Gitea Actions workflow 管理、Runner 管理、PR 操作、仓库配置。当用户提到 Gitea、Actions、Runner、CI/CD workflow、PR 检查相关任务时自动激活。
---
# Gitea Skill
Gitea 代码托管平台管理,覆盖 Actions CI/CD、Runner、PR、仓库配置。
## 服务器信息
| 服务 | 地址 | SSH |
|------|------|-----|
| Gitea Web | https://gitea.pipexerp.com | — |
| Gitea SSH | gitea.pipexerp.com:10022 | `ssh -i ~/.ssh/id_ed25519 git@gitea.pipexerp.com -p 10022` |
| Gitea 服务器 | 123.56.89.187 | `ssh -i ~/.ssh/tools.pem root@123.56.89.187` |
| Runner 服务器 | 101.200.136.200 (Jenkins 服务器) | `ssh -i ~/.ssh/tools.pem root@101.200.136.200` |
## API 访问
```bash
# Gitea API Token (仓库级)
GITEA_TOKEN="483a2b65219625ee382eb6d023cda39238c32e24"
# 通用请求格式
curl -s "https://gitea.pipexerp.com/api/v1/repos/pipexerp/<repo>/..." \
-H "Authorization: token $GITEA_TOKEN"
```
### 常用 API
| 操作 | 方法 | 端点 |
|------|------|------|
| 创建 PR | POST | `/repos/{owner}/{repo}/pulls` |
| 更新 PR | PATCH | `/repos/{owner}/{repo}/pulls/{id}` |
| 列出 Runs | GET | `/repos/{owner}/{repo}/actions/runs` |
| Run 详情 | GET | `/repos/{owner}/{repo}/actions/runs/{id}` |
| Job 详情 | GET | `/repos/{owner}/{repo}/actions/runs/{id}/jobs` |
| 手动触发 Workflow | POST | `/repos/{owner}/{repo}/actions/workflows/{file}/dispatches` body: `{"ref":"main"}` |
| 获取 Runner Token | POST | `/repos/{owner}/{repo}/actions/runners/registration-token` |
| 添加 Secret | PUT | `/repos/{owner}/{repo}/actions/secrets/{name}` body: `{"data":"value"}` |
| 删除 Run仅已完成| DELETE | `/repos/{owner}/{repo}/actions/runs/{id}` |
**注意**: Gitea 1.25 **不支持**通过 API cancel 正在排队/运行的 run。
## 仓库
| 仓库 | 地址 | 主分支 |
|------|------|--------|
| coolbuy-paas | pipexerp/coolbuy-paas | main |
| dotfiles | huangjun/dotfiles | main |
| claude-marketplace | huangjun/claude-marketplace | main |
## Actions Runners
### 主 Runner (lint/test/e2e)
| 项目 | 值 |
|------|-----|
| 名称 | jenkins-runner |
| 配置 | `/opt/act_runner/config.yaml` |
| Capacity | 3 |
| Labels | `ubuntu-latest`, `ubuntu-22.04`, `ubuntu-20.04` |
| 进程 | `/usr/local/bin/act_runner daemon --config /opt/act_runner/config.yaml` |
### Deploy Runner (staging 部署专用)
| 项目 | 值 |
|------|-----|
| 名称 | deploy-runner |
| 配置 | `/opt/act_runner_deploy/config.yaml` |
| Capacity | 1 |
| Labels | `deploy:host` |
| PID | `/opt/act_runner_deploy/runner.pid` |
| 日志 | `/opt/act_runner_deploy/runner.log` |
| 启动 | `cd /opt/act_runner_deploy && nohup act_runner daemon --config config.yaml > runner.log 2>&1 &` |
### 注册新 Runner
```bash
# 1. 获取 registration token
curl -s -X POST "https://gitea.pipexerp.com/api/v1/repos/pipexerp/coolbuy-paas/actions/runners/registration-token" \
-H "Authorization: token $GITEA_TOKEN"
# 2. SSH 到 runner 服务器
ssh -i ~/.ssh/tools.pem root@101.200.136.200
# 3. 创建目录和配置
mkdir -p /opt/act_runner_<name>
cat > /opt/act_runner_<name>/config.yaml << 'EOF'
log:
level: info
runner:
file: .runner
capacity: 1
timeout: 30m
labels:
- "<label>:host" # host 模式用系统 shell
# 或 "<label>:docker://image" # docker 模式
cache:
enabled: false
EOF
# 4. 注册
cd /opt/act_runner_<name>
act_runner register --instance https://gitea.pipexerp.com \
--token <TOKEN> --name <NAME> --labels '<LABEL>:host' \
--config config.yaml --no-interactive
# 5. 启动
nohup act_runner daemon --config config.yaml > runner.log 2>&1 &
echo $! > runner.pid
```
### Runner 运维
```bash
# 检查 runner 状态
ssh -i ~/.ssh/tools.pem root@101.200.136.200 "ps aux | grep act_runner | grep -v grep"
# 查看 deploy runner 日志
ssh -i ~/.ssh/tools.pem root@101.200.136.200 "tail -20 /opt/act_runner_deploy/runner.log"
# 重启 deploy runner
ssh -i ~/.ssh/tools.pem root@101.200.136.200 "
kill \$(cat /opt/act_runner_deploy/runner.pid) 2>/dev/null
cd /opt/act_runner_deploy
nohup act_runner daemon --config config.yaml > runner.log 2>&1 &
echo \$! > runner.pid
"
```
## Workflows (coolbuy-paas)
| Workflow | 触发 | Runner | paths-ignore | 用途 |
|----------|------|--------|-------------|------|
| 🚀 deploy-staging.yml | push → main | `deploy` | md, docs, .gitea, scripts, *_test.go | 触发 Jenkins 部署到 staging |
| 🔍 lint.yml | PR → main | `ubuntu-latest` | md, docs, .gitea, scripts | Go lint + ESLint auto-fix |
| 🧪 unit-test.yml | PR → main | `ubuntu-latest` | md, docs, .gitea, scripts | 4 个 Go 服务单元测试 |
| 🎭 e2e-tests.yml | schedule 12h | `ubuntu-latest` | — | Playwright E2E仅定时 |
| 📋 notify-aiproj.yml | PR merged | `ubuntu-latest` | — | 同步需求状态到 ai-proj |
| 📦 build.yaml | 手动 | `ubuntu-latest` | — | Docker 构建推 Hub |
### Workflow 编写规范
```yaml
# 1. 名称加 emoji 前缀
name: "🚀 Deploy Staging"
# 2. 非代码变更加 paths-ignore
on:
push:
branches: [main]
paths-ignore:
- '*.md'
- 'docs/**'
- '.gitea/**'
- 'scripts/**'
# 3. 加 concurrency 防重复
concurrency:
group: deploy-staging
cancel-in-progress: true
# 4. 仅定时的 workflow 加 event 守卫
jobs:
e2e:
if: github.event_name == 'schedule'
# 5. auto-fix 提交加 [skip ci]
git commit -m "style: auto-fix [skip ci]"
```
### Checkout 模式(容器内)
Gitea Actions 不支持 `actions/checkout`,用原生 git
```yaml
- name: Checkout
env:
TOKEN: ${{ github.token }}
run: |
git config --global --add safe.directory "$(pwd)"
git init
git remote add origin "https://oauth2:${TOKEN}@gitea.pipexerp.com/${{ github.repository }}.git"
git fetch origin "${{ github.event.pull_request.head.ref }}"
git checkout -b pr-branch "origin/${{ github.event.pull_request.head.ref }}"
git config user.name "CI Bot"
git config user.email "ci@pipexerp.com"
```
## Secrets 管理
### 当前 Secrets (coolbuy-paas 仓库级)
| Secret | 用途 |
|--------|------|
| `JENKINS_USER` | Jenkins API 用户名 |
| `JENKINS_TOKEN` | Jenkins API Token |
| `DOCKER_HUB_TOKEN` | Docker Hub 推送 |
| `AI_PROJ_TOKEN` | ai-proj API 认证 |
### 添加/更新 Secret
```bash
curl -s -X PUT \
"https://gitea.pipexerp.com/api/v1/repos/pipexerp/coolbuy-paas/actions/secrets/<NAME>" \
-H "Authorization: token $GITEA_TOKEN" \
-H "Content-Type: application/json" \
-d '{"data": "<VALUE>"}'
```
## CI/CD 完整流程
```
PR → main
├── 🧪 unit-test.yml (Go 服务测试)
├── 🔍 lint.yml (auto-fix 格式)
└── merge 后:
├── 📋 notify-aiproj.yml (需求状态 → testing)
└── 🚀 deploy-staging.yml (Jenkins → staging)
├── ≥5 commits/2h → 立即部署
└── <5 commits → 等3分钟 debounce
定时:
└── 🎭 e2e-tests.yml (每12h Playwright)
手动:
└── 📦 build.yaml (Docker 构建推 Hub)
生产部署:
└── ./scripts/build-and-push.sh prod --deploy (触发 Jenkins)
```
## 本地 CLI 工具
### tea CLI (Gitea 官方命令行)
tea 是 Gitea 官方 CLI 客户端,已配置好认证信息。
```bash
# 配置文件位置
~/Library/Application Support/tea/config.yml
# 或 ~/.config/tea/config.yml
# gitea-runs 脚本从 tea config 读取 url 和 token
```
### gitea-runs (Actions 快捷命令)
位置: `~/.local/bin/gitea-runs`
自动从 git remote 检测仓库,从 tea CLI 配置读取认证信息。
| 命令 | 说明 |
|------|------|
| `gitea-runs` | 列出最近 10 条 run |
| `gitea-runs list [N]` | 列出最近 N 条 run |
| `gitea-runs view <run_number>` | 查看 run 详情和 jobs |
| `gitea-runs open [run_number]` | 在浏览器打开 run 页面 |
| `gitea-runs workflows` | 列出所有 workflow |
| `gitea-runs dispatch <wf> [ref]` | 手动触发 workflow |
```bash
# 示例
gitea-runs # 查看最近 runs
gitea-runs view 303 # 查看 run #303 详情
gitea-runs dispatch deploy-staging.yml main # 手动触发部署
gitea-runs open # 打开 Actions 页面
```
**优先使用 `gitea-runs` 而非 curl API**,更简洁且自动处理认证。
## 常见问题
| 问题 | 原因 | 解决 |
|------|------|------|
| Run 一直 queued | Runner 被占满 | 等其他 job 完成,或加 runner |
| deploy 被 test 阻塞 | 共用 runner | 用 `runs-on: deploy` 专属 runner |
| Workflow 被误触发 | push 新 workflow 文件到 main | 加 `if: github.event_name == 'schedule'` 守卫 |
| auto-fix 无限循环 | 提交触发新 run | 提交信息加 `[skip ci]` |
| API 无法 cancel run | Gitea 1.25 限制 | 网页手动取消,或等完成后 DELETE |
| `date -d` 报错 | 容器 date 不兼容 | 用 host 模式 runner或兼容写法 |