Blog

Från Jenkins till GitLab CI: Hur kommer du i gång?

DEC 6, 2024

Har jag rätt i att du hittade den här sidan eftersom du söker vägledning i hur du börjar migrera från Jenkins till GitLab CI? Om svaret är ja har du kommit rätt! Men innan vi dyker in börjar vi med en snabb introduktion till vad vi menar när vi pratar om pipelines för mjukvaruutveckling.

Joonas Jauhiainen

DevOps Lead

Joonas is a DevOps lead with experience in telecom, banking, insurance, and manufacturing, among other industries. His hobbies include investigation of IT devices, developing games and other SW projects not to mention underwater rugby!

Enligt Wikipedia: 

A software pipeline is an automated process for executing defined stages in software development—build, test, deploy, and release—in a systematic, repeatable way.

När du förstår vad en pipeline är ser du hur valet av CI/CD-verktyg påverkar arbetsflödets effektivitet och tillförlitlighet. Eftersom GitLab CI är ditt nya verktyg markerar det början på ett nytt kapitel i mjukvarans livscykel och förändrar även teamets arbetssätt.

Innan du försöker göra en 1:1-migrering (vilket troligen inte kommer att vara möjligt) rekommenderar jag att du stannar upp och diskuterar med teamet om ni är nöjda med hur er pipeline har fungerat hittills. Du kan använda olika verktyg för att underlätta samtalet, till exempel vårt pipelinespel!

Kom igång med migreringen

Nu när du har tagit fram dina planer, vad är målet med pipelinen och hur skapar den värde för dig och utvecklingsteamet som använder den (det bästa är förstås om du själv ingår i utvecklingsteamet)? Låt oss se vad vi behöver.

För att komma igång med en migrering från Jenkins till GitLab CI rekommenderar jag att du har följande kunskaper:

  • YAML

  • YAML

  • YAML

  • Förståelse för teamets domän och arbete

Varför fokusera så mycket på YAML? Svaret är enkelt: Allt i GitLab CI använder YAML-syntax. Nästa del av kursen handlar om att förstå vad som behövs från Jenkins i GitLab CI.

Terminologi inom CI

Eftersom GitLab CI är ett helt annat verktyg än Jenkins (tekniskt sett är båda förhärligade cronjob-körare) är det viktigt att enas om terminologin.

Jenkins

GitLab

Difference

Agent/Node

GitLab runner

In Jenkins, an "agent" or "node" is a machine where jobs run. In GitLab, the equivalent is a "runner," which executes jobs defined in .gitlab-ci.yml. GitLab offers shared runners (hosted by GitLab) or self-managed runners.

Jenkinsfile

.gitlab-ci.yml

The Jenkinsfile defines the pipeline in Jenkins, typically using Groovy-based syntax. In GitLab CI, the pipeline is defined using the .gitlab-ci.yml file, which uses YAML syntax.

Stages and steps

Stages and jobs

A pipeline is divided into stages in both Jenkins and GitLab CI. In Jenkins, each stage contains multiple steps, while in GitLab CI, a stage contains jobs (which can run sequentially or in parallel).

Trigger / Build trigger

Pipeline triggers

Jenkins triggers jobs via SCM polling, webhook, or manual triggers. GitLab has similar options, such as webhooks, schedules, and manual pipeline runs, but GitLab also integrates with GitLab-specific events (e.g., push events).

Workspace

CI/CD Runner directory

In Jenkins, the workspace is a directory on the agent machine where jobs run. The runner's working directory functions similarly in GitLab, but the GitLab Runner manages it, and artifacts are stored differently (using GitLab's artifact storage).

Jenkins plugin

GitLab CI templates /components

GitLab CI minimizes dependency on external extensions, simplifying management. Components provide modularity, while templates enable reuse. Explore more at GitLab CI Catalog.

Artifacts

Artifacts

Both Jenkins and GitLab CI allow the storage of build artifacts (e.g., logs and reports). GitLab CI has a built-in feature for managing and downloading artifacts stored for a specific duration or pipeline job.

Jobs

Jobs

In Jenkins, a job represents a single unit of work (e.g., a build). In GitLab, a job is a single task within a pipeline stage. The key difference is how jobs are defined and executed in .gitlab-ci.yml vs. in Jenkins' job configuration.

Jenkins

GitLab

Skillnad

Agent/nod

GitLab runner

I Jenkins är en ”agent” eller ”nod” en maskin där jobb körs. I GitLab är motsvarigheten en ”runner”, som kör jobb definierade i .gitlab-ci.yml. GitLab erbjuder delade runners (hostade av GitLab) eller self-managed runners.

Jenkinsfile

.gitlab-ci.yml

