2017-07-06 1 views
0

Ich erstelle meine eigene Jenkins shared library, um etwas Code zwischen Pipelines wiederzuverwenden. Ich weiß, wie man Schritte erstellt (wirklich wirklich einfach), aber ich habe ein Problem, wenn ich meine "utils-Klasse" in der jenkinsfile (oder WorkflowScript, wie Jenkins in Protokollen sagt) zugänglich machen möchte. Ich nenne „Util Klasse“ eine groovige Klasse in Ordner src/my/Domain/gelegen ... die viele Methoden, zum Beispiel, ich möchte eine Log-Klasse wie folgt erstellen:Jenkins Shared Library instanziieren util-Klasse und verwenden in Workflowscript

# src/my/domain/group 

package my.domain.group 

class Console implements Serializable { 

    def log(msg) { 
     spit(msg, '\033[34m') 
    } 

    def error(msg) { 
     spit(msg, '\033[31m') 
    } 

    def warning(msg){ 
     spit(msg, '\033[33m') 
    } 

    def success(msg){ 
     spit(msg, '\033[32m') 
    } 

    private def spit(msg, color){ 
     ansiColor('xterm') { 
      echo color + msg + '\033[0m' 
     } 
    } 

} 

Und dann ich versuchen, in einer Datei in /vars/library.groovy instanziiert so von der Jenkinsfile mit einigem Code, wie beispielsweise zugegriffen werden kann:

node("mynode"){ 
    console.log("Hello World!") 
} 

die Idee zu vermeiden, ist die Konsole in allen Skript zu instanziiert und es macht Automatisch habe ich verschiedene Dinge wie

# vars/library.groovy 

import my.domain.group.Console 
import groovy.transform.Field 

@Field String console = new Console() 
012 ausprobiert

oder

# vars/library.groovy 

import my.domain.group.Console 

def load(){ 
    this.console = new Console() 
    // And also 
    console = new Console() 
} 

Aber wenn man versucht, aus jenkins Datei zuzugreifen bekomme ich immer die Fehlermeldung: groovy.lang.MissingPropertyException: Keine solche Eigenschaft: Konsole für Klasse: WorkflowScript

Ich verstehe, dass diese Mittel dass die Instanz nicht im richtigen Bereich ist, also nicht direkt vom Skript gesehen werden kann, aber wie kann ich das tun?

Danke!

Antwort

2

Sieht aus wie Sie Ihr vars Skript falsch in Ihrem Jenkinsfile, aber ich werde versuchen, einige Verwirrungen zu lösen :)

  1. Groovy Skripte im vars Verzeichnis definiert werden durch ihre Dateinamen wie „custom genannt "Schritt in deiner Jenkinsfile. Angenommen, Ihr Skript Name bleibt library.groovy, sollte Ihr Jenkinsfile so aussehen

    node ("mynode") { 
        library("Hello World!") 
    } 
    

    oder alternativ (da die Klammern sind optional)

    node ("mynode") { 
        library "Hello World!" 
    } 
    
  2. Zusätzlich sollten vars Scripts enthalten nur eine einzige Funktion mit dem Namen call und notwendig Importe. Da Sie Ihre Log-Nachricht als String übergeben möchten, benötigt die Funktion call zusätzlich einen Parameter. Also Ihr library.groovy Skript in vars könnte diese aussehen

    # vars/library.groovy 
    
    import my.domain.group.Console 
    
    def call(msg){ 
        Console console = new Console(steps) 
        console.log(msg) 
    } 
    

    Innerhalb der call Funktion können Sie alle grundlegenden Jenkins Schritte verwenden (sh, bat, etc.) wie Sie können in Ihrem Jenkinsfile, sowie alle Groovy/Java-Klassen importiert über import (wie Ihre Console Klasse).

    Wie Sie vielleicht bemerkt haben, fügte ich auch eine steps Variable (die nicht manuell deklariert oder instanziiert werden muss) zum Konstruktor Ihrer Klasse Console hinzu. Dies ist notwendig, da Sie keine Jenkins-Schritte direkt in einer Ihrer Klassen verwenden können, die im Verzeichnis src definiert sind.Resultierende, wobei das Verfahren

    private def spit(msg, color){   
        ansiColor('xterm') { 
         echo color + msg + '\033[0m' 
        } 
    } 
    

    nicht funktionieren würde, weil echo einen Schritt Jenkins ist. Um innerhalb Ihrer Klasse echo zu verwenden, können Sie die Variable steps an den Konstruktor übergeben und sie in einer anderen Variablen innerhalb Ihrer Klasse speichern. Dann können Sie alle Jenkins Schritte nennen wie steps.echo "Hello World"

    # src/my/domain/group 
    
    package my.domain.group 
    
    class Console implements Serializable { 
    
        def steps 
    
        Console(steps) { 
         this.steps = steps 
        } 
    
        def log(msg) { 
         spit(msg, '\033[34m') 
        } 
    
        def error(msg) { 
         spit(msg, '\033[31m') 
        } 
    
        def warning(msg){ 
         spit(msg, '\033[33m') 
        } 
    
        def success(msg){ 
         spit(msg, '\033[32m') 
        } 
    
        private def spit(msg, color){ 
         ansiColor('xterm') { 
          steps.echo color + msg + '\033[0m' 
         } 
        } 
    } 
    

