以「编译失败自动修复」为入口,介绍如何用 ai-agent 插件让流水线在构建挂掉后,自动让 AI 定位修复、验证、并提交 PR。全程无人工干预的关键是回答三个问题:怎么获取到错误信息?修复成没成功?PR 怎么提交?


一、核心三问

问题 答案
如何精确的获取到错误信息? 通常pipeline是多stage,多step的,如何明确失败发生在哪
如何知道 AI 修复成功了? 不信 AI 的自我汇报,让流水线在同一 workspace 里重新编译一次,用 returnStatus: true 拿到退出码做权威判定
怎么提交 PR? Jenkins 侧用受控凭据提交gh CLI / git+token / GitHub API),不把 push 权交给 AI

二、整体流程

build 失败
   │
   ├─ 1. 拿到失败日志(shared-library 的 getStageLog,或 tee + readFile)
   │
   ├─ 2. aiAgent 调用 AI 修复(只改代码,不做 git 提交)
   │
   ├─ 3. 同一 workspace 重新编译(returnStatus 判定)
   │        ├─ 0  → 修复成功
   │        └─ ≠0 → 修复失败,error 终止
   │
   └─ 4. 提交 PR(Jenkins 用受控凭据,分支 ai-fix/build-N)

三、完整 Jenkinsfile(开箱即用)

@Library('test-library@main') _

// 编译命令只维护一份,build 与复验复用,避免写两遍
def BUILD_CMD = 'mvn clean package'

pipeline {
    agent { node { label "mac-node" } }

    stages {
        stage("checkout") {
            steps {
                script { env.FAILED_STAGE = 'checkout' }
                checkout scmGit(
                    branches: [[name: '*/main']],
                    extensions: [],
                    userRemoteConfigs: [[
                        credentialsId: 'credId',
                        url: 'https://github.com/Walk119/jekins-test.git'
                    ]]
                )
            }
        }
        stage("build") {
            steps {
                script { env.FAILED_STAGE = 'build' }
                sh "${BUILD_CMD}"
            }
        }
    }

    post {
        failure {
            script {
                def logs = readJSON(text: getStageLog())
                if (env.FAILED_STAGE == 'build') {
                    // 1) AI 修复(只改代码,不做 git 提交)
                    def prompt = '请分析代码库并修复编译失败的问题。改完代码即可,不要做 git 提交操作。\n\n' + logs.build
                    aiAgent(
                        agent: codex(),
                        prompt: prompt,
                        yoloMode: true          // ⚠️ 是 aiAgent 参数,不是 codex() 参数
                    )

                    // 2) 同 workspace 复验,判定修复是否成功
                    def ret = sh(script: BUILD_CMD, returnStatus: true)
                    if (ret == 0) {
                        currentBuild.result = 'SUCCESS'
                        submitPr()              // 3) 提交 PR 持久化改动
                    } else {
                        error('AI 修复后仍编译失败,放弃提交 PR')
                    }
                }
            }
        }
    }
}

def submitPr() {
    withCredentials([usernamePassword(credentialsId: 'credId', usernameVariable: 'GH_USER', passwordVariable: 'GH_TOKEN')]) {
        sh '''
          BRANCH="ai-fix/build-$BUILD_NUMBER"
          git checkout -b "$BRANCH"
          git add -A
          git commit -m "fix: AI 修复编译错误 (build $BUILD_NUMBER)"
          gh auth setup-git
          git push origin "HEAD:refs/heads/$BRANCH"
          gh pr create --base main --head "$BRANCH" \
            --title "fix: AI 修复编译错误 (build $BUILD_NUMBER)" \
            --body "由 Jenkins AI Agent 自动修复编译错误并提交。"
        '''
    }
}

四、分步拆解

4.1 拿到失败日志

两种方式,二选一:

方式 A:shared-library(本项目所用)

def logs = readJSON(text: getStageLog())   // getStageLog 来自 test-library
def prompt = '...修复编译错误...\n\n' + logs.build

方式 B:标准步骤(不依赖任何共享库)

stage("build") {
    steps { sh 'mvn clean package 2>&1 | tee build.log' }
}
post {
    failure {
        script {
            def log = readFile('build.log')   // 通用,无外部依赖
            aiAgent(agent: codex(), prompt: "日志:\n${log}")
        }
    }
}

4.2 AI 修复

aiAgent(
    agent: codex(),      // 七选一:codex / claudecode / opencode / antigravity / cursor / geminicli / grokbuild
    prompt: "构建失败,请修复编译错误,改完代码即可,不要做 git 提交。\n\n${log}",
)

提示词要点:明确"只改代码、不要提交",因为提交交给 Jenkins 做,避免 AI 去碰 git/push。

4.3 复验判定

def ret = sh(script: BUILD_CMD, returnStatus: true)   // 返回 0/非0,不抛异常
if (ret == 0) { /* 成功 */ } else { error('仍失败') }
  • returnStatus: true 让编译失败不中断 post 块,由我们自己判断分支。
  • 复验跑的是能判定「编译是否通过」的最小命令(通常一条 mvn clean package 就够),不必照搬完整构建链路(含 npm、docker 等)。
  • 复验通过后记得 currentBuild.result = 'SUCCESS',把原本的 FAILURE 改回成功,否则修好了构建状态仍是红的。

4.4 提交 PR

提交由 Jenkins 用受控凭据完成,三种方式任选:

// 方式一:gh CLI(最简洁)
withCredentials([string(credentialsId: 'github-token', variable: 'GH_TOKEN')]) {
    sh 'gh auth setup-git && git push ... && gh pr create ...'
}

// 方式二:纯 git + token(不依赖 gh)
withCredentials([usernamePassword(credentialsId: 'github-cred',
        usernameVariable: 'GIT_USER', passwordVariable: 'GIT_TOKEN')]) {
    sh 'git push https://${GIT_USER}:${GIT_TOKEN}@github.com/org/repo.git HEAD:ai-fix/build-N'
}

// 方式三:GitHub API(最通用)
sh 'curl -X POST https://api.github.com/repos/org/repo/pulls -H "Authorization: token $GIT_TOKEN" -d "..."'
Logo

中国智能体开发者社区,聚焦智能体与大模型开发,提供前沿资讯、实用工具链、开源项目及行业案例。通过技术沙龙、开发者大赛等活动,促进经验交流与协作,助力开发者快速构建创新智能应用。

更多推荐