CircleCI to GitLab CI Converter

Convert CircleCI 2.1 config.yml to .gitlab-ci.yml. Translates Docker executors, jobs, workflows, orb commands, restore_cache/save_cache, and artifacts.

Migrating from CircleCI to GitLab CI

Going CircleCI → GitLab is the inverse of the GitLab → CircleCI translation: each CircleCI workflow job becomes a GitLab job, with `requires:` mapped to `needs:` and stages assigned by topological depth. CircleCI cache pairs (`restore_cache` + `save_cache`) collapse into a single GitLab `cache:` block at the job level. Workspace persistence (`persist_to_workspace` / `attach_workspace`) becomes `needs: [<job>, artifacts: true]`.

Syntax cheat sheet

ConceptCircleCIGitLab CI
Executor imagedocker: [{ image: cimg/node:20 }]image: cimg/node:20
Workflow → stagesworkflows.main.jobs: - lint - test: requires: [lint]stages: [lint, test]
Cache- restore_cache: { keys } - save_cache: { key, paths }cache: key: <key> paths: [<path>]
Artifact- store_artifacts: { path }artifacts: paths: [<path>]
Orb command- node/install(shell equivalent)

Gotchas to watch for

  • warning

    Stages must be ordered explicitly

    GitLab requires a top-level `stages:` list. The converter generates one based on the topological order of CircleCI workflow jobs.

  • warning

    Pipeline parameters → variables

    CircleCI pipeline parameters (`<< pipeline.parameters.foo >>`) become GitLab `variables:` with the same default value. Rules referencing parameters become rules referencing variables.

  • warning

    Approval jobs become manual gates

    A `type: approval` job translates to a job with `when: manual` in GitLab. Define the trigger UX explicitly in `rules:`.

  • warning

    macOS executor has no equivalent

    GitLab's macOS runners are a separately-billed tier. The converter flags `macos:` jobs for manual review.

Worked examples

CircleCI Node → GitLab

Workflow flattens to stages: [test], single job.

CircleCI
version: 2.1
jobs:
  test:
    docker:
      - image: cimg/node:20.10
    steps:
      - checkout
      - run: npm ci
      - run: npm test
workflows:
  build:
    jobs: [test]
GitLab CI
stages:
  - stage-0
test:
  stage: stage-0
  image: cimg/node:20.10
  script:
    - npm ci
    - npm test

Frequently asked questions

How are orbs handled?expand_more

Common orbs map to shell commands or GitLab includes. Less common orbs become flagged stubs with a TODO comment.

What about CircleCI dynamic config?expand_more

Dynamic config and the continuation orb have no GitLab equivalent. Use GitLab's parent-child pipelines (`trigger: include:`) for similar fan-out.

Related Tools