Vad är Jenkins? CI-servern förklarade

Jenkins erbjuder ett enkelt sätt att skapa en kontinuerlig integrations- eller kontinuerlig leveransmiljö (CI / CD) för nästan alla kombinationer av språk och källkodsförvar med pipelines, samt automatisera andra rutinutvecklingsuppgifter. Medan Jenkins inte eliminerar behovet av att skapa skript för enskilda steg, ger det dig ett snabbare och mer robust sätt att integrera hela din kedja av verktyg för att bygga, testa och distribuera än du enkelt kan bygga själv.

"Bryt inte den nattliga byggnaden!" är en huvudregel i programvaruutvecklingsbutiker som publicerar en nybyggd daglig produktversion varje morgon för sina testare. Innan Jenkins var det bästa en utvecklare kunde göra för att undvika att bryta den nattliga byggnaden att bygga och testa noggrant och framgångsrikt på en lokal maskin innan man begick koden. Men det innebar att testa ens förändringar i isolering, utan att alla andra dagliga åtaganden. Det fanns ingen bestämd garanti för att den nattliga byggnaden skulle överleva ens åtagande.

Jenkins - ursprungligen Hudson - var ett direkt svar på denna begränsning.

Hudson och Jenkins

2004 var Kohsuke Kawaguchi Java-utvecklare på Sun. Kawaguchi blev trött på att bryta byggnader i sitt utvecklingsarbete och ville hitta ett sätt att veta innan koden förvarades i förvaret om koden skulle fungera. Så Kawaguchi byggde en automatiseringsserver i och för Java för att göra det möjligt, kallat Hudson. Hudson blev populär på Sun och spred sig till andra företag som öppen källkod.

Snabbspolning fram till 2011 och en tvist mellan Oracle (som hade förvärvat Sun) och den oberoende Hudson open source-communityn ledde till en gaffel med namnbyte, Jenkins. 2014 blev Kawaguchi CTO för CloudBees, som erbjuder Jenkins-baserade kontinuerliga leveransprodukter.

Båda gafflarna fortsatte att existera, även om Jenkins var mycket mer aktiv. Idag är Jenkins-projektet fortfarande aktivt. Hudson-webbplatsen stängdes den 31 januari 2020.

I mars 2019 lanserade Linux Foundation tillsammans med CloudBees, Google och ett antal andra företag en ny öppen källkodsstiftelse som heter Continuous Delivery Foundation (CDF). Jenkins bidragsgivare beslutade att deras projekt skulle gå med i den här nya stiftelsen. Kawaguchi skrev då att inget av betydelse skulle förändras för användarna.

I januari 2020 meddelade Kawaguchi att han flyttade till sin nya start, Launchable. Han sa också att han officiellt skulle gå tillbaka från Jenkins, även om han stannade kvar i den tekniska tillsynskommittén för Continuous Delivery Foundation, och bytte sin roll på CloudBees till en rådgivare.

Relaterad video: Hur man levererar kod snabbare med CI / CD

Jenkins automatisering

Idag är Jenkins den ledande automatiseringsservern med öppen källkod med cirka 1600 plug-ins för att stödja automatisering av alla typer av utvecklingsuppgifter. Problemet som Kawaguchi ursprungligen försökte lösa, kontinuerlig integration och kontinuerlig leverans av Java-kod (dvs. byggprojekt, körning av tester, analys av statisk kod och distribution) är bara en av många processer som människor automatiserar med Jenkins. Dessa 1600 plug-ins spänner över fem områden: plattformar, användargränssnitt, administration, källkodshantering och, oftast, bygghantering.

Hur Jenkins fungerar

Jenkins distribueras som ett WAR-arkiv och som installationspaket för de viktigaste operativsystemen, som ett Homebrew-paket, som en Docker-bild och som källkod. Källkoden är mestadels Java, med några Groovy-, Ruby- och Antlr-filer.

Du kan köra Jenkins WAR fristående eller som en servlet i en Java-applikationsserver som Tomcat. I båda fallen producerar det ett webbanvändargränssnitt och accepterar samtal till sitt REST API.

När du kör Jenkins för första gången skapar den en administrativ användare med ett långt slumpmässigt lösenord, som du kan klistra in på dess första webbsida för att låsa upp installationen.

Jenkins-plugin-program

När Jenkins är installerat kan du antingen acceptera listan med standardinsticksprogram eller välja dina egna insticksprogram.

