How to Automate Sync from Bitbucket to GitHub Using Bitbucket Pipelines

How to Automate Sync from Bitbucket to GitHub Using Bitbucket Pipelines

Publish Date: Aug 22 '25
1 0

This guide walks you through setting up automated syncing from a private Bitbucket repository to GitHub using Bitbucket Pipelines, helping you leverage GitHub's generous CI/CD minutes while keeping Bitbucket as your primary development hub.

Overview

Here's why I have made the sync :
Bitbucket offers only 50 free pipeline minutes, while GitHub provides 2000 minutes - a significant difference for CI/CD workflows. Bitbucket remains my primary repository where all development happens. Only sync the main branch and git tags to create a broad deployment pipeline from Git.

How It Works

  1. You push code or create tags in Bitbucket → Bitbucket Pipelines automatically triggers → Only new commits on main branch and new tags get pushed to GitHub → Then you can do anything with Github actions later.

Prerequisites

Before starting, ensure you have:

  • Administrative access to both repositories (Bitbucket source and GitHub target)
  • Private repositories on both Bitbucket and GitHub
  • Git installed locally for initial full mirror setup
  • SSH key authentication already set up for your local machine (skip if already configured)

Optional: SSH Authentication Setup (Skip if Already Configured)

If you haven't set up SSH authentication with GitHub and Bitbucket, follow these steps:

Generate SSH Key Pair

ssh-keygen -t ed25519 -C "actual_email@example.com"
Enter fullscreen mode Exit fullscreen mode

Add SSH Key to SSH Agent

eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
Enter fullscreen mode Exit fullscreen mode

Copy Public Key to Clipboard

cat ~/.ssh/id_ed25519.pub
Enter fullscreen mode Exit fullscreen mode

Add to GitHub and Bitbucket

  1. GitHub: Settings (user) → SSH and GPG keys → New SSH key → Paste your key
  2. Bitbucket: Personal settings → SSH keys → Add key → Paste your key

Upload SSH keys

Test SSH Connection

ssh -T git@github.com
ssh -T git@bitbucket.org
Enter fullscreen mode Exit fullscreen mode

Configure Git

git config --global user.name "Your Name"
git config --global user.email "your_email@example.com"
Enter fullscreen mode Exit fullscreen mode

Step-by-Step Mirror and Sync Setup

Step 1: Create GitHub Repository

  1. Go to GitHub and create a new private repository.
  2. Important: Do not initialize with README, .gitignore, or license
  3. Note your GitHub repository URL: git@github.com:username/repository-name.git

Step 2: Enable Bitbucket Pipelines

  1. In your Bitbucket repository, go to Repository Settings
  2. Navigate to PipelinesSettings
  3. Enable Pipelines by toggling the switch

enable pipeline

Step 3: Generate SSH Keys in Bitbucket

  1. Go to Repository SettingsPipelinesSSH keys
  2. Click Generate keys then
  3. Copy the public key to your clipboard
  4. most of the time system detects known host so don't need to add.

Generate keys in bitbucket

Step 4: Configure GitHub Deploy Key

  1. Go to your GitHub repository
  2. Navigate to SettingsDeploy keys
  3. Click Add deploy key
  4. Paste the Bitbucket public key
  5. Check "Allow write access"
  6. Click Add key

Paste the deploy key, and give write access

Step 5: Configure Bitbucket Access Key

  1. Return to Bitbucket Repository SettingsSecurityAccess keys
  2. Click Add key
  3. Paste the same public key you used for GitHub
  4. This allows Bitbucket to authenticate with your repository

Paste the key

Step 6: Initial Full Mirror (One-Time Setup)

Run this command on your local machine to sync past commits:

# Clone the Bitbucket repository
git clone --mirror git@bitbucket.org:your-workspace/your-repo.git

# Navigate to the repository
cd your-repo.git

# Add GitHub as a remote
git remote add github git@github.com:your-username/your-github-repo.git

# Push everything to GitHub (one-time full sync)
git push --mirror github
Enter fullscreen mode Exit fullscreen mode

Why do this locally? If you add logic of mirror in pipelines than that will runs all the time , which is resource and time taking, instead for once locally in a temporary folder we can mirror that, once successful then we can delete the local folder.

Step 7: Create Pipeline Configuration

Create a bitbucket-pipelines.yml file in your Bitbucket repository root, or locally & push that . Choose one of these two options (I recommend Option A for simplicity):

