Wie greife ich in einem parametrisierten Build auf Parameter zu?

73

Wie greifen Sie auf parametersset im Abschnitt "Dieser Build ist parametrisiert" eines Jenkins-Jobs "Workflow" zu?

TESTFALL

  1. Erstellen Sie einen WORKFLOW-Job.
  2. Aktivieren Sie "Dieser Build ist parametrisiert".
  3. Fügen Sie einen STRING-PARAMETER foomit dem Standardwert hinzu bar text.
  4. Fügen Sie den folgenden Code hinzu Workflow Script:

    node()
    {
         print "DEBUG: parameter foo = ${env.foo}"
    }
    
  5. Job ausführen.

ERGEBNIS

DEBUG: parameter foo = null

Vizionz
quelle
2
Ein weiteres Missverständnis (Autojack in #jenkins: Transkript ) ist, dass Sie $foowie in verwenden sollten if ($PARAM == 'true') {…}. Das ist nur eine Variablenkennung in Groovy. $ist nur ein Metazeichen innerhalb einiger Arten von Zeichenfolgen.
Jesse Glick
Versuchen Sie das EnvInject-Plugin, um Jenkins-Parameter zu ändern. Hier ein Beispiel: stackoverflow.com/a/7067223/658497
Noam Manos

Antworten:

90

Ich denke, die Variable ist direkt und nicht über env verfügbar, wenn das Workflow-Plugin verwendet wird. Versuchen:

node()
{
    print "DEBUG: parameter foo = ${foo}"
}
Nick
quelle
2
Richtig, wie hier erklärt .
Jesse Glick
aber um es für eine Shell-Aufgabe verfügbar zu machen, muss ich anscheinend 'env' zuweisen - das fühlt sich seltsam an ... zB: env.PARAM = PARAM
domi
2
nein, ich habe mich geirrt - ich habe sh '' 'echo X' '' anstelle von sh "" "echo X" "" verwendet
domi
5
Stellen Sie sicher, dass Sie doppelte Anführungszeichen anstelle von einfachen Anführungszeichen verwenden. Letzterer überspringt die Interpolation.
Henrique Gontijo
Stellen Sie sicher, dass Sie "env" nicht als einen Ihrer Parameter verwenden, da es sich um ein reserviertes Schlüsselwort handelt und es nicht funktioniert
Yeikel
64

Ich habe einige der Lösungen aus diesem Thread ausprobiert. Es schien zu funktionieren, aber meine Werte stimmten immer und ich stieß auch auf das folgende Problem: JENKINS-40235

Ich habe es geschafft, Parameter in Groovy jenkinsfilemit der folgenden Syntax zu verwenden:params.myVariable

Hier ist ein Arbeitsbeispiel:

Lösung

print 'DEBUG: parameter isFoo = ' + params.isFoo
print "DEBUG: parameter isFoo = ${params.isFoo}"

Ein detaillierteres (und funktionierendes) Beispiel:

node() {
   // adds job parameters within jenkinsfile
   properties([
     parameters([
       booleanParam(
         defaultValue: false,
         description: 'isFoo should be false',
         name: 'isFoo'
       ),
       booleanParam(
         defaultValue: true,
         description: 'isBar should be true',
         name: 'isBar'
       ),
     ])
   ])

   // test the false value
   print 'DEBUG: parameter isFoo = ' + params.isFoo
   print "DEBUG: parameter isFoo = ${params.isFoo}"
   sh "echo sh isFoo is ${params.isFoo}"
   if (params.isFoo) { print "THIS SHOULD NOT DISPLAY" }

   // test the true value
   print 'DEBUG: parameter isBar = ' + params.isBar
   print "DEBUG: parameter isBar = ${params.isBar}"
   sh "echo sh isBar is ${params.isBar}"
   if (params.isBar) { print "this should display" }
}

Ausgabe

[Pipeline] {
[Pipeline] properties
WARNING: The properties step will remove all JobPropertys currently configured in this job, either from the UI or from an earlier properties step.
This includes configuration for discarding old builds, parameters, concurrent builds and build triggers.
WARNING: Removing existing job property 'This project is parameterized'
WARNING: Removing existing job property 'Build triggers'
[Pipeline] echo
DEBUG: parameter isFoo = false
[Pipeline] echo
DEBUG: parameter isFoo = false
[Pipeline] sh
[wegotrade-test-job] Running shell script
+ echo sh isFoo is false
sh isFoo is false
[Pipeline] echo
DEBUG: parameter isBar = true
[Pipeline] echo
DEBUG: parameter isBar = true
[Pipeline] sh
[wegotrade-test-job] Running shell script
+ echo sh isBar is true
sh isBar is true
[Pipeline] echo
this should display
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS

Ich habe eine Pull-Anfrage gesendet , um das irreführende Pipeline-Tutorial # build-parameters quote zu aktualisieren, das besagt, dass auf sie als gleichnamige Groovy-Variablen zugegriffen werden kann. . ;)

Bearbeiten: Wie Jesse Glick betonte: Release Notes gehen auf weitere Details ein

Sie sollten auch das Pipeline Job Plugin auf 2.7 oder höher aktualisieren, damit Build-Parameter als Umgebungsvariablen definiert werden und somit so zugänglich sind, als wären sie globale Groovy-Variablen.

GabLeRoux
quelle
4
Die Parameter sind weiterhin ohne paramswie zuvor verfügbar (als flache Zeichenfolgen, keine Unterstützung für Standardwerte). Sie sind jetzt technisch gesehen Umgebungsvariablen, obwohl Sie immer noch mit einem bloßen Ausdruck auf ihre Werte verweisen können, da das env.Präfix jetzt auch für Zugriffe optional ist. Versionshinweise gehen detaillierter.
Jesse Glick
1
Dies hat mir wirklich geholfen, mein Problem zu lösen: stackoverflow.com/questions/42115868/… Vielen Dank.
Basti
Gibt es einen Hinweis, wie ich damit umgehen könnte: stackoverflow.com/questions/42277315/… ?
Basti
1
@ Basti: Die Antwort von Jon S stimmt mit Ihrer propertiesFrage überein. Sie müssen nur einmal anrufen oder jedes Mal alle Parameter neu schreiben.
GabLeRoux
4
The properties section has been renamed as of version 0.8. Use options instead.Dies funktioniert nicht mehr
Carmageddon
16

Wenn Sie einen Build-Parameter foo hinzufügen, wird dieser in etwas konvertiert, das sich wie eine "nackte Variable" verhält. In Ihrem Skript würden Sie also Folgendes tun:

node {
   echo foo
}

Wenn Sie sich die Implementierung des Workflow-Skripts ansehen, werden Sie feststellen, dass bei der Ausführung eines Skripts eine Klasse namens WorkflowScript dynamisch generiert wird. Alle Anweisungen im Skript werden im Kontext dieser Klasse ausgeführt. Alle an dieses Skript übergebenen Build-Parameter werden in Eigenschaften konvertiert, auf die von dieser Klasse aus zugegriffen werden kann.

Zum Beispiel können Sie Folgendes tun:

node {
    getProperty("foo")
}

Wenn Sie neugierig sind, ist hier ein Workflow-Skript, das ich geschrieben habe und das versucht, die Build-Parameter, Umgebungsvariablen und Methoden für die WorkflowScript-Klasse auszudrucken.

node {
   echo "I am a "+getClass().getName()

   echo "PARAMETERS"
   echo "=========="
   echo getBinding().getVariables().getClass().getName()
   def myvariables = getBinding().getVariables()
   for (v in myvariables) {
       echo "${v} " + myvariables.get(v)
   }
   echo STRING_PARAM1.getClass().getName()

   echo "METHODS"
   echo "======="
   def methods = getMetaClass().getMethods()

   for (method in methods) {
       echo method.getName()    
   } 

   echo "PROPERTIES"
   echo "=========="
   properties.each{ k, v -> 
       println "${k} ${v}" 
   }
   echo properties
   echo properties["class"].getName()

   echo "ENVIRONMENT VARIABLES"
   echo "======================"
   echo "env is " + env.getClass().getName()
   def envvars = env.getEnvironment()
   envvars.each{ k, v ->
        println "${k} ${v}"
   }
}

Hier ist ein weiteres Codebeispiel, das ich ausprobiert habe und bei dem ich testen wollte, ob ein Build-Parameter festgelegt wurde oder nicht.

node {
   groovy.lang.Binding myBinding = getBinding()
   boolean mybool = myBinding.hasVariable("STRING_PARAM1")
   echo mybool.toString()
   if (mybool) {
       echo STRING_PARAM1
       echo getProperty("STRING_PARAM1")
   } else {
       echo "STRING_PARAM1 is not defined"
   }

   mybool = myBinding.hasVariable("DID_NOT_DEFINE_THIS")
   if (mybool) {
       echo DID_NOT_DEFINE_THIS
       echo getProperty("DID_NOT_DEFINE_THIS")
   } else {
       echo "DID_NOT_DEFINE_THIS is not defined"
   }
}
Craig Rodrigues
quelle
1
Für mich ergibt dies: org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Skripte dürfen die Methode java.lang.Class getName nicht verwenden
Thomas Hirsch
8

Fügen Sie der Parametervariablen das Präfix "params" hinzu. Zum Beispiel:

params.myParam

Vergessen Sie nicht: Wenn Sie eine Methode von myParam verwenden, sollten Sie diese möglicherweise unter "Skriptgenehmigung" genehmigen.

burtsevyg
quelle
3
Dies wurde hier bereits erklärt , warum Sie es wiederholen?
Liam
Was ist das Problem, weil ich einen wichtigen Hinweis hinzugefügt habe?
Burtsevyg
Wenn Sie das Original ergänzen möchten, sollten Sie hier die ursprüngliche Antwort kommentieren. Fügen Sie 1 Jahr später keine neue Antwort hinzu. Ich habe auch keine Ahnung, was Ihr "wichtiger Hinweis" eigentlich ist.
Liam
1
Einige Leute halten es für nützlich.
Burtsevyg
8

Verwenden Sie doppelte Anführungszeichen anstelle von einfachen Anführungszeichen

zB echo "$foo"im Gegensatz zuecho '$foo'

Wenn Sie Ihre Pipeline so konfiguriert haben, dass sie Parameter mit der Option Mit Parametern erstellen akzeptiert, können Sie auf diese Parameter als gleichnamige Groovy-Variablen zugreifen. Siehe hier .

Sie können das Semikolon ( ;), die Klammern ( ( and )) und einfache Anführungszeichen ( ') anstelle von double ( ") löschen, wenn Sie keine Variablensubstitutionen durchführen müssen . Siehe hier . Dies hat mich auf mein Problem aufmerksam gemacht, obwohl ich festgestellt habe, dass nur das double ( ") erforderlich ist, damit es funktioniert.

Ken Goodridge
quelle
4

Hoffe, der folgende Code funktioniert für Sie:

def item = hudson.model.Hudson.instance.getItem('MyJob')

def value = item.lastBuild.getEnvironment(null).get('foo')
DevD
quelle
2
Dies ist viel zu viel Arbeit und funktioniert nicht einmal, wenn Sie den Sandbox-Modus verwenden oder das Projekt gleichzeitig erstellt wird.
Jesse Glick
Sie können auch verwendenjenkins.model.Jenkins.instance
Noam Manos
2

Mit dem folgenden Snippet können Sie auf alle Job-Parameter zugreifen

    def myparams = currentBuild.rawBuild.getAction(ParametersAction)
    for( p in myparams ) {
        pMap[p.name.toString()] = p.value.toString()
    }
ScaryGhast
quelle
2

Bitte beachten Sie, dass sich die Art und Weise, wie auf Build-Parameter in Pipeline-Skripten zugegriffen wird (Pipeline-Plugin), geändert hat. Dieser Ansatz:

getBinding().hasVariable("MY_PARAM")

Funktioniert nicht mehr. Bitte versuchen Sie dies stattdessen:

def myBool = env.getEnvironment().containsKey("MY_BOOL") ? Boolean.parseBoolean("$env.MY_BOOL") : false
Maksim
quelle
Ich habe dies versucht und env.getEnvironment()scheitert mit folgendem Fehler:Scripts not permitted to use method org.jenkinsci.plugins.workflow.support.actions.EnvironmentAction getEnvironment
GabLeRoux
1
@GabLeRoux Sie können die Berechtigung in Jenkins unter Jenkins verwalten> In-Process-Skriptgenehmigung hinzufügen (was in einigen Fällen möglicherweise keine besonders gute Idee ist, da Sie eine schwächere Sicherheit haben)
Maksim
2
In der Tat würde das wahrscheinlich funktionieren, aber ich ziehe es vor, die Sicherheitsrisiken niedrig zu halten :) Ich habe es geschafft, es zum
Laufen
2

Sie können auch versuchen, die Parameteranweisung zu verwenden, um Ihren Build zu parametrisieren und auf Parameter zuzugreifen:

Doc: Pipeline-Syntax: Parameter

Beispiel:

pipeline{

agent { node { label 'test' } }
options { skipDefaultCheckout() }

parameters {
    string(name: 'suiteFile', defaultValue: '', description: 'Suite File')
}
stages{

    stage('Initialize'){

        steps{

          echo "${params.suiteFile}"

        }
    }
 }
Shivankur Pal
quelle
0

Gemäß Pipeline-Plugin-Tutorial :

Wenn Sie Ihre Pipeline so konfiguriert haben, dass sie beim Erstellen Parameter akzeptiert - Mit Parametern erstellen - können Sie als gleichnamige Groovy- Variablen darauf zugreifen .

Versuchen Sie also, direkt auf die Variable zuzugreifen, z.

node()
{
     print "DEBUG: parameter foo = " + foo
     print "DEBUG: parameter bar = ${bar}"
}
Kenorb
quelle