Migrate our CI/CD pipeline from CircleCI to GitHub Actions. For each repository:
1. Read the existing .circleci/config.yml
2. Create an equivalent .github/workflows/ci.yml
3. Map CircleCI jobs to GitHub Actions jobs, preserving:
- Build steps and commands
- Environment variables (use GitHub Actions env: syntax)
- Caching strategies (convert CircleCI cache keys to actions/cache)
- Artifact uploads (convert to actions/upload-artifact)
- Service containers (convert to services: in the job)
4. Use ubuntu-latest as the runner unless the CircleCI config specifies a specific OS
5. Convert CircleCI orb commands to their equivalent GitHub Actions or inline steps
6. Preserve any workflow-level dependencies between jobs using needs:
7. Remove the .circleci/ directory
Do not modify any application code, test commands, or build scripts, only migrate the CI configuration. The Problem
When your organization decides to move from CircleCI to GitHub Actions, every repository with a CI pipeline needs its configuration rewritten. The CircleCI `config.yml` syntax (orbs, executors, workflows, jobs) doesn't map one-to-one to GitHub Actions. Each repo may use different CircleCI features: some use orbs for common tasks, others have complex workflow fan-out/fan-in patterns, and many rely on CircleCI-specific caching mechanisms.
The migration itself isn't conceptually hard for any single repo. A developer who knows both platforms could convert one config file in 30 minutes. But when you multiply that by 200 repositories, factor in the review cycles with each team, and add the coordination overhead of tracking which repos have been migrated, you're looking at weeks or months of work that competes directly with feature development.
Most teams end up running both CI platforms in parallel for far longer than planned, paying for two systems while the migration stalls at 60% complete.
What Tidra Does
- Reads each repository's
.circleci/config.ymlto understand the existing pipeline structure, including orbs, executors, and workflow dependencies - Maps CircleCI concepts to GitHub Actions equivalents, orb commands become action steps or inline scripts, executors become runner specifications, workflow triggers become
on:event configurations - Generates a new
.github/workflows/ci.ymlfile with the equivalent pipeline, preserving build steps, environment variables, caching, and artifact handling - Removes the
.circleci/directory from each repository - Creates a pull request with a clear description explaining what changed and any manual steps needed (e.g., setting up GitHub Actions secrets)
Before & After
Customization Tips
- Parallel jobs: If your CircleCI config uses
workflowswith parallel jobs, map them usingneeds:in GitHub Actions to preserve the dependency graph. - Self-hosted runners: Replace
ubuntu-latestwith your self-hosted runner label if your builds need access to internal resources. - Monorepo path filters: Add
paths:filters underon.pushif you only want to trigger builds when specific directories change. - Matrix builds: Add
strategy: { matrix: { node-version: [18, 20, 22] } }if you need to test across multiple runtimes. - Secrets: CircleCI environment variables stored in project settings need to be recreated as GitHub Actions secrets. Add a note in the PR description listing which secrets are required.