chore: 重构 OpenCode 命令和技能文档体系
- 新增:统一的 git 命令文档(add/commit/push/pull 等) - 新增:整合的 Gitea 技能文档(API、运行器、工作流等) - 新增:工作流模板(Android、Go、Node.js 等) - 移除:已弃用的旧命令脚本和发布脚本 - 改进:.gitignore 添加敏感文件保护规则 - 改进:AGENTS.md 完善了开发规范和示例 此次重组统一了命令和技能的文档结构,便于后续维护和扩展。
This commit is contained in:
397
skill/gitea/workflow-templates/nodejs-frontend.md
Normal file
397
skill/gitea/workflow-templates/nodejs-frontend.md
Normal file
@@ -0,0 +1,397 @@
|
||||
# Node.js 前端 Workflow 模板
|
||||
|
||||
适用于 Node.js 前端项目的 CI/CD workflow,支持 React、Vue、Vite、Next.js 等框架。
|
||||
|
||||
## 适用场景
|
||||
|
||||
- React / Vue / Angular 前端项目
|
||||
- Vite / Webpack 构建的 SPA
|
||||
- Next.js / Nuxt.js SSR 应用
|
||||
- 需要构建 Docker 镜像的前端项目
|
||||
|
||||
## 环境要求
|
||||
|
||||
| 依赖 | Runner 要求 |
|
||||
|------|------------|
|
||||
| Node.js 20+ | Runner 主机已安装 |
|
||||
| pnpm / npm | Runner 主机已安装或动态安装 |
|
||||
| Docker | Runner 主机已安装 |
|
||||
|
||||
## Workflow 骨架模板
|
||||
|
||||
```yaml
|
||||
name: Web Frontend - Build & Publish
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- 'web/**' # 修改为实际目录
|
||||
- '.gitea/workflows/web.yml'
|
||||
tags:
|
||||
- 'web-*' # 修改为实际 tag 前缀
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
SERVICE_PREFIX: web # 修改为实际服务名
|
||||
SERVICE_DIR: web # 修改为实际目录名
|
||||
NPM_REGISTRY: https://registry.npmmirror.com
|
||||
|
||||
jobs:
|
||||
build-and-publish:
|
||||
name: Build & Publish
|
||||
runs-on: darwin-arm64
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
outputs:
|
||||
git_tag: ${{ steps.vars.outputs.git_tag }}
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Verify Node.js environment
|
||||
run: |
|
||||
node --version
|
||||
npm --version
|
||||
|
||||
- name: Set up pnpm
|
||||
run: |
|
||||
npm config set registry ${{ env.NPM_REGISTRY }}
|
||||
npm install -g pnpm@latest-10
|
||||
|
||||
- name: Get pnpm-hashfiles
|
||||
id: hash-pnpm
|
||||
working-directory: ${{ env.SERVICE_DIR }}
|
||||
run: |
|
||||
HASH=$(sha256sum package.json pnpm-lock.yaml 2>/dev/null | sha256sum | awk '{print $1}' | head -c 16)
|
||||
echo "hash=${HASH}" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Cache pnpm modules
|
||||
uses: https://github.com/actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
~/.local/share/pnpm/store
|
||||
~/.pnpm-store
|
||||
${{ env.SERVICE_DIR }}/node_modules
|
||||
key: pnpm-${{ env.SERVICE_PREFIX }}-${{ steps.hash-pnpm.outputs.hash }}
|
||||
restore-keys: pnpm-${{ env.SERVICE_PREFIX }}-
|
||||
|
||||
- name: Set variables
|
||||
id: vars
|
||||
run: |
|
||||
git_tag=$(git describe --tags --abbrev=0 --always)
|
||||
registry=$(echo ${{ github.server_url }} | cut -d '/' -f 3)
|
||||
image_repo="${{ github.event.repository.name }}"
|
||||
|
||||
{
|
||||
echo "git_tag=${git_tag}"
|
||||
echo "registry=${registry}"
|
||||
echo "image_repo=${image_repo}"
|
||||
echo "latest_tag=${{ env.SERVICE_PREFIX }}-latest"
|
||||
} >> $GITHUB_ENV
|
||||
|
||||
echo "git_tag=${git_tag}" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Install & Build
|
||||
working-directory: ${{ env.SERVICE_DIR }}
|
||||
env:
|
||||
NODE_ENV: production
|
||||
# ============================================
|
||||
# 用户自定义环境变量(按项目需求修改)
|
||||
# ============================================
|
||||
# VITE_API_URL: https://api.example.com
|
||||
# VITE_APP_TITLE: My App
|
||||
# NEXT_PUBLIC_API_URL: https://api.example.com
|
||||
run: |
|
||||
# 安装依赖
|
||||
pnpm install --frozen-lockfile
|
||||
|
||||
# ============================================
|
||||
# 用户自定义构建步骤(按项目需求修改)
|
||||
# ============================================
|
||||
|
||||
# 类型检查(按需启用)
|
||||
# pnpm run typecheck
|
||||
# pnpm run lint
|
||||
|
||||
# 构建(必须)
|
||||
pnpm run build
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: ${{ env.SERVICE_PREFIX }}-dist
|
||||
path: ${{ env.SERVICE_DIR }}/dist
|
||||
|
||||
- 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: ./${{ env.SERVICE_DIR }}
|
||||
file: ./${{ env.SERVICE_DIR }}/Dockerfile
|
||||
push: true
|
||||
platforms: linux/amd64
|
||||
tags: |
|
||||
${{ env.registry }}/${{ github.repository_owner }}/${{ env.image_repo }}:${{ env.latest_tag }}
|
||||
${{ env.registry }}/${{ github.repository_owner }}/${{ env.image_repo }}:${{ env.git_tag }}
|
||||
cache-from: type=registry,ref=${{ env.registry }}/${{ github.repository_owner }}/${{ env.image_repo }}:buildcache
|
||||
cache-to: type=registry,ref=${{ env.registry }}/${{ github.repository_owner }}/${{ env.image_repo }}:buildcache,mode=max
|
||||
|
||||
- name: Notify
|
||||
if: always()
|
||||
continue-on-error: true
|
||||
env:
|
||||
WEBHOOK_URL: ${{ vars.WEBHOOK_URL }}
|
||||
run: |
|
||||
status="${{ job.status }}"
|
||||
[ "$status" = "success" ] && status_text="Build Success" || status_text="Build Failed"
|
||||
|
||||
curl -s -H "Content-Type: application/json" -X POST -d \
|
||||
"{\"msg_type\":\"text\",\"content\":{\"text\":\"${{ env.image_repo }}-${{ env.SERVICE_PREFIX }} ${status_text}\"}}" \
|
||||
"$WEBHOOK_URL" || true
|
||||
|
||||
release:
|
||||
name: Create Release
|
||||
runs-on: darwin-arm64
|
||||
needs: build-and-publish
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Download artifact
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: ${{ env.SERVICE_PREFIX }}-dist
|
||||
path: dist
|
||||
|
||||
- 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 }}"
|
||||
|
||||
# 打包构建产物
|
||||
cd dist
|
||||
zip -r "${{ env.SERVICE_PREFIX }}-dist.zip" .
|
||||
sha256sum "${{ env.SERVICE_PREFIX }}-dist.zip" > "${{ env.SERVICE_PREFIX }}-dist.zip.sha256"
|
||||
cd ..
|
||||
|
||||
# 创建 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/${{ env.SERVICE_PREFIX }}-dist.zip" \
|
||||
"${api_url}/repos/${repo}/releases/${release_id}/assets"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Dockerfile 模板
|
||||
|
||||
### 静态文件部署(Nginx)
|
||||
|
||||
```dockerfile
|
||||
FROM nginx:alpine
|
||||
|
||||
# 复制构建产物
|
||||
COPY dist /usr/share/nginx/html
|
||||
|
||||
# 复制 nginx 配置(可选)
|
||||
# COPY nginx.conf /etc/nginx/conf.d/default.conf
|
||||
|
||||
# 健康检查
|
||||
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
||||
CMD wget --no-verbose --tries=1 --spider http://localhost/ || exit 1
|
||||
|
||||
EXPOSE 80
|
||||
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
```
|
||||
|
||||
### SPA 路由配置(nginx.conf)
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 80;
|
||||
server_name localhost;
|
||||
root /usr/share/nginx/html;
|
||||
index index.html;
|
||||
|
||||
# SPA 路由支持
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
|
||||
# 静态资源缓存
|
||||
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2)$ {
|
||||
expires 1y;
|
||||
add_header Cache-Control "public, immutable";
|
||||
}
|
||||
|
||||
# 禁止缓存 HTML
|
||||
location ~* \.html$ {
|
||||
expires -1;
|
||||
add_header Cache-Control "no-store, no-cache, must-revalidate";
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 缓存配置
|
||||
|
||||
### pnpm 缓存路径
|
||||
|
||||
```yaml
|
||||
path: |
|
||||
~/.local/share/pnpm/store # pnpm 全局存储
|
||||
~/.pnpm-store # 备选路径
|
||||
web/node_modules # 项目依赖
|
||||
```
|
||||
|
||||
### npm 缓存路径
|
||||
|
||||
```yaml
|
||||
path: |
|
||||
~/.npm
|
||||
web/node_modules
|
||||
```
|
||||
|
||||
### Key 计算
|
||||
|
||||
```bash
|
||||
# pnpm
|
||||
HASH=$(sha256sum package.json pnpm-lock.yaml | sha256sum | awk '{print $1}' | head -c 16)
|
||||
|
||||
# npm
|
||||
HASH=$(sha256sum package.json package-lock.json | sha256sum | awk '{print $1}' | head -c 16)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 包管理器选择
|
||||
|
||||
### pnpm(推荐)
|
||||
|
||||
```yaml
|
||||
- name: Set up pnpm
|
||||
run: |
|
||||
npm install -g pnpm@latest-10
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
```
|
||||
|
||||
### npm
|
||||
|
||||
```yaml
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
```
|
||||
|
||||
### yarn
|
||||
|
||||
```yaml
|
||||
- name: Set up yarn
|
||||
run: npm install -g yarn
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn install --frozen-lockfile
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 环境变量注入
|
||||
|
||||
### Vite
|
||||
|
||||
```yaml
|
||||
env:
|
||||
VITE_API_URL: https://api.example.com
|
||||
VITE_APP_TITLE: My App
|
||||
```
|
||||
|
||||
### Next.js
|
||||
|
||||
```yaml
|
||||
env:
|
||||
NEXT_PUBLIC_API_URL: https://api.example.com
|
||||
```
|
||||
|
||||
### Vue CLI / CRA
|
||||
|
||||
```yaml
|
||||
env:
|
||||
VUE_APP_API_URL: https://api.example.com
|
||||
REACT_APP_API_URL: https://api.example.com
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Secrets 配置
|
||||
|
||||
| Secret | 用途 |
|
||||
|--------|------|
|
||||
| `REGISTRY_PASSWORD` | Docker Registry 密码 |
|
||||
| `RELEASE_TOKEN` | Gitea API 令牌(创建 Release) |
|
||||
|
||||
---
|
||||
|
||||
## 常见构建命令
|
||||
|
||||
根据项目使用的框架,在 Build 步骤中添加相应的命令:
|
||||
|
||||
| 框架 | 构建命令 |
|
||||
|------|---------|
|
||||
| Vite | `pnpm run build` |
|
||||
| Next.js | `pnpm run build` |
|
||||
| Nuxt.js | `pnpm run generate` 或 `pnpm run build` |
|
||||
| Vue CLI | `pnpm run build` |
|
||||
| CRA | `npm run build` |
|
||||
|
||||
---
|
||||
|
||||
## 使用步骤
|
||||
|
||||
1. 复制上方 workflow 模板到 `.gitea/workflows/web.yml`
|
||||
2. 修改 `SERVICE_PREFIX` 和 `SERVICE_DIR` 为实际值
|
||||
3. 修改 `paths` 和 `tags` 触发条件
|
||||
4. 根据项目需求配置环境变量
|
||||
5. 创建 `Dockerfile` 文件
|
||||
6. 配置 Secrets
|
||||
7. 推送代码触发 workflow
|
||||
|
||||
---
|
||||
|
||||
## 版本发布
|
||||
|
||||
```bash
|
||||
# 创建并推送 tag
|
||||
git tag web-1.0.0
|
||||
git push origin web-1.0.0
|
||||
```
|
||||
Reference in New Issue
Block a user