1. 概述

直接在 GitHub 中监控 Jenkins 构建状态,有助于我们在不切换平台的前提下掌握代码质量。相比手动检查 Jenkins,将构建状态展示在 GitHub 上,可以让我们更早发现问题,保持工作流顺畅。

在本教程中,我们将配置 Jenkins,使其自动在 GitHub 上更新构建状态。

2. 前置条件

开始前,我们需要准备以下内容:

  • 一个 GitHub 仓库
  • 一个正在运行的 Jenkins 实例(自建或云服务均可)
  • 本地已安装并配置好 Git
  • 熟悉 Jenkins 和 GitHub 工作流的基本知识

3. 配置演示项目

在集成 GitHub Actions 与 Jenkins 之前,我们先配置一个简单的 Node.js 项目,并设置 Jenkins 和 GitHub Secrets。

3.1. 克隆演示项目

首先,执行以下命令克隆项目:

$ git clone https://github.com/Baeldung/ops-tutorials.git

然后进入项目目录:

$ cd ops-tutorials/jenkins-modules/monitor-jenkins-build-status/starter

3.2. 配置 Jenkins

我们先在 Jenkins 中创建一个任务(Job),用于被 GitHub Actions 触发。

  1. 打开 Jenkins 控制台,点击 New Item
  2. 输入任务名称,选择 Freestyle Project,点击 OK

Jenkins New Job

  1. 勾选 GitHub project,并填写你的 GitHub 仓库地址;

GitHub Project URL

  1. Source Code Management 部分选择 Git,并填写仓库地址;

Source Code Management

  1. Triggers 部分勾选 *Trigger builds remotely (e.g., from scripts)*,并设置一个认证 Token,比如 secret-token

  2. Environment 部分勾选 Delete workspace before build starts,确保每次构建都在干净环境中进行;

Triggers Build Remotely

  1. Build Steps 中添加一个 Execute shell 步骤,输入以下命令安装依赖并运行测试:
npm install
npm test

Build steps

配置完成后点击 Save

3.3. 生成 Jenkins API Token

为了让 GitHub Actions 能与 Jenkins 通信,需要生成一个 API Token。

  1. 点击右上角用户名,选择 Security
  2. 输入 Token 名称,点击 Generate
  3. 保存生成的 Token,后续将用于认证。

New API token

3.4. 配置 GitHub Secrets

为了安全起见,我们将 Jenkins 的认证信息存储在 GitHub Secrets 中。

  1. 进入仓库的 Settings 页面;
  2. Secrets and variables 下选择 Actions
  3. 添加以下 Secrets:
    • JENKINS_URL:Jenkins 地址
    • JENKINS_USER:用户名
    • JENKINS_API_TOKEN:API Token
    • JENKINS_JOB_NAME:任务名称
    • JENKINS_SECRET_TOKEN:触发 Token

这样,GitHub Actions 就可以安全地触发 Jenkins 构建了。

4. GitHub Actions 与 Jenkins 集成

配置好 Jenkins 后,我们通过 GitHub Actions 自动化构建流程。

4.1. 实现原理

GitHub Actions 工作流会:

  1. 监听代码推送事件
  2. 发送 API 请求触发 Jenkins 构建
  3. 等待构建完成并获取状态
  4. 根据构建结果更新 GitHub 上的提交状态

4.2. 创建 GitHub Actions 工作流

在项目根目录下创建 .github/workflows/trigger-jenkins.yml 文件,并粘贴以下内容:

name: GitHub Actions + Jenkins Integration

on:
    push:
        branches:
            - main

