Migrate from GitLab CI to GitHub Actions: Step-by-Step
Moving from GitLab CI to GitHub Actions is mostly a translation job: .gitlab-ci.yml become workflows and jobs. This guide maps the concepts and walks the steps.
GitLab CI and GitHub Actions share the same building blocks - pipelines, jobs, and steps - under different names. The migration is methodical: translate the config, port secrets and caching, and verify in parallel before cutting over.
Concept mapping
| GitLab CI | GitHub Actions |
|---|---|
| .gitlab-ci.yml | Workflow (.github/workflows/*.yml) |
| job | Job (jobs.<id>) |
| Step / command | Step (run: or uses:) |
| CI/CD variables | Encrypted secrets / variables |
| cache: | actions/cache |
| Agent / executor | Runner (runs-on:) |
Migration steps
- Inventory your GitLab CI pipelines and list every job, trigger, and secret.
- Create
.github/workflows/ci.ymland translate one pipeline at a time. - Move secrets into GitHub Actions encrypted secrets (port stages and rules).
- Add
actions/cachefor dependencies to match prior build speed. - Run the new workflow in parallel with the old pipeline on a branch and compare results.
- Cut over once green, then archive the old config.
Common pitfalls
stagesandneedsmap to GitHubneedsdependencies.rules:/only:/except:becomeon:triggers andif:conditions.- GitLab
artifactsmap toactions/upload-artifact.
After you migrate: cut cost and flakiness
Once on GitHub Actions, the next wins are cost and reliability. Managed runners like Latchkey run the same workflows at roughly 69% lower per-minute cost, and self-healing retries transient failures automatically - so the pipeline you just migrated stays green and cheap.
Key takeaways
- .gitlab-ci.yml map cleanly to GitHub Actions workflows.
- Port secrets and caching to match speed and security.
- Run both pipelines in parallel before cutting over.
- Then move to managed runners to cut cost and flaky re-runs.