如何在GitHub Actions工作流中获取main分支最后合并的PR?
在GitHub Actions中获取main分支最后合并PR的覆盖率数据并拦截不合格PR
完全可以实现这个需求,下面是具体的步骤和实现思路:
1. 获取main分支最后合并的PR信息
你可以用GitHub CLI(gh)快速筛选出最近合并到main的PR,在Actions工作流中配置好权限后就能直接调用:
- 首先在工作流中添加权限配置:
permissions: contents: read, pull-requests: read, actions: read,确保能读取PR和工作流运行信息。 - 执行命令获取最新合并PR的编号:
gh pr list --state merged --base main --sort merged-at --limit 1 --json number | jq -r '.[0].number'
如果没有jq,也可以用awk或其他工具解析JSON,或者直接调用GitHub API的GET /repos/{owner}/{repo}/pulls接口筛选。
2. 获取该PR的覆盖率基准数据
有两种常用方式存储和获取基准覆盖率:
方式一:通过GitHub Artifacts读取
如果之前的PR在合并时,工作流会生成覆盖率报告并上传为Artifact,你可以通过该PR对应的工作流运行ID下载这个Artifact:
# 获取最新合并PR对应的工作流运行ID RUN_ID=$(gh run list --branch main --event pull_request --limit 1 --json id | jq -r '.[0].id') # 下载名为coverage-report的Artifact gh run download $RUN_ID --name coverage-report
方式二:直接读取main分支的覆盖率文件
如果每次PR合并后,工作流会自动将覆盖率数据(比如coverage-summary.json)提交到main分支,那直接checkout main分支读取该文件即可:
- name: Checkout main branch uses: actions/checkout@v4 with: ref: main path: main-branch - name: Copy baseline coverage run: cp main-branch/coverage-summary.json ./baseline-coverage.json
3. 对比覆盖率并设置检查结果
- 生成当前PR的覆盖率报告:用你项目的测试工具(比如jest、pytest)生成覆盖率文件,比如
npm test -- --coverage。 - 编写对比脚本:用Node.js、Python等写一个脚本,读取基准覆盖率和当前覆盖率,对比总体覆盖率或关键模块的覆盖率。如果当前覆盖率低于基准(可设置允许微小波动的阈值),就让脚本以非0状态退出(比如
exit 1)。 - 工作流会因为脚本失败而标记为不通过,从而拦截PR合并。
示例工作流片段
name: Coverage Guard on: [pull_request] permissions: contents: read pull-requests: read actions: read jobs: validate-coverage: runs-on: ubuntu-latest steps: - name: Checkout current PR code uses: actions/checkout@v4 with: fetch-depth: 0 - name: Set up Node.js uses: actions/setup-node@v4 with: node-version: 20 - name: Install dependencies run: npm ci - name: Install GitHub CLI run: npm install -g gh - name: Authenticate GH CLI run: echo "${{ secrets.GITHUB_TOKEN }}" | gh auth login --with-token - name: Get latest merged PR to main id: latest-pr run: | PR_NUM=$(gh pr list --state merged --base main --sort merged-at --limit 1 --json number | jq -r '.[0].number') echo "pr_number=$PR_NUM" >> $GITHUB_OUTPUT - name: Download baseline coverage artifact run: | RUN_ID=$(gh run list --pr ${{ steps.latest-pr.outputs.pr_number }} --json id | jq -r '.[0].id') gh run download $RUN_ID --name coverage-report - name: Generate current coverage run: npm test -- --coverage --coverageReporters json-summary - name: Compare coverage run: node scripts/compare-coverage.js # 脚本逻辑:读取coverage-summary.json和baseline/coverage-summary.json,对比后决定是否exit 1
注意事项
- 确保所有涉及的工作流步骤都有足够权限,比如上传Artifact的工作流需要
actions: write权限。 - 可以给对比脚本设置合理的阈值,比如允许覆盖率下降0.5%以内,避免因测试的微小波动导致误拦截。
- 如果用GitHub API而不是gh CLI,要注意请求频率,Actions中用
${{ secrets.GITHUB_TOKEN }}做认证即可。
内容的提问来源于stack exchange,提问作者Oana Marina
相关产品推荐
相关产品推荐

