You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为Jenkins Pipelines编写可供其他var文件调用的公共代码

Jenkins共享库开发问题解答

认知正确性确认

你对vars/和src/目录的认知完全正确:

  • vars/目录下的Groovy文件会被注册为全局步骤,加载后可直接在Pipeline语法中调用,文件名即为调用时的步骤名
  • src/目录为标准Groovy源码结构,需要先导入对应包和类、完成实例化后才能使用,通常用于封装通用逻辑,供vars/下的步骤调用

现有代码问题汇总

  1. 包名拼写错误:src下类定义的包名写为com.mycomany.awsCommon,和导入时的com.mycompany.awsCommon拼写不一致
  2. 类使用逻辑错误:直接调用未实例化的普通类方法,且导入语句仅指向包名,未指定具体类
  3. 变量调用错误:类中定义的账号映射名为小写accounts,调用时错写为大写Accounts,且Groovy类中使用不存在的self关键字,应使用this指代当前类实例
  4. 参数取值错误:取账号映射值的写法错误,正确写法为accounts[config.account],而非self.Accounts([config.account])
  5. 注解冗余错误:vars/下的步骤文件无需单独添加@Library注解,仅当跨共享库调用时才需要该配置
  6. 上下文缺失错误: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 15:24:03