GitHub工作流自动化Skill github-workflow-automation

该技能用于自动化GitHub工作流程,包括AI辅助的PR代码审查、问题自动分类、CI/CD管道集成和Git操作自动化。关键词:GitHub自动化、AI代码审查、DevOps、Git操作、工作流优化。

DevOps 0 次安装 0 次浏览 更新于 3/21/2026

name: github-workflow-automation description: “使用AI辅助自动化GitHub工作流。包括PR代码审查、问题分类、CI/CD集成和Git操作。适用于自动化GitHub工作流、设置PR审查自动化、创建GitHub Actions或问题分类。”

🔧 GitHub工作流自动化

使用AI辅助自动化GitHub工作流的模式,灵感来自Gemini CLI和现代DevOps实践。

何时使用此技能

在以下情况下使用此技能:

  • 使用AI自动化PR审查
  • 设置问题分类自动化
  • 创建GitHub Actions工作流
  • 将AI集成到CI/CD管道中
  • 自动化Git操作(如变基、挑选提交)

1. 自动化PR审查

1.1 PR审查操作

# .github/workflows/ai-review.yml
name: AI代码审查

on:
  pull_request:
    types: [opened, synchronize]

jobs:
  review:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      pull-requests: write

    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: 获取更改的文件
        id: changed
        run: |
          files=$(git diff --name-only origin/${{ github.base_ref }}...HEAD)
          echo "files<<EOF" >> $GITHUB_OUTPUT
          echo "$files" >> $GITHUB_OUTPUT
          echo "EOF" >> $GITHUB_OUTPUT

      - name: 获取差异
        id: diff
        run: |
          diff=$(git diff origin/${{ github.base_ref }}...HEAD)
          echo "diff<<EOF" >> $GITHUB_OUTPUT
          echo "$diff" >> $GITHUB_OUTPUT
          echo "EOF" >> $GITHUB_OUTPUT

      - name: AI审查
        uses: actions/github-script@v7
        with:
          script: |
            const { Anthropic } = require('@anthropic-ai/sdk');
            const client = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY });

            const response = await client.messages.create({
              model: "claude-3-sonnet-20240229",
              max_tokens: 4096,
              messages: [{
                role: "user",
                content: `审查此PR差异并提供反馈:
                
                更改的文件: ${{ steps.changed.outputs.files }}
                
                差异:
                ${{ steps.diff.outputs.diff }}
                
                提供:
                1. 更改摘要
                2. 潜在问题或错误
                3. 改进建议
                4. 安全关注点(如有)
                
                格式化为GitHub markdown。`
              }]
            });

            await github.rest.pulls.createReview({
              owner: context.repo.owner,
              repo: context.repo.repo,
              pull_number: context.issue.number,
              body: response.content[0].text,
              event: 'COMMENT'
            });
        env:
          ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}

1.2 审查评论模式

# AI审查结构

## 📋 摘要

此PR内容的简要描述。

## ✅ 看起来不错的地方

- 结构良好的代码
- 良好的测试覆盖率
- 清晰的命名约定

## ⚠️ 潜在问题

1. **第42行**:可能的空指针异常
   ```javascript
   // 当前
   user.profile.name;
   // 建议
   user?.profile?.name ?? "Unknown";
   ```
  1. 第78行:考虑错误处理
    // 添加 try-catch 或 .catch()
    

💡 建议

  • 考虑将验证逻辑提取到单独的函数中
  • 为公共方法添加JSDoc注释

🔒 安全注意事项

  • 未检测到敏感数据暴露
  • API密钥处理看起来正确

### 1.3 聚焦审查

