What this converter does
Paste a .circleci/config.yml and you get a GitHub Actions workflow plus a list of everything that did not map cleanly. Executors are resolved, reusable commands are expanded inline with their parameters, and every workflow becomes a set of jobs with needs. Conversion runs entirely in your browser; nothing is uploaded.
Orbs are not fetched. The commonest orb steps (node, python, docker, aws-cli, codecov, slack, browser-tools) are mapped; others become TODO steps that fail loudly with the original quoted.
How CircleCI concepts map to GitHub Actions
| CircleCI | GitHub Actions | Notes |
|---|---|---|
docker: executor | container: + services: | First image is the job container; the rest become services. |
machine: / macos: | runs-on | ubuntu, windows, macOS and arm classes. |
executors: | resolved into each job | |
commands: | inlined steps | << parameters.x >> substituted. |
workflows: jobs: requires | needs: | Several workflows merge into one file with prefixed job ids. |
filters: branches / tags | if: | Tag-only jobs detected; on.push.tags added. |
type: approval | environment: manual-approval | Add required reviewers. |
triggers: schedule | on.schedule + if: github.event_name == 'schedule' | Other workflows get the opposite condition. |
matrix: parameters | strategy.matrix | |
parallelism: N | index matrix | Replace circleci tests split with your own sharding. |
restore_cache / save_cache | actions/cache | {{ checksum "f" }} becomes hashFiles('f'). |
persist_to_workspace / attach_workspace | upload-artifact / download-artifact | Sources found by walking needs. |
store_artifacts, store_test_results | upload-artifact, action-junit-report | |
when: / unless: steps | step if: | Simple equal and parameter conditions. |
setup_remote_docker, add_ssh_keys | dropped / webfactory/ssh-agent | Docker is native on the runner. |
$CIRCLE_SHA1, $CIRCLE_BRANCH … | env: shim | Used variables are defined from the github context. |
pipeline.parameters, contexts | workflow_dispatch.inputs, secrets | Contexts must be recreated as secrets. |
Things to check by hand
- Orb jobs (
node/test,aws-ecr/build-and-push-image…) are not expanded; write the equivalent job from the Marketplace action. - Secondary containers were reachable on
localhostin CircleCI; on GitHub they are reachable by service name from a container job. - Dynamic config (
setup: true) cannot be converted; convert the generated config instead.
FAQ
Is my config uploaded anywhere?
No. The converter runs in your tab. Read circleci.js on GitHub.
Can I run this from the command line?
Yes: npx jenkins-to-actions convert .circleci/config.yml.
Migrating a whole organisation?
The same converters ship as a command-line audit. Point it at a GitHub organisation, a GitLab group, an Azure DevOps organisation, a Bitbucket workspace or a Jenkins server and it inventories every CI configuration it finds, converts what it can, estimates the effort per repository and lists the secrets to create. With --open-prs it opens a pull request in each GitHub repository with the workflow and the notes. Nothing is sent anywhere except the platform you point it at.
GITHUB_TOKEN=… npx jenkins-to-actions audit --github-org acme # report + workflows GITHUB_TOKEN=… npx jenkins-to-actions audit --github-org acme --open-prs # one PR per repository GITLAB_TOKEN=… npx jenkins-to-actions audit --gitlab-group acme/platform AZURE_DEVOPS_TOKEN=… npx jenkins-to-actions audit --azure-org acme npx jenkins-to-actions audit --bitbucket-workspace acme --user me --token APP_PASSWORD npx jenkins-to-actions audit --url https://jenkins.example.com --user me --token APITOKEN
See a real result: this pull request was opened by one command on a repository holding one config per system. The README has the details, and the migration page describes the fixed-fee audit if you would rather have it done for you. Once you are on Actions, the cost calculator and the free CI Cost Report action show what the minutes cost.