Files
xgj/release-web/README.md

14 KiB
Raw Blame History

Web 项目发布构建 Action

GitHub

自动化 Web 项目发布流程的 GitHub Action专注于版本管理和发布核心功能智能处理各种版本格式。

功能特性

  • 🚀 自动化发布: 支持任意发布命令进行版本管理和发布
  • 🌍 环境变量支持: 支持传递任意数量的环境变量给发布命令
  • 📦 智能版本处理: 自动获取版本号,确保输出格式一致(无 v 前缀)
  • 📊 状态监控: 实时监控发布状态,支持成功/失败状态输出和退出码
  • 🔧 简洁配置: 最小化配置,专注于发布核心功能
  • 灵活使用: 可配置发布命令,适应不同项目需求
  • 🛡️ 错误控制: 可配置发布失败时的行为(中断或继续)

快速开始

基础用法

- name: 发布Web项目
  uses: actions/xgj/release-web@main
  env:
    GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}

使用环境变量

- 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' }}
    # ... 更多任意环境变量

完整示例

- 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"

自定义版本文件路径

- name: 发布Web项目
  uses: actions/xgj/release-web@main
  with:
    version-file: "./dist/version.txt" # 自定义版本文件位置
  env:
    GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}

版本格式处理

Action 自动处理各种版本格式,确保输出一致:

# 输入可能的格式:
# - 版本文件: "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 或其他发布命令:

- 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 项目发布:

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 流程

包含完整的构建、测试、发布流程:

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. 多环境发布

支持不同环境的差异化配置:

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. 状态检查和错误处理

演示如何处理发布状态和错误:

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. 严格模式发布(默认行为)

适用于生产环境,发布失败时立即停止:

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.31.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 配置:

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 多阶段构建

推荐使用多阶段构建优化镜像大小:

# 构建阶段
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. 检查发布状态

    - 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. 宽松模式处理

    - name: 发布项目
      uses: actions/xgj/release-web@main
      with:
        fail-on-error: false # 失败时不中断
    
    - name: 清理操作
      if: always()
      run: echo "总是执行清理"
    

Q: 如何获取发布失败的详细信息?

A: 通过输出参数获取:

  • release-status: successfailure
  • exit-code: 失败时的命令退出码
  • 检查 action 日志中的详细错误信息

Q: 无法获取版本信息

❌ 错误: 无法获取版本信息

A: Action 会按优先级尝试多种方法获取版本:

  1. 版本文件 (推荐):确保发布命令创建版本文件

    // .release-it.js
    hooks: {
      'before:release': ['echo \'v${version}\' > /tmp/last-version']
    }
    
  2. Git Tags:确保发布过程创建了 git tag

    git tag v1.2.3
    
  3. package.json:确保 package.json 包含有效的 version 字段

    {
      "version": "1.2.3"
    }
    
  4. 提交信息:在提交信息中包含版本号

    git commit -m "release: v1.2.3"
    # 或者
    git commit -m "release: 1.2.3"
    

Q: Gitea Token 权限不足

A: 确保 token 具有以下权限:

  • Repository 写权限
  • Releases 创建权限

调试模式

启用详细调试信息:

- uses: actions/xgj/release-web@main
  with:
    node-debug: "true"
  env:
    GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}

更新日志

查看 Releases 获取详细的更新历史。

贡献

欢迎提交 Issue 和 Pull Request 来改进这个 Action

许可证

MIT License - 详见 LICENSE 文件。