web-dev-qa-db-fra.com

Jenkins pipeline sh ne semble pas respecter le tuyau dans la commande Shell

J'utilise un Jenkinsfile dans un pipeline sur la version 2.32.2. 

Pour diverses raisons, je souhaite extraire la version de chaîne du pom. J'espérais ne pas avoir à ajouter le plugin maven help et à évaluer. 

Je suis rapidement arrivé avec une petite expression sed pour le sortir du pom qui utilise des tuyaux et travaille sur la ligne de commande dans l'espace de travail jenkins de l'exécuteur.

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

Il pourrait probablement être optimisé, mais je veux comprendre pourquoi le pipeline semble échouer avec les commandes piped sh. J'ai joué avec différents formats de cordes et j'utilise actuellement une chaîne d'un dollar.

L'étape de pipeline ressemble à ceci pour permettre une sortie facile de la chaîne de commande:

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}"
}

Lorsqu'il est exécuté dans le pipeline jenkins, j'obtiens la sortie de console suivante où il semble séparer les commandes acheminées en commandes séparées:

[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

Avez-vous des conseils pour utiliser correctement les commandes piped dans un fichier jenkins?

10
sporkthrower

J'ai finalement réfléchi et me suis rendu compte que les sous-coques de tuyaux étaient probablement à l'origine du problème. Je connais certains des maux d’éval mais j’ai fini par en parler dans un 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}"
}   
5
sporkthrower

Si votre environnement le permet, j'ai trouvé une solution simple à ce problème: placer votre script contenant des tubes dans un fichier, puis l'exécuter avec sh, comme suit:

script.sh :

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

Jenkinsfile :

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

Je suis également aux prises avec l'utilisation de pipe dans mon pipeline Jenkins, mais en passant, si vous voulez un moyen simple d'extraire la version d'un pom maven, voici une solution très propre que j'ai trouvée dans un autre post et que j'utilise : 

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

vous donne : 

[Pipeline] echo
releaseVersion : 0.1.24
[Pipeline] sh
0
mattvbv

Le pipeline pipeline-utility-étapes plugin comprend de nos jours une readMavenPom step, qui permet d’accéder à la version de la manière suivante:

version = readMavenPom.getVersion()
0
StephenKing