Git in CI/CD Pipelines: Jenkins, GitLab CI, GitHub Actions
What is CI/CD and why Git matters
Continuous Integration (CI) and Continuous Delivery (CD) are practices where code changes are automatically built, tested, and deployed. Git is the perfect version control backbone for these pipelines because every push can trigger a workflow. By integrating Git with CI/CD tools, you get immediate feedback, catch bugs early, and deliver features faster.
Key idea: Every Git event (push, pull request, tag) can automatically start a pipeline that builds, tests, and deploys your application. This is the foundation of modern DevOps.
Common CI/CD triggers from Git
Pipelines are usually triggered by specific Git actions:
- Push to a branch – e.g., running tests on feature branches
- Pull request / merge request – run validation before merging
- Tag creation – often used to deploy to production
- Scheduled runs – nightly builds based on the default branch
Jenkins + Git: classic automation
Jenkins is a self‑hosted automation server. It can poll your Git repository or use webhooks to trigger builds.
Example: Jenkins pipeline from a Jenkinsfile (stored in Git)
pipeline {
agent any
stages {
stage('Checkout') {
steps {
git 'https://github.com/user/my-app.git'
}
}
stage('Build') {
steps {
sh 'npm install'
sh 'npm run build'
}
}
stage('Test') {
steps {
sh 'npm test'
}
}
}
}
With this Jenkinsfile in the repository, Jenkins automatically fetches the code and runs the pipeline on every push.
GitHub Actions: workflows inside your repository
GitHub Actions uses YAML files stored in .github/workflows/. They are triggered by GitHub events.
Example: Run tests on every push
name: CI Pipeline
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- run: npm ci
- run: npm test
actions/checkout is the official action that checks out your Git repository so the workflow can access it.
GitLab CI: integrated with GitLab
GitLab CI uses a .gitlab-ci.yml file in the repository root. Pipelines run on GitLab runners.
Example: Build and test with GitLab CI
stages:
- build
- test
build-job:
stage: build
script:
- echo "Compiling the code..."
- make
artifacts:
paths:
- bin/
test-job:
stage: test
script:
- echo "Running tests..."
- make test
Handling Git branches in pipelines
Most CI systems provide environment variables with the branch name, commit hash, and tag. You can conditionally run steps based on the branch.
on:
push:
branches: [ main ]
# GitLab CI – run deploy job only for tags
deploy:
script: echo "Deploying..."
only:
- tags
Using Git commit information in builds
You can embed the Git commit hash into your application to know which version is running. Example with Node.js:
- name: Set commit hash
run: echo "REACT_APP_COMMIT_HASH=${{ github.sha }}" >> .env
In the code you can then display process.env.REACT_APP_COMMIT_HASH.
Protecting branches with CI checks
Modern Git hosting platforms allow you to require CI checks to pass before merging a pull request. For example, in GitHub you can set up branch protection rules that require the “CI Pipeline” check to succeed.
Why it matters: This ensures that no broken code ever reaches the main branch – your CI pipeline acts as a safety gate.
Practical workflow: from commit to production
- Developer pushes code to a feature branch.
- CI pipeline runs tests and linting.
- If tests pass, the branch can be merged via pull request.
- Merging to main triggers a new pipeline that builds and deploys to a staging environment.
- After manual approval (or automatically if tests pass), the same artifact is deployed to production.
All steps are defined in Git and versioned together with the code.
Exercise: Which CI system uses a Jenkinsfile stored in Git?
Frequently Asked Questions
Absolutely. In GitHub Actions you use on: push: tags: - 'v*'. In GitLab CI: only: - tags. Jenkins can be configured via webhooks or polling to detect tag pushes.
Both are YAML‑based and deeply integrated with their respective Git platforms. GitHub Actions is more focused on ecosystem integrations, while GitLab CI has a built‑in container registry and environments. The choice usually depends on where your code lives.
Use secrets management: GitHub Secrets, GitLab CI variables, or Jenkins credentials. They are masked in logs. Never hardcode secrets in your Git repository.
Yes. GitHub Actions supports on: push: paths: - 'backend/**'. GitLab CI has only: changes: - "frontend/*". This avoids running unnecessary builds.