Jenkinsfile definierar pipelinen i Jenkins, vanligtvis med Groovy-baserad syntax. I GitLab CI definieras pipelinen i filen .gitlab-ci.yml, som använder YAML-syntax.

Faser och steg

Faser och jobb

En pipeline delas in i faser i både Jenkins och GitLab CI. I Jenkins innehåller varje fas flera steg, medan en fas i GitLab CI innehåller jobb (som kan köras sekventiellt eller parallellt).

Trigger / Build-trigger

Pipeline-triggers

Jenkins triggar jobb via SCM-pollning, webhook eller manuella triggers. GitLab har liknande alternativ, som webhooks, scheman och manuella pipeline-körningar, men GitLab integrerar också med GitLab-specifika händelser (t.ex. push-händelser).

Arbetsyta

CI/CD Runner-katalog

I Jenkins är arbetsytan en katalog på agentmaskinen där jobb körs. Runnerns arbetskatalog fungerar på liknande sätt i GitLab, men hanteras av GitLab Runner och artefakter lagras på ett annat sätt (med GitLabs artefaktlagring).

Jenkins-plugin

GitLab CI-mallar /komponenter

GitLab CI minimerar beroendet av externa tillägg, vilket förenklar hanteringen. Komponenter ger modularitet, medan mallar möjliggör återanvändning. Läs mer i GitLab CI Catalog.

Artefakter

Artefakter

Både Jenkins och GitLab CI gör det möjligt att lagra buildartefakter (t.ex. loggar och rapporter). GitLab CI har en inbyggd funktion för att hantera och ladda ner artefakter som lagras under en viss tidsperiod eller för ett specifikt pipeline-jobb.

Jobb

Jobb

I Jenkins representerar ett jobb en enskild arbetsenhet (t.ex. en build). I GitLab är ett jobb en enskild uppgift i ett pipeline-steg. Den viktigaste skillnaden är hur jobb definieras och körs i .gitlab-ci.yml jämfört med i Jenkins jobbkonfiguration.

De miljöer du behöver

Som vi kan se av terminologin har GitLab CI inte några "inbyggda" eller "noder" eller ”agenter” på samma sätt som Jenkins. I stället används runners. Här kommer din domänexpertis in i bilden, eftersom du behöver ta hänsyn till teamets specifika krav.

Vilka miljöer behöver du? Du måste konfigurera egna runners om du kör GitLab on-premises. De kan köras direkt på Linux, Windows eller macOS. Du kan också köra dem via Docker på dessa operativsystem eller använda Kubernetes för att orkestrera Docker-runners på begäran i bakgrunden. Om du har valt GitLab.com (SaaS-alternativet) kan du använda publika runners, beroende på företagets policyer.

Nu när du har definierat dina krav är det dags att utvärdera dina befintliga Jenkins-noder/-agenter. Kontrollera om de kan återanvändas genom att installera GitLab Runner, eller om det är dags att avveckla dem och skicka dem till det stora server-Valhalla, där all pensionerad hårdvara får vila.

Tips när du konverterar från Jenkinsfile till GitLab CI-yaml-fil

Innan du börjar med .gitlab-ci.yaml-filen bör du titta på dina befintliga Jenkinsfiles eller konfigurationer för freestyle-jobb.

Förstår du verkligen vad de gör? Om svaret är nej rekommenderar jag starkt att du först betalar av den tekniska skulden och använder tasker-verktyget.

sh '''

if ! command -v node &> /dev/null; then

curl -fsSL https://deb.nodesource.com/setup_${LTS}.x -o nodesource_setup.sh

            bash nodesource_setup.sh

            rm nodesource_setup.sh

            apt-get install -y nodejs

else

node -v

fi

npm install -g grunt-cli

rm -rf node_modules && ||

npm cache clean --force && npm install -g npm@latest

npm -v

npm outdated --long

npm install

npm audit fix

npm ls --depth=0

npm cache verify

node -v

npm install --no-save eslint prettier jest

which node

which npm

npm ls -g --depth=0

'''

Detta kan alltså omvandlas till exempelvis sh 'npm run install-global-dependencies'

Nu till de konkreta tipsen och knepen. Det kan finnas goda skäl att ha shell-/bash-skript över flera rader som inte motiverar att de läggs i en task runner eller en separat skriptfil.

Exempel med flera rader från Jenkins

 sh '''

# Skapa en virtuell Python-miljö

python3 -m venv venv

# Activate the virtual environment

source venv/bin/activate

# Install dependencies from requirements.txt

pip install -r requirements.txt

# Run the Python script

python my_script.py

# Avaktivera den virtuella miljön

deactivate

'''

Så använder du artefakter från olika steg

I Jenkinsfile finns steg som kallas stash och unstash för att lagra buildbinärer och andra artefakter under pipelinekörningen. GitLab har inget motsvarande koncept, men har konceptet ”artifacts”.

