当前位置: 首页 > article >正文

Jenkins Pipeline 脚本踩坑记:我是如何被两种语法折磨并最终选择的

最近在折腾公司的 CI/CD 流水线想把原来那套老掉牙的构建脚本升级一下。本以为 Jenkins Pipeline 挺简单的结果一上手就懵了——竟然有两种写法这不是逼死选择困难症吗我当时的内心OS这玩意儿就像去饭店点菜服务员问你要清汤还是麻辣的你以为选完就完事了结果又问你要不要加香菜、要不要加醋… 选择太多反而不知道怎么选了。Pipeline 的两种口味Jenkins Pipeline 主要有两种写法Declarative Pipeline声明式流水线和 Scripted Pipeline脚本式流水线。Declarative Pipeline 就像是傻瓜相机你只需要按快门就行其他的都帮你调好了。它用的是一种 DSLDomain Specific Language说白了就是专门为 Pipeline 设计的语言。整个 Pipeline 必须包在pipeline块里面然后用stages和steps来组织你的构建步骤。而 Scripted Pipeline 呢更像是单反相机功能强大但你得自己调参数。它直接用的是 Groovy 语言灵活性爆表但也意味着你得有点 Groovy 基础。整个脚本是在node块里执行的[4]。我的踩坑之旅第一坑语法差异刚开始我用的是 Declarative Pipeline写起来确实简单pipeline{agent any stages{stage(Build){steps{echoBuilding...}}}}看着挺清爽的对吧结构一目了然。后来有个需求需要在构建过程中动态判断一些条件我就想着用 if-else。结果发现 Declarative Pipeline 里不能直接写 if 语句你得用when指令stage(Deploy){when{branchmaster}steps{echoDeploying to production...}}这时候我就想要不试试 Scripted Pipeline切换过去一看node{stage(Build){echoBuilding...if(env.BRANCH_NAMEmaster){echoThis is master branch}}}嘿这下自由了想怎么写就怎么写。但问题又来了…第二坑错误处理Declarative Pipeline 的错误处理特别规范有专门的post块pipeline{agent any stages{stage(Test){steps{shmake test}}}post{always{echoThis will always run}success{echoOnly on success}failure{echoOnly on failuremail to:teamexample.com,subject:Build Failed}}}但在 Scripted Pipeline 里你得自己写 try-catchnode{try{stage(Test){shmake test}echoSuccess!}catch(e){echoFailed!throwe}finally{echoCleanup}}说实话写多了 try-catch 真的很烦。有一次我忘了写 finally 块结果构建失败后一些临时文件没清理磁盘差点爆了。第三坑并行执行这个是我觉得两种 Pipeline 差异最大的地方。Declarative Pipeline 的并行执行写法很直观pipeline{agent any stages{stage(Parallel Stage){parallel{stage(Unit Tests){steps{echoRunning unit tests...}}stage(Integration Tests){steps{echoRunning integration tests...}}}}}}而 Scripted Pipeline 的写法… 说实话第一次看到我是懵的node{stage(Parallel Stage){parallel(Unit Tests:{echoRunning unit tests...},Integration Tests:{echoRunning integration tests...})}}这种 Map 的写法不知道为啥总让我想起 JavaScript 的对象字面量。实战经验分享经过这么多坑我总结了一些实战经验。如果你的项目比较简单构建流程相对固定强烈建议用 Declarative Pipeline。为啥因为它语法检查更严格写错了立马报错结构清晰新人上手快自带很多实用功能比如options、parameters、triggers等[3]我们有个前端项目就是用的 Declarativepipeline{agent{docker{imagenode:14-alpine}}options{timeout(time:30,unit:MINUTES)buildDiscarder(logRotator(numToKeepStr:10))}parameters{choice(name:ENVIRONMENT,choices:[dev,test,prod],description:Deploy environment)}stages{stage(Install){steps{shnpm ci}}stage(Build){steps{shnpm run build:${params.ENVIRONMENT}}}stage(Deploy){when{expression{params.ENVIRONMENTprod}}steps{input message:Deploy to production?sh./deploy.sh}}}}但如果你的构建逻辑很复杂需要大量的条件判断、循环处理或者要调用很多 Groovy 的高级特性那 Scripted Pipeline 可能更合适。我们有个数据处理的项目需要根据不同的数据源动态生成构建步骤node{defdataSources[mysql,postgres,mongodb]defstages[:]dataSources.each{source-stages[Process${source}]{stage(Process${source}){echoProcessing${source}data...defconfigreadJSON file:${source}.jsonconfig.tables.each{table-shpython process.py --source${source}--table${table}}}}}parallel stages}这种动态生成 stage 的需求用 Declarative 就很难实现了。性能和维护性对比从性能角度看两者其实差不多。Jenkins 最终都会把它们转换成同样的执行逻辑。但从维护性来说Declarative Pipeline 胜出太多了。我们团队之前有个项目用的 Scripted Pipeline写得那叫一个自由奔放。后来换了个人维护看着那些嵌套的闭包和各种 Groovy 黑魔法直接崩溃了。最后花了一周时间重写成 Declarative 的。我的最终选择折腾了这么久我的选择是能用 Declarative 就用 Declarative实在不行再用 Scripted。为啥因为大部分场景下Declarative Pipeline 真的够用了。而且 Jenkins 官方也推荐优先使用 Declarative。它的限制反而是优点能让团队的 Pipeline 风格保持一致。当然如果你遇到这些情况可能真的需要 Scripted Pipeline需要复杂的流程控制逻辑要动态生成大量的 stages需要使用 Groovy 的高级特性要集成一些特殊的 Jenkins 插件一些实用技巧不管用哪种 Pipeline这些技巧都很有用使用共享库把通用的逻辑抽取到共享库里避免重复代码参数化构建灵活使用 parameters让 Pipeline 更通用合理使用 agent不同的 stage 可以用不同的 agent提高资源利用率做好错误处理该 catch 的要 catch该重试的要重试日志要清晰多用 echo 输出关键信息方便排查问题总结Jenkins Pipeline 的两种写法各有千秋。Declarative Pipeline 像是给你画好了框你只需要往里面填东西Scripted Pipeline 则是给你一张白纸你想怎么画就怎么画。我的建议是如果你刚接触 Jenkins Pipeline从 Declarative 开始。等你熟悉了再根据实际需求决定是否需要 Scripted 的灵活性。记住工具是为了解决问题的不要为了炫技而选择复杂的方案。最后不管选择哪种记得多写注释相信我三个月后的你会感谢现在的自己的。如果这篇文章对你有帮助欢迎关注运维躬行录我会持续分享更多运维实战经验。遇到 Pipeline 的坑也欢迎留言交流说不定我也踩过呢公众号运维躬行录个人博客躬行笔记

