网易首页 > 网易号 > 正文 申请入驻

Jenkins藏了8年的免费API,80%的人只会点鼠标

0
分享至


全球超过100万台服务器在跑的Jenkins,多数人只用过它的Web界面。那个藏在地址栏里的/api/json,很多人部署三年都没碰过。

REST API(应用程序编程接口)是Jenkins最被低估的功能。触发构建、查状态、管插件、建任务、搭自定义仪表盘——全都能用HTTP请求搞定。不用装额外插件,开箱即用。

本文用代码说话。从curl到Python封装,再到一个能跑的健康度仪表盘,帮你把Jenkins从"鼠标密集型"工具变成可编程的基础设施。

第一步:拿到入场券

调用API需要两样东西:用户令牌和正确的认证头。在Jenkins用户设置里生成API Token,然后塞进环境变量:

export JENKINS_URL="http://localhost:8080"
export JENKINS_USER="admin"
export JENKINS_TOKEN="your-api-token"

认证方式选Basic Auth,用户名拼令牌当密码。curl里用-u参数,Python的requests库直接传元组。

先探探家底,看看Jenkins在跑什么:

curl -s -u "$JENKINS_USER:$JENKINS_TOKEN" \
"$JENKINS_URL/api/json" | jq \
'{mode: .mode, numExecutors: .numExecutors, jobs: [.jobs[] | {name: .name, color: .color}]}'

返回的JSON里,color字段就是状态:blue是成功,red是失败,aborted是手动终止。这个设计挺复古,但一眼能看懂。

触发构建更简单,POST过去就行:

curl -s -u "$JENKINS_USER:$JENKINS_TOKEN" -X POST \
"$JENKINS_URL/job/my-project/build"

带参数的构建用buildWithParameters端点,参数直接拼URL:


curl -s -u "$JENKINS_USER:$JENKINS_TOKEN" -X POST \
"$JENKINS_URL/job/deploy/buildWithParameters?ENVIRONMENT=staging&VERSION=2.1.0"

注意这里用了&转义,实际写代码时换成&。Jenkins对参数顺序不敏感,但大小写敏感。

第二步:封装成能复用的Python类

curl适合一次性操作,要集成到工作流还得上代码。下面这个JenkinsClient类覆盖了日常80%的需求:

class JenkinsClient:
def __init__(self, url, user, token):
self.url = url
self.auth = (user, token)

初始化只存两个东西:根地址和认证元组。requests库会自动处理Basic Auth的Base64编码,不用手动算。

查任务列表用get_jobs(),返回的是个字典数组。每个任务有name、url、color三个核心字段:

def get_jobs(self):
resp = requests.get(f"{self.url}/api/json", auth=self.auth)
return resp.json()['jobs']

构建信息要分层查。先拿到任务,再点进具体构建号。lastBuild是个虚拟编号,永远指向最新一次:

def get_build_info(self, job, build_number):
resp = requests.get(f"{self.url}/job/{job}/{build_number}/api/json", auth=self.auth)
return resp.json()

触发构建分有无参数两种情况。有参数走buildWithParameters,用params字典传;无参数直接POST到/build:

def trigger_build(self, job, parameters=None):
if parameters:
resp = requests.post(f"{self.url}/job/{job}/buildWithParameters", params=parameters, auth=self.auth)
else:
resp = requests.post(f"{self.url}/job/{job}/build", auth=self.auth)
return resp.status_code in (200, 201)

状态码201表示构建已入队,200是立即执行。实际两者都算成功,队列深度取决于你的Executor数量。


最实用的是wait_for_build()。触发后轮询状态,直到构建完成或超时。默认5秒查一次,300秒封顶:

def wait_for_build(self, job, build_number=None, timeout=300):
if not build_number:
time.sleep(3)
build_number = self.get_last_build(job)['number']
start = time.time()
while time.time() - start < timeout:
info = self.get_build_info(job, build_number)
if not info.get('building', True):
return info
time.sleep(5)
raise TimeoutError(f"Build {build_number} timed out")

这个轮询逻辑可以优化。Jenkins支持Webhook回调,但配置门槛高。对于大多数内部CI场景,轮询够用了。

第三步:搭一个健康度仪表盘

有了封装好的客户端,可以干点Web界面做不到的事。比如一个纯文本的健康度报告,扔给企业微信或钉钉机器人:

jenkins = JenkinsClient('http://localhost:8080', 'admin', 'your-token')
for job in jenkins.get_jobs():
status = 'PASS' if job['color'] == 'blue' else 'FAIL' if 'red' in job['color'] else job['color']
print(f"{status:6s} | {job['name']}")

输出长这样:

PASS | backend-service
FAIL | frontend-build
aborted | legacy-migration

颜色转状态用了个嵌套三元表达式,不够Pythonic但够短。实际生产建议用枚举类,方便扩展。

完整部署流程可以串起来:触发、等待、拿结果、发通知。五行代码搞定:

jenkins.trigger_build('deploy', {'ENVIRONMENT': 'staging', 'VERSION': '2.1.0'})
result = jenkins.wait_for_build('deploy')
print(f"Build #{result['number']}: {result['result']}")

result['result']只有四种值:SUCCESS、FAILURE、ABORTED、UNSTABLE。UNSTABLE通常是测试通过但有警告,比如覆盖率不达标。

想再进一步,可以抓控制台日志做失败分析。get_console_output()返回纯文本,正则匹配"ERROR"或"FAILURE"关键字,自动归类失败原因。这比打开浏览器翻几百行日志快多了。

Jenkins的API设计不算现代,端点命名混乱、文档散落在各插件页面。但它稳定,8年前的脚本今天还能跑。对于已经重度依赖Jenkins的团队,与其折腾迁移,不如把API用透。

