You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GitHub Pull Request构建失败时新增可点击按钮实现咨询

实现方案

不用第三方插件、不用注入前端脚本,全靠GitHub原生Checks API就能实现,稳定性有保障,整体链路是:

  • 你现有PR触发Jenkins构建的逻辑保持不变
  • Jenkins构建失败时,调用GitHub接口在对应PR上创建一个带自定义操作按钮的Check Run
  • 提前配置好GitHub webhook,监听按钮点击事件,收到事件后触发你预设的自定义逻辑
前置配置
  1. 打开目标仓库的Settings页面,找到Personal access tokens生成入口,创建一个勾选repo、checks:write权限的访问令牌,后续调用GitHub接口会用到
  2. 在仓库Webhooks配置页新增两个webhook:
    • 你已经配置过的PR事件触发Jenkins的webhook,保持不变
    • 新增一个监听check_run事件的webhook,请求地址填你用来处理按钮点击逻辑的服务公网地址,记得设置webhook密钥用来校验请求来源合法性
步骤1:Jenkins构建失败时自动给PR添加按钮

按钮是Check Run的原生组件,会直接展示在PR的检查项区域,不需要额外注入前端代码。你只需要在Jenkins构建失败的回调节点加一段调用GitHub接口的逻辑即可。
下面是可直接复用的代码示例,你可以根据自己的技术栈换成Groovy(Jenkins原生支持)、Go等其他语言:

import requests
import os

# 以下参数均可从Jenkins内置环境变量直接读取,无需硬编码
GITHUB_TOKEN = "你提前生成的具备Checks写权限的访问令牌"
REPO_FULL_NAME = os.getenv("GIT_REPO_FULLNAME")  # 格式:仓库所属空间/仓库名
PR_HEAD_SHA = os.getenv("ghprbActualCommit")  # PR当前最新提交的SHA,Jenkins的PR触发插件会自动注入这个变量
CURRENT_JENKINS_BUILD_URL = os.getenv("BUILD_URL")  # 当前失败构建的Jenkins地址

def create_failed_build_check_with_button():
    api_endpoint = f"https://api.github.com/repos/{REPO_FULL_NAME}/check-runs"
    request_headers = {
        "Accept": "application/vnd.github+json",
        "Authorization": f"Bearer {GITHUB_TOKEN}",
        "X-GitHub-Api-Version": "2022-11-28"
    }
    request_payload = {
        "name": "Jenkins构建检查",
        "head_sha": PR_HEAD_SHA,
        "status": "completed",
        "conclusion": "failure",
        "details_url": CURRENT_JENKINS_BUILD_URL,
        "output": {
            "title": "Jenkins构建执行失败",
            "summary": "本次PR触发的构建任务未通过,可点击下方按钮执行预设修复操作后重试"
        },
        # 自定义按钮配置,单个Check Run最多支持添加3个按钮
        "actions": [
            {
                "label": "执行自定义修复并重试",  # 按钮上展示的文字
                "description": "自动执行缓存清理、依赖重装等预设操作后重跑构建",
                "identifier": "custom_fix_rebuild_001",  # 按钮唯一标识,后续点击事件靠这个区分
            }
        ]
    }
    resp = requests.post(api_endpoint, json=request_payload, headers=request_headers)
    resp.raise_for_status()

# 仅在构建失败时触发按钮创建逻辑
if os.getenv("BUILD_STATUS") == "FAILURE":
    create_failed_build_check_with_button()

代码部署位置

直接把这段逻辑放到Jenkinsfile的post失败触发块里就行,参考片段:

pipeline {
    agent any
    // 保留你原有的构建步骤
    stages {
        // 你原来的拉代码、编译、测试等逻辑
    }
    post {
        failure {
            script {
                // 执行上面的按钮创建逻辑,不想用Python的话也可以用Jenkins的httpRequest插件直接发请求
                sh 'python3 ./scripts/add_pr_button.py'
            }
        }
    }
}
步骤2:实现按钮点击后的自定义逻辑

用户点击你创建的按钮时,GitHub会向你之前配置的check_run事件webhook发送POST请求,请求中action字段值为requested_action,你只需要在接收服务里匹配按钮的唯一标识,执行对应逻辑即可。
最简接收服务示例(基于Flask,可部署在任意能被GitHub公网访问的服务器上,也可以换成GitHub Actions、云函数等托管服务):

from flask import Flask, request
import hmac
import hashlib

app = Flask(__name__)
WEBHOOK_SECRET = "你配置webhook时设置的签名密钥"

def your_custom_business_logic(repo_name, pr_num):
    # 这里写你需要执行的自定义操作,比如:
    # 1. 调用Jenkins接口清理工作空间、重跑构建
    # 2. 自动给PR提交修复代码、发表评论通知
    # 3. 触发其他内部系统的联动流程
    print(f"收到按钮点击请求,仓库{repo_name}的PR#{pr_num}开始执行自定义修复逻辑")

def validate_github_signature(request):
    # 校验请求确实来自GitHub,避免伪造请求
    signature = request.headers.get("X-Hub-Signature-256")
    if not signature:
        return False
    sha_name, signature_hash = signature.split("=")
    if sha_name != "sha256":
        return False
    mac = hmac.new(WEBHOOK_SECRET.encode(), msg=request.data, digestmod=hashlib.sha256)
    return hmac.compare_digest(mac.hexdigest(), signature_hash)

@app.route("/github-webhook-receiver", methods=["POST"])
def webhook_entry():
    if not validate_github_signature(request):
        return "invalid signature", 403
    event_type = request.headers.get("X-GitHub-Event")
    payload = request.json
    # 只处理自定义按钮点击事件
    if event_type == "check_run" and payload.get("action") == "requested_action":
        clicked_action = payload.get("requested_action", {})
        # 匹配你之前给按钮设置的唯一标识
        if clicked_action.get("identifier") == "custom_fix_rebuild_001":
            repo_info = payload["repository"]["full_name"]
            related_pr = payload["check_run"]["pull_requests"][0]["number"]
            your_custom_business_logic(repo_info, related_pr)
            return "operation triggered", 200
    return "event ignored", 200

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=8000)
步骤3:PR页面按钮展示校验

如果配置完按钮没显示,按以下顺序排查:

  1. 创建Check Run时传入的head_sha必须是对应PR当前最新的commit SHA,填错会导致Check Run无法关联到PR,按钮自然不展示
  2. 生成访问令牌的账号必须有目标仓库的写权限,否则调用创建Check Run接口会返回404/403错误
  3. 不要把Check Run的可见范围设为私有,仓库内所有有PR查看权限的用户都能看到按钮
  4. 按钮默认展示在两个位置:PR对话页的检查项列表底部、PR的Checks标签页对应检查项的右侧,不需要额外配置前端脚本

可选优化

自定义逻辑执行过程中,你可以随时调用GitHub的Check Run更新接口,修改Check Run的状态为执行中、成功、失败,用户在PR页面可以直接看到操作的执行进度,不需要跳转其他页面。

内容的提问来源于stack exchange,提问作者Sujatha N Anjan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.01 03:03:39