Exempel på Jenkinsfile:

stage('Build Python Project') {

steps {

script {

// Build the Python project using pdm

sh '''

pdm build

'''

// Stash the build artifacts (e.g., .whl or .tar.gz files)

stash name: 'build-artifacts', includes: 'dist/*'

}

}

}

stage('Deploy Python Project') {

steps {

script {

// Unstash the build artifacts from the previous stage

unstash 'build-artifacts'

// Installera det byggda paketet från dist-mappen

sh '''

pip install dist/*.whl

python -m my_module

'''

}

}

}

Exempel på GitLab CI-yaml:

build_python_project:

  stage: build

  script:

- pdm build  # Bygg Python-projektet

  artifacts:

sökvägar:

- dist/*  # Lagra de byggda artefakterna (t.ex. .whl, .tar.gz)

expire_in: 1 hour  # Ange utgångstid för artefakterna

deploy_python_project:

  stage: deploy

  dependencies:

- build_python_project  # Detta säger åt GitLab CI att använda artefakter från build-steget

  script:

- pip install dist/*.whl  # Installera det byggda wheel-paketet

- python -m my_module  # Kör Python-modulen

Åtgärder efter build

I Jenkins är åtgärder efter build kraftfulla. Du kan definiera dem med ytterligare steg, till exempel always, failure och cleanup. I GitLab har du bara after_script, som förstås kan innehålla villkor. En av de största sakerna jag lade märke till i GitLab CI är att du inte kan få pipelinen att misslyckas med blocket after_script. Om du alltså vill att pipelinen ska misslyckas, till exempel om dina enhetstester inte når en tillräckligt hög godkännandegrad, behöver du göra det i ett script-block i stället för i after_script.

Jenkinsfile-exempel:

stage('Run JUnit Tests') 

  steps 

script {

sh 'mvn test'

}

  }

  post {

always {

junit '**/target/test-classes/*.xml'

}

  }

}

Exempel på GitLab CI YAML:

test:

  stage: test

  script:

- mvn test

  after_script:

- |

if [ -f "target/test-classes/*.xml" ]; then

echo "JUnit test results found. Archiving..."

# Use GitLab's artifact feature to store the test results

mv target/test-classes/*.xml /tmp/junit-test-results/

else

echo "No JUnit test results found."

            exit 1 # doesn’t affect the pipeline status

fi

  artifacts:

paths:

- /tmp/junit-test-results/*.xml

expire_in: 1 hour

Här är några konkreta exempel på vad du kan stöta på vid en 1:1-migrering från Jenkinsfiles till GitLab CI YAML. Jag rekommenderar starkt att du kör YAMLLint lokalt mot filen .gitlab-ci.yml innan du pushar den till fjärrrepo:t. AI-verktyg som GitHub Copilot kan också vara användbara för att göra grovjobbet när du har skaffat dig en grundläggande förståelse.

Jenkins-pluginer

”Men hur är det med Jenkins-pluginer?” kanske du undrar. De tidigare exemplen nämnde eller använde dem inte eftersom GitLab CI inte är beroende av pluginer. Slipp hantering av pluginer och problem med Maven-/Gradle-versioner eller Java-beroenden!

I stället för pluginer och delade bibliotek använder GitLab CI mallar! GitLab erbjuder många fördefinierade mallar som du kan skapa och dela inom hela organisationen.

Ett annat alternativ till pluginer är att leta efter CLI-verktyg för olika användningsfall. JFrog erbjuder till exempel både en Artifactory Jenkins-plugin och ett CLI-verktyg.

I stället för att skapa ett eget anpassat verktyg rekommenderar jag därför att du först undersöker om det redan finns ett lämpligt verktyg tillgängligt direkt.

Sammanfattning

Innan du påbörjar det faktiska arbetet rekommenderar jag att du tar dig tid att planera. Ställ följande frågor till dig själv och teamet som använder pipelinen:

  • Producerar den nuvarande pipelinen det resultat vi behöver?

  • Skapar den nuvarande pipelinen värde för oss?

  • Vad är det mest irriterande med den nuvarande pipelinen?

Att byta verktyg är som att börja med en tom duk – en situation som bör hanteras varsamt.

När pipeline-målen och grindvakterna har definierats bör du jämföra dem med vad som behövs från det gamla systemet. Därefter kan du börja det faktiska arbetet. Ta också tid att bekanta dig med GitLab CI/CD – förstå vad som finns och var. Webbgränssnittet skiljer sig en hel del från Jenkins, så jag rekommenderar att du går en utbildning eller åtminstone tittar på några exempelvideor.

Och om du behöver hjälp med uppgiften är du alltid välkommen att kontakta oss!

  • GitLab
  • CI/CD
  • Software development

Subscribe to our newsletter