相关文章:

Jenkins Pipeline 脚本踩坑记:我是如何被两种语法折磨并最终选择的

最近在折腾公司的 CI/CD 流水线,想把原来那套老掉牙的构建脚本升级一下。本以为 Jenkins Pipeline 挺简单的,结果一上手就懵了——竟然有两种写法!这不是逼死选择困难症吗? 我当时的内心OS:这玩意儿就像去饭店点菜&am…...

【26最新大英赛】全国大学生英语竞赛高频核心词汇表pdf电子版(考前必背单词)

2026年全国大学生英语竞赛将于4月12日举行,倒计时6天!帮助广大考生高效备考,小编精心整理了最新的大英赛核心词汇,PDF电子版,可下载打印! 资料下载: 资料下载https://pan.quark.cn/s/13eaf6fb0…...

Rust内存管理与安全:告别内存泄漏和空指针

Rust内存管理与安全:告别内存泄漏和空指针 后端转 Rust 的萌新,ID "第一程序员"——名字大,人很菜(暂时)。正在跟所有权和生命周期死磕,日常记录 Rust 学习路上的踩坑经验和"啊哈时刻"…...

嵌入式Linux无线服务器搭建指南

1. 项目概述在嵌入式Linux开发中,传统的有线网络连接方式往往限制了设备的灵活性和部署便捷性。作为一名嵌入式开发者,我最近成功在S3C2410开发板上实现了基于WiFi模块的无线服务器搭建,彻底摆脱了网线的束缚。这套方案不仅适用于智能家居控制…...

从单机到网络存储:用Windows Server自带的iSCSI功能,5分钟为你的测试机挂载个‘云硬盘’

从单机到网络存储:5分钟用Windows Server打造高效iSCSI共享空间 在软件开发与测试工作中,我们经常遇到需要快速共享存储空间的场景。无论是团队协作开发、自动化测试日志收集,还是临时搭建的演示环境,一个灵活高效的网络存储解决方…...

嵌入式调试技巧:使用串口、J-Link 定位 Bug 效率翻倍

在嵌入式软件开发领域,有一句广为流传的话:“写代码只占20%的时间,调试占了80%。”虽然这个比例因人而异,但调试确实是整个开发流程中最不可预测、最消耗精力的环节。当一个程序在硬件上“跑飞”了,或者某个外设莫名其…...

OpenClaw+Phi-3-mini-128k-instruct:自动化技术面试题库更新系统