jobs:
    trigger-jenkins:
        runs-on: ubuntu-latest

        steps:
            - name: Securely Trigger Jenkins Build
              env:
                  JENKINS_URL: ${{ secrets.JENKINS_URL }}
                  JENKINS_USER: ${{ secrets.JENKINS_USER }}
                  JENKINS_API_TOKEN: ${{ secrets.JENKINS_API_TOKEN }}
                  JENKINS_JOB_NAME: ${{ secrets.JENKINS_JOB_NAME }}
                  JENKINS_SECRET_TOKEN: ${{ secrets.JENKINS_SECRET_TOKEN }}
              run: |
                  RESPONSE=$(curl -s -w "%{http_code}" -o output.txt \
                  -X POST "$JENKINS_URL/job/$JENKINS_JOB_NAME/build?token=$JENKINS_SECRET_TOKEN" \
                  --user "$JENKINS_USER:$JENKINS_API_TOKEN")

                  if [[ $RESPONSE -ne 201 ]]; then
                    echo "❌ Jenkins build trigger failed!"
                    cat output.txt
                    exit 1
                  fi

            - name: Monitor Jenkins Build Status
              env:
                  JENKINS_URL: ${{ secrets.JENKINS_URL }}
                  JENKINS_USER: ${{ secrets.JENKINS_USER }}
                  JENKINS_API_TOKEN: ${{ secrets.JENKINS_API_TOKEN }}
                  JENKINS_JOB_NAME: ${{ secrets.JENKINS_JOB_NAME }}
              run: |
                  echo "🔍 Waiting for Jenkins build to start..."
                  sleep 10  # Wait before checking status

                  BUILD_URL="$JENKINS_URL/job/$JENKINS_JOB_NAME/lastBuild/api/json"

                  while true; do
                    STATUS=$(curl -s --user "$JENKINS_USER:$JENKINS_API_TOKEN" $BUILD_URL | jq -r '.result')

                    if [[ "$STATUS" == "SUCCESS" ]]; then
                      echo "✅ Jenkins Build Successful!"
                      exit 0
                    elif [[ "$STATUS" == "FAILURE" ]]; then
                      echo "❌ Jenkins Build Failed!"
                      exit 1
                    elif [[ "$STATUS" == "null" ]]; then
                      echo "⏳ Jenkins build still running..."
                      sleep 10
                    else
                      echo "⚠️ Unexpected status: $STATUS"
                      exit 1
                    fi
                  done

该工作流监听 main 分支的推送事件,触发 Jenkins 构建,并通过轮询获取构建结果。构建失败时,GitHub Actions 也会标记失败,便于及时发现问题。

4.3. 优缺点分析

优点

  • 工作流和 Jenkins 任务逻辑可独立修改
  • 敏感信息通过 GitHub Secrets 管理
  • GitHub Actions 负责调度,Jenkins 负责构建和测试
  • 每次推送都会在 GitHub 上反馈构建结果

缺点

  • 构建结果仅显示在 GitHub Actions 日志中
  • Jenkins 必须在 GitHub 工作流运行时可用
  • Jenkins 任务需手动或脚本创建

该方法简单有效,无需复杂配置即可从 GitHub 触发 Jenkins 构建。

5. Jenkins 可嵌入构建状态徽章

另一种监控 Jenkins 构建状态的方式是使用可嵌入徽章(Embeddable Build Status Badge)。它可以直接在 GitHub 仓库中以图像形式展示最新的构建状态,无需手动访问 Jenkins。

5.1. 实现原理

Jenkins 的 Embeddable Build Status 插件会生成一个动态徽章图片,反映指定任务的最新构建状态。我们可以通过 Markdown 将其嵌入到 GitHub 的 README.md 文件中。

⚠️ 注意事项:

  • 徽章需要 Jenkins 公网可访问,或启用匿名用户 ViewStatus 权限
  • 如果 Jenkins 需要认证,徽章可能无法正常显示

5.2. 在 Jenkins 中启用徽章支持

  1. 进入 Jenkins 的 Manage Jenkins > Plugins
  2. 搜索 embeddable-build-status 并安装;

Plugins homepage

Embeddable Build Search

安装完成后,进入任务页面,点击左侧 Embeddable Build Status,选择徽章样式(如 flatplasticball-size),复制 Markdown 代码并粘贴到 README.md 中。

如果 Jenkins 无法公网访问,有两种解决方式:

  • 允许匿名访问:进入 Manage Jenkins -> Security,在 Matrix-based security 中给 Anonymous 用户添加 ViewStatus 权限;

View status

  • 通过反向代理暴露 Jenkins:使用 NGINX 或 Apache 反向代理 Jenkins,并配置 SSL/TLS 加密。

5.3. 优缺点分析

优点

  • 不离开 GitHub 即可查看构建状态
  • 易于嵌入 README.md
  • 减少手动检查

缺点

  • Jenkins 若非公网可访问需额外配置
  • 仅显示基础状态(成功/失败),无详细日志
  • 若 Jenkins 有认证,徽章可能无法加载

该方法适合快速查看构建状态,尤其适用于对外公开的项目。

6. 总结

本文介绍了两种在 GitHub 中监控 Jenkins 构建状态的方法:

  1. 使用 GitHub Actions 自动触发并监控 Jenkins 构建,实现实时反馈;
  2. 利用 Jenkins 的 Embeddable Build Status 插件在 GitHub 中显示构建状态徽章。

这些集成方式简化了 CI/CD 流程,减少了手动检查 Jenkins 的频率,帮助我们更快发现问题并及时修复。

完整代码可在 GitHub 获取。


原始标题:Monitor Jenkins Build Status in a GitHub Repository