När du väl har valt din ursprungliga uppsättning plugin-program klickar du på Installera-knappen så lägger Jenkins till dem.

Huvudskärmen för Jenkins visar den aktuella byggkön och Executor-statusen och erbjuder länkar för att skapa nya objekt (jobb), hantera användare, visa bygghistorik, hantera Jenkins, titta på dina anpassade vyer och hantera dina referenser.

Ett nytt Jenkins-objekt kan vara vilken som helst av sex typer av jobb plus en mapp för att organisera objekt.

Det finns 18 saker du kan göra från sidan Hantera Jenkins, inklusive möjligheten att öppna ett kommandoradsgränssnitt. Vid denna punkt bör vi dock titta på rörledningar, som är förbättrade arbetsflöden som vanligtvis definieras av skript.

Jenkins rörledningar

När du har konfigurerat Jenkins är det dags att skapa några projekt som Jenkins kan bygga åt dig. Även om du kan använda webbgränssnittet för att skapa skript, är den nuvarande bästa praxis för att skapa en pipeline manus som heter Jenkinsfile , och kolla in den på din förvaret. Skärmdumpen nedan visar konfigurationswebben för en multibranch-pipeline.

Som du kan se kan grenkällor för denna typ av pipeline i min grundläggande Jenkins-installation vara Git- eller Subversion-förvar, inklusive GitHub. Om du behöver andra typer av förvar eller andra onlineförvarstjänster är det bara att lägga till lämpliga plugin-program och starta om Jenkins. Jag försökte men kunde inte tänka på ett källkodshanteringssystem (SCM) som inte redan har ett Jenkins-plugin-program.

Jenkins-rörledningar kan vara deklarativa eller skriptade. En deklarativ pipeline, den enklare av de två, använder Groovy-kompatibel syntax — och om du vill kan du starta filen med för #!groovyatt peka din kodredigerare i rätt riktning. En deklarativ pipeline börjar med ett pipelineblock, definierar en agentoch definierar stagessom inkluderar körbar steps, som i tre-stegsexemplet nedan.

rörledning {

    agent någon

    etapper {

        scen ('Bygg') {

            steg {

                eko 'Building ..'

            }

        }

        scen ("Test") {

            steg {

                eko 'Testing ..'

            }

        }

        scen ('Distribuera') {

            steg {

                eko 'Deploying ....'

            }

        }

    }

}

pipelineär det obligatoriska yttre blocket för att åberopa Jenkins pipeline plugin. agentdefinierar var du vill köra rörledningen. anysäger att använda någon tillgänglig agent för att köra rörledningen eller scenen. En mer specifik agent kan förklara en behållare att använda, till exempel:

agent {

    docker {

        bild 'maven: 3-alpine'

        etikett 'min-definierade-etikett'

        args '-v / tmp: / tmp'

    }

}

stagesinnehåller en sekvens av ett eller flera scendirektiv. I exemplet ovan är de tre stegen Build, Test och Deploy.

stepsgöra det verkliga arbetet. I exemplet ovan stegen bara utskrivna meddelanden. Ett mer användbart byggsteg kan se ut som följande:

rörledning {

    agent någon

    etapper {

        scen ('Bygg') {

            steg {

                sh 'gör'

                archiveArtifacts artefakter: '** / target / *. jar', fingeravtryck: true

            }

        }

    }

}

Här åberopar vi makefrån ett skal och arkiverar sedan alla producerade JAR-filer till Jenkins-arkivet.

I postavsnitt definierar åtgärder som kommer att köras i slutet av rörledningen springa eller scen. Du kan använda ett antal post-condition block inom efter avsnitt: always, changed, failure, success, unstable, och aborted.

Till exempel kör Jenkinsfilen alltid JUnit efter testfasen, men skickar bara ett e-postmeddelande om pipelinen misslyckas.

rörledning {

    agent någon

    etapper {

        scen ("Test") {

            steg {

                sh 'gör check'

            }

        }

    }

    posta {

        alltid {

            junit '** / target / *. xml'

        }

        misslyckande {

            maila till: [email protected], ämne: 'Rörledningen misslyckades :('

        }

    }

}

Den deklarativa pipelinen kan uttrycka det mesta av vad du behöver för att definiera pipelines och är mycket lättare att lära sig än den skriptade pipeline-syntaxen, som är en Groovy-baserad DSL. Den skriptade pipelinen är i själva verket en fullständig programmeringsmiljö.

Som jämförelse är följande två Jenkinsfiles helt likvärdiga.