OpenClawPhi-3-mini-128k-instruct:自动化技术面试题库更新系统 1. 为什么需要自动化题库更新 作为一名技术面试官转行的开发者,我深知保持题库时效性的痛苦。去年帮朋友准备面试时,发现他还在刷2018年的LeetCode老题,而新出现的…...

MacBook上运行OpenClaw:轻量级部署Kimi-VL-A3B-Thinking图文模型

MacBook上运行OpenClaw:轻量级部署Kimi-VL-A3B-Thinking图文模型 1. 为什么选择MacBook部署OpenClaw 作为一个长期在MacBook Pro上折腾AI工具的开发者,我一直在寻找能在本地流畅运行的多模态模型方案。直到遇到Kimi-VL-A3B-Thinking这个镜像&#xff0…...

Unity游戏开发:用Obi Softbody插件5分钟搞定角色手臂的弹性软体效果

Unity游戏开发:5分钟实现角色手臂弹性软体效果的高效方案 在风格化游戏角色设计中,弹性软体效果能为生物角色增添生动的物理质感。想象一个卡通章鱼角色的触须自然摆动,或是奇幻生物柔软触角对环境的真实反应——这些效果过去需要复杂的物理编…...

别再只盯着report_timing了!DC综合后,用report_constraint -all_violation全面排查时序与DRC违规(附实战解读)

别再只盯着report_timing了!DC综合后全面排查时序与DRC违规的实战指南 在数字IC设计流程中,Design Compiler(DC)综合后的时序分析环节往往让工程师们又爱又恨。面对密密麻麻的违规报告,新手工程师常陷入两个极端&#…...

从CAN到UAVCAN:一文搞懂两种协议的核心差异及迁移指南

从CAN到UAVCAN:两种通信协议的深度解析与迁移实战 在嵌入式系统开发领域,CAN总线协议已经服务了汽车电子和工业控制三十余年,而它的进化版本UAVCAN正在无人机和机器人领域掀起一场通信革命。当我第一次在四旋翼飞行器项目中尝试将传统CAN节点…...

好消息!内存条开始降价了,价格能否回到2025年年初价?

今天又开始因为各种原因在电脑上折腾大模型了,但是发现一件很可怕的事情:16GB的内存真的不够用。 哈哈哈哈……这个Windows电脑因为有很长一段时间没有使用,所以在粉丝需要的时候,直接把一对16GB的内存条拆出来卖了,后…...

Flowable任务超时监控与自动化处理实战

1. 为什么需要Flowable任务超时监控? 在实际业务流程中,任务超时是个常见但容易被忽视的问题。想象一下,你提交了一个采购审批流程,但审批人迟迟没有处理,导致整个采购计划被耽误。这种情况在企业内部每天都在发生&…...

微元理论的数学化演算

一、理论思想总结(一段式,完全还原你最新表述)本理论借用希格斯标量场解释统标量场为宇宙唯一本源,在微观尺度下,标量场中两个无质量特性的标量子,当其间距大于普朗克作用量 h 所界定的临界尺度时&#xff…...

SAP ABAP老系统也能玩转REST API?手把手教你用SICF和IF_HTTP_EXTENSION打通接口

SAP ABAP老系统也能玩转REST API?手把手教你用SICF和IF_HTTP_EXTENSION打通接口 在数字化转型浪潮中,许多企业仍运行着历史悠久的SAP ABAP系统。这些系统承载着核心业务逻辑,却常因技术栈陈旧而难以与现代应用生态对接。本文将揭示如何利用AB…...

用SDNET2018和Crack500数据集训练YOLOv8,手把手教你搞定混凝土裂缝检测模型

基于SDNET2018与Crack500的YOLOv8裂缝检测实战指南 混凝土结构的安全评估中,裂缝检测是关键环节。传统人工巡检效率低下且易漏检,而基于深度学习的自动化方案能显著提升检测精度与效率。本文将手把手带您完成从数据集处理到模型部署的全流程,…...

OpenClaw文件管理:Qwen3-4B驱动的智能归类与重命名

OpenClaw文件管理:Qwen3-4B驱动的智能归类与重命名 1. 为什么需要智能文件管理 每次打开电脑,看到满屏杂乱无章的下载文件夹,我的强迫症都要发作一次。从项目文档、会议录音到临时截图,所有文件都堆在同一个目录下,找…...

跨平台协作:Windows主机OpenClaw调用mac部署的Qwen3.5-9B

跨平台协作:Windows主机OpenClaw调用mac部署的Qwen3.5-9B 1. 为什么需要跨设备调用大模型? 去年我遇到一个典型困境:主力开发机是Windows台式机,但需要频繁调用大模型处理代码生成和文档分析。直接在Windows本地部署Qwen3.5-9B这…...

