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

如何在本地Groovy脚本中创建Jenkins实例并兼容WorkflowJob类?

问题:本地Groovy脚本调用Jenkins API替代脚本控制台的困惑

我想在本地Groovy脚本里调用Jenkins API,替代Jenkins的脚本控制台功能。目前已经成功导入了Jenkins相关依赖包:

@GrabResolver(name='jenkins', root='https://repo.jenkins-ci.org/releases')
@Grab(group='org.jenkins-ci.main', module='jenkins-core', version='2.377')
@Grab(group='org.jenkins-ci.plugins.workflow', module='workflow-api', version='1200.v8005c684b_a_c6')
@Grab(group='org.jenkins-ci.plugins.workflow', module='workflow-job', version='1254.v3f64639b_11dd')
@Grab(group='org.jenkins-ci.plugins.workflow', module='workflow-step-api', version='639.v6eca_cd8c04a_a_')

import jenkins.model.Jenkins
import hudson.Util
import hudson.model.Job
import org.jenkinsci.plugins.workflow.job.WorkflowJob

String rootUrl  = 'https://my.jenkins.com'
String username = 'admin'
String password = 'admin'

// .. how to new a Jenkins instance here ..
// i.e.: Jenkins jenkins = new Jenkins.instance( url, username, password )

// list all workflowjobs
Jenkins.instance.getAllItems( WorkflowJob.class ).collect { it.fullName }

但我不知道怎么通过URL、用户名和密码创建Jenkins实例,实现像jenkins.model.Jenkins.instance.xxx这样的操作。另外我试过用jenkinsci/java-client-api创建JenkinsServer实例:

@GrabResolver(name='jenkins', root='https://repo.jenkins-ci.org/releases')
@Grab(group='org.jenkins-ci.main', module='jenkins-core', version='2.377')
@Grab(group='com.offbytwo.jenkins', module='jenkins-client', version='0.3.8')

import com.offbytwo.jenkins.JenkinsServer

String rootUrl  = 'https://my.jenkins.com'
String username = 'admin'
String password = 'admin'

JenkinsServer jenkins = new JenkinsServer( new URI(rootUrl), username, password )
jenkins.getJobs()

但这个API识别不了AbstractItem.class、WorkflowJob.class这类类,想问下有没有办法把com.offbytwo.jenkins.JenkinsServer转换成jenkins.model.Jenkins?


解决方案

首先明确:jenkins.model.Jenkins是Jenkins服务端运行时的核心类,它只能在Jenkins服务器本地的JVM里直接实例化调用,没办法通过远程URL直接创建这个类的实例——因为它绑定了Jenkins服务器的本地资源和运行环境,远程场景下没法直接复用这个类的API。

方案1:使用Jenkins远程API提交Groovy脚本(最贴近脚本控制台体验)

Jenkins脚本控制台本质是在服务器端执行Groovy代码,我们可以直接通过远程API提交脚本到服务器执行,这样就能完全复用jenkins.model.Jenkins等服务端类的API。示例代码:

@GrabResolver(name='jenkins', root='https://repo.jenkins-ci.org/releases')
@Grab(group='org.apache.httpcomponents', module='httpclient', version='4.5.14')

import org.apache.http.HttpEntity
import org.apache.http.auth.AuthScope
import org.apache.http.auth.UsernamePasswordCredentials
import org.apache.http.client.CredentialsProvider
import org.apache.http.client.methods.HttpPost
import org.apache.http.entity.StringEntity
import org.apache.http.impl.client.BasicCredentialsProvider
import org.apache.http.impl.client.CloseableHttpClient
import org.apache.http.impl.client.HttpClients
import org.apache.http.util.EntityUtils

String rootUrl = 'https://my.jenkins.com'
String username = 'admin'
String password = 'admin'
String script = '''
import jenkins.model.Jenkins
import org.jenkinsci.plugins.workflow.job.WorkflowJob
Jenkins.instance.getAllItems(WorkflowJob.class).collect { it.fullName }
'''

// 构建带认证的HTTP客户端
CredentialsProvider provider = new BasicCredentialsProvider()
provider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password))
CloseableHttpClient client = HttpClients.custom().setDefaultCredentialsProvider(provider).build()

try {
    HttpPost post = new HttpPost("${rootUrl}/scriptText")
    // 编码脚本内容并设置请求实体
    String encodedScript = URLEncoder.encode(script, 'UTF-8')
    post.setEntity(new StringEntity("script=${encodedScript}", "application/x-www-form-urlencoded"))
    def response = client.execute(post)
    HttpEntity entity = response.getEntity()
    // 打印执行结果
    println EntityUtils.toString(entity)
} finally {
    client.close()
}

这个方案直接模拟脚本控制台的行为,提交Groovy代码到服务器执行并返回结果,完全支持所有服务端类的API。

方案2:适配jenkins-client库实现需求(如果坚持用客户端库)

com.offbytwo.jenkins.JenkinsServer是基于Jenkins REST API封装的客户端,它本身不会直接映射服务端的AbstractItem、WorkflowJob等类。如果要用这个库获取流水线任务,可以通过REST API返回的_class字段来筛选:

@GrabResolver(name='jenkins', root='https://repo.jenkins-ci.org/releases')
@Grab(group='com.offbytwo.jenkins', module='jenkins-client', version='0.3.8')

import com.offbytwo.jenkins.JenkinsServer
import com.offbytwo.jenkins.model.Job

String rootUrl = 'https://my.jenkins.com'
String username = 'admin'
String password = 'admin'

JenkinsServer jenkins = new JenkinsServer(new URI(rootUrl), username, password)
// 过滤出流水线类型的任务(通过_class字段匹配)
List<Job> workflowJobs = jenkins.getJobs().findAll { job ->
    job.get("_class") == "org.jenkinsci.plugins.workflow.job.WorkflowJob"
}
// 输出所有流水线任务的全名
workflowJobs.each { println it.fullName }

这种方式依赖Jenkins REST API返回的类型标识字段,虽然不能直接使用服务端的WorkflowJob类,但可以实现类似的筛选功能。


内容的提问来源于stack exchange,提问作者Marslo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 14:50:44