
写在前面
好久不见~最近状态稍缓,更新也慢了些,这篇文章同样让大家等了挺久,先跟大家说声抱歉。
如果你认真读了前面几篇,还跟着实践了,那到这里,咱们就要正式开启真正的 “进阶阶段” 啦!
确实,大多数公司内部的 Jenkins Shared Library 不只是简单的“封装几个 stage”而已,它们往往包含:
- workspace 清理机制(避免磁盘爆满)
- 缓存/依赖重用逻辑
- 多分支/多环境配置
- 动态参数和条件逻辑
- 流水线钩子(pre/post hooks)
- 高级通知系统(Slack、邮件、飞书、Teams)
下面,我们可以一起写一个更“企业级”的案例,会让你看懂为什么公司那套 Shared Library 那么复杂了。
目标:构建一个带 workspace 清理、缓存管理、错误恢复、通知系统的可复用 CI Pipeline。
一、项目结构
jenkins-shared-lib-enterprise/ ├── vars/ │ ├── enterprisePipeline.groovy # 主入口 Pipeline │ ├── workspaceManager.groovy # 清理与准备工作区 │ ├── notifyManager.groovy # 通知模块 │ ├── gitHelper.groovy # Git 拉取与分支操作 ├── src/org/company/ │ ├── Utils.groovy # 工具类(时间戳、日志、重试等) │ └── ConfigLoader.groovy # YAML/JSON 配置读取器 └── resources/templates/ └── notifyTemplate.txt
二、清理函数
📄 vars/cleanWorkspace.groovy
def call(Map config = [:]) { def cleanBeforeBuild = config.get('clean', true) def keepPatterns = config.get('keep', ['.git', '.gradle']) if (!cleanBeforeBuild) { echo "⏭️ Skipping workspace cleanup." echo "✅ Workspace ready at: ${pwd()}" return } echo "🧹 Cleaning workspace, preserving: ${keepPatterns}" def os = getOS() if (os == 'Windows') { cleanWindows(keepPatterns) } else { cleanUnix(keepPatterns) } echo "✅ Workspace ready at: ${pwd()}" } // 判断操作系统 private String getOS() { def osName = System.getProperty('os.name').toLowerCase() return osName.contains('windows') ? 'Windows' : 'Unix' } // Unix/Linux/macOS 清理方式 private void cleanUnix(List keepPatterns) { def patternStr = keepPatterns.join('|') sh """ echo "Running on Unix/Linux..." ls -A1 | grep -v -E '^(${patternStr})$' | xargs rm -rf || true """ } // Windows 清理方式(使用 cmd 或 PowerShell) private void cleanWindows(List keepPatterns) { // 转成小写用于比较 def keepSet = keepPatterns.collect { it.toLowerCase() } as Set // 获取当前目录下所有文件/目录(包括隐藏) def files = new File(pwd()).listFiles() if (!files) return files.each { file -> def name = file.name.toLowerCase() if (!keepSet.contains(name)) { echo "🗑️ Deleting: ${file.name}" deleteFileOrDir(file) } } } // 安全删除文件或目录(递归) private void deleteFileOrDir(File file) { try { if (file.directory) { file.deleteDir() // 递归删除目录 } else { file.delete() } } catch (Exception e) { echo "⚠️ Failed to delete ${file.name}: ${e.message}" } }
功能说明:
-
默认在每次构建前清理工作区(但保留
.git、.gradle等缓存目录) -
公司里这样做是为了避免:
- Jenkins 节点磁盘爆满
- 前次构建残留文件导致构建异常
Jenkinsfile 调用方式
@Library('my-shared-lib') _ pipeline { agent any stages { stage('Cleanup') { steps { script { cleanWorkspace( clean: true, keep: ['.git', '.gradle', 'settings.gradle'] ) } } } // ... 其他阶段 } }
运行后,你会在控制台输出看到:

三、通知模块
📄 vars/notifyManager.groovy
def call(Map args = [:]) { def status = args.status ?: 'SUCCESS' def message = args.message ?: "Build completed." def color = status == 'SUCCESS' ? 'good' : (status == 'FAILURE' ? 'danger' : 'warning') def project = env.JOB_NAME def buildUrl = env.BUILD_URL def fullMessage = """ [${status}] ${project} ${message} 👉 ${buildUrl} """ echo "🔔 Notify: ${fullMessage.trim()}" }
Jenkinsfile 调用方式
@Library('my-shared-lib') _ pipeline { agent any // 可以是 linux、windows、docker 等 stages { stage('Cleanup') { steps { script { notifyManager( status: 'SUCCESS', message: 'Build completed.' ) } } } // ... 其他阶段 } }
运行后,你会在控制台输出看到:

四、Git 操作封装
📄 vars/gitHelper.groovy
// vars/gitCheckout.groovy def call(Map config = [:]) { def repo = config.repo def branch = config.get('branch', 'main') def credentialsId = config.get('credentialsId', 'git-credentials') if (!repo) { error "❌ gitCheckout: 'repo' parameter is required!" } echo "🔁 Checking out ${repo} (branch: ${branch})" checkout([ $class: 'GitSCM', branches: [[name: branch]], userRemoteConfigs: [[ url: repo, credentialsId: credentialsId ]] ]) }
Jenkinsfile 调用方式
@Library('my-shared-lib') _ pipeline { agent any options { skipDefaultCheckout() // 👈 关键!跳过默认的 SCM 步骤 } parameters { string(name: 'GIT_REPO', defaultValue: 'your giturl', description: 'Git repository URL') string(name: 'GIT_BRANCH', defaultValue: 'master', description: 'Branch to build') } stages { stage('Checkout Code') { steps { script { def repo = params.GIT_REPO def branch = params.GIT_BRANCH echo "🔁 开始拉取代码:${repo} (分支:${branch})" // 调用 vars/gitHelper.groovy gitHelper( repo: repo, branch: branch, credentialsId: 'gitee-credentials' // 替换为你的实际凭据 ID ) } } } stage('Debug') { steps { echo "📦 当前路径:${pwd()}" bat 'git branch -a' bat 'git log --oneline -5' } } } post { failure { echo "❌ 构建失败!" } } }
运行后,你会在控制台输出看到:

五、核心 Pipeline
📄 vars/enterprisePipeline.groovy
import com.company.Utils def call(Map config = [:], Closure customStages = null) { echo "repo: ${config.repo}, branch: ${config.branch}" // 初始化 Utils.printHeader(this, "Initializing Pipeline") cleanWorkspace([clean: true, keep: ['.git']]) gitHelper([repo: config.repo, branch: config.branch]) // 构建 Utils.printHeader(this, "Build Stage") try { bat config.buildCommand ?: 'mvn clean package -DskipTests' } catch (err) { notifyManager([status: 'FAILURE', message: "Build failed: ${err.message}"]) error("Build failed.") } // 测试 Utils.printHeader(this, "Test Stage") try { bat config.testCommand ?: 'mvn compile test' } catch (err) { notifyManager([status: 'FAILURE', message: "Tests failed: ${err.message}"]) error("Tests failed.") } // 自定义阶段 if (customStages != null) { Utils.printHeader(this, "Custom Stages") customStages() } // 部署 if (config.deploy == true) { Utils.printHeader(this, "Deploy Stage") // bat config.deployCommand ?: './deploy.sh' notifyManager([status: 'SUCCESS', message: "Deployed successfully!"]) } // 收尾 def result = currentBuild.result ?: 'SUCCESS' notifyManager([status: result, message: "Pipeline finished with status: ${result}"]) Utils.printHeader(this, "Cleaning workspace after build") cleanWorkspace([clean: true]) }
Jenkinsfile 调用方式
@Library('my-shared-lib') _ pipeline { agent any tools { maven 'maven' } parameters { string(name: 'REPO_URL', defaultValue: 'your giturl', description: 'Git仓库地址') string(name: 'BRANCH', defaultValue: 'master', description: '分支') } stages { stage('企业流水线') { steps { script { enterprisePipeline([ repo: params.REPO_URL, branch: params.BRANCH ]) } } } } }
运行后,你会在控制台输出看到:

写在最后
本文以 Maven 项目为示例,核心思路可迁移至其他语言项目,后续仍有扩展空间,感兴趣者可自行探索。
感谢你的认真阅读!若文章对你有价值,欢迎文末留言交流,也请帮忙点赞转发,谢谢支持!