384 lines
8.6 KiB
Markdown
384 lines
8.6 KiB
Markdown
---
|
||
name: gitea-workflow
|
||
description: Gitea Actions Workflow foundation and templates for various project types with CI/CD best practices
|
||
---
|
||
|
||
# Gitea Actions Workflow Skill
|
||
|
||
Gitea Actions workflow 基础知识和项目模板指南,兼容 GitHub Actions 语法。
|
||
|
||
## 概述
|
||
|
||
Gitea Actions workflows 定义在 `.gitea/workflows/*.yml` 文件中。本 skill 提供:
|
||
- Workflow 基础结构和通用组件
|
||
- 各项目类型的骨架模板(用户按需填充具体构建逻辑)
|
||
|
||
## 项目类型模板
|
||
|
||
| 类型 | 文档 | 适用场景 |
|
||
|------|------|---------|
|
||
| Go 后端 | [go-backend.md](./go-backend.md) | API 服务、微服务、CLI 工具 |
|
||
| Node.js 前端 | [nodejs-frontend.md](./nodejs-frontend.md) | React/Vue/Vite/Next.js |
|
||
| Android 应用 | [android-app.md](./android-app.md) | Kotlin/Java/Jetpack Compose |
|
||
| 微信小程序 | [wechat-miniprogram.md](./wechat-miniprogram.md) | 微信小程序 CI/CD |
|
||
|
||
---
|
||
|
||
## Workflow 基础结构
|
||
|
||
### 文件位置
|
||
|
||
```
|
||
project/
|
||
├── .gitea/
|
||
│ └── workflows/
|
||
│ ├── backend.yml
|
||
│ ├── frontend.yml
|
||
│ └── ...
|
||
└── ...
|
||
```
|
||
|
||
### 骨架模板
|
||
|
||
```yaml
|
||
name: Service Name - Build & Publish
|
||
|
||
on:
|
||
push:
|
||
paths:
|
||
- 'service-dir/**' # 仅相关目录变更时触发
|
||
- '.gitea/workflows/this-workflow.yml'
|
||
tags:
|
||
- 'service-prefix-*' # Tag 触发 Release
|
||
|
||
concurrency:
|
||
group: ${{ github.workflow }}-${{ github.ref }}
|
||
cancel-in-progress: true # 取消同分支旧的运行
|
||
|
||
env:
|
||
SERVICE_PREFIX: service-name # 服务标识
|
||
|
||
jobs:
|
||
build:
|
||
name: Build
|
||
runs-on: darwin-arm64 # Runner 标签
|
||
permissions:
|
||
contents: read
|
||
packages: write
|
||
|
||
outputs:
|
||
version: ${{ steps.vars.outputs.version }}
|
||
|
||
steps:
|
||
- name: Checkout
|
||
uses: actions/checkout@v4
|
||
with:
|
||
fetch-depth: 0 # 完整历史(用于 git describe)
|
||
|
||
# ... 构建步骤
|
||
|
||
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 点
|
||
```
|
||
|
||
### 并发控制
|
||
|
||
```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` |
|
||
|
||
### 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/
|
||
```
|
||
|
||
### 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 }}/${{ github.repository_owner }}/image:latest
|
||
${{ env.registry }}/${{ github.repository_owner }}/image:${{ env.git_tag }}
|
||
cache-from: type=registry,ref=image:buildcache
|
||
cache-to: type=registry,ref=image:buildcache,mode=max
|
||
```
|
||
|
||
### 通知 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 的项目 |
|
||
|
||
### 项目特定 Secrets
|
||
|
||
参考各项目类型子文档。
|
||
|
||
### 安全最佳实践
|
||
|
||
1. **不要在日志中打印 secrets**
|
||
2. **使用 `vars.` 存储非敏感变量**(如用户名、URL)
|
||
3. **secrets 仅用于敏感信息**(如密码、密钥)
|
||
4. **定期轮换密钥**
|
||
|
||
---
|
||
|
||
## 最佳实践
|
||
|
||
### 1. 路径过滤
|
||
|
||
仅相关文件变更时触发,避免无关构建:
|
||
|
||
```yaml
|
||
on:
|
||
push:
|
||
paths:
|
||
- 'backend/**'
|
||
- '.gitea/workflows/backend.yml'
|
||
```
|
||
|
||
### 2. Tag 命名规范
|
||
|
||
使用前缀区分不同服务:
|
||
|
||
```bash
|
||
git tag server-1.0.0 && git push origin server-1.0.0
|
||
git tag web-1.0.0 && git push origin web-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()
|
||
```
|
||
|
||
---
|
||
|
||
## 快速参考
|
||
|
||
| 任务 | 命令/语法 |
|
||
|------|----------|
|
||
| 获取 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. **选择项目类型**:参考上方索引表,选择对应的子文档
|
||
2. **复制骨架模板**:将模板复制到 `.gitea/workflows/`
|
||
3. **填充构建逻辑**:根据项目需求填充 `# 用户自定义` 部分
|
||
4. **配置 Secrets**:在 Gitea 中配置所需的 Secrets
|
||
5. **推送触发**:推送代码或 Tag 触发 workflow
|
||
|
||
---
|
||
|
||
## 版本
|
||
|
||
- **Skill Version**: 2.0
|
||
- **Last Updated**: 2026-01-12
|
||
- **Structure**: 主文档 + 4 个项目类型子文档
|