目录

tech-leads-club-release-bot:Tech Leads Club 的自动化发布机器人深度解读

tech-leads-club-release-bot:Tech Leads Club 的自动化发布机器人深度解读

项目概览

tech-leads-club-release-botgithub.com/apps/tech-leads-club-release-bot)是 Tech Leads Club 社区开发者 Felipe Rodrigues 开发的 GitHub App,核心职责是为 agent-skills 仓库自动化处理版本号管理、Tag 创建和 Changelog 更新,深度集成 Nx Release 与 semantic-release 生态。

维度数据
GitHub App slugtech-leads-club-release-bot
开发者Felipe Rodrigues(felipfr,巴西)
关联仓库tech-leads-club/agent-skills
主要语言TypeScript
目标生态Nx Monorepo, npm (@tech-leads-club), GitHub Pages
许可证MIT

它解决了什么问题

agent-skills 是一个面向专业 AI 编程 Agent(Claude Code、Cursor、Copilot、Windsurf 等)的安全技能库,采用 Nx Monorepo 架构,包含 CLI、skills-catalog 和 MCP Server 三个发布单元。

这类多包项目的发布痛点在于:

  • 多包联动发布:CLI、skills-catalog、MCP Server 三个包版本必须同步关联
  • 安全扫描前置:每次发布前必须通过 Snyk 安全扫描,阻断有漏洞的版本
  • 快照发布需求:PR 场景下需要发布 snapshot 版本供测试
  • 防自触发死循环:bot 自己 push 的 release commit 不应再次触发发布

tech-leads-club-release-bot 的设计目标正是解决这一整套发布流程的自动化。


核心架构

作为 GitHub App 的角色

该 Bot 以 GitHub App 身份运行,相比 Personal Access Token 具有以下优势:

Bot 身份优势:
├── 基于 GitHub App JWT 认证,权限精控
├── 操作记录归属清晰(app[bot] 而非个人账号)
├── 可安装到指定仓库,权限边界明确
└── 不受个人 Token 过期影响

Bot 在 workflow 中的典型使用模式:

- name: Generate App Token
  uses: actions/create-github-app-token@v1
  id: app-token
  with:
    app-id: ${{ secrets.RELEASE_APP_ID }}
    private-key: ${{ secrets.RELEASE_APP_PRIVATE_KEY }}

- name: Checkout Code
  uses: actions/checkout@v4
  with:
    token: ${{ steps.app-token.outputs.token }}
    fetch-depth: 0
    filter: tree:0

发布工作流设计

Bot 驱动的发布体系包含四个核心 Job:

┌─────────────────────────────────────────────────────────────┐
│                    Push to main                             │
└──────────┬──────────────────┬──────────────────┬────────────┘
           ▼                  ▼                  ▼
   ┌───────────────┐  ┌───────────────┐  ┌───────────────────┐
   │ approve-release│  │ security-scan  │  │  (other jobs...)  │
   │ (Environment)   │  │  (Snyk scan)   │  └───────────────────┘
   └───────┬───────┘  └───────┬───────┘
           │                  │
           └──────────┬───────┘
                      ▼
              ┌───────────────┐
              │    release    │
              │ (needs both)  │
              └───────┬───────┘
                      │
        ┌─────────────┼─────────────┐
        ▼             ▼             ▼
   ┌──────────┐ ┌──────────┐ ┌──────────┐
   │ Release  │ │ Release  │ │ Release  │
   │   CLI    │ │  Catalog │ │   MCP    │
   └──────────┘ └──────────┘ └──────────┘

多包分组发布机制

Nx Release 支持 --groups 参数,Bot 所触发的发布流程通过检测变更自动判断需要发布的包组:

# 检查各包组的变更情况
GROUPS_TO_RELEASE=""

# 检查 CLI 包组(packages/cli/ + libs/core/)
CLI_CHANGES=$(git diff --name-only "$CLI_TAG"..HEAD -- packages/cli/ libs/core/)
if [ -n "$CLI_CHANGES" ]; then
  GROUPS_TO_RELEASE="${GROUPS_TO_RELEASE:+$GROUPS_TO_RELEASE,}cli"
fi

# 检查 skills-catalog 包组
CATALOG_CHANGES=$(git diff --name-only "$CATALOG_TAG"..HEAD -- packages/skills-catalog/)
if [ -n "$CATALOG_CHANGES" ]; then
  GROUPS_TO_RELEASE="${GROUPS_TO_RELEASE:+$GROUPS_TO_RELEASE,}skills-catalog"