你的CI/CD流水线有多少环节还在手动点鼠标?第一个能自动化的,会是什么?

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
1992 年,叶利钦将苏联最后的核心军事遗产交付中国

1992 年,叶利钦将苏联最后的核心军事遗产交付中国

磊子讲史
2026-03-30 17:06:41
公安部亮剑!2026民生乱象零容忍,再不整治普通人寸步难行

公安部亮剑!2026民生乱象零容忍,再不整治普通人寸步难行

叮当当科技
2026-04-01 05:43:23
比尔盖茨:下一代发电技术已经近在眼前

比尔盖茨:下一代发电技术已经近在眼前

快科技
2026-03-31 13:33:19
1万美军斩断大动脉!德黑兰面临亡国,伊朗强硬派:敢来都别活!

1万美军斩断大动脉!德黑兰面临亡国,伊朗强硬派:敢来都别活!

兴史兴谈
2026-03-31 11:15:00
虞莉清被取消享受的待遇,曾主动交代问题

虞莉清被取消享受的待遇,曾主动交代问题

观察者网
2026-03-31 21:36:05
直到看见蒋万安给儿子们起的名字,就知道他骨子里的身份瞒不住

直到看见蒋万安给儿子们起的名字,就知道他骨子里的身份瞒不住

历史人文2
2026-02-23 10:29:02
蔡正元入狱第三天,大陆正式发布公告,信号明确,郑丽文或成功臣

蔡正元入狱第三天,大陆正式发布公告,信号明确,郑丽文或成功臣

沧海旅行家
2026-03-31 14:21:27
2-4,中国男足下半场丢4球,无缘双杀澳大利亚,杨铭锐双响难救主

2-4,中国男足下半场丢4球,无缘双杀澳大利亚,杨铭锐双响难救主

侧身凌空斩
2026-03-31 21:29:32
5-0!阿根廷5连胜:梅西破门 主动让点球 38岁老将洒泪告别

5-0!阿根廷5连胜:梅西破门 主动让点球 38岁老将洒泪告别

叶青足球世界
2026-04-01 09:33:53
社保缴费新规:需经员工本人签字确认!

社保缴费新规:需经员工本人签字确认!

新浪财经
2026-03-31 13:04:28
好可怕!40岁中年男人就有老人味吗,差一点吐了,网友发帖引热议

好可怕!40岁中年男人就有老人味吗,差一点吐了,网友发帖引热议

火山詩话
2026-03-30 07:38:38
张本智和怒了:我是自愿退出中国籍去日本,凭啥让我滚出四川?

张本智和怒了:我是自愿退出中国籍去日本,凭啥让我滚出四川?

拳击时空
2026-04-01 03:28:41
普京三个月几乎不出莫斯科,露面骤减,背后压力浮出水面

普京三个月几乎不出莫斯科,露面骤减,背后压力浮出水面

桂系007
2026-03-31 23:57:09
人民日报评张雪机车夺冠

人民日报评张雪机车夺冠

澎湃新闻
2026-03-31 11:05:13
45岁男子突发心梗离世!两天前还在跑马拉松,家属:他生活习惯好

45岁男子突发心梗离世!两天前还在跑马拉松,家属:他生活习惯好

马拉松跑步健身
2026-03-30 06:30:08
澳门世界杯捷报:男单爆大冷!国乒首败,日本冠军松岛辉空剃光头

澳门世界杯捷报:男单爆大冷!国乒首败,日本冠军松岛辉空剃光头

吴蛛旅行ing
2026-04-01 05:33:43
美媒:特朗普已无法恢复政治地位,他的总统任期在实质上已经结束

美媒:特朗普已无法恢复政治地位,他的总统任期在实质上已经结束

青烟小先生
2026-03-31 10:19:42
商业航天90%都是炒概念,真正有实锤订单的仅这8家

商业航天90%都是炒概念,真正有实锤订单的仅这8家

风风顺
2026-04-01 07:23:08
不打伊朗了?特朗普通告全世界,战争费由22国承担,一共5万亿

不打伊朗了?特朗普通告全世界,战争费由22国承担,一共5万亿

知法而形
2026-03-31 18:13:14
梅西让点!奥塔门迪主场告别战破门,长久亲吻队徽,阿尔马达造点

梅西让点!奥塔门迪主场告别战破门,长久亲吻队徽,阿尔马达造点

奥拜尔
2026-04-01 08:54:22
2026-04-01 12:24:49
碳基打工人
碳基打工人
坐标北京,靠咖啡续命,靠小红书下饭的普通人类。
643文章数 4关注度
往期回顾 全部

科技要闻

营收翻倍、巨亏31亿!中国大模型太烧钱了

头条要闻

牛弹琴:战争开始烂尾 特朗普要跑了以色列目瞪口呆

头条要闻

牛弹琴:战争开始烂尾 特朗普要跑了以色列目瞪口呆

体育要闻

美加墨梦碎!意大利连续三届无缘世界杯

娱乐要闻

宋宁峰人设崩塌!带娃偷情+反向索赔

财经要闻

电商售械三水光针 机构倒货or假货猖獗?

汽车要闻

2026年3月小米汽车交付超2万台 新SU7上市即交付

态度原创

时尚
教育
本地
数码
游戏

“灰色阔腿裤"今年春天火爆了,怎么搭都时髦高级!

教育要闻

以爱为舟渡学海,以智为帆引航程——刘洪雨家教好故事

本地新闻

春日吃花第五期——江西

数码要闻

有线耳机穿搭火了 手机未必配合拒绝回旋镖

魔兽世界:60版本最抢手的极品饰品,你觉得哪款最恐怖如斯?

无障碍浏览 进入关怀版