共享库 #
共享库(Shared Library)是Jenkins提供的一种代码复用机制,可以将通用的Pipeline代码抽取出来,在多个Pipeline中共享使用。
为什么需要共享库? #
问题场景 #
- 多个Pipeline重复相同代码
- 维护困难,修改需要多处同步
- 代码质量难以保证
解决方案 #
共享库提供:
- 代码复用
- 集中维护
- 版本控制
- 统一标准
创建共享库 #
目录结构 #
text
shared-library/
├── vars/
│ ├── standardBuild.groovy
│ ├── deployToK8s.groovy
│ └── notifySlack.groovy
├── src/
│ └── org/
│ └── company/
│ ├── Constants.groovy
│ └── Utilities.groovy
└── resources/
└── templates/
└── deployment.yaml
目录说明 #
| 目录 | 说明 |
|---|---|
| vars/ | 全局变量/函数 |
| src/ | Groovy类库 |
| resources/ | 资源文件 |
配置共享库 #
全局配置 #
- 进入 Manage Jenkins → System
- 找到 Global Pipeline Libraries
- 添加共享库:
text
Name: my-shared-library
Default version: main
Retrieval method: Modern SCM
Git:
Repository URL: https://github.com/org/shared-library.git
Credentials: github-credentials
在Pipeline中使用 #
groovy
@Library('my-shared-library') _
pipeline {
agent any
stages {
stage('Build') {
steps {
standardBuild()
}
}
}
}
指定版本 #
groovy
@Library('my-shared-library@v1.0') _
@Library('my-shared-library@feature-branch') _
@Library('my-shared-library@abc123') _
动态加载 #
groovy
pipeline {
agent any
stages {
stage('Load Library') {
steps {
script {
library 'my-shared-library'
}
}
}
}
}
全局变量(vars/) #
简单函数 #
创建 vars/standardBuild.groovy:
groovy
def call() {
sh 'mvn clean package'
}
使用:
groovy
@Library('my-shared-library') _
pipeline {
agent any
stages {
stage('Build') {
steps {
standardBuild()
}
}
}
}
带参数函数 #
groovy
def call(String appName, String version = 'latest') {
echo "Building ${appName}:${version}"
sh "mvn clean package -Dapp.name=${appName} -Dapp.version=${version}"
}
使用:
groovy
standardBuild('myapp', '1.0.0')
standardBuild('myapp')
块参数 #
groovy
def call(Closure body) {
node {
stage('Setup') {
sh 'setup.sh'
}
body()
stage('Cleanup') {
sh 'cleanup.sh'
}
}
}
使用:
groovy
standardBuild {
sh 'mvn clean package'
}
配置参数 #
groovy
def call(Map config) {
def appName = config.appName ?: 'myapp'
def version = config.version ?: "${BUILD_NUMBER}"
def environment = config.environment ?: 'dev'
echo "Building ${appName}:${version} for ${environment}"
sh "mvn clean package -Dapp.name=${appName} -Dapp.version=${version}"
}
使用:
groovy
standardBuild(
appName: 'myapp',
version: '1.0.0',
environment: 'production'
)
完整示例 #
创建 vars/buildAndDeploy.groovy:
groovy
def call(Map config) {
def appName = config.appName ?: error("appName is required")
def version = config.version ?: "${BUILD_NUMBER}"
def environment = config.environment ?: 'dev'
def skipTests = config.skipTests ?: false
pipeline {
agent any
environment {
APP_NAME = "${appName}"
VERSION = "${version}"
ENVIRONMENT = "${environment}"
}
stages {
stage('Checkout') {
steps {
checkout scm
}
}
stage('Build') {
steps {
sh "mvn clean package ${skipTests ? '-DskipTests' : ''}"
}
}
stage('Test') {
when {
expression { !skipTests }
}
steps {
sh 'mvn test'
}
post {
always {
junit '**/target/surefire-reports/*.xml'
}
}
}
stage('Docker Build') {
steps {
sh "docker build -t ${appName}:${version} ."
}
}
stage('Deploy') {
steps {
sh "kubectl set image deployment/${appName} ${appName}=${appName}:${version} -n ${environment}"
}
}
}
post {
always {
cleanWs()
}
}
}
}
使用:
groovy
@Library('my-shared-library') _
buildAndDeploy(
appName: 'myapp',
version: '1.0.0',
environment: 'production',
skipTests: false
)
类库(src/) #
创建类 #
创建 src/org/company/Constants.groovy:
groovy
package org.company
class Constants {
static final String DOCKER_REGISTRY = 'registry.example.com'
static final String KUBERNETES_NAMESPACE = 'default'
static final Map ENVIRONMENTS = [
dev: [
namespace: 'dev',
replicas: 1
],
staging: [
namespace: 'staging',
replicas: 2
],
prod: [
namespace: 'production',
replicas: 3
]
]
}
创建 src/org/company/Utilities.groovy:
groovy
package org.company
class Utilities implements Serializable {
def steps
Utilities(steps) {
this.steps = steps
}
def buildDockerImage(String appName, String version) {
steps.sh "docker build -t ${appName}:${version} ."
}
def pushDockerImage(String appName, String version, String registry) {
steps.sh "docker tag ${appName}:${version} ${registry}/${appName}:${version}"
steps.sh "docker push ${registry}/${appName}:${version}"
}
def deployToK8s(String appName, String version, String namespace) {
steps.sh """
kubectl set image deployment/${appName} \
${appName}=${appName}:${version} \
-n ${namespace}
"""
}
}
使用类库 #
groovy
@Library('my-shared-library') _
import org.company.Constants
import org.company.Utilities
pipeline {
agent any
stages {
stage('Build') {
steps {
script {
def utils = new Utilities(this)
utils.buildDockerImage('myapp', "${BUILD_NUMBER}")
utils.pushDockerImage('myapp', "${BUILD_NUMBER}", Constants.DOCKER_REGISTRY)
}
}
}
stage('Deploy') {
steps {
script {
def utils = new Utilities(this)
def env = Constants.ENVIRONMENTS[params.ENVIRONMENT]
utils.deployToK8s('myapp', "${BUILD_NUMBER}", env.namespace)
}
}
}
}
}
资源文件(resources/) #
创建模板 #
创建 resources/templates/deployment.yaml:
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: ${APP_NAME}
namespace: ${NAMESPACE}
spec:
replicas: ${REPLICAS}
selector:
matchLabels:
app: ${APP_NAME}
template:
metadata:
labels:
app: ${APP_NAME}
spec:
containers:
- name: ${APP_NAME}
image: ${IMAGE}
ports:
- containerPort: 8080
使用资源文件 #
groovy
def call(Map config) {
def template = libraryResource 'templates/deployment.yaml'
def deployment = template
.replace('${APP_NAME}', config.appName)
.replace('${NAMESPACE}', config.namespace)
.replace('${REPLICAS}', config.replicas.toString())
.replace('${IMAGE}', "${config.registry}/${config.appName}:${config.version}")
writeFile file: 'deployment.yaml', text: deployment
sh 'kubectl apply -f deployment.yaml'
}
最佳实践 #
1. 版本控制 #
使用Git管理共享库,并使用标签管理版本。
2. 文档注释 #
groovy
/**
* 构建并部署应用
*
* @param appName 应用名称
* @param version 版本号
* @param environment 部署环境
* @param skipTests 是否跳过测试
*/
def call(Map config) {
}
3. 参数验证 #
groovy
def call(Map config) {
if (!config.appName) {
error "appName is required"
}
}
4. 错误处理 #
groovy
def call(Map config) {
try {
sh 'deploy.sh'
} catch (e) {
echo "Deployment failed: ${e.message}"
throw e
}
}
5. 单元测试 #
使用JenkinsPipelineUnit测试共享库:
groovy
class StandardBuildTest extends BasePipelineTest {
@Test
void testBuild() {
def script = loadScript('vars/standardBuild.groovy')
script.call()
printCallStack()
assertJobStatusSuccess()
}
}
完整示例 #
共享库结构 #
text
jenkins-shared-library/
├── vars/
│ ├── standardJavaBuild.groovy
│ ├── dockerBuild.groovy
│ ├── kubernetesDeploy.groovy
│ └── notify.groovy
├── src/
│ └── org/
│ └── company/
│ ├── Constants.groovy
│ └── Utilities.groovy
└── resources/
└── kubernetes/
├── deployment.yaml
└── service.yaml
使用示例 #
groovy
@Library('jenkins-shared-library@v1.0') _
standardJavaBuild(
appName: 'myapp',
environment: 'production',
skipTests: false
) {
dockerBuild(
registry: 'registry.example.com',
push: true
)
kubernetesDeploy(
namespace: 'production',
replicas: 3
)
notify(
slack: true,
email: true
)
}
下一步学习 #
小结 #
- 共享库实现代码复用
- vars/目录存放全局变量
- src/目录存放Groovy类
- resources/目录存放资源文件
- 使用版本控制管理共享库
- 遵循最佳实践提高代码质量
最后更新:2026-03-28