如何将正在运行的Jenkins构建放回队列并通过Groovy脚本重启?
Great question! This is absolutely feasible with Jenkins' Groovy script API—you just need to handle a few critical steps to abort the running build, requeue a matching replacement, and retain that run #1 number. Let’s break this down step by step:
Step 1: Abort the Running Executor for Run #1
First, we need to locate the active build and terminate its execution cleanly. Here’s a script snippet that does this:
// Replace "your-job-full-name" with your actual job's full name def job = Jenkins.instance.getItemByFullName("your-job-full-name") def targetBuild = job.getBuildByNumber(1) if (targetBuild.isBuilding()) { def executor = targetBuild.getExecutor() if (executor) { // Mark the build as aborted (cleaner than a forced kill) executor.interrupt(Result.ABORTED) println "Successfully aborted run #1 on its executor" } else { println "Run #1 is marked as building but has no active executor" } } else { println "Run #1 is not currently building" }
Note: Using Result.ABORTED ensures the build is marked properly in Jenkins history, but you can adjust the interrupt reason (like Result.FAILURE) if needed for your workflow.
Step 2: Recreate Run #1 with the Same Number (Start from Scratch)
Jenkins doesn’t natively let you requeue an existing build, but we can create a new build that reuses the run #1 number. The catch is Jenkins won’t allow duplicate build numbers by default, so we need to:
- Remove the aborted run #1 from the job’s history (save its logs/artifacts first if you need them!)
- Temporarily override the job’s next build number to 1
- Schedule a new build (which will take the #1 number)
- Revert the job’s next build number to its original value
Here’s the script to handle this:
// After aborting the build (from Step 1) def originalNextBuildNumber = job.getNextBuildNumber() // Optional: Archive original build logs/artifacts before deletion // targetBuild.getArtifacts().each { it.copyTo(new File("/path/to/archive/${targetBuild.number}")) } // Delete the aborted build to free up the #1 number targetBuild.delete() // Override next build number to 1 job.setNextBuildNumber(1) // Schedule a new build with the same parameters as the original run #1 (if applicable) def originalParams = targetBuild.getAction(ParametersAction.class) def restartedBuild = job.scheduleBuild2(0, new Cause.UserIdCause(), originalParams).get() // Revert next build number to avoid messing up future builds job.setNextBuildNumber(originalNextBuildNumber) println "Successfully restarted run #1—new build with number 1 is in the queue"
Key Things to Keep in Mind
- Administrator Privileges: This level of script access requires Jenkins admin rights—you’ll need to run this from the Script Console or a trusted pipeline with elevated permissions.
- Log/Artifact Retention: If you need to keep the original run #1’s logs or artifacts, make sure to archive them before deleting the build (see the optional comment in the script).
- Queue Position: The restarted build will go to the end of the build queue by default. If you need it to run sooner, you can use priority queue plugins or adjust queue priorities via script.
- Plugin Compatibility: If your job uses plugins that store build-specific data (like test results, deployment histories), the new run #1 will start fresh—so ensure those plugins don’t rely on the old build’s data unless you explicitly migrate it.
Final Verdict
Yes, you can achieve exactly what you want: abort the running run #1, remove it from its executor, and get a new run #1 that starts from scratch in the build queue. The core steps are aborting the executor, managing the build number override, and preserving any original build parameters if needed.
内容的提问来源于stack exchange,提问作者Corey Olson