掌握Rustaceanvim工作区管理:符号搜索、模块导航和依赖分析全攻略

掌握Rustaceanvim工作区管理:符号搜索、模块导航和依赖分析全攻略 【免费下载链接】rustaceanvim 🦀 Supercharge your Rust experience in Neovim! A heavily modified fork of rust-tools.nvim 项目地址: https://gitcode.com/gh_mirrors/ru/rustace…...

Python中正则表达式详解——从入门到精通,这一篇就够了!

目录 一、正则表达式是什么? 1.1 一个生活化的理解 1.2 正则表达式能做什么? 1.3 开始前的准备 二、正则表达式基础语法 2.1 元字符详解 2.2 预定义字符集(简化写法) 2.3 理解“贪婪”与“非贪婪” 三、re模块常用函数 …...

C++的std--ranges适配器视图迭代器有效性保证与悬垂引用检测

C20引入的std::ranges库彻底改变了序列操作的范式,其中适配器视图(如filter、transform)通过惰性求值实现了高效的管道式编程。这种延迟执行特性也带来了迭代器有效性风险——视图可能持有悬垂引用或失效迭代器,导致未定义行为。本…...

sveltekit-superforms 终极指南:如何在 SvelteKit 中构建完美表单体验

sveltekit-superforms 终极指南:如何在 SvelteKit 中构建完美表单体验 【免费下载链接】sveltekit-superforms Making SvelteKit forms a pleasure to use! 项目地址: https://gitcode.com/gh_mirrors/sv/sveltekit-superforms 想要在 SvelteKit 应用中快速构…...

如何安装Dr. Memory:Windows、Linux、Mac完整安装教程

如何安装Dr. Memory:Windows、Linux、Mac完整安装教程 【免费下载链接】drmemory Memory Debugger for Windows, Linux, Mac, and Android 项目地址: https://gitcode.com/gh_mirrors/dr/drmemory Dr. Memory是一款功能强大的内存调试工具,能够检…...

快速上手klein.php:PHP轻量级路由器的完整入门指南

快速上手klein.php:PHP轻量级路由器的完整入门指南 【免费下载链接】klein.php A fast & flexible router 项目地址: https://gitcode.com/gh_mirrors/kl/klein.php klein.php是一款快速灵活的PHP路由器,专为简化Web应用的路由管理而设计。作…...

Tide静态文件服务终极指南:快速实现高效文件处理方案

Tide静态文件服务终极指南:快速实现高效文件处理方案 【免费下载链接】tide Fast and friendly HTTP server framework for async Rust 项目地址: https://gitcode.com/gh_mirrors/ti/tide Tide是一个为异步Rust打造的快速友好的HTTP服务器框架,提…...

终极指南:使用eksctl Karpenter支持实现AWS EKS集群智能节点调度和成本优化

终极指南:使用eksctl Karpenter支持实现AWS EKS集群智能节点调度和成本优化 【免费下载链接】eksctl The official CLI for Amazon EKS 项目地址: https://gitcode.com/gh_mirrors/ek/eksctl eksctl作为Amazon EKS的官方命令行工具,提供了强大的K…...

麦科奥特冲刺港股:年亏损1.85亿 估值26亿

雷递网 雷建平 4月5日陕西麦科奥特医药科技股份有限公司(简称“麦科奥特”)日前更新招股书,准备在港交所上市。麦科奥特2025年9月26日完成2.36亿元,投后估值为26.36亿元。年亏损1.85亿麦科奥特成立于2007年,是一家平台…...

OpenClaw+千问3.5-9B:社交媒体内容自动生成与发布

OpenClaw千问3.5-9B:社交媒体内容自动生成与发布 1. 为什么需要自动化社交媒体运营 作为一个独立开发者兼技术博主,我每天需要维护多个社交媒体账号的内容更新。从选题构思、内容创作到排版发布,整个过程耗时耗力。最痛苦的是灵感枯竭时&am…...

机器学习模型测试与验证终极指南:Have Fun with Machine Learning质量控制方法详解

机器学习模型测试与验证终极指南:Have Fun with Machine Learning质量控制方法详解 【免费下载链接】have-fun-with-machine-learning An absolute beginners guide to Machine Learning and Image Classification with Neural Networks 项目地址: https://gitcod…...

MVP.css vs 其他CSS框架:哪个才是快速原型开发的终极选择?

MVP.css vs 其他CSS框架:哪个才是快速原型开发的终极选择? 【免费下载链接】mvp MVP.css — Minimalist classless CSS stylesheet for HTML elements 项目地址: https://gitcode.com/gh_mirrors/mv/mvp GitHub 加速计划 / mv / mvp 项目中的 MVP…...