Migrate from Concourse to GitHub Actions: Step-by-Step
Moving from Concourse to GitHub Actions is mostly a translation job: Pipeline (jobs + resources) become workflows and jobs. This guide maps the concepts and shows the before/after.
Concourse and GitHub Actions share the same primitives - 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
| Concourse | GitHub Actions |
|---|---|
| Pipeline (jobs + resources) | Workflow (.github/workflows/*.yml) |
| job / task | Job (jobs.<id>) |
| Step / command | Step (run: or uses:) |
| Credential manager (Vault, etc.) | Encrypted secrets / variables |
| task caches / resource versions | actions/cache |
| Agent / executor | Runner (runs-on:) |
Before and after
jobs:
- name: test
plan:
- get: repo
- task: run-tests
config:
run:
path: sh
args: ["-c", "npm ci && npm test"]The GitHub Actions equivalent
name: CI
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci && npm testMigration steps
- Inventory your Concourse 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 resources and put/get steps).
- 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
- Concourse
resourcesandget/putsteps have no direct equal - checkout isactions/checkout, and publishing becomes explicit steps or actions. - Concourse
passed:constraints between jobs map toneeds:. - External credential managers map to GitHub secrets (or OIDC for cloud creds).
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 than GitHub-hosted, warm pools remove queue time, and self-healing retries transient failures automatically - so the pipeline you just migrated stays green and cheap. The switch is usually a one-line runs-on: change.
Key takeaways
- Pipeline (jobs + resources) 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.