Deklarativ pipeline

rörledning {

    agent {docker 'nod: 6.3'}

    etapper {

        stage ('build') {

            steg {

                sh 'npm —version'

            }

        }

    }

Skriptad pipeline

nod ('docker') {

    kassa scm

    scen ('Bygg') {

        docker.image ('nod: 6.3'). inuti {

            sh 'npm —version'

        }

    }

}

Blue Ocean, Jenkins GUI

Om du vill ha det senaste och bästa Jenkins-gränssnittet kan du använda Blue Ocean-plugin-programmet, vilket ger en grafisk användarupplevelse. Du kan lägga till Blue Ocean-plugin-programmet till din befintliga Jenkins-installation eller köra en Jenkins / Blue Ocean Docker-behållare. Med Blue Ocean installerat kommer din Jenkins huvudmeny att ha en extra ikon:

Du kan öppna Blue Ocean direkt om du vill. Den finns i mappen / blue på Jenkins-servern. Pipeline-skapande i Blue Ocean är lite mer grafiskt än i vanliga Jenkins:

Jenkins Docker

Som jag nämnde tidigare distribueras Jenkins också som en Docker-bild. Det finns inte mycket mer i processen: När du väl har valt SCM-typen anger du en URL och referenser och skapar sedan en pipeline från ett enda arkiv eller skannar alla arkiv i organisationen. Varje filial med en Jenkinsfil får en pipeline.

Här kör jag en Blue Ocean Docker-avbildning, som levererades med några fler Git-tjänsteinsticksprogram installerade än standardlistan över SCM-leverantörer:

När du har kört några rörledningar visar plugin-programmet Blue Ocean deras status, som visas ovan. Du kan zooma in på en enskild pipeline för att se steg och steg:

Du kan också zooma in på grenar (överst) och aktiviteter (längst ner):  

-

Varför använda Jenkins?

Den Jenkins Pipeline-plugin som vi har använt stöder ett allmänt användningsfall för kontinuerlig integration / kontinuerlig leverans (CICD), vilket förmodligen är den vanligaste användningen för Jenkins. Det finns särskilda överväganden för vissa andra användningsfall.

Java-projekt var den ursprungliga grunden för Jenkins. Vi har redan sett att Jenkins stöder byggandet med Maven; det fungerar också med Ant, Gradle, JUnit, Nexus och Artifactory.

Android kör ett slags Java, men introducerar frågan om hur man testar på det breda utbudet av Android-enheter. Med plugin-programmet Android-emulator kan du bygga och testa så många emulerade enheter som du vill definiera. Med plugin-programmet Google Play Publisher kan du skicka byggnader till en alfakanal i Google Play för att släppas eller vidare testas på faktiska enheter.

Jag har visat exempel där vi angav en Docker-container som agent för en pipeline och där vi körde Jenkins och Blue Ocean i en Docker-container. Docker-behållare är mycket användbara i en Jenkins-miljö för att förbättra hastighet, skalbarhet och konsistens.

Det finns två stora användningsfall för Jenkins och GitHub. En är byggintegration, som kan inkludera en servicekrok för att utlösa Jenkins vid varje engagemang för ditt GitHub-arkiv. Den andra är användningen av GitHub-autentisering för att kontrollera åtkomst till Jenkins via OAuth.

Jenkins stöder många andra språk förutom Java. För C / C ++ finns plug-ins för att fånga fel och varningar från konsolen, generera byggskript med CMake, köra enhetstester och utföra statisk kodanalys. Jenkins har ett antal integrationer med PHP-verktyg.

Medan Python-kod inte behöver byggas (såvida du inte använder Cython till exempel eller skapar ett Python-hjul för installation) är det användbart att Jenkins integreras med Python-test- och rapporteringsverktyg, som Nose2 och Pytest, och kodkvalitet. verktyg som Pylint. På samma sätt integreras Jenkins med Ruby-verktyg som Rake, Gurka, Brakeman och CI :: Reporter.

Jenkins för CI / CD

Sammantaget erbjuder Jenkins ett enkelt sätt att skapa en CI / CD-miljö för i stort sett alla kombinationer av språk och källkodsförvar med pipelines, samt automatisera ett antal andra rutinutvecklingsuppgifter. Medan Jenkins inte eliminerar behovet av att skapa skript för enskilda steg, ger det dig ett snabbare och mer robust sätt att integrera hela din kedja av verktyg för att bygga, testa och distribuera än du enkelt kan bygga själv.