Option A: Using Bitbucket Built-in SSH Key (Recommended)

image: atlassian/default-image:3

pipelines:
  branches:
    main:
      - step:
          name: Sync main branch to GitHub
          image: alpine/git:latest
          clone:
            enabled: false
          script:
            - git clone --branch=main --single-branch git@bitbucket.org:your-workspace/your-repo.git
            - cd your-repo
            - git remote add github git@github.com:your-username/your-github-repo.git
            - git push github main

  tags:
    '*':
      - step:
          name: Sync new tag to GitHub
          image: alpine/git:latest
          clone:
            enabled: false
          script:
            - git clone --branch=main --single-branch git@bitbucket.org:your-workspace/your-repo.git
            - cd your-repo
            - git remote add github git@github.com:your-username/your-github-repo.git
            - git push github $BITBUCKET_TAG
Enter fullscreen mode Exit fullscreen mode

Option B: Using Custom SSH Key (Advanced)

If you prefer using your own SSH key:

  1. Generate a custom SSH key pair locally:
ssh-keygen -t ed25519 -C "bitbucket-pipeline" -f bitbucket_pipeline_key
Enter fullscreen mode Exit fullscreen mode
  1. Encode the private key:
base64 -w 0 < bitbucket_pipeline_key
Enter fullscreen mode Exit fullscreen mode
  1. Add the public key to GitHub deploy keys (with write access)

  2. Add the base64-encoded private key as a secured variable in Bitbucket:

    • Go to Repository SettingsPipelinesRepository variables
    • Create variable GITHUB_SSH_KEY with the base64 value
    • Check "Secured"
  3. Use this pipeline configuration:

image: atlassian/default-image:3

pipelines:
  branches:
    main:
      - step:
          name: Sync main → GitHub
          image: alpine/git:latest
          clone:
            enabled: false
          script:
            - apk add --no-cache openssh-client
            - mkdir -p ~/.ssh
            - echo "$GITHUB_SSH_KEY" | base64 -d > ~/.ssh/id_ed25519
            - chmod 600 ~/.ssh/id_ed25519
            - ssh-keyscan -H github.com >> ~/.ssh/known_hosts
            - git clone --branch=main --single-branch git@bitbucket.org:your-workspace/your-repo.git
            - cd your-repo
            - git remote add github git@github.com:your-username/your-github-repo.git
            - GIT_SSH_COMMAND='ssh -i ~/.ssh/id_ed25519' git push github main

  tags:
    '*':
      - step:
          name: Sync new tag → GitHub
          image: alpine/git:latest
          clone:
            enabled: false
          script:
            - apk add --no-cache openssh-client
            - mkdir -p ~/.ssh
            - echo "$GITHUB_SSH_KEY" | base64 -d > ~/.ssh/id_ed25519
            - chmod 600 ~/.ssh/id_ed25519
            - ssh-keyscan -H github.com >> ~/.ssh/known_hosts
            - git clone --branch=main --single-branch git@bitbucket.org:your-workspace/your-repo.git
            - cd your-repo
            - git remote add github git@github.com:your-username/your-github-repo.git
            - GIT_SSH_COMMAND='ssh -i ~/.ssh/id_ed25519' git push github $BITBUCKET_TAG
Enter fullscreen mode Exit fullscreen mode

Step 8: Commit Pipeline Configuration

  1. Add the bitbucket-pipelines.yml file to your repository
  2. Commit and push to Bitbucket
  3. The pipeline should trigger automatically

Test :

  • Push a Commit to Main Branch:

    git add .
    git commit -m "Test sync to GitHub"
    git push origin main
    
    • For tags
    git tag v1.0.0
    git push origin v1.0.0
    

    Check the pipeline execution in your Bitbucket repository under Pipelines section.

Notes:

  • --single-branch reduces data transfer
  • clone: enabled: false prevents unnecessary default cloning
  • Avoid --mirror in pipelines (use only for initial setup)

Summary

This setup creates an efficient, automated sync between Bitbucket and GitHub that:

  • Keeps Bitbucket as your source of truth
  • Syncs only main branch (or you can do for any branch or whole repo ) and tags
  • Maintains security through SSH key authentication

The pipeline runs automatically whenever you push to main or create tags, ensuring your GitHub repository stays synchronized without manual intervention.

Comments 0 total

Загрузка комментариев...
Add comment