Files
xgj/release-web/README.md

525 lines
14 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.

# Web 项目发布构建 Action
[![GitHub](https://img.shields.io/badge/github-actions-blue.svg)](https://github.com/features/actions)
自动化 Web 项目发布流程的 GitHub Action专注于版本管理和发布核心功能智能处理各种版本格式。
## 功能特性
- 🚀 **自动化发布**: 支持任意发布命令进行版本管理和发布
- 🌍 **环境变量支持**: 支持传递任意数量的环境变量给发布命令
- 📦 **智能版本处理**: 自动获取版本号,确保输出格式一致(无 `v` 前缀)
- 📊 **状态监控**: 实时监控发布状态,支持成功/失败状态输出和退出码
- 🔧 **简洁配置**: 最小化配置,专注于发布核心功能
-**灵活使用**: 可配置发布命令,适应不同项目需求
- 🛡️ **错误控制**: 可配置发布失败时的行为(中断或继续)
## 快速开始
### 基础用法
```yaml
- name: 发布Web项目
uses: actions/xgj/release-web@main
env:
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
```
### 使用环境变量
```yaml
- name: 发布Web项目
uses: actions/xgj/release-web@main
env:
# 🌍 可以传递任意数量的环境变量给发布命令
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
APP_ENV: production
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_DSN: ${{ vars.SENTRY_DSN }}
SENTRY_VITE: true
BUILD_NUMBER: ${{ github.run_number }}
CUSTOM_CONFIG: "your-value"
FEATURE_FLAG: ${{ github.ref == 'refs/heads/main' }}
# ... 更多任意环境变量
```
### 完整示例
```yaml
- name: 发布Web项目
uses: actions/xgj/release-web@main
with:
release-command: "npm run release -- --release -V"
env:
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
APP_ENV: "production"
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_DSN: ${{ vars.SENTRY_DSN }}
SENTRY_VITE: "true"
```
### 自定义版本文件路径
```yaml
- name: 发布Web项目
uses: actions/xgj/release-web@main
with:
version-file: "./dist/version.txt" # 自定义版本文件位置
env:
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
```
### 版本格式处理
Action 自动处理各种版本格式,确保输出一致:
```yaml
# 输入可能的格式:
# - 版本文件: "v1.2.3" 或 "1.2.3"
# - Git tag: "v1.2.3" 或 "1.2.3"
# - package.json: "v1.2.3" 或 "1.2.3"
# - 提交信息: "release: v1.2.3" 或 "release: 1.2.3"
# 输出始终为: "v1.2.3" (统一添加 v 前缀)
# 带横线版本: "v1-2-3" (保持 v 前缀)
```
## 输入参数
| 参数名 | 描述 | 必需 | 默认值 |
| ----------------- | ---------------------------- | ---- | --------------------------------- |
| `release-command` | 发布命令 | ❌ | `npm run release -- --release -V` |
| `node-debug` | 是否启用 Node.js 调试模式 | ❌ | `false` |
| `version-file` | 自定义版本文件路径 | ❌ | `/tmp/last-version` |
| `fail-on-error` | 发布失败时是否让 action 失败 | ❌ | `true` |
## 环境变量支持
Action 支持通过 `env` 传递**任意数量**的环境变量给发布命令,这些环境变量会自动传递给 `npm run release` 或其他发布命令:
```yaml
- uses: actions/xgj/release-web@main
env:
# 🌍 任意环境变量都会自动传递给发布命令
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
APP_ENV: production
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_TOKEN }}
CUSTOM_VAR: "your-value"
BUILD_NUMBER: ${{ github.run_number }}
FEATURE_FLAG: ${{ github.ref == 'refs/heads/main' }}
# ... 更多任意变量
```
### 常用环境变量示例
| 环境变量名 | 描述 | 示例值 |
| ------------------- | ---------------- | ----------------------------- |
| `GITEA_TOKEN` | Gitea 访问令牌 | `${{ secrets.GITEA_TOKEN }}` |
| `APP_ENV` | 应用环境 | `production` |
| `SENTRY_AUTH_TOKEN` | Sentry 认证令牌 | `${{ secrets.SENTRY_TOKEN }}` |
| `SENTRY_DSN` | Sentry DSN 配置 | `${{ vars.SENTRY_DSN }}` |
| `SENTRY_VITE` | 是否启用 Sentry | `true` |
| `NODE_DEBUG` | Node.js 调试模式 | `release-it:*` |
| `BUILD_NUMBER` | 构建编号 | `${{ github.run_number }}` |
## 输出参数
| 参数名 | 描述 |
| ------------------- | -------------------------------------- |
| `version` | 发布的版本号(带 v 前缀) |
| `version-with-dash` | 版本号(带 v 前缀,点号替换为横线) |
| `release-status` | 发布命令执行状态 (`success`/`failure`) |
| `exit-code` | 发布命令退出码(仅在失败时有值) |
## 使用场景
### 1. 基础发布流程
适用于简单的 Web 项目发布:
```yaml
steps:
- uses: actions/checkout@v4
- name: 设置环境
uses: actions/xgj/setup-env@main
with:
docker-password: ${{ secrets.DOCKER_PASSWORD }}
- name: 安装依赖
uses: actions/xgj/npm-install@main
- name: 发布项目
uses: actions/xgj/release-web@main
env:
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
```
### 2. 完整 CI/CD 流程
包含完整的构建、测试、发布流程:
```yaml
steps:
- uses: actions/checkout@v4
- name: 设置构建环境
uses: actions/xgj/setup-env@main
with:
docker-password: ${{ secrets.DOCKER_PASSWORD }}
kube-config: ${{ secrets.KUBE_CONFIG }}
- name: 安装依赖
uses: actions/xgj/npm-install@main
with:
package-manager: "pnpm"
- name: 运行测试
run: npm run test
- name: 发布构建
id: release
uses: actions/xgj/release-web@main
env:
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
APP_ENV: ${{ github.ref == 'refs/heads/main' && 'production' || 'staging' }}
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_DSN: ${{ vars.SENTRY_DSN }}
SENTRY_VITE: "true"
- name: 部署到Kubernetes
run: |
kubectl set image deployment/web-app web-app=docker-registry.bjxgj.com/${{ github.event.repository.name }}:${{ steps.release.outputs.version }}
```
### 3. 多环境发布
支持不同环境的差异化配置:
```yaml
strategy:
matrix:
environment: [staging, production]
include:
- environment: staging
dockerfile: "./container/dev/Dockerfile"
app-env: "staging"
- environment: production
dockerfile: "./container/prod/Dockerfile"
app-env: "production"
steps:
- name: 发布到 ${{ matrix.environment }}
uses: actions/xgj/release-web@main
env:
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
APP_ENV: ${{ matrix.app_env }}
```
### 4. 状态检查和错误处理
演示如何处理发布状态和错误:
```yaml
steps:
- uses: actions/checkout@v4
- name: 发布项目
id: release
uses: actions/xgj/release-web@main
with:
fail-on-error: false # 发布失败时不中断 workflow
env:
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
# 总是执行的清理步骤
- name: 清理临时文件
if: always()
run: |
echo "清理临时文件..."
rm -rf temp/ dist/temp/
# 根据发布状态执行不同操作
- name: 处理发布结果
if: always()
run: |
echo "发布状态: ${{ steps.release.outputs.release-status }}"
if [[ "${{ steps.release.outputs.release-status }}" == "success" ]]; then
echo "✅ 发布成功,版本: ${{ steps.release.outputs.version }}"
echo "开始部署流程..."
else
echo "❌ 发布失败,退出码: ${{ steps.release.outputs.exit-code }}"
echo "发送失败通知..."
# 这里可以添加通知逻辑
fi
# 只在成功时执行的部署步骤
- name: 部署到生产环境
if: steps.release.outputs.release-status == 'success'
run: |
echo "部署版本 ${{ steps.release.outputs.version }} 到生产环境"
kubectl set image deployment/app app=registry.com/app:${{ steps.release.outputs.version }}
# 失败时的回退操作
- name: 回退操作
if: steps.release.outputs.release-status == 'failure'
run: |
echo "执行回退操作..."
# 回退到上一个稳定版本的逻辑
```
### 5. 严格模式发布(默认行为)
适用于生产环境,发布失败时立即停止:
```yaml
steps:
- uses: actions/checkout@v4
- name: 发布项目
id: release
uses: actions/xgj/release-web@main
with:
fail-on-error: true # 默认值,发布失败时中断 workflow
env:
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
APP_ENV: "production"
# 这个步骤只有在发布成功时才会执行
- name: 部署到生产环境
run: |
echo "部署版本 ${{ steps.release.outputs.version }}"
kubectl apply -f k8s/
```
## 工作流程
1. **发布构建**: 执行指定的发布命令进行版本发布
- 捕获命令执行状态和退出码
- 设置 `release-status` 输出(`success`/`failure`
- 失败时记录 `exit-code` 输出
2. **智能版本获取**: 只在发布成功时执行,通过多种方法自动获取版本号
- 优先从版本文件读取(`/tmp/last-version` 或自定义路径)
- 回退到最新 git tag保持原始格式
- 回退到 `package.json` 中的版本
- 最后尝试从提交信息解析(支持 `v1.2.3``1.2.3` 格式)
- **所有方法都确保输出统一包含 `v` 前缀**
3. **发布总结**: 显示详细的发布状态信息
- 成功时:显示版本号和发布信息
- 失败时:显示错误状态和退出码
4. **状态检查**: 根据 `fail-on-error` 参数决定最终行为
- `true`(默认):发布失败时让 action 失败,中断 workflow
- `false`:发布失败时继续完成,允许后续步骤执行
## 依赖要求
### 项目要求
- 包含 `package.json` 文件(用于版本回退)
- 配置了发布工具(如 `release-it`
- 包含发布脚本(如 `npm run release`
- 推荐发布命令生成版本文件到 `/tmp/last-version`(或自定义路径)
### 环境依赖
- Node.js 环境
- npm/pnpm/yarn 包管理器
- 配置好的 Gitea 访问权限
## 配置示例
### release-it 配置
确保项目中有类似的 `.release-it.js` 配置:
```javascript
module.exports = {
hooks: {
"before:release": [
"echo 'v${version}' > /tmp/last-version",
"npm run build",
],
},
git: {
tagName: "v${version}",
commitMessage: "chore: released version v${version} [no ci]",
},
npm: {
publish: false,
},
};
```
### Docker 多阶段构建
推荐使用多阶段构建优化镜像大小:
```dockerfile
# 构建阶段
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
# 运行阶段
FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/node_modules ./node_modules
COPY dist ./dist
EXPOSE 3000
CMD ["npm", "start"]
```
## 错误处理
### 发布失败处理
Action 提供灵活的错误处理机制:
**严格模式** (`fail-on-error: true` - 默认)
- 发布命令失败时action 立即失败并中断 workflow
- 适用于生产环境,确保发布质量
**宽松模式** (`fail-on-error: false`)
- 发布命令失败时action 继续完成并返回状态信息
- 允许执行清理、通知等后续操作
- 可通过 `outputs.release-status` 检查发布结果
### 常见错误情况
Action 会在以下情况报错:
- 发布命令执行失败(返回非零退出码)
- 无法获取版本信息(所有版本获取方法都失败)
- 版本文件不存在且无其他版本源
## 安全注意事项
- 🔒 始终通过 `secrets` 传递敏感令牌
- 🔍 定期检查和轮换访问令牌
- 📋 限制 Docker 仓库访问权限
- 🚫 避免在日志中暴露敏感信息
## 故障排除
### 常见问题
### Q: 如何处理发布失败的情况?
A: Action 提供了多种方式处理发布失败:
1. **检查发布状态**
```yaml
- name: 发布项目
id: release
uses: actions/xgj/release-web@main
- name: 检查发布结果
run: |
if [[ "${{ steps.release.outputs.release-status }}" == "failure" ]]; then
echo "发布失败,退出码: ${{ steps.release.outputs.exit-code }}"
# 执行失败处理逻辑
fi
```
2. **宽松模式处理**
```yaml
- name: 发布项目
uses: actions/xgj/release-web@main
with:
fail-on-error: false # 失败时不中断
- name: 清理操作
if: always()
run: echo "总是执行清理"
```
### Q: 如何获取发布失败的详细信息?
A: 通过输出参数获取:
- `release-status`: `success` 或 `failure`
- `exit-code`: 失败时的命令退出码
- 检查 action 日志中的详细错误信息
### Q: 无法获取版本信息
```bash
❌ 错误: 无法获取版本信息
```
A: Action 会按优先级尝试多种方法获取版本:
1. **版本文件** (推荐):确保发布命令创建版本文件
```javascript
// .release-it.js
hooks: {
'before:release': ['echo \'v${version}\' > /tmp/last-version']
}
```
2. **Git Tags**:确保发布过程创建了 git tag
```bash
git tag v1.2.3
```
3. **package.json**:确保 package.json 包含有效的 version 字段
```json
{
"version": "1.2.3"
}
```
4. **提交信息**:在提交信息中包含版本号
```bash
git commit -m "release: v1.2.3"
# 或者
git commit -m "release: 1.2.3"
```
### Q: Gitea Token 权限不足
A: 确保 token 具有以下权限:
- Repository 写权限
- Releases 创建权限
### 调试模式
启用详细调试信息:
```yaml
- uses: actions/xgj/release-web@main
with:
node-debug: "true"
env:
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
```
## 更新日志
查看 [Releases](https://github.com/your-org/actions/releases) 获取详细的更新历史。
## 贡献
欢迎提交 Issue 和 Pull Request 来改进这个 Action
## 许可证
MIT License - 详见 [LICENSE](../LICENSE) 文件。