当前位置: 首页 > 知识库问答 >
问题:

Jenkins多分支管道工作区位置:shell与Groovy

马坚白
2023-03-14

摘要:当使用并行构建时,Groovy中的工作区路径与shell不同。如何从DSL或Groovy获取实际工作区?

细节:

我们的工作区是通过ws('/path/to/workspace')定义的。

我试图使用一个相对路径,简单地package.json,在当前目录中打开该文件,该目录通常是工作区根目录。当运行为shell,sh'jq-r". version"package.json'它工作正常,我可以阅读package.json没有任何问题。

但是使用Groovy:

def version = new groovy.json.JsonSlurper().parseText( new File( "package.json" ).text )[ 'version' ]

请注意文件(“package.json”)然后它将无法声明$WORKSPACE/package。json不存在。尽管我们在上面用ws设置了工作区,但我可以看到它最终类似于/path/to/workspace/my_job-SOMERANDOMCHARS。。。不是ws中指定的目录。

我理解,在并行工作负载中,我们需要使工作区唯一,这样就不会意外了。但是我应该如何从Groovy确定工作区呢?还是期望总是突破到实际在节点上运行的shell?

更新:更多上下文

关于这是如何使用的更多信息。我们的Groovy(非声明性)管道按照以下思路执行一些操作:

stage('tests') {
  parallel(
    'Unit Tests': {
       node('unitNode') {
         ws('/path/to/workspace') {
           new file("${env.WORKSPACE}/package.json") // does not work 
           sh 'cat $WORKSPACE/package.json' // works OK
         }
       }
    },
    'E2E Tests': {
       node('e2eNode') {
         ws('/path/to/workspace') {
           new file("${env.WORKSPACE}/package.json") // does not work 
           sh 'cat $WORKSPACE/package.json' // works OK
         }
       }
    }
  )
}

共有2个答案

华化
2023-03-14

相对于工作区访问文件的最佳方法是使用readFile,或者在本例中更方便地使用readJSON。这对我来说很有效,我不必关心工作空间的实际绝对路径。

还有其他readXXXX方法,如readYAML、readManifest、readMavenPom等。有关完整列表和示例,请参阅管道实用程序步骤文档。

吕鸿朗
2023-03-14

我正在假设您是如何使用ws()的。在没有看到实际代码的情况下,您的描述暗示您正在做这样的事情:

ws(/new/path/to/workspace) {
    sh "cat package.json"
}

def version = new groovy.json.JsonSlurper().parseText( new File( "package.json" ).text )[ 'version' ]

如果您是这样做的,那么工作区将不再适用于ws{}块之外。

显示的路径( /path/to/workspace/my_job-SOMERANDOMCHARS)似乎是运行ws()之前的原始工作区路径。或者它可能是您的管道文件正在签出的地方。如果没有看到代码,就很难猜出你想把工作区文件放在哪里。

无论哪种方式,如果使用WORKSPACE变量,都可以获得当前工作空间。运行以下管道代码并检查输出。这应该解释这一切是如何运作的。

pipeline {
    agent any

    stages {
        stage('first'){
            steps {
                ws('/tmp/foobar') {
                    sh "pwd"
                    sh 'echo New Workspace - ${WORKSPACE}' //environment variable
                    echo 'New Workspace' + WORKSPACE //groovy variable
                }
                sh "pwd"
                sh "echo Original Workspace - ${WORKSPACE}"  //interpolated groovy variable
                echo "Original Workspace - ${WORKSPACE}"       //interpolated groovy variable
            }
        }
    }

}

编辑:我将您的示例修改为在我的机器上运行的示例,以尝试复制,但效果很好。这是你的詹金斯吗?

stage('tests') {
  parallel(
    'Unit Tests': {
       node('Linux') {
         ws('/tmp/foobar') {
           def file1 = new File("${env.WORKSPACE}/package.json")
           println 'File1 is: ' + file1
           echo "${env.WORKSPACE}"
           sh 'echo $WORKSPACE/package.json'
         }
       }
    },
    'E2E Tests': {
       node('Linux') {
         ws('/tmp/baz') {
           def file2 = new File("${env.WORKSPACE}/package.json")
           println 'File2 is: ' + file2
           echo "${env.WORKSPACE}"
           sh 'echo $WORKSPACE/package.json'
         }
       }
    }
  )
}

也许问题不在你认为的地方,或者也许Jenkins的版本或你正在使用的插件中有一个bug。如果文件句柄的println显示正确的路径,则可能是其他问题。

 类似资料:
  • 我遇到了JENKINS-38706。由于它已经开放了一段时间,我正在努力解决这个问题。 我的问题是我正在运行一个多节点管道,其中一个节点是Windows从节点,具有255个字符路径限制。 因此,我正在尝试更改我的Windows从属阶段的工作区,而不是使用多分支管道使用的C:\jenkins\workspace\job-分支-随机字符,我正在尝试将其移动到c:\w\Jobs\分支。 它立即失效: 我

  • 现在多分支管道作业类型已经成熟,还有什么理由再使用简单的管道作业类型吗?即使您现在只有一个分支,考虑到未来多个分支的可能性可能是明智的,那么假设您将Jenkins管道存储在SCM中,那么为您的Jenkins管道使用管道作业类型与始终使用多分支管道作业类型的动机是什么?现在这两种作业类型之间是否存在功能平价?

  • 对于一个新项目,我想使用Jenkins CI的新管道功能。我们的Git存储库中有几个分支,应该以同样的方式进行测试。它还应该自动跟踪和处理新的分支。因此,我创建了一个多分支管道作业。但它的配置有两个问题: 1) 为了被Jenkins标记为有效,分行需要一个“Jenkinsfile”。如果这不存在,詹金斯将忽略该分支。有没有办法标记与模式匹配的所有分支,而不需要在其中包含此文件? 2) 每个分支都应

  • null null 我怎样才能想象这些工作类型之间的关系?还有其他插件支持这些类型吗?

  • 我是詹金的新手,我在比特桶里有4个回购,比如甲、乙、丙、丁。我必须去拿甲、乙 在Jenkinsfile中添加了上面的脚本,我将其放在repo中。 现在,我已经创建了一个多分支管道来获取所有和分支内的源- 我在源代码管理方面创造了自由式的新工作- 任何帮助都很感激。

  • 我正在努力使用Jenkins 2.1多分支管道,在这里,我从同一个git存储库构建了多个工件。一些工件是独立的,应该根据它们各自目录中的更改触发构建。有些是依赖的,应该由先前的步骤/构建触发。 存储库有一个控制整个管道的文件。Jenkins多分支管道作业会在所有更改时触发(无其他行为)。 我不知道如何在目录dirA发生变化时触发工件A的构建。 git回购协议中的Jenkins文件file:///r