What this converter does
Paste a bitbucket-pipelines.yml and you get a GitHub Actions workflow plus a list of everything that did not map cleanly. YAML anchors in definitions are resolved; every pipeline section (default, branches, pull-requests, tags, custom) becomes a chain of jobs with the right trigger condition. Conversion runs entirely in your browser; nothing is uploaded.
Common Atlassian pipes are mapped to Marketplace actions; others become TODO steps that fail loudly with their variables quoted.
How Bitbucket Pipelines concepts map to GitHub Actions
| Bitbucket Pipelines | GitHub Actions | Notes |
|---|---|---|
pipelines: default | jobs on push | Excluded on branches that have their own pipeline. |
branches: name | jobs with if: github.ref == … | Globs become startsWith. |
pull-requests: | on.pull_request jobs | |
tags: | on.push.tags jobs | |
custom: | workflow_dispatch with a pipeline choice | Pipeline variables become inputs. |
- step: | one job each, chained with needs | Later jobs download earlier jobs' artifacts. |
- parallel: | sibling jobs | The next step waits for all of them. |
- stage: | flattened steps with the stage's environment | |
image: | container: | Private image credentials become secrets; atlassian/default-image is dropped. |
services: | services: | From definitions.services; the docker service is dropped. |
caches: | actions/cache | Presets (node, pip, maven, gradle, composer …) and custom definitions. |
artifacts: | upload-artifact + download-artifact | |
deployment:, trigger: manual | environment: | Add required reviewers for manual steps. |
max-time, clone: depth, runs-on | timeout-minutes, fetch-depth, self-hosted labels | |
after-script | step with if: always() | |
pipe: atlassian/aws-s3-deploy, ssh-run, scp-deploy, slack-notify, npm-publish, heroku-deploy, firebase-deploy, aws-ecs-deploy … | matching actions or run: | docker://image pipes become docker run. |
$BITBUCKET_COMMIT, $BITBUCKET_BUILD_NUMBER … | env: shim | Used variables are defined from the github context. |
Things to check by hand
- Repository and deployment variables set in Bitbucket must be recreated as GitHub variables or secrets.
- Condition changesets become notes; use
on.push.pathsordorny/paths-filter. - Runner size (
size: 2x) has no direct equivalent; pick a larger hosted runner if memory matters.
FAQ
Is my pipeline uploaded anywhere?
No. The converter runs in your tab. Read bitbucket.js on GitHub.
Can I run this from the command line?
Yes: npx jenkins-to-actions convert bitbucket-pipelines.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.