Das sollte es funktioniert.

Sie sollten jedoch darüber nachdenken, Ihre library.groovy innerhalb vars obwohl (zum Beispiel myLog.groovy) umbenennen. Dann könnte Ihr Jenkinsfile aussehen dieser

node ("mynode") { 
    myLog "Hello World!" 
} 

Um die anderen Methoden Ihrer Console Klasse zu verwenden, Sie zusätzliche Skripte innerhalb vars erstellen können. Mit ihnen wie diesem

node ("mynode") { 
    myLog "Hello World!" 
    myWarning "Hello World!" 
    myError "Hello World!" 
    mySuccess "Hello World!" 
} 

aussehen könnten (im den my Präfix Namenskollisionen mit bereits bestehenden Jenkins Schritten zu vermeiden. Zum Beispiel gibt es den error Schritt bereits und es in Ihrem Jenkinsfile Aufruf wird stornieren Build)

bei https://jenkins.io/doc/pipeline/steps/workflow-basic-steps/

Für weitere Informationen über gemeinsam genutzte Bibliotheken überprüfen Sie die Jenkins Dokumentation aus bei https://jenkins.io/doc/book/pipeline/shared-libraries/

Sie eine vollständige Liste aller grundlegenden Jenkins Schritte finden

Die Arbeit mit Jenkins und Pipelines kann sehr mühsam sein, aber am Ende ist es das wert. Ich hoffe, dass diese Textwand ein wenig hilft. Viel Glück und glückliche Kodierung :)

+0

Danke für deine Antwort Adrian! Ich weiß, wie man die Schritte benutzt, aber ich habe vergessen, diesen Code in mein Beispiel zu schreiben, sorry :-). Wenn Sie Ihre Antwort lesen, kann ich verstehen, dass ich keine Instanz einer Klasse angeben kann, die direkt in Jenkins-Pipelines verwendet werden soll. Ich kenne die Option zum Erstellen verschiedener Schritte für jede meiner Methoden in der Konsole, aber ich denke, dass es klarer ist, eine Instanz der Konsole direkt aus Vars zu entlarven (ich weiß nicht, ob das möglich ist) und dann in der Jenkins-Datei zu verwenden direkt wie ich es in meinem Beispiel zeige. – joliva

+0

Nun, Sie könnten vollständig auf Ihr 'library.groovy'-Skript in' vars' verzichten und die 'Console'-Klasse direkt in Ihrer Jenkins-Datei verwenden. Stellen Sie sicher, dass Sie Ihre gemeinsam genutzte Bibliothek über '@Library ('[LIB_NAME]') _' importieren, wobei' [LIB_NAME] 'der Name Ihrer in den Jenkins-Einstellungen angegebenen Bibliothek und Ihre Klasse über' import my.domain 'ist. util.Console' von innerhalb Ihrer Jenkinsfile. –

Verwandte Themen