如何为Jenkins Pipelines编写可供其他var文件调用的公共代码
Jenkins共享库开发问题解答
认知正确性确认
你对vars/和src/目录的认知完全正确:
vars/目录下的Groovy文件会被注册为全局步骤,加载后可直接在Pipeline语法中调用,文件名即为调用时的步骤名src/目录为标准Groovy源码结构,需要先导入对应包和类、完成实例化后才能使用,通常用于封装通用逻辑,供vars/下的步骤调用
现有代码问题汇总
- 包名拼写错误:
src下类定义的包名写为com.mycomany.awsCommon,和导入时的com.mycompany.awsCommon拼写不一致 - 类使用逻辑错误:直接调用未实例化的普通类方法,且导入语句仅指向包名,未指定具体类
- 变量调用错误:类中定义的账号映射名为小写
accounts,调用时错写为大写Accounts,且Groovy类中使用不存在的self关键字,应使用this指代当前类实例 - 参数取值错误:取账号映射值的写法错误,正确写法为
accounts[config.account],而非self.Accounts([config.account]) - 注解冗余错误:
vars/下的步骤文件无需单独添加@Library注解,仅当跨共享库调用时才需要该配置 - 上下文缺失错误:
src下的类无法直接调用Jenkins Pipeline内置方法(如echo、sh、withCredentials等),需要传入Pipeline上下文对象才能调用
调整后代码示例
src/com/mycompany/awsCommon/AwsCommon.groovy(公共逻辑类)
#!/usr/bin/env groovy package com.mycompany.awsCommon class AwsCommon { // 存储Pipeline上下文,用于调用Jenkins内置步骤 private def pipeline def Map accounts = [ "dev": "123", "shared": "456" ] // 构造方法,实例化时传入Pipeline上下文 AwsCommon(def pipeline) { this.pipeline = pipeline } def String ecrAddress(Map config=[:]) { return "${accounts[config.account]}.dkr.ecr.eu-west-1.amazonaws.com/${config.name}" } def dockerLogin(String account) { switch(account) { case "shared": pipeline.echo 'login to Shared ECR' pipeline.withCredentials([pipeline.aws(credentialsId: 'jenkins-aws-shared')]){ pipeline.sh '$(aws ecr get-login --no-include-email --region eu-west-1)' } break case "dev": pipeline.echo 'login to Dev ECR' pipeline.withCredentials([pipeline.aws(credentialsId: 'jenkins-aws-dev')]){ pipeline.sh '$(aws ecr get-login --no-include-email --region eu-west-1)' } break } } }
vars/ECRPush.groovy(全局调用步骤)
import com.mycompany.awsCommon.AwsCommon def call(Map config=[:]) { // 实例化公共类,传入当前Pipeline上下文 def awsCommon = new AwsCommon(this) awsCommon.dockerLogin(config.account) def ecrAddress = "${awsCommon.ecrAddress(account: config.account, name: config.name)}:${config.tag}" sh("docker tag ${config.sourceContainer} ${ecrAddress}") sh("docker push ${ecrAddress}") }
最终使用示例
和你期望的调用方式基本一致,仅补充Pipeline必填的agent和stages语法块即可:
@Library('jenkins-shared-lib-global') _ pipeline { agent any stages { stage('ecr push') { steps { ECRPush( account: 'dev', name: 'ecs-testing', sourceContainer: 'ecs-testing:dev', tag: 'jenkins' ) } } } }
内容的提问来源于stack exchange,提问作者Randy Coburn
相关产品推荐
相关产品推荐

