Den här Groovy-handledningen för Jenkins visar hur du använder Apache Groovy-skript för att bygga en Jenkins-pipeline. Groovy passar nybörjare och är ett bra val för att samla teamens skript.
Sandeep Kinayath
Sandy works as a consultant at Eficode Denmark. He’s passionate about cloud computing, IoT, and hardware integrations. While also having a penchant for football and cricket!
Men vad är Groovy? Apache Groovy är ett objektorienterat programmeringsspråk som används för JVM-plattformen. Det här dynamiska språket har många funktioner inspirerade av Python, Smalltalk och Ruby. Det kan användas för att orkestrera din pipeline i Jenkins och kan koppla ihop olika språk, vilket innebär att team i ditt projekt kan bidra på olika språk.
Groovy kan integreras smidigt med Java, och syntaxen i Java och Groovy är mycket lik. Om du glömmer syntaxen när du skriver Groovy kan du fortsätta att skriva direkt med Java-syntax. Groovy kan också användas som ett av skriptspråken för Java-plattformen. Groovy-skript kan anropas i Java, vilket effektivt minskar tiden som läggs på Java-utveckling.
Det erbjuder också många produktivitetsfunktioner, som stöd för DSL, closures och dynamisk typning. Till skillnad från vissa andra språk fungerar det som ett komplement till Java, inte som en ersättare. Groovy-källkod kompileras till JVM-bytecode och kan därför köras på alla plattformar.
Varför använda Groovy?
Här är de främsta anledningarna till att överväga Groovy, ett vanligt val för att skapa pipeline-filer.
1. Som vi nämnde tidigare är Groovy ett agilt och dynamiskt språk. Det integreras smidigt med alla befintliga Java-objekt och bibliotek.
Groovy är Java utan typer, alltså utan att definiera grundläggande datatyper som int, float, String och så vidare. I grunden fungerar det på samma sätt som Java: definiera en variabel utan att ange en typ. Groovy avgör typen utifrån objektets värde.
2. I Groovy blir "for"-loopen mer kortfattad och lättare att läsa. Groovys loop-satser har stöd för: while, for, for-in, break och continue, och allt är konsekvent med Java.
Till exempel:
0..5 anger att heltalen 0, 1, 2, 3, 4 och 5 ingår
0..<5 betyder 0, 1, 2, 3, 5 och a..d betyder a, b, c, d:
Groovy har också stöd för standardvärden för parametrar:
3. I Groovy kan vi använda scopes för att definiera samlingar eller arrayer.
Sökmetoden i Groovy är också mer flexibel
Groovy låter dig också lägga till eller ta bort samlingar från samlingar.
När du lägger till element i en samling kan du använda följande metoder
4. En ytterligare fördel med Groovy är dess operatorer:
Groovys aritmetiska operatorer, logiska operatorer, relationsoperatorer och bitvisa operatorer är alla konsekventa med språk som nodeJS. Groovys == motsvarar equals-metoderna i Java.
5. De List-metoder som finns i Groovy är ytterligare en fördel.
Add( ) Lägger till det nya värdet i slutet av listan.
Get( ) Returnerar elementet på den angivna positionen i listan.
Contains( ) Returnerar true om listan innehåller det angivna värdet.
Minus( ) Skapar en ny lista av de ursprungliga elementen där det angivna elementet har tagits bort.
Plus ( ) Skapar en ny lista med elementen från den ursprungliga listan och de angivna elementen.
Pop( ) Tar bort det sista objektet från listan.
Remove( ) Ta bort element från den angivna positionen i listan
Reverse() Skapa en ny lista med elementen i omvänd ordning jämfört med originallistan
Size( ) Hämta antalet element i listan.
Sort( ) Returnerar en sorterad kopia av originallistan.
6. I alla andra objektorienterade språk finns begrepp som objekt och klasser för att representera den objektorienterade karaktären hos ett programmeringsspråk. Groovy skapar implicit getters och setter-metoder samt tillhandahåller konstruktorer med argument.
7. Undantagshantering fungerar på samma sätt som i Java, där try och catch används för att fånga undantag i Groovy.
Det finns många avancerade ämnen i Groovy (JSON-hantering, metoder, maps med mera) som du kan läsa mer om i den officiella Apache-dokumentationen.
Groovy kombinerar även funktioner från Python, Ruby och andra skriptspråk. Det erbjuder mycket syntaktiskt socker i grammatiken. Inom Java-utveckling finns det mycket kod som måste skrivas i Java men som kan utelämnas i Groovy, vilket framgår av de tidigare kodexemplen.
Sammanfattningsvis är den främsta fördelen med Groovy att du kan skriva samma funktion med mindre kod, vilket enligt mig innebär mer koncis och meningsfull kod jämfört med Java.
Vilka är nackdelarna med att använda Groovy?
Vissa skulle säga att en enklare infrastruktur som kod med deklarativa filer, vilket Groovy kanske inte erbjuder, är ett bättre långsiktigt alternativ när du arbetar med DevOps. Dessutom kan Apache Groovy till en början uppfattas som ett lite hackigt språk.
I praktiken har jag dock sett att införandet av Groovy har fört team närmare varandra i organisationer som tidigare inte uttryckligen har arbetat med DevOps. Det har gjort det möjligt för dem att arbeta självständigt samtidigt som mängden delade bibliotek har ökat.
För mer djupgående kunskap om Groovy rekommenderar vi deras dokumentation.
Jenkins Pipeline i Jenkinsfile
Låt oss prata om Jenkins Pipeline-metoden i Jenkins och korrekt pipeline-syntax. Med Jenkins inbyggda stöd för Groovy och en omfattande referens för Pipeline Step-biblioteket kan du implementera komplexa bygg- och releaseprocesser genom att skriva egna pipeline-skript.
Jenkins Pipeline kan skapas på följande sätt:
Via det klassiska gränssnittet/Blue Ocean – du kan ange en grundläggande Pipeline direkt i Jenkins via det klassiska gränssnittet eller via Blue Ocean-gränssnittet. Med Blue Ocean-gränssnittet kan du skriva Pipelines Jenkinsfile och skicka det till versionshantering [här finns mer information om Blue Ocean]
I SCM – Jenkinsfile kan skrivas för hand och skickas till projektets versionshanteringsrepo.
I stället för att skapa och konfigurera freestyle-jobb har Jenkins Pipeline en uppsättning instruktioner som Jenkins-jobbet ska köra.
Jenkinsfile som skapas via det klassiska gränssnittet sparas direkt av Jenkins. En Pipeline som skapas från Jenkins klassiska gränssnitt sparas i Jenkins rotkatalog och skriptet körs i Jenkins skriptkonsol. Jenkinsfile är grundkoden för Jenkins, som kör den som ett Groovy-skript i Jenkins skriptkonsol.
Anatomi för Jenkinsfile
Den första raden, shebang, definierar filen som ett skript i språket Groovy:
Inbäddade Pipeline-filer har ingen shebang eftersom den tillhandahålls internt.
Samma exempel ovan (deklarativ pipeline) kan också skrivas som scripted pipeline-kod.
En scripted pipeline är ett DSL baserat på Groovy. Den ger Jenkins-användare större flexibilitet och skalbarhet än Declarative pipeline.
Groovy-skript passar inte nödvändigtvis alla användare, så Jenkins skapade Declarative pipeline. Syntaxen för Declarative Pipeline är mer strikt. Den måste följa Jenkins fördefinierade DSL-struktur, som ger en enklare och mer tydlig syntax för att skriva Jenkins-pipelines.
Detta anger på vilken maskin koden ska köras.
eller
Sektionen måste definieras på toppnivå i pipeline-blocket, men användning på stage-nivå är valfri.
Som bakgrund: Jenkins har ett koncept med Master- och worker-noder, det vill säga slaves.
Varför behöver vi flera noder?
1. För att fördela arbetsbelastningen i Jenkins
2. Vi har flera noder för olika typer av projekt
Anta till exempel att vi har två olika typer av projekt:
Java
iOS
För att bygga ett Java-jobb behöver vi använda en Java Build Machine / nod.
På samma sätt behöver vi för en iOS build en MAC Slave/maskin/Windows.
Stage
Vi har flera stages i vår build, där varje stage-sektion har olika steg och kommandon att följa. När merparten av arbetet i Jenkins Pipeline utförs består det av en sekvens med en eller flera stages. Det rekommenderas att stages innehåller minst ett stage-direktiv för att koppla samman olika leveransprocesser, till exempel build, test och driftsättning.
Parallella stages
Stages i en pipeline kan deklarera flera kapslade stages i ett parallellt block. Det kan förbättra den operativa effektiviteten för stages som tar lång tid och inte är beroende av varandra. Dessutom kan flera steg i samma parallella block också köras parallellt.
Steg
Den centrala och grundläggande delen av en pipeline är ett step. Pipelines består av flera steg som gör att du kan bygga, testa och driftsätta applikationer. I grunden är steg de mest grundläggande byggblocken i syntaxen för declarative pipeline och scripted pipeline, och talar om för Jenkins vad som ska göras.
Scripted pipeline beskriver inte steg specifikt som en del av sin syntax, men i referensdokumentet för pipeline-steg beskrivs de steg som ingår i pipelinen och dess plugins i detalj.
Jenkins pipeline låter dig sätta samman flera steg som hjälper dig att skapa alla typer av automatiseringsprocesser. Se ett step som ett enskilt kommando som utför en åtgärd. När ett steg lyckas går pipelinen vidare till nästa steg. Om ett steg inte körs korrekt misslyckas pipelinen.
När alla steg i pipelinen har slutförts utan problem anses pipelinen ha körts framgångsrikt.
Timeout och återförsök
Triggers
Direktivet triggers definierar hur Pipeline automatiserar triggers. Enligt Jenkins-dokumentationen är de triggers som för närvarande är tillgängliga cron, pollSCM och upstream.
Cron
Accepterar en cron-liknande sträng för att definiera det regelbundna intervallet då pipelinen utlöses, till exempel:
pollSCM
Accepterar en cron-liknande sträng som anger det regelbundna intervallet för när Jenkins ska kontrollera ändringar i SCM-källan. Om det finns nya ändringar utlöses pipelinen på nytt.
When
Kommandot when gör det möjligt för pipelinen att avgöra om denna fas ska köras utifrån angivna villkor. Kommandot when måste innehålla minst ett villkor. Mer komplexa villkorsstrukturer för pipelinen kan skapas med kapslade villkor: not, allOf eller anyOf. Om direktivet when innehåller flera villkor måste alla undervillkor returnera true för att steget ska köras. Kapslade villkor kan kapslas på valfritt djup.
Det används främst för att hoppa över eller köra ett steg/en fas
Avsnitt efter build
Definiera åtgärden i slutet av pipeline- eller faskörningen. Du kan behöva köra rensningssteg eller utföra vissa åtgärder baserat på pipeline-resultatet. Blocket för postvillkor har stöd för följande komponenter: always, changed, failure, success, unstable och aborted. Dessa block gör det möjligt att utföra steg i slutet av pipeline- eller faskörningen, beroende på pipelinens status.
Miljövariabler
Miljövariabler kan anges globalt, som i exemplet nedan, eller per fas. Som du kanske förväntar dig gäller miljövariabler som anges per fas endast för den fas där de definieras.
Undantagshantering i Jenkins Pipeline
För undantagshantering kan du nu använda try catch-blocket för att köra steget och fånga undantag.
Registrera tester och artefakter
Jenkins kan registrera och sammanställa testresultat så länge din test runner kan skapa testresultatfiler. Jenkins levereras vanligtvis med JUnit-steget, men om dina testverktyg inte kan skapa XML-rapporter i JUnit-format finns ytterligare plugin-program som kan bearbeta i stort sett alla vanligt förekommande format för testrapporter.
För att samla in våra testresultat och artefakter använder vi post-avsnittet.
Skicka notifieringar
När pipelinen lyckas eller misslyckas behöver en statusnotifiering skickas till det berörda teamet. Vi kan lägga till notifieringar eller andra steg i pipelinen för att utföra slutbehandling, skicka notifieringar eller hantera andra uppgifter i slutet av pipelinen.
E-postnotifiering
Slack-notifiering
Jenkins Pipeline Groovy: delade bibliotek
När pipelinen används i allt fler projekt inom en organisation uppstår sannolikt gemensamma mönster. Det är ofta användbart att dela delar av pipelines mellan olika projekt för att minska dubbelarbete.
Pipeline har stöd för att skapa delade bibliotek som kan definieras i externa repositories för källkodshantering och laddas in i befintliga pipelines
Ett delat bibliotek definieras med ett namn, en metod för att hämta källkod, till exempel via SCM, samt valfritt en standardversion. Namnet bör vara en kort identifierare eftersom det används i skript.
Titta på följande mappstruktur nedan: (direkt från Jenkins dokumentation)
Katalogen src ska ha samma struktur som en vanlig Java-källkodskatalog. Den här katalogen läggs till i classpath när pipelines körs.
Katalogen vars innehåller scriptfiler som exponeras som variabler i pipelines. Filnamnet blir namnet på variabeln i pipelinen. En mer detaljerad genomgång av hur du definierar ett shared library i Jenkins finns här. Det finns fler alternativ och andra tillgängliga kodavsnitt som du kan prova att skapa och köra i Jenkins med hjälp av en Jenkins-fil.
I katalogen resources kan du hantera alla icke-Groovy-filer och hjälpscript som behövs för pipelinen. I strukturen ovan lagras exempel-JSON-mallen i resources-katalogen och kan anropas i shared library med funktionen libraryResource.
Du kan använda eller anropa biblioteket du har skapat genom att
Exempel på hur du skriver funktioner i Groovy shared library
Definiera globala variabler i shared library
Katalogen vars innehåller script som definierar globala variabler som är åtkomliga från pipelinen.
Internt instansieras script i katalogen vars vid behov som singletons. Det gör det enkelt att definiera flera metoder i en och samma .Groovy-fil.
Åtkomst till steg
Groovy-klasser i shared library kan inte direkt anropa steg som sh eller git. Du kan uttryckligen skicka de specifika globala variablerna env (som innehåller alla aktuella miljövariabler) och steps (som innehåller alla vanliga pipelinesteg) till en metod i klassen. Däremot kan de implementera metoder utanför omfattningen för en omslutande klass, som i sin tur anropar pipelinesteg.
Till exempel:
Som sedan kan anropas från en scripted pipeline:
En komplett exempelstruktur för en Groovy-fil med Jenkins-script ser ut så här
Fler Jenkins-Groovy-kodavsnitt finns i Dennyzhangs GitHub-repository.
Jag hoppas att detta har hjälpt dig på din Groovy-resa!
- DevOps
- CI/CD
Subscribe to our newsletter
Related blogs