fi

# 检查 MCP 包组
MCP_CHANGES=$(git diff --name-only "$MCP_TAG"..HEAD -- packages/mcp/ libs/core/)
if [ -n "$MCP_CHANGES" ]; then
  GROUPS_TO_RELEASE="${GROUPS_TO_RELEASE:+$GROUPS_TO_RELEASE,}mcp"
fi

# 执行分组发布
npx nx release --yes --groups=$GROUPS_TO_RELEASE

快照发布(Snapshot Release)

当 PR 被标记 action: snapshot 时,Bot 触发独立的 snapshot 发布流程:

snapshot:
  name: Snapshot Release
  if: |
    github.event_name == 'pull_request' &&
    github.event.action == 'labeled' &&
    github.event.label.name == 'action: snapshot'
  steps:
    - name: Publish Snapshot
      run: |
        SHORT_SHA=$(git rev-parse --short HEAD)
        npx nx release version 0.0.0-pr${{ github.event.number }}.${SHORT_SHA} \
          --git-tag=false --git-commit=false --stage-changes=false && \
        npx nx release publish --tag snapshot --provenance

版本号格式:0.0.0-pr123.abc1234(PR 编号 + 短 SHA),发布到 npm 的 snapshot tag。


防自触发机制:关键设计

Bot 面临的核心问题是:Bot 自己 push 的 release commit(包含 chore(release): 消息)不应再次触发发布

解决方案通过两个 filter 组合实现:

# approve-release 和 security-scan 的触发条件
if: |
  github.event_name == 'push' &&
  github.ref == 'refs/heads/main' &&
  github.actor != 'tech-leads-club-release-bot[bot]' &&   # ← Bot 不是触发者
  !startsWith(github.event.head_commit.message, 'chore(release):')  # ← 非 release commit

具体效果:

  • 人工 push 到 main → 触发 approve-release + security-scan
  • Bot push release commit → 两个 job 都不触发,release job 的 needs 得不到满足,自然不会发布
  • PR labeled with action: snapshot → 走独立的 snapshot job,不走 main 分支流程

安装与配置

前提条件

  1. 拥有 GitHub App:在 GitHub Settings → Developer settings → GitHub Apps 创建新 App
  2. 仓库权限:App 需要对目标仓库具有 contents: write(写 tag 和 commit)、pull-requests: write(写 PR comment)
  3. Secrets 配置
# GitHub Actions Secrets
RELEASE_APP_ID          # GitHub App 的 APP ID
RELEASE_APP_PRIVATE_KEY # App 的私钥(.pem 文件内容)
SNYK_TOKEN              # Snyk 账户 token(用于安全扫描)
NX_CLOUD_ACCESS_TOKEN   # Nx Cloud token(可选,本地模式可绕过)

私钥生成与注册

# 1. 生成私钥(在 GitHub App 页面下载)
# 2. 本地读取并处理(注意换行符)
cat app-private-key.pem | pbcrypt  # macOS
# 3. 将输出结果存入 Actions Secret: RELEASE_APP_PRIVATE_KEY

App 权限配置(最低要求)

PermissionAccess
ContentsRead and write
Pull requestsRead and write
ActionsRead
EnvironmentsRead(若使用 environment gate)

Webhook 配置

Bot 订阅以下事件:

  • push(检测 main 分支推送)
  • pull_request(检测 label 和 PR 同步)
  • merge_group(Merge Queue 场景)

与同级工具的差异化定位

特性tech-leads-club-release-botautofix.cirelease-pleasesemantic-release
核心定位Nx Monorepo 多包联动发布 + 安全扫描前置PR 格式自动修复单一仓库 changelog 驱动发布通用 semantic versioning
触发方式GitHub App + Actions hybridGitHub ActionGitHub Action / AppGitHub Action / CLI
多包分组✅ Nx groups 原生支持⚠️ 需要手动配置
安全扫描前置✅ Snyk scan in CI⚠️ 需自行集成
Snapshot 发布✅ PR label 触发✅ (通过 config)
防自触发✅ explicit actor checkN/A
适用场景Nx Monorepo,@tech-leads-club 体系格式化修复开源库 changelog 管理通用单/多包项目

agent-skills 实战参考

agent-skills 是 Bot 所服务的目标仓库,其 workflow 完整展示了 Bot 的集成方式:

完整 release.yml 关键片段

# 生成 App Token(供 Git 操作使用)
- name: Generate App Token
  uses: actions/create-github-app-token@v1
  id: app-token
  with:
    app-id: ${{ secrets.RELEASE_APP_ID }}
    private-key: ${{ secrets.RELEASE_APP_PRIVATE_KEY }}

# 使用 Bot Token 检出代码(filter: tree:0 跳过未追踪文件)
- name: Checkout Code
  uses: actions/checkout@v4
  with:
    fetch-depth: 0
    filter: tree:0
    token: ${{ steps.app-token.outputs.token }}

# Git 配置 Bot 用户信息
- name: Git Config
  run: |
    git config user.name "tech-leads-club-release-bot[bot]"
    git config user.email "tech-leads-club-release-bot[bot]@users.noreply.github.com"
    git remote set-url origin "https://x-access-token:${{ steps.app-token.outputs.token }}@github.com/${{ github.repository }}.git"

# 生成 skills 数据文件(skills-registry.json, skills.json)
- name: Generate Skills Data
  run: npm run generate:data || NX_NO_CLOUD=true npm run generate:data

# 有变更则提交(Bot 身份的自动化数据更新)
- name: Commit Data if Changed
  run: |
    git add packages/skills-catalog/skills-registry.json \
          packages/marketplace/src/data/skills.json \
          packages/skills-catalog/skills
    if ! git diff --cached --quiet; then
      git commit -m "chore(release): update generated skills data"
    fi

# 检查并发布
- name: Release Version and Publish
  run: |
    npx nx release --yes --groups=$GROUPS_TO_RELEASE || \
    NX_NO_CLOUD=true npx nx release --yes --groups=$GROUPS_TO_RELEASE
  env:
    GITHUB_TOKEN: ${{ steps.app-token.outputs.token }}
    NODE_AUTH_TOKEN: ''
    NPM_CONFIG_PROVENANCE: true
    NX_NO_CLOUD: true

环境 Gate

approve-release job 使用 environment: publish 配置,需要在 GitHub Repository Settings 中创建 publish 环境并指定所需的审批人员:

approve-release:
  name: Approve Release
  runs-on: ubuntu-latest
  environment: publish  # ← 需要环境审批
  timeout-minutes: 60
  if: |
    github.event_name == 'push' &&
    github.ref == 'refs/heads/main' &&
    github.actor != 'tech-leads-club-release-bot[bot]' &&
    !startsWith(github.event.head_commit.message, 'chore(release):')
  steps:
    - name: Approval Gate
      run: echo "✅ Release approved for publish"

安全扫描集成

Bot 驱动的 workflow 将 Snyk 安全扫描作为强制门禁:

security-scan:
  name: Security Scan
  if: |
    github.event_name == 'push' &&
    github.ref == 'refs/heads/main' &&
    github.actor != 'tech-leads-club-release-bot[bot]'
  steps:
    - name: Security Scan
      id: security-scan
      uses: ./.github/actions/security-scan
      with:
        snyk_token: ${{ secrets.SNYK_TOKEN }}
        artifact-name: security-scan-results

    - name: Notify on failure
      if: steps.security-scan.outputs.scan-outcome == 'failure'
      uses: ./.github/actions/security-scan-notify

    - name: Fail job if scan failed
      if: steps.security-scan.outputs.scan-outcome == 'failure'
      run: exit 1

扫描结果汇总输出:

Critical: 0 | High: 2 | Medium: 3
- playwright-skill: prototype-pollution (high) - user-controlled items in for-in loop
- figma: code-injection (high) - unsafe eval usage

总结

tech-leads-club-release-bot 是一个高度定位于 Nx Monorepo 生态的发布自动化解决方案,它通过 GitHub App 身份精控权限、Nx Release 分组发布、Snyk 安全扫描前置和环境审批 Gate,构建了一套适合多包 AI 工具库(CLI + Skills Catalog + MCP Server)的安全发布流水线。

其中最值得留意的设计细节是防自触发机制——通过 github.actor 和 commit message 双重检查,确保 Bot push 的 release commit 不会触发二次发布,形成了一个可靠的死循环防护。这对于任何以 bot 身份操作 git 的自动化系统都有借鉴意义。

如果你的项目使用 Nx 管理多包发布、对安全性有高要求、且需要在发布前强制通过安全扫描,可以参考这套架构。