```yaml
# 仅审查特定文件类型
- name: 过滤代码文件
  run: |
    files=$(git diff --name-only origin/${{ github.base_ref }}...HEAD | \
            grep -E '\.(ts|tsx|js|jsx|py|go)$' || true)
    echo "code_files=$files" >> $GITHUB_OUTPUT

# 带上下文的审查
- name: 带上下文的AI审查
  run: |
    # 包含相关上下文文件
    context=""
    for file in ${{ steps.changed.outputs.files }}; do
      if [[ -f "$file" ]]; then
        context+="=== $file ===
$(cat $file)

"
      fi
    done

    # 发送给AI并附上完整的文件上下文

2. 问题分类自动化

2.1 自动标记问题

# .github/workflows/issue-triage.yml
name: 问题分类

on:
  issues:
    types: [opened]

jobs:
  triage:
    runs-on: ubuntu-latest
    permissions:
      issues: write

    steps:
      - name: 分析问题
        uses: actions/github-script@v7
        with:
          script: |
            const issue = context.payload.issue;

            // 调用AI进行分析
            const analysis = await analyzeIssue(issue.title, issue.body);

            // 应用标签
            const labels = [];

            if (analysis.type === 'bug') {
              labels.push('bug');
              if (analysis.severity === 'high') labels.push('priority: high');
            } else if (analysis.type === 'feature') {
              labels.push('enhancement');
            } else if (analysis.type === 'question') {
              labels.push('question');
            }

            if (analysis.area) {
              labels.push(`area: ${analysis.area}`);
            }

            await github.rest.issues.addLabels({
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: issue.number,
              labels: labels
            });

            // 添加初始响应
            if (analysis.type === 'bug' && !analysis.hasReproSteps) {
              await github.rest.issues.createComment({
                owner: context.repo.owner,
                repo: context.repo.repo,
                issue_number: issue.number,
                body: `感谢报告此问题!

为了帮助我们调查,请提供:
- 重现问题的步骤
- 预期行为
- 实际行为
- 环境(操作系统、版本等)

这将帮助我们更快地解决您的问题。 🙏`
              });
            }

2.2 问题分析提示

const TRIAGE_PROMPT = `
分析此GitHub问题并分类:

标题:{title}
正文:{body}

