Jenkins pipeline sh, похоже, не уважает трубу в команде оболочки

Я использую файл Jenkinsfile в конвейере версии 2.32.2.

по разным причинам я хочу извлечь строку версии с пом. Я надеялся, что мне не придется добавлять плагин Maven help и использовать evaluate.

я быстро придумал небольшое выражение sed, чтобы получить его из pom, который использует трубы и работает над командной строкой в рабочей области Дженкинса на исполнителе.

$ sed -n '/<version>/,/<version/p' pom.xml | head -1 | sed 's/[[:blank:]]*</*version>//g' 1.0.0-SNAPSHOT

вероятно, его можно было бы оптимизировать, но я хотите понять, почему конвейер, похоже, терпит неудачу на командах piped sh. Я играл с различными строковыми форматами и в настоящее время использую строку Dollar slashy.

шаг конвейера выглядит следующим образом, чтобы обеспечить легкий вывод командной строки:

script {
    def ver_script = $/sed -n '/<version>/,/<version/p' pom.xml | head -1 | sed 's/[[:blank:]]*</*version>//g'/$
    echo "${ver_script}"
    POM_VERSION = sh(script: "${ver_script}", returnStdout: true)
    echo "${POM_VERSION}"
}

при запуске в конвейере Дженкинса я получаю следующий консольный вывод, где он, кажется, разделяет переданные команды на отдельные команды:

[Pipeline] script
[Pipeline] {
[Pipeline] echo
sed -n '/<version>/,/<version/p' pom.xml | head -1 | sed 's/[[:blank:]]*</*version>//g'
[Pipeline] sh
[FRA-198-versioned-artifacts-44SD6DBQOGOI54UEF7NYE4ECARE7RMF7VQYXDPBVFOHS5CMSTFLA] Running shell script
+ sed -n /<version>/,/<version/p pom.xml
+ head -1
+ sed s/[[:blank:]]*</*version>//g
sed: couldn't write 89 items to stdout: Broken pipe
[Pipeline] }
[Pipeline] // script

каких-либо указаний на как правильно использовать конвейерные команды в файле jenkinsfile ?

4 ответов


Я, наконец, подумал об этом и понял, что подрешетки труб, вероятно, вызывают проблему. Я знаю некоторые из зол eval, но я закончил тем, что обернул это в eval:

script {
    def ver_script = $/eval "sed -n '/<version>/,/<version/p' pom.xml | head -1 | sed 's/[[:blank:]]*<\/*version>//g'"/$
    echo "${ver_script}"
    POM_VERSION = sh(script: "${ver_script}", returnStdout: true)
    echo "${POM_VERSION}"
}   

Если ваша среда позволяет это, я нашел простое решение этой проблемы, чтобы поместить ваш скрипт, содержащий каналы, в файл, а затем запустить его с помощью sh, например:

script.sh:

#!/bin/sh
kubectl exec --container bla -i $(kubectl get pods | awk '/foo-/{ print  }') -- php /code/dostuff

Jenkinsfile:

stage('Run script with pipes') {
  steps {
    sh "./script.sh"
  }
}

Я также борюсь с использованием трубы внутри моего трубопровода Дженкинса, но в качестве примечания, если вы хотите простой способ извлечь версию Maven pom, вот очень чистый, который я нашел в другом сообщении, и который я использую:

stage('Preparation') {
 version = getVersion()
 print "version : " + version
}
def getVersion() {
  def matcher = readFile('pom.xml') =~ '<version>(.+)</version>'
  matcher ? matcher[0][1] : null
}

дает вам :

[Pipeline] echo
releaseVersion : 0.1.24
[Pipeline] sh

на плагин в настоящее время включает в себя readMavenPom шаг, который позволяет получить доступ к версии следующим образом:

version = readMavenPom.getVersion()