术语定义
名词 |
说明 |
job |
任务 |
payload |
在POST请求中提交的数据 |
{optionalFolderPath} |
可选参数:任务所在目录的路径 |
{job_name} |
必须参数:任务名称 |
- 在 GET/POST 时需要附加 HTTP 认证才能访问 API
- 本文使用的数据结构可以在 jenkins-rest/domain 中查看详细定义
API类型
API类型 |
说明 |
JobsAP |
任务管理(任务信息、创建、修改) |
OBPluginManagerAPI |
插件管理(插件信息、安装插件) |
QueueAPI |
任务队列相关(队列状态) |
StatisticsAPI |
Jenkins统计信息 |
CrumbIssuerAPI |
系统哈希值信息(用于防御CSRF攻击) |
SystemAPI |
Jenkins系统状态(版本、路径) |
API汇总
名称 |
API |
创建 Job |
POST http://localhost:8080/createItem/api/json |
更新 Job |
POST http://localhost:8080/job/{job_name}/config.xml/api/json |
获取 Job |
GET http://localhost:8080/job/{job_name}/api/json |
获取 JobXml |
GET http://localhost:8080/job/{job_name}/config.xml/api/json |
删除 Job |
POST http://127.0.0.1:8080/{optionalFolderPath}job/{job_name}/doDelete |
enable Job |
POST http://127.0.0.1:8080/{optionalFolderPath}job/{job_name}/enable |
disable Job |
POST http://127.0.0.1:8080/{optionalFolderPath}job/{job_name}/disable |
获取任务描述 |
GET http://127.0.0.1:8080/{optionalFolderPath}job/{job_name}/description |
设置任务描述 |
POST http://127.0.0.1:8080/{optionalFolderPath}job/{job_name}/description |
创建 Build |
POST http://localhost:8080/job/{job_name}/build/api/json |
获取 QueueItem |
GET http://localhost:8080/queue/item/17/api/json |
取消任务队列 |
POST http://127.0.0.1:8080/cancelItem?id={id} |
所有任务队列信息 |
GET http://127.0.0.1:8080/queue/api/json |
获取 Build信息 |
GET http://localhost:8080/job/test/6/api/json |
获取上次构建序号 |
GET http://127.0.0.1:8080/{optionalFolderPath}job/{job_name}/lastBuild/buildNumber |
获取上次构建时间戳 |
GET http://127.0.0.1:8080/{optionalFolderPath}job/{job_name}/lastBuild/buildTimestamp |
获取TXT日志 |
GET http://localhost:8080/job/test/{build_number}/logText/progressiveText/api/json |
获取 Html 日志 |
GET http://localhost:8080/job/test/{build_number}/logText/progressiveHtml/api/json |
系统哈希值信息 |
GET http://127.0.0.1:8080/crumbIssuer/api/xml?{key}={value} |
load统计信息 |
GET http://127.0.0.1:8080/overallLoad/api/json |
插件管理 |
GET http://127.0.0.1:8080/pluginManager/api/json |
安装插件 |
POST http://127.0.0.1:8080/pluginManager/installNecessaryPlugins |
API详述
创建 Job
jenkins 的配置都是靠 xml 的格式落地的,所以配置其实都是 xml 的形式.
1
| POST http://127.0.0.1:8080/createItem
|
参数
key |
value |
name 任务名称 |
|
payload XML配置文件 |
|
返回类型:RequestStatus
字段 |
类型 |
说明 |
value |
Boolean |
|
errors |
List |
|
如何知道 config.xml应该如何编写呢?
- 可以在 jenkins 收工创建一个需要的项目,然后编辑完成后,到 jenkins 工作目录下 找到 jobs/{job_name}/config.xml 用他作为模板来书写你需要的模板.
- 通过获取 xml 的 api 来获取
GET http://localhost:8080/job/{job_name}/config.xml/api/json
Java Client
1 2
| jenkinsServer.createJob("auto_test_job", replacedText, true); String xml = jenkinsServer.getJobXml("auto_test_job");
|
更新Job
1
| POST http://localhost:8080/job/{job_name}/config.xml/api/json
|
参数
config.xml的内容传入到 body 中,contentType 设置为text/xml
返回类型:Boolean
Java Client
1
| jenkinsServer.updateJob("auto_test_job", replacedText, true);
|
job-info 获取任务信息
GET http://127.0.0.1:8080/{optionalFolderPath}job/{job_name}/api/json
返回类型:JobInfo
字段 |
类型 |
说明 |
description |
String |
描述 |
name |
String |
项目名称 |
url |
boolean |
路径 |
buildable |
String |
是否可构建 |
builds |
List |
构建记录 |
lastBuild |
BuildInfo |
上次构建记录 |
…… |
|
|
delete 删除任务
1
| POST http://127.0.0.1:8080/{optionalFolderPath}job/{project_name}/doDelete
|
返回类型:RequestStatus
补充:
也可以使用
1
| DELETE https://<Jenkins_url>/job/<job_name>/
|
注意最后有个 /
,不加 /
不能正常删除
enable允许任务
1
| POST http://127.0.0.1:8080/{optionalFolderPath}job/{project_name}/enable
|
返回类型:Boolean
disable 禁止任务
1
| POST http://127.0.0.1:8080/{optionalFolderPath}job/{project_name}/disable
|
返回类型:Boolean
get-description 获取任务描述
1
| GET http://127.0.0.1:8080/{optionalFolderPath}job/{project_name}/description
|
返回类型:String
set-description 设置任务描述
1
| POST http://127.0.0.1:8080/{optionalFolderPath}job/{project_name}/description
|
参数
返回类型:Boolean
创建 Build
1 2
| POST http://127.0.0.1:8080/{optionalFolderPath}job/{job_name}/build POST http://localhost:8080/job/{job_name}/build/api/json
|
返回类型: IntegerResponse
字段 |
类型 |
说明 |
value |
Integer |
|
errors |
List |
|
build-with-params 使用参数创建任务
1
| POST http://127.0.0.1:8080/{optionalFolderPath}job/{job_name}/buildWithParameters
|
参数
key |
value |
payload |
Map<String, List> properties |
返回类型: IntegerResponse
新的构建请求提交到服务器成功后返回一个类似于队列ID的东西,因为是异步构建,那么要获取构建的状态,就需要,用这个队列 id去进一步的获取. 例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| $ curl -v -XPOST http://localhost:8080/job/test/build/api/json * Trying ::1... * TCP_NODELAY set * Connected to localhost (::1) port 8080 (#0) > POST /job/test/build/api/json HTTP/1.1 > Host: localhost:8080 > User-Agent: curl/7.54.0 > Accept: */* > < HTTP/1.1 201 Created < Date: Sat, 05 Jan 2019 08:33:45 GMT < X-Content-Type-Options: nosniff < Location: http://localhost:8080/queue/item/17/ < Content-Length: 0 < Server: Jetty(9.4.z-SNAPSHOT) < * Connection
|
上面的Location: http://localhost:8080/queue/item/17/
就是返回的队列信息,下面的 queueItem 获取就是依赖这个.
根据 QueueId 获取 QueueItem
1
| GET http://localhost:8080/queue/item/17/api/json
|
参数
返回类型:QueueItem
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| $ curl http://localhost:8080/queue/item/17/api/json\?pretty\=true { "_class" : "hudson.model.Queue$LeftItem", "actions" : [ { "_class" : "hudson.model.CauseAction", "causes" : [ { "_class" : "hudson.model.Cause$UserIdCause", "shortDescription" : "由用户 anonymous 启动", "userId" : null, "userName" : "anonymous" } ] } ], "blocked" : false, "buildable" : false, "id" : 17, "inQueueSince" : 1546677225670, "params" : "", "stuck" : false, "task" : { "_class" : "hudson.maven.MavenModuleSet", "name" : "test", "url" : "http://localhost:8080/job/test/", "color" : "blue" }, "url" : "queue/item/17/", "why" : null, "cancelled" : false, "executable" : { "_class" : "hudson.maven.MavenModuleSetBuild", "number" : 6, "url" : "http://localhost:8080/job/test/6/" } }
|
cancel 取消任务队列
1
| POST http://127.0.0.1:8080/cancelItem?id={id}
|
参数
返回类型:RequestStatus
queue 所有任务队列信息
1
| GET http://127.0.0.1:8080/queue/api/json
|
返回类型:List
字段 |
类型 |
说明 |
blocked |
Boolean |
是否阻塞 |
buildable |
Boolean |
是否可构建 |
id |
Integer |
|
inQueueSince |
Long |
|
params |
Map<String, String> |
任务参数 |
task |
Task |
Task中包含任务名称和URL |
…… |
|
|
获取 Build 详情
1
| GET http://127.0.0.1:8080/{optionalFolderPath}job/{job_name}/{number}/api/json
|
返回类型:BuildInfo
字段 |
类型 |
说明 |
artifacts |
List |
artifacts |
actions |
Lis |
actions |
building |
boolean 路径 |
|
description |
String |
描述 |
…… |
|
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| curl http://localhost:8080/job/test/6/api/json\?pretty\=true { ... "building" : false, "description" : null, "displayName" : "#6", "duration" : 13631, "estimatedDuration" : 17999, "executor" : null, "fullDisplayName" : "test #6", "id" : "6", "keepLog" : false, "number" : 6, "queueId" : 17, "result" : "SUCCESS", "timestamp" : 1546677234794, "url" : "http://localhost:8080/job/test/6/", "builtOn" : "", ... }
|
从返回结果可以看到 是否还在 build:"building" : false
,如果 build 结束状态就在:"result" : "SUCCESS"
获取上次Build详情
1
| curl http://172.12.12.234:8080/job/pytest_7.0/lastBuild/api/xml --user jenkins:1
|
last-build-number 获取上次构建序号
1
| GET http://127.0.0.1:8080/{optionalFolderPath}job/{job_name}/lastBuild/buildNumber
|
返回类型:Integer
last-build-timestamp 获取上次构建时间戳
1
| GET http://127.0.0.1:8080/{optionalFolderPath}job/{job_name}/lastBuild/buildTimestamp
|
返回类型:String
progressive-text 获取构建控制台输出
获取上次构建的日志
1
| GET http://127.0.0.1:8080/{optionalFolderPath}job/{job_name}/lastBuild/logText/progressiveText
|
返回类型:ProgressiveText
字段 |
类型 |
说明 |
text |
String |
控制台输出 |
size |
Integer |
字数 |
hasMoreData |
Boolean |
是否有更多数据 |
获取某次构建的日志
1 2 3 4 5
| // text GET http://localhost:8080/job/test/{build_number}/logText/progressiveText/api/json
// html GET http://localhost:8080/job/test/{build_number}/logText/progressiveHtml/api/json
|
1 2 3 4 5 6 7 8 9 10 11 12
| JobWithDetails job = jenkinsServer.getJob(jenkinsJob); ... QueueReference reference = job.build( true); ... QueueItem queueItem = jenkinsServer.getQueueItem(new QueueReference(queuePart)); ... Build build = jenkinsServer.getBuild(queueItem); ... BuildWithDetails details = build.details(); BuildResult result = details.getResult(); ... String logs = details.getConsoleOutputText();
|
CrumbIssuer 系统哈希值信息(用于防御CSRF攻击)
- CrumbIssuerApi
- path: /crumbIssuer/api/xml
crumb
1
| GET http://127.0.0.1:8080/crumbIssuer/api/xml?{key}={value}
|
参数
key |
value |
xpath |
concat(//crumbRequestField,”:”,//crumb) |
返回类型:Crumb
字段 |
类型 |
value |
String |
errors |
List |
Statistics 统计信息
overall-load
1
| GET http://127.0.0.1:8080/overallLoad/api/json
|
返回类型:OverallLoad
字段 |
类型 |
说明 |
availableExecutors |
Map<String, String> |
|
busyExecutors |
Map<String, String> |
|
connectingExecutors |
Map<String, String> |
|
definedExecutors |
Map<String, String> |
|
idleExecutors |
Map<String, String> |
|
onlineExecutors |
Map<String, String> |
|
queueLength |
Map<String, String> |
|
totalExecutors |
Map<String, String> |
|
totalQueueLength |
Map<String, String> |
|
System 系统信息
返回类型:SystemInfo
字段 |
类型 |
说明 |
hudsonVersion |
String |
|
jenkinsVersion |
String |
|
jenkinsSession |
String |
|
instanceIdentity |
String |
|
sshEndpoint |
String |
|
server |
String |
|
PluginManager 插件管理(插件信息、安装插件)
- PluginManagerApi
- path: /pluginManager
plugins 插件列表
1
| GET http://127.0.0.1:8080/pluginManager/api/json
|
返回类型:List
字段 |
类型 |
说明 |
active |
Boolean |
|
backupVersion String |
|
|
bundled |
Boolean |
|
deleted |
Boolean |
|
downgradable |
Boolean |
|
enabled |
Boolean |
|
longName |
String |
|
…… |
|
|
installNecessaryPlugins 安装插件
1
| POST http://127.0.0.1:8080/pluginManager/installNecessaryPlugins
|
参数
1
| payload: <jenkins><install plugin="{pluginID}"/></jenkins>
|
字段 |
说明 |
{pluginID} |
要安装的插件ID |
返回类型:RequestStatus
代码示例
配置
导入依赖
1 2 3 4 5 6
| <dependency> <groupId>com.offbytwo.jenkins</groupId> <artifactId>jenkins-client</artifactId> <version>0.3.8</version> </dependency>
|
创建连接配置,配置对应的信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| import com.offbytwo.jenkins.JenkinsServer; import com.offbytwo.jenkins.client.JenkinsHttpClient; import java.net.URI; import java.net.URISyntaxException; public class JenkinsConnect { private JenkinsConnect(){} static final String JENKINS_URL = "http://jenkins:8080/"; static final String JENKINS_USERNAME = "jenkins"; static final String JENKINS_PASSWORD = "jenkins";
public static JenkinsHttpClient getClient(){ JenkinsHttpClient jenkinsHttpClient = null; try { jenkinsHttpClient = new JenkinsHttpClient(new URI(JENKINS_URL), JENKINS_USERNAME, JENKINS_PASSWORD); } catch (URISyntaxException e) { e.printStackTrace(); } return jenkinsHttpClient; }
public static JenkinsServer connection() { JenkinsServer jenkinsServer = null; try { jenkinsServer = new JenkinsServer(new URI(JENKINS_URL), JENKINS_USERNAME, JENKINS_PASSWORD); } catch (URISyntaxException e) { e.printStackTrace(); } return jenkinsServer; } }
|
JENKINS_URL是Jenkins的反向代理地址, Configure System -> Jenkins location url
, 一般和Jenkins首页访问地址一致
JENKINS_USERNAME Jenkins登录账号
JENKINS_PASSWORD Jenkins账号密码

使用示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288
| import com.offbytwo.jenkins.JenkinsServer; import com.offbytwo.jenkins.client.JenkinsHttpClient; import com.offbytwo.jenkins.model.Build; import com.offbytwo.jenkins.model.Job; import com.offbytwo.jenkins.model.JobWithDetails; import com.offbytwo.jenkins.model.MavenJobWithDetails; import java.io.IOException; import java.util.HashMap; import java.util.Map; public class JobApi { private JenkinsServer jenkinsServer; private JenkinsHttpClient jenkinsHttpClient;
JobApi() { jenkinsServer = JenkinsConnect.connection(); jenkinsHttpClient = JenkinsConnect.getClient(); }
public void ceateJob(){ try { String script = "node(){ \n" + "echo 'hello world!' \n" + "}"; String xml = "<flow-definition plugin=\"workflow-job@2.32\">\n" + "<description>测试项目</description>\n" + "<definition class=\"org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition\" plugin=\"workflow-cps@2.66\">\n" + "<script>" + script + "</script>\n" + "<sandbox>true</sandbox>\n" + "</definition>\n" + "</flow-definition>"; jenkinsServer.createJob("test-job",xml, true); } catch (IOException e) { e.printStackTrace(); } }
public void updateJob(){ try {
String script = "node(){ \n" + "echo \"${key}\" \n" + "}"; String xml = "<flow-definition plugin=\"workflow-job@2.32\">\n" + "<actions/>\n" + "<description>测试项目</description>\n" + "<keepDependencies>false</keepDependencies>\n" + "<properties>\n" + "<hudson.model.ParametersDefinitionProperty>\n" + "<parameterDefinitions>\n" + "<hudson.model.StringParameterDefinition>\n" + "<name>key</name>\n" + "<description>用于测试的字符变量</description>\n" + "<defaultValue>hello</defaultValue>\n" + "<trim>false</trim>\n" + "</hudson.model.StringParameterDefinition>\n" + "</parameterDefinitions>\n" + "</hudson.model.ParametersDefinitionProperty>\n" + "</properties>\n" + "<definition class=\"org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition\" plugin=\"workflow-cps@2.66\">\n" + "<script>" + script + "</script>\n" + "<sandbox>true</sandbox>\n" + "</definition>\n" + "<disabled>false</disabled>\n" + "</flow-definition>"; jenkinsServer.updateJob("test-job",xml, true); } catch (IOException e) { e.printStackTrace(); } }
public void getJob(){ try { JobWithDetails job = jenkinsServer.getJob("das-app-android-pkg"); System.out.println(job.getName()); System.out.println(job.getUrl()); System.out.println(job.getNextBuildNumber()); System.out.println(job.getDisplayName()); System.out.println(job.getDescription()); System.out.println(job.getDownstreamProjects()); System.out.println(job.getUpstreamProjects()); } catch (IOException e) { e.printStackTrace(); } }
public void getMavenJob(){ try { MavenJobWithDetails job = jenkinsServer.getMavenJob("test-job"); } catch (IOException e) { e.printStackTrace(); } }
public void getJobList(){ try { Map<String, Job> jobs = jenkinsServer.getJobs(); for (Job job:jobs.values()){ System.out.println(job.getName()); } } catch (IOException e) { e.printStackTrace(); } }
public void getJobListByView(){ try { Map<String,Job> jobs = jenkinsServer.getJobs("all"); for (Job job:jobs.values()){ System.out.println(job.getName()); } } catch (IOException e) { e.printStackTrace(); } }
public void getJobConfig(){ try { String xml = jenkinsServer.getJobXml("test-job"); System.out.println(xml); } catch (IOException e) { e.printStackTrace(); } }
public void buildJob(){ try { jenkinsServer.getJob("test-job").build(true); } catch (IOException e) { e.printStackTrace(); } }
public void buildParamJob(){ try {
Map<String,String> param = new HashMap<>(); param.put("way","gm-R-b"); jenkinsServer.getJob("das-app-android-pkg").build(param, true); } catch (IOException e) { e.printStackTrace(); } }
public void stopLastJobBuild(){ try { Build build = jenkinsServer.getJob("test-job").getLastBuild(); build.Stop(); } catch (IOException e) { e.printStackTrace(); } }
public void deleteJob(){ try { jenkinsServer.deleteJob("test-job", true); } catch (IOException e) { e.printStackTrace(); } }
public void disableJob(){ try { jenkinsServer.disableJob("test-job", true); } catch (IOException e) { e.printStackTrace(); } }
public void enableJob(){ try { jenkinsServer.enableJob("test-job", true); } catch (IOException e) { e.printStackTrace(); } } public static void main(String[] args) { JobApi jobApi = new JobApi();
jobApi.buildParamJob();
} }
|