chore: 重构 OpenCode 命令和技能文档体系
- 新增:统一的 git 命令文档(add/commit/push/pull 等) - 新增:整合的 Gitea 技能文档(API、运行器、工作流等) - 新增:工作流模板(Android、Go、Node.js 等) - 移除:已弃用的旧命令脚本和发布脚本 - 改进:.gitignore 添加敏感文件保护规则 - 改进:AGENTS.md 完善了开发规范和示例 此次重组统一了命令和技能的文档结构,便于后续维护和扩展。
This commit is contained in:
624
skill/gitea/workflow-generator.md
Normal file
624
skill/gitea/workflow-generator.md
Normal file
@@ -0,0 +1,624 @@
|
||||
# Gitea Workflow 生成器
|
||||
|
||||
根据项目类型自动生成 CI/CD workflow 文件。
|
||||
|
||||
## 概述
|
||||
|
||||
Gitea Actions 使用 GitHub Actions 兼容的 workflow 语法,定义在 `.gitea/workflows/*.yml` 文件中。
|
||||
|
||||
本 skill 提供:
|
||||
- 自动检测项目类型
|
||||
- 根据类型生成适配的 workflow 模板
|
||||
- 自动填充项目特定变量
|
||||
- 智能配置触发条件和缓存策略
|
||||
|
||||
## 项目类型模板
|
||||
|
||||
| 类型 | 模板文档 | 适用场景 |
|
||||
|------|---------|---------|
|
||||
| Go 后端 | [go-backend.md](./workflow-templates/go-backend.md) | API 服务、微服务、CLI 工具 |
|
||||
| Node.js 前端 | [nodejs-frontend.md](./workflow-templates/nodejs-frontend.md) | React/Vue/Vite/Next.js |
|
||||
| Android 应用 | [android-app.md](./workflow-templates/android-app.md) | Kotlin/Java/Jetpack Compose |
|
||||
| 微信小程序 | [wechat-miniprogram.md](./workflow-templates/wechat-miniprogram.md) | 微信小程序 CI/CD |
|
||||
|
||||
## 自动生成流程
|
||||
|
||||
### 步骤 1: 检测项目类型
|
||||
|
||||
当用户说"为我的项目生成 workflow"时,AI 会自动检测项目类型:
|
||||
|
||||
```bash
|
||||
# Go 项目特征
|
||||
if [ -f "go.mod" ] || [ -f "main.go" ]; then
|
||||
project_type="go"
|
||||
fi
|
||||
|
||||
# Node.js 项目特征
|
||||
if [ -f "package.json" ]; then
|
||||
project_type="nodejs"
|
||||
|
||||
# 细分类型
|
||||
if grep -q "\"react\"" package.json; then
|
||||
framework="react"
|
||||
elif grep -q "\"vue\"" package.json; then
|
||||
framework="vue"
|
||||
elif grep -q "\"vite\"" package.json; then
|
||||
framework="vite"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Android 项目特征
|
||||
if [ -f "build.gradle" ] || [ -f "build.gradle.kts" ]; then
|
||||
if [ -d "app/src/main/java" ] || [ -d "app/src/main/kotlin" ]; then
|
||||
project_type="android"
|
||||
fi
|
||||
fi
|
||||
|
||||
# 微信小程序特征
|
||||
if [ -f "project.config.json" ] && [ -f "app.json" ]; then
|
||||
project_type="wechat-miniprogram"
|
||||
fi
|
||||
```
|
||||
|
||||
### 步骤 2: 提示用户确认
|
||||
|
||||
```
|
||||
检测到项目类型: Go 后端服务
|
||||
服务目录: ./backend
|
||||
是否正确? [Y/n]
|
||||
```
|
||||
|
||||
### 步骤 3: 收集项目信息
|
||||
|
||||
根据项目类型,收集必要信息:
|
||||
|
||||
**Go 项目**:
|
||||
- 服务目录(如 `./backend`)
|
||||
- 服务名称(如 `api-server`)
|
||||
- 是否需要 Docker 构建
|
||||
- Docker Registry 地址
|
||||
|
||||
**Node.js 项目**:
|
||||
- 项目目录
|
||||
- 包管理器(npm/pnpm/yarn)
|
||||
- 构建命令
|
||||
- 输出目录
|
||||
|
||||
**Android 项目**:
|
||||
- 模块名称(如 `app`)
|
||||
- 构建类型(release/debug)
|
||||
- 签名配置
|
||||
|
||||
**微信小程序**:
|
||||
- 项目目录
|
||||
- 版本号规则
|
||||
- 上传配置
|
||||
|
||||
### 步骤 4: 选择 Runner
|
||||
|
||||
```
|
||||
请选择 Runner:
|
||||
1) darwin-arm64 (macOS ARM64)
|
||||
2) ubuntu-latest (Docker)
|
||||
3) 自定义
|
||||
|
||||
[1]:
|
||||
```
|
||||
|
||||
### 步骤 5: 生成 Workflow 文件
|
||||
|
||||
基于模板生成 workflow,自动替换变量:
|
||||
|
||||
```yaml
|
||||
name: Backend Service - Build & Publish
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- 'backend/**' # 自动填充:项目目录
|
||||
- '.gitea/workflows/backend.yml'
|
||||
tags:
|
||||
- 'backend-*' # 自动填充:服务前缀
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
SERVICE_PREFIX: backend # 自动填充:服务名称
|
||||
SERVICE_DIR: backend # 自动填充:服务目录
|
||||
GOPROXY: https://goproxy.cn,direct
|
||||
|
||||
jobs:
|
||||
build-and-publish:
|
||||
name: Build & Publish
|
||||
runs-on: darwin-arm64 # 自动填充:Runner
|
||||
# ... 其余配置
|
||||
```
|
||||
|
||||
### 步骤 6: 创建文件
|
||||
|
||||
```bash
|
||||
# 创建 .gitea/workflows 目录
|
||||
mkdir -p .gitea/workflows
|
||||
|
||||
# 写入 workflow 文件
|
||||
cat > .gitea/workflows/backend.yml << 'EOF'
|
||||
[生成的 workflow 内容]
|
||||
EOF
|
||||
|
||||
echo "✓ Workflow 已生成: .gitea/workflows/backend.yml"
|
||||
```
|
||||
|
||||
### 步骤 7: 提示配置 Secrets
|
||||
|
||||
根据 workflow 需求,提示用户配置 Secrets:
|
||||
|
||||
```
|
||||
需要配置以下 Secrets:
|
||||
- REGISTRY_PASSWORD: Docker Registry 密码
|
||||
- RELEASE_TOKEN: Gitea API Token(创建 Release 用)
|
||||
|
||||
配置方法:
|
||||
1. 在 Gitea 中打开仓库设置
|
||||
2. 进入 Settings → Secrets → Actions
|
||||
3. 添加上述 Secrets
|
||||
|
||||
或使用 API:
|
||||
source ~/.config/gitea/config.env
|
||||
echo -n "password" | base64 | xargs -I {} \
|
||||
curl -X PUT \
|
||||
-H "Authorization: token $GITEA_TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"data":"{}"}' \
|
||||
"$GITEA_URL/api/v1/repos/owner/repo/actions/secrets/REGISTRY_PASSWORD"
|
||||
```
|
||||
|
||||
## Workflow 基础结构
|
||||
|
||||
### 完整骨架
|
||||
|
||||
```yaml
|
||||
name: Service Name - Build & Publish
|
||||
|
||||
# 触发条件
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- 'service-dir/**'
|
||||
- '.gitea/workflows/this-workflow.yml'
|
||||
tags:
|
||||
- 'service-prefix-*'
|
||||
|
||||
# 并发控制
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
# 环境变量
|
||||
env:
|
||||
SERVICE_PREFIX: service-name
|
||||
SERVICE_DIR: service-dir
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: darwin-arm64
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
outputs:
|
||||
version: ${{ steps.vars.outputs.version }}
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
# 项目特定的构建步骤
|
||||
|
||||
release:
|
||||
name: Create Release
|
||||
runs-on: darwin-arm64
|
||||
needs: build
|
||||
if: startsWith(github.ref, 'refs/tags/service-prefix-')
|
||||
steps:
|
||||
# Release 步骤
|
||||
```
|
||||
|
||||
## 触发条件配置
|
||||
|
||||
### 常用触发模式
|
||||
|
||||
```yaml
|
||||
on:
|
||||
# 分支推送
|
||||
push:
|
||||
branches: [main, develop]
|
||||
|
||||
# 路径过滤(推荐:仅相关文件变更时触发)
|
||||
push:
|
||||
paths:
|
||||
- 'src/**'
|
||||
- '*.yml'
|
||||
|
||||
# Tag 推送(用于 Release)
|
||||
push:
|
||||
tags:
|
||||
- 'v*'
|
||||
- 'service-*'
|
||||
|
||||
# Pull Request
|
||||
pull_request:
|
||||
branches: [main]
|
||||
|
||||
# 手动触发
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
environment:
|
||||
description: 'Deploy environment'
|
||||
required: true
|
||||
default: 'staging'
|
||||
|
||||
# 定时触发
|
||||
schedule:
|
||||
- cron: '0 2 * * *' # 每天凌晨 2 点
|
||||
```
|
||||
|
||||
### 并发控制
|
||||
|
||||
避免同一分支的多个 workflow 同时运行:
|
||||
|
||||
```yaml
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true # 取消旧的运行
|
||||
```
|
||||
|
||||
## 通用组件
|
||||
|
||||
### Checkout
|
||||
|
||||
```yaml
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0 # 完整历史,用于 git describe
|
||||
# fetch-depth: 1 # 仅最新提交,加快速度
|
||||
```
|
||||
|
||||
### 变量设置
|
||||
|
||||
```yaml
|
||||
- name: Set variables
|
||||
id: vars
|
||||
run: |
|
||||
git_tag=$(git describe --tags --abbrev=0 --always)
|
||||
registry=$(echo ${{ github.server_url }} | cut -d '/' -f 3)
|
||||
|
||||
# 写入环境变量(当前 job 可用)
|
||||
{
|
||||
echo "git_tag=${git_tag}"
|
||||
echo "registry=${registry}"
|
||||
} >> $GITHUB_ENV
|
||||
|
||||
# 写入输出(其他 job 可用)
|
||||
echo "version=${git_tag}" >> $GITHUB_OUTPUT
|
||||
```
|
||||
|
||||
### Cache Action
|
||||
|
||||
```yaml
|
||||
- name: Cache dependencies
|
||||
uses: https://github.com/actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
~/.cache/directory
|
||||
./node_modules
|
||||
key: cache-name-${{ hashFiles('**/lockfile') }}
|
||||
restore-keys: cache-name-
|
||||
```
|
||||
|
||||
**各语言缓存路径**:
|
||||
|
||||
| 语言 | 缓存路径 | Key 文件 |
|
||||
|------|---------|----------|
|
||||
| Go | `~/go/pkg/mod`, `~/.cache/go-build` | `go.mod`, `go.sum` |
|
||||
| Node.js (pnpm) | `~/.pnpm-store`, `node_modules` | `pnpm-lock.yaml` |
|
||||
| Node.js (npm) | `~/.npm`, `node_modules` | `package-lock.json` |
|
||||
| Gradle | `~/.gradle/caches`, `~/.gradle/wrapper` | `*.gradle*`, `gradle-wrapper.properties` |
|
||||
|
||||
### Docker 构建推送
|
||||
|
||||
```yaml
|
||||
- name: Docker - Login
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{ env.registry }}
|
||||
username: ${{ vars.REGISTRY_USERNAME }}
|
||||
password: ${{ secrets.REGISTRY_PASSWORD }}
|
||||
|
||||
- name: Docker - Setup Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Docker - Build & Push
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: ./service-dir
|
||||
file: ./service-dir/Dockerfile
|
||||
push: true
|
||||
platforms: linux/amd64
|
||||
tags: |
|
||||
${{ env.registry }}/owner/image:latest
|
||||
${{ env.registry }}/owner/image:${{ env.git_tag }}
|
||||
cache-from: type=registry,ref=image:buildcache
|
||||
cache-to: type=registry,ref=image:buildcache,mode=max
|
||||
```
|
||||
|
||||
### Artifact 上传/下载
|
||||
|
||||
```yaml
|
||||
# 上传
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: build-artifact
|
||||
path: dist/
|
||||
|
||||
# 下载(另一个 job)
|
||||
- name: Download artifact
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: build-artifact
|
||||
path: dist/
|
||||
```
|
||||
|
||||
### 通知 Webhook
|
||||
|
||||
```yaml
|
||||
- name: Notify
|
||||
if: always()
|
||||
continue-on-error: true
|
||||
env:
|
||||
WEBHOOK_URL: ${{ vars.WEBHOOK_URL }}
|
||||
run: |
|
||||
status="${{ job.status }}"
|
||||
[ "$status" = "success" ] && text="Build Success" || text="Build Failed"
|
||||
|
||||
curl -s -H "Content-Type: application/json" -X POST \
|
||||
-d "{\"msg_type\":\"text\",\"content\":{\"text\":\"${{ env.SERVICE_PREFIX }} ${text}\"}}" \
|
||||
"$WEBHOOK_URL"
|
||||
```
|
||||
|
||||
### Release 创建(Gitea API)
|
||||
|
||||
```yaml
|
||||
- name: Create Release
|
||||
env:
|
||||
GITEA_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
||||
run: |
|
||||
git_tag=$(git describe --tags --abbrev=0)
|
||||
api_url="${{ github.server_url }}/api/v1"
|
||||
repo="${{ github.repository }}"
|
||||
|
||||
# 创建 Release
|
||||
release_id=$(curl -s -X POST \
|
||||
-H "Authorization: token $GITEA_TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{\"tag_name\":\"${git_tag}\",\"name\":\"Release ${git_tag}\"}" \
|
||||
"${api_url}/repos/${repo}/releases" | jq -r '.id')
|
||||
|
||||
# 上传附件
|
||||
curl -s -X POST \
|
||||
-H "Authorization: token $GITEA_TOKEN" \
|
||||
-F "attachment=@dist/artifact.zip" \
|
||||
"${api_url}/repos/${repo}/releases/${release_id}/assets"
|
||||
```
|
||||
|
||||
## Secrets 配置
|
||||
|
||||
### 通用 Secrets
|
||||
|
||||
| Secret | 用途 | 适用项目 |
|
||||
|--------|------|---------|
|
||||
| `REGISTRY_PASSWORD` | Docker Registry 密码 | 需要 Docker 发布的项目 |
|
||||
| `RELEASE_TOKEN` | Gitea API 令牌 | 需要创建 Release 的项目 |
|
||||
|
||||
### 安全最佳实践
|
||||
|
||||
1. **不要在日志中打印 secrets**
|
||||
2. **使用 `vars.` 存储非敏感变量**(如用户名、URL)
|
||||
3. **secrets 仅用于敏感信息**(如密码、密钥)
|
||||
4. **定期轮换密钥**
|
||||
|
||||
### 配置 Secrets
|
||||
|
||||
**方法 1: 通过 Gitea UI**
|
||||
|
||||
1. 打开仓库 → Settings → Secrets → Actions
|
||||
2. 点击 "Add Secret"
|
||||
3. 输入 Name 和 Value
|
||||
4. 保存
|
||||
|
||||
**方法 2: 通过 API**
|
||||
|
||||
```bash
|
||||
source ~/.config/gitea/config.env
|
||||
|
||||
secret_name="REGISTRY_PASSWORD"
|
||||
secret_value="my-password"
|
||||
|
||||
# Base64 编码
|
||||
encoded=$(echo -n "$secret_value" | base64)
|
||||
|
||||
# 调用 API
|
||||
curl -X PUT \
|
||||
-H "Authorization: token $GITEA_TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{\"data\":\"${encoded}\"}" \
|
||||
"$GITEA_URL/api/v1/repos/owner/repo/actions/secrets/$secret_name"
|
||||
```
|
||||
|
||||
## 最佳实践
|
||||
|
||||
### 1. 路径过滤
|
||||
|
||||
仅相关文件变更时触发,避免无关构建:
|
||||
|
||||
```yaml
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- 'backend/**'
|
||||
- '.gitea/workflows/backend.yml'
|
||||
```
|
||||
|
||||
### 2. Tag 命名规范
|
||||
|
||||
使用前缀区分不同服务:
|
||||
|
||||
```bash
|
||||
git tag backend-1.0.0 && git push origin backend-1.0.0
|
||||
git tag frontend-1.0.0 && git push origin frontend-1.0.0
|
||||
git tag android-1.0.0 && git push origin android-1.0.0
|
||||
```
|
||||
|
||||
### 3. Job 输出传递
|
||||
|
||||
```yaml
|
||||
jobs:
|
||||
build:
|
||||
outputs:
|
||||
version: ${{ steps.vars.outputs.version }}
|
||||
|
||||
deploy:
|
||||
needs: build
|
||||
env:
|
||||
VERSION: ${{ needs.build.outputs.version }}
|
||||
```
|
||||
|
||||
### 4. 条件执行
|
||||
|
||||
```yaml
|
||||
# 仅 Tag 推送时执行
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
|
||||
# 仅主分支执行
|
||||
if: github.ref == 'refs/heads/main'
|
||||
|
||||
# 始终执行(用于通知)
|
||||
if: always()
|
||||
```
|
||||
|
||||
### 5. 使用缓存加速构建
|
||||
|
||||
合理使用缓存可以显著减少构建时间:
|
||||
|
||||
```yaml
|
||||
# Go 项目
|
||||
- name: Cache Go modules
|
||||
uses: https://github.com/actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
~/go/pkg/mod
|
||||
~/.cache/go-build
|
||||
key: go-${{ hashFiles('**/go.sum') }}
|
||||
|
||||
# Node.js 项目
|
||||
- name: Cache pnpm store
|
||||
uses: https://github.com/actions/cache@v3
|
||||
with:
|
||||
path: ~/.pnpm-store
|
||||
key: pnpm-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
```
|
||||
|
||||
## 项目特定模板
|
||||
|
||||
### Go 后端服务
|
||||
|
||||
详见:[Go 后端模板](./workflow-templates/go-backend.md)
|
||||
|
||||
**特点**:
|
||||
- 支持 monorepo 和 polyrepo
|
||||
- Docker 多阶段构建
|
||||
- 自动版本管理
|
||||
- Release 创建和附件上传
|
||||
|
||||
### Node.js 前端应用
|
||||
|
||||
详见:[Node.js 前端模板](./workflow-templates/nodejs-frontend.md)
|
||||
|
||||
**特点**:
|
||||
- pnpm/npm/yarn 支持
|
||||
- 依赖缓存优化
|
||||
- 静态资源构建
|
||||
- Docker 部署
|
||||
|
||||
### Android 应用
|
||||
|
||||
详见:[Android 应用模板](./workflow-templates/android-app.md)
|
||||
|
||||
**特点**:
|
||||
- Gradle 缓存优化
|
||||
- 多 flavor 支持
|
||||
- 签名配置
|
||||
- APK/AAB 生成
|
||||
|
||||
### 微信小程序
|
||||
|
||||
详见:[微信小程序模板](./workflow-templates/wechat-miniprogram.md)
|
||||
|
||||
**特点**:
|
||||
- 自动版本号管理
|
||||
- miniprogram-ci 集成
|
||||
- 预览/上传自动化
|
||||
- 体验版分发
|
||||
|
||||
## 快速参考
|
||||
|
||||
| 任务 | 命令/语法 |
|
||||
|------|----------|
|
||||
| 获取 git tag | `git describe --tags --abbrev=0 --always` |
|
||||
| 提取 registry | `echo ${{ github.server_url }} \| cut -d '/' -f 3` |
|
||||
| 设置环境变量 | `echo "KEY=value" >> $GITHUB_ENV` |
|
||||
| 设置输出 | `echo "key=value" >> $GITHUB_OUTPUT` |
|
||||
| 计算哈希 | `sha256sum file1 file2 \| sha256sum \| head -c 16` |
|
||||
|
||||
## 使用方式
|
||||
|
||||
1. **自然语言触发**:
|
||||
```
|
||||
用户: 为我的项目生成 workflow
|
||||
用户: 创建 CI/CD 配置
|
||||
用户: 添加自动化构建
|
||||
```
|
||||
|
||||
2. **AI 自动检测项目类型**
|
||||
|
||||
3. **填充项目特定信息**
|
||||
|
||||
4. **生成 workflow 文件**:`.gitea/workflows/*.yml`
|
||||
|
||||
5. **配置 Secrets**(如需要)
|
||||
|
||||
6. **推送代码触发**:
|
||||
```bash
|
||||
git add .gitea/workflows
|
||||
git commit -m "Add CI/CD workflow"
|
||||
git push origin main
|
||||
```
|
||||
|
||||
## 相关资源
|
||||
|
||||
- [Gitea Actions 文档](https://docs.gitea.com/usage/actions/overview)
|
||||
- [GitHub Actions Workflow 语法](https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions)
|
||||
- [环境配置指南](./setup-guide.md)
|
||||
- [Runner 管理](./runner-management.md)
|
||||
|
||||
## 版本
|
||||
|
||||
- **文档版本**: 1.0
|
||||
- **最后更新**: 2026-01-12
|
||||
- **整合内容**: gitea-workflow skill 的所有模板
|
||||
Reference in New Issue
Block a user