Blog

Modernizing CI/CD: Migrating Bitbucket Pipelines to GitHub Actions

26.05.2026
Reading time: 4 mins.
Last Updated: 26.05.2026

Table of Contents

In earlier articles, we covered migrating repositories from Bitbucket Cloud, securely updating project dependencies, and modernizing CI/CD workflows by translating Jenkins and Bash-based pipelines to GitHub Actions. With those foundations in place, the final step is to migrate native Bitbucket Pipelines and complete the transition to a fully unified CI/CD system.

This article focuses on translating YAML-based Bitbucket Pipelines into GitHub Actions workflows. By doing so, all pipelines across projects follow the same execution model, improving consistency, maintainability, and long-term scalability.

bitbucket
github

Bitbucket Pipelines are defined in a bitbucket-pipelines.yml file located at the root of the repository. This file controls how CI/CD workflows behave, including:

  • When pipelines are triggered
  • Which steps or jobs are executed
  • Job ordering and dependencies
  • Artifact creation and reuse between steps

Before migrating to GitHub Actions, it’s essential to fully understand the behavior of the existing pipeline so it can be accurately reproduced.

Below is an example Bitbucket pipeline used in this project:

definitions:
  commonItems:
    &setupEnvironment |
      export COMMIT=$(echo $BITBUCKET_COMMIT | cut -b 1-8)
      git submodule update --init --recursive
      echo "#define REVISION_NUMBER 0x$COMMIT" > src/revision.h

  git:
    &gitSubmoduleUpdate |
      git submodule update --init

verify_release_version: &verify_release_version
  step:
    name: Verify release version
    script:
      - git submodule update --init
      - ./scripts/check_release_version.sh

cpplint: &cpplint
  step:
    name: Lint code
    image: my-registry/lint-image:latest
    script:
      - *gitSubmoduleUpdate
      - ./scripts/lint.sh

test: &test
  step:
    name: Run tests
    runs-on:
      - self.hosted
      - linux
    script:
      - *setupEnvironment
      - make test

build: &build
  step:
    name: Build project
    runs-on:
      - self.hosted
      - linux
    script:
      - *setupEnvironment
      - make build
    artifacts:
      - build/**

upload: &upload
  step:
    name: Upload build output
    script:
      - export DESTINATION=builds/$BITBUCKET_BRANCH
      - mkdir -p $DESTINATION
      - cp -r build/* $DESTINATION/
      - scp -r builds user@remote-server:/path/to/storage

Several important behaviors stand out:

  • Reusable scripts using YAML anchors (&setupEnvironment)
  • Parallel execution of steps to speed up builds
  • Artifacts generated in one step and reused later
  • Branch-specific pipelines, controlling which jobs run on main, feature/*, or release/*

Understanding these patterns is critical before translating the pipeline to GitHub Actions.

GitHub Actions workflows are defined under .github/workflows/, typically with one workflow per file. Each workflow specifies:

  • Triggers that control when the workflow runs
  • Jobs representing units of work
  • Dependencies between jobs using needs
  • Artifacts passed between jobs

Below is the migrated workflow that mirrors the Bitbucket pipeline behavior:

name: CI Workflow

on:
  push:
    branches:
      - main
      - 'feature/*'
      - 'release/*'

env:
  BUCKET: example-bucket
  AWS_REGION: region-value

jobs:
  lint:
    name: Lint code
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          submodules: recursive
      - run: ./scripts/lint.sh

  test:
    name: Run tests
    runs-on: [ "self-hosted", "ap-southeast-2", "ubuntu", "x64" ]
    steps:
      - uses: actions/checkout@v4
        with:
          submodules: recursive
      - run: ./scripts/setup_environment.sh
      - run: make test

  build:
    name: Build project
    runs-on: [ "self-hosted", "ap-southeast-2", "ubuntu", "x64" ]
    steps:
      - uses: actions/checkout@v4
        with:
          submodules: recursive
      - run: ./scripts/setup_environment.sh
      - run: make build
      - uses: actions/upload-artifact@v4
        with:
          name: build-artifacts
          path: build/

  release:
    name: Release build
    runs-on: ubuntu-latest
    needs: [build]
    steps:
      - uses: actions/checkout@v4
        with:
          submodules: recursive
      - uses: actions/download-artifact@v4
        with:
          name: build-artifacts
          path: build/
      - run: |
          mkdir -p deploy/${GITHUB_REF_NAME}
          tar -czf deploy/${GITHUB_REF_NAME}/artifacts.tar.gz -C build .
          echo "{\"artifact\":\"artifacts.tar.gz\",\"revision\":\"${GITHUB_SHA}\"}" > deploy/${GITHUB_REF_NAME}/release_info.json
      - name: Upload to S3
        run: |
          aws s3 sync deploy "s3://${BUCKET}/" \
            --region $AWS_REGION \
            --acl private

The workflow runs automatically on pushes to main, feature/*, and release/*, replicating Bitbucket’s branch-based pipelines.

Jobs such as lint and test can run in parallel, while others wait for dependencies.

The needs keyword ensures the release job only starts after build completes successfully.

Artifacts are uploaded in the build job and downloaded in the release job using GitHub’s native artifact actions.

Environment variables define bucket and region values, and artifacts are uploaded using standard AWS CLI commands. A dedicated GitHub Action could also be used for S3 uploads if preferred.

With native Bitbucket Pipelines successfully migrated to GitHub Actions, all CI/CD workflows now run on a single, unified automation platform. This ensures consistent behavior across projects, simplifies maintenance, and provides a secure and scalable foundation for ongoing development.

This migration journey demonstrates a practical path for moving repositories, securing dependencies, and modernizing pipelines-bringing all automation under GitHub Actions in a structured and maintainable way.

Check out more of our blog posts here.

More Posts

The ITGix AWS Landing Zone continues to evolve with a clear goal: enabling organizations to build secure, compliant, and scalable AWS environments with less operational overhead. Across recent releases (v1.2.0...
Reading
Infrastructure automation in Kubernetes is largely a solved problem-until secret management enters the picture. As environments scale, distributing and rotating secrets across multiple isolated clusters quickly becomes a major operational...
Reading
Get In Touch
ITGix provides you with expert consultancy and tailored DevOps services to accelerate your business growth.
Newsletter for
Tech Experts
Join 12,000+ business leaders and engineers who receive blogs, e-Books, and case studies on emerging technology.