Migrating GitHub Actions¶
GitLab CI/CD and GitHub Actions have some similarities in configuration, making migration to GitLab CI/CD relatively easy:
Workflow configuration files are written in YAML and are stored in the repository along with the code.
Workflows contain one or more jobs.
Jobs include one or more steps or individual commands.
Jobs can run on either managed or self-hosted machines.
However, there are also some differences, and this guide will show you the main differences so that you can migrate your workflow to GitLab CI/CD.
Jobs¶
Jobs in GitHub Actions are very similar to jobs in GitLab CI/CD. Both have the following characteristics:
Jobs contain a series of steps or scripts that are executed in sequence.
Jobs can be run on separate machines or in separate containers.
Jobs are executed in parallel by default, but can also be configured to run sequentially.
Jobs can execute a script or shell command, and in GitHub Actions all scripts are specified with the
run
key. In GitLab CI/CD, however, the script steps are specified with thescript
key.
Below is an example of the syntax of the two systems.
GitHub Actions syntax for jobs¶
jobs:
my_job:
steps:
- uses: actions/checkout@v4
- run: echo "Run my script here"
GitLab CI/CD syntax for jobs¶
my_job:
variables:
GIT_CHECKOUT: "true"
script:
- echo "Run my script here"
Runners¶
Runners are machines on which jobs are run. Both GitHub Actions and GitLab CI/CD
offer managed and self-hosted variants of runners. In GitHub Actions, the
runs-on
key is used to run jobs on different platforms, while in GitLab
CI/CD this is done with tags
.
GitHub Actions syntax for Runner¶
my_job:
runs-on: ubuntu-latest
steps:
- run: echo "Hello Pythonistas!"
GitLab CI/CD syntax for Runner¶
my_job:
tags:
- linux
script:
- echo "Hello Pythonistas!"
Docker images¶
GitHub Actions syntax for Docker images¶
jobs:
my_job:
container: python:3.10
GitLab CI/CD syntax for Docker images¶
my_job:
image: python:3.10
Syntax for conditions and expressions¶
GitHub Actions uses the if
keyword to prevent a job from running if a
condition is not met. GitLab CI/CD uses rules
to determine whether a job is
executed under a certain condition.
Below is an example of the syntax of the two systems.
GitHub syntax for conditions and expressions¶
jobs:
deploy:
if: contains( github.ref, 'main')
runs-on: ubuntu-latest
steps:
- run: echo "Deploy to production server"
GitLab syntax for conditions and expressions¶
deploy:
stage: deploy
script:
- echo "Deploy to production server"
rules:
- if: '$CI_COMMIT_BRANCH == "main"'
Besides if
, GitLab also offers other rules such as changes
, exists
,
allow_failure
, variables
and when
.
See also
Dependencies between jobs¶
Both GitHub Actions and GitLab CI/CD allow you to set dependencies for a job. In
both systems, jobs run in parallel by default, but GitLab CI/CD has a stages
concept where jobs in one stage run concurrently, but the next stage does not
start until all jobs in the previous stage have completed. In GitHub Actions,
dependencies between jobs can be explicitly mapped with the needs
key.
Below is an example of the syntax for each system. The workflows start with two
jobs running in parallel named unit-test
and lint
. When these jobs are
completed, another job called deploy-to-stage
is run. Finally, when
deploy-to-stage
is complete, the job deploy-to-prod
is executed.
GitHub Actions syntax for dependencies between jobs¶
jobs:
unit-test:
runs-on: ubuntu-latest
steps:
- run: echo "Running unit tests... This will take about 60 seconds."
- run: sleep 60
- run: echo "Code coverage is 0%"
lint:
runs-on: ubuntu-latest
steps:
- run: echo "Linting code... This will take about 10 seconds."
- run: sleep 10
- run: echo "No lint issues found."
deploy-to-stage:
runs-on: ubuntu-latest
needs: [unit-test,lint]
steps:
- run: echo "Deploying application in staging environment..."
- run: echo "Application successfully deployed to staging."
deploy-to-prod:
runs-on: ubuntu-latest
needs: [deploy-to-stage]
steps:
- run: echo "Deploying application in production environment..."
- run: echo "Application successfully deployed to production."
GitLab CI/CD syntax for dependencies between jobs¶
stages:
- test
- stage
- prod
unit-test:
stage: test
script:
- echo "Running unit tests... This will take about 60 seconds."
- sleep 60
- echo "Code coverage is 0%"
lint:
stage: test
script:
- echo "Linting code... This will take about 10 seconds."
- sleep 10
- echo "No lint issues found."
deploy-to-stage:
stage: stage
script:
- echo "Deploying application in staging environment..."
- echo "Application successfully deployed to staging."
deploy-to-prod:
stage: prod
script:
- echo "Deploying application in production environment..."
- echo "Application successfully deployed to production."
Artefacts¶
Both GitHub Actions and GitLab CI/CD can upload files and directories created by a job as artefacts. These artefacts can be used to preserve data across multiple jobs.
Below is an example of the syntax for both systems.
GitHub Actions syntax for artefacts¶
- name: Archive code coverage results
uses: actions/upload-artifact@v3
with:
name: code-coverage-report
path: output/test/code-coverage.html
GitLab CI/CD syntax for artefacts¶
script:
artifacts:
paths:
- output/test/code-coverage.html
Databases and service containers¶
Both systems allow you to include additional containers for databases, caching or other dependencies.
GitHub Actions uses the container
key, while in GitLab CI/CD a container for
the job is specified with the image
key. In both systems, additional service
containers are specified with the services
key.
Below is an example of the syntax of the two systems.
GitHub Actions syntax for databases and service containers¶
jobs:
test:
runs-on: ubuntu-latest
services:
postgres:
image: postgres
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: postgres
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- name: Python
uses: actions/checkout@v4
uses: actions/setup-python@v5
with:
python-version: '3.10'
- name: Test with pytest
run: python -m pytest
env:
DATABASE_URL: 'postgres://postgres:postgres@localhost:${{ job.services.postgres.ports[5432] }}/postgres'
GitLab CI/CD syntax for database and service containers¶
test:
variables:
POSTGRES_PASSWORD: postgres
POSTGRES_HOST: postgres
POSTGRES_PORT: 5432
image: python:latest
services:
- postgres
script:
- python -m pytest
Mapping¶
GitHub |
GitLab |
---|---|
Concepts |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Environment variables |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|