返回JSON:
{
  "type": "bug" | "feature" | "question" | "docs" | "other",
  "severity": "low" | "medium" | "high" | "critical",
  "area": "frontend" | "backend" | "api" | "docs" | "ci" | "other",
  "summary": "一行摘要",
  "hasReproSteps": boolean,
  "isFirstContribution": boolean,
  "suggestedLabels": ["label1", "label2"],
  "suggestedAssignees": ["username"] // 基于领域专业知识
}
`;

2.3 陈旧问题管理

# .github/workflows/stale.yml
name: 管理陈旧问题

on:
  schedule:
    - cron: "0 0 * * *" # 每天

jobs:
  stale:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/stale@v9
        with:
          stale-issue-message: |
            此问题已自动标记为陈旧,因为最近没有活动。如果14天内没有进一步活动,将关闭它。

            如果此问题仍然相关:
            - 添加带有更新的评论
            - 移除 `stale` 标签

            感谢您的贡献! 🙏

          stale-pr-message: |
            此PR已自动标记为陈旧。请更新它,否则将在14天内关闭。

          days-before-stale: 60
          days-before-close: 14
          stale-issue-label: "stale"
          stale-pr-label: "stale"
          exempt-issue-labels: "pinned,security,in-progress"
          exempt-pr-labels: "pinned,security"

3. CI/CD集成

3.1 智能测试选择

# .github/workflows/smart-tests.yml
name: 智能测试选择

on:
  pull_request:

jobs:
  analyze:
    runs-on: ubuntu-latest
    outputs:
      test_suites: ${{ steps.analyze.outputs.suites }}

    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: 分析更改
        id: analyze
        run: |
          # 获取更改的文件
          changed=$(git diff --name-only origin/${{ github.base_ref }}...HEAD)

          # 确定要运行的测试套件
          suites="[]"

          if echo "$changed" | grep -q "^src/api/"; then
            suites=$(echo $suites | jq '. + ["api"]')
          fi

          if echo "$changed" | grep -q "^src/frontend/"; then
            suites=$(echo $suites | jq '. + ["frontend"]')
          fi

          if echo "$changed" | grep -q "^src/database/"; then
            suites=$(echo $suites | jq '. + ["database", "api"]')
          fi

          # 如果没有特定更改,运行所有测试
          if [ "$suites" = "[]" ]; then
            suites='["all"]'
          fi

          echo "suites=$suites" >> $GITHUB_OUTPUT

  test:
    needs: analyze
    runs-on: ubuntu-latest
    strategy:
      matrix:
        suite: ${{ fromJson(needs.analyze.outputs.test_suites) }}

    steps:
      - uses: actions/checkout@v4

      - name: 运行测试
        run: |
          if [ "${{ matrix.suite }}" = "all" ]; then
            npm test
          else
            npm test -- --suite ${{ matrix.suite }}
          fi

3.2 使用AI验证的部署

# .github/workflows/deploy.yml
name: 使用AI验证的部署

on:
  push:
    branches: [main]

jobs:
  validate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: 获取部署更改
        id: changes
        run: |
          # 获取自上次部署以来的提交
          last_deploy=$(git describe --tags --abbrev=0 2>/dev/null || echo "")
          if [ -n "$last_deploy" ]; then
            changes=$(git log --oneline $last_deploy..HEAD)
          else
            changes=$(git log --oneline -10)
          fi
          echo "changes<<EOF" >> $GITHUB_OUTPUT
          echo "$changes" >> $GITHUB_OUTPUT
          echo "EOF" >> $GITHUB_OUTPUT

      - name: AI风险评估
        id: assess
        uses: actions/github-script@v7
        with:
          script: |
            // 分析更改以评估部署风险
            const prompt = `
            分析这些更改以评估部署风险:

            ${process.env.CHANGES}

            返回JSON:
            {
              "riskLevel": "low" | "medium" | "high",
              "concerns": ["concern1", "concern2"],
              "recommendations": ["rec1", "rec2"],
              "requiresManualApproval": boolean
            }
            `;

            // 调用AI并解析响应
            const analysis = await callAI(prompt);

            if (analysis.riskLevel === 'high') {
              core.setFailed('检测到高风险部署。需要手动审核。');
            }

            return analysis;
        env:
          CHANGES: ${{ steps.changes.outputs.changes }}

  deploy:
    needs: validate
    runs-on: ubuntu-latest
    environment: production
    steps:
      - name: 部署
        run: |
          echo "正在部署到生产环境..."
          # 部署命令放在这里

3.3 回滚自动化

# .github/workflows/rollback.yml
name: 自动回滚

on:
  workflow_dispatch:
    inputs:
      reason:
        description: "回滚原因"
        required: true

jobs:
  rollback:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: 查找最后一个稳定版本
        id: stable
        run: |
          # 查找最后一个成功部署
          stable=$(git tag -l 'v*' --sort=-version:refname | head -1)
          echo "version=$stable" >> $GITHUB_OUTPUT

      - name: 回滚
        run: |
          git checkout ${{ steps.stable.outputs.version }}
          # 部署稳定版本
          npm run deploy

      - name: 通知团队
        uses: slackapi/slack-github-action@v1
        with:
          payload: |
            {
              "text": "🔄 生产已回滚到 ${{ steps.stable.outputs.version }}",
              "blocks": [
                {
                  "type": "section",
                  "text": {
                    "type": "mrkdwn",
                    "text": "*已执行回滚*
• 版本:`${{ steps.stable.outputs.version }}`
• 原因:${{ inputs.reason }}
• 触发者:${{ github.actor }}"
                  }
                }
              ]
            }

4. Git操作

4.1 自动化变基

# .github/workflows/auto-rebase.yml
name: 自动变基

on:
  issue_comment:
    types: [created]

jobs:
  rebase:
    if: github.event.issue.pull_request && contains(github.event.comment.body, '/rebase')
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
          token: ${{ secrets.GITHUB_TOKEN }}

      - name: 设置Git
        run: |
          git config user.name "github-actions[bot]"
          git config user.email "github-actions[bot]@users.noreply.github.com"

      - name: 变基PR
        run: |
          # 获取PR分支
          gh pr checkout ${{ github.event.issue.number }}

          # 变基到main分支
          git fetch origin main
          git rebase origin/main

          # 强制推送
          git push --force-with-lease
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: 评论结果
        uses: actions/github-script@v7
        with:
          script: |
            github.rest.issues.createComment({
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: context.issue.number,
              body: '✅ 成功变基到main!'
            })

4.2 智能挑选提交

// 处理冲突的AI辅助挑选提交
async function smartCherryPick(commitHash: string, targetBranch: string) {
  // 获取提交信息
  const commitInfo = await exec(`git show ${commitHash} --stat`);

  // 检查潜在冲突
  const targetDiff = await exec(
    `git diff ${targetBranch}...HEAD -- ${affectedFiles}`
  );

  // AI分析
  const analysis = await ai.analyze(`
    我需要将此次提交挑选到 ${targetBranch}:
    
    ${commitInfo}
    
    受影响的文件在 ${targetBranch} 上的当前状态:
    ${targetDiff}
    
    会有冲突吗?如果有,建议解决策略。
  `);

  if (analysis.willConflict) {
    // 创建用于手动解决冲突的分支
    await exec(
      `git checkout -b cherry-pick-${commitHash.slice(0, 7)} ${targetBranch}`
    );
    const result = await exec(`git cherry-pick ${commitHash}`, {
      allowFail: true,
    });

    if (result.failed) {
      // AI辅助冲突解决
      const conflicts = await getConflicts();
      for (const conflict of conflicts) {
        const resolution = await ai.resolveConflict(conflict);
        await applyResolution(conflict.file, resolution);
      }
    }
  } else {
    await exec(`git checkout ${targetBranch}`);
    await exec(`git cherry-pick ${commitHash}`);
  }
}

4.3 分支清理

# .github/workflows/branch-cleanup.yml
name: 分支清理

on:
  schedule:
    - cron: '0 0 * * 0'  # 每周
  workflow_dispatch:

jobs:
  cleanup:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: 查找陈旧分支
        id: stale
        run: |
          # 超过30天未更新的分支
          stale=$(git for-each-ref --sort=-committerdate refs/remotes/origin \
            --format='%(refname:short) %(committerdate:relative)' | \
            grep -E '[3-9][0-9]+ days|[0-9]+ months|[0-9]+ years' | \
            grep -v 'origin/main\|origin/develop' | \
            cut -d' ' -f1 | sed 's|origin/||')

          echo "branches<<EOF" >> $GITHUB_OUTPUT
          echo "$stale" >> $GITHUB_OUTPUT
          echo "EOF" >> $GITHUB_OUTPUT

      - name: 创建清理PR
        if: steps.stale.outputs.branches != ''
        uses: actions/github-script@v7
        with:
          script: |
            const branches = `${{ steps.stale.outputs.branches }}`.split('
').filter(Boolean);

            const body = `## 🧹 陈旧分支清理

以下分支超过30天未更新:

${branches.map(b => `- \`${b}\``).join('
')}

### 操作:
- [ ] 审核每个分支
- [ ] 删除不再需要的分支
- 评论 \`/keep branch-name\` 以保留特定分支
`;

            await github.rest.issues.create({
              owner: context.repo.owner,
              repo: context.repo.repo,
              title: '陈旧分支清理',
              body: body,
              labels: ['housekeeping']
            });

5. 按需辅助

5.1 @提及机器人

# .github/workflows/mention-bot.yml
name: AI提及机器人

on:
  issue_comment:
    types: [created]
  pull_request_review_comment:
    types: [created]

jobs:
  respond:
    if: contains(github.event.comment.body, '@ai-helper')
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - name: 提取问题
        id: question
        run: |
          # 提取@ai-helper后的文本
          question=$(echo "${{ github.event.comment.body }}" | sed 's/.*@ai-helper//')
          echo "question=$question" >> $GITHUB_OUTPUT

      - name: 获取上下文
        id: context
        run: |
          if [ "${{ github.event.issue.pull_request }}" != "" ]; then
            # 是PR - 获取差异
            gh pr diff ${{ github.event.issue.number }} > context.txt
          else
            # 是问题 - 获取描述
            gh issue view ${{ github.event.issue.number }} --json body -q .body > context.txt
          fi
          echo "context=$(cat context.txt)" >> $GITHUB_OUTPUT
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: AI响应
        uses: actions/github-script@v7
        with:
          script: |
            const response = await ai.chat(`
              上下文: ${process.env.CONTEXT}
              
              问题: ${process.env.QUESTION}
              
              提供有帮助、具体的回答。如果相关,包括代码示例。
            `);

            await github.rest.issues.createComment({
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: context.issue.number,
              body: response
            });
        env:
          CONTEXT: ${{ steps.context.outputs.context }}
          QUESTION: ${{ steps.question.outputs.question }}

5.2 命令模式

## 可用命令

| 命令              | 描述                 |
| :------------------- | :-------------------------- |
| `@ai-helper explain` | 解释此PR中的代码 |
| `@ai-helper review`  | 请求AI代码审查      |
| `@ai-helper fix`     | 建议问题的修复方法    |
| `@ai-helper test`    | 生成测试用例         |
| `@ai-helper docs`    | 生成文档      |
| `/rebase`            | 将PR变基到main分支         |
| `/update`            | 从main分支更新PR分支  |
| `/approve`           | 标记为机器人批准     |
| `/label bug`         | 添加'bug'标签             |
| `/assign @user`      | 分配给用户              |

6. 仓库配置

6.1 CODEOWNERS

# .github/CODEOWNERS

# 全局所有者
* @org/core-team

# 前端
/src/frontend/ @org/frontend-team
*.tsx @org/frontend-team
*.css @org/frontend-team

# 后端
/src/api/ @org/backend-team
/src/database/ @org/backend-team

# 基础设施
/.github/ @org/devops-team
/terraform/ @org/devops-team
Dockerfile @org/devops-team

# 文档
/docs/ @org/docs-team
*.md @org/docs-team

# 安全敏感
/src/auth/ @org/security-team
/src/crypto/ @org/security-team

6.2 分支保护

# 通过GitHub API设置
- name: 配置分支保护
  uses: actions/github-script@v7
  with:
    script: |
      await github.rest.repos.updateBranchProtection({
        owner: context.repo.owner,
        repo: context.repo.repo,
        branch: 'main',
        required_status_checks: {
          strict: true,
          contexts: ['test', 'lint', 'ai-review']
        },
        enforce_admins: true,
        required_pull_request_reviews: {
          required_approving_review_count: 1,
          require_code_owner_reviews: true,
          dismiss_stale_reviews: true
        },
        restrictions: null,
        required_linear_history: true,
        allow_force_pushes: false,
        allow_deletions: false
      });

最佳实践

安全

  • [ ] 将API密钥存储在GitHub Secrets中
  • [ ] 在工作流中使用最小权限
  • [ ] 验证所有输入
  • [ ] 不在日志中暴露敏感数据

性能

  • [ ] 缓存依赖项
  • [ ] 使用矩阵构建进行并行测试
  • [ ] 使用路径过滤器跳过不必要的工作
  • [ ] 使用自托管运行器处理繁重工作负载

可靠性

  • [ ] 为作业添加超时
  • [ ] 优雅处理速率限制
  • [ ] 实现重试逻辑
  • [ ] 有回滚程序

资源