Transitioning from GitFlow to GitHub PR Workflow: A Journey in Streamlining Our Development Process
Introduction
In our company, we originally adopted the GitFlow model for our development workflow. This model served us well, facilitating a structured approach to feature development, release management, and hotfixes. However, with the introduction of GitHub and its powerful pull request (PR) workflow, we decided to transition to a more integrated system. This blog post outlines our journey, the challenges we faced, and the solutions we implemented to streamline our development process.
The GitFlow Model
Under the GitFlow model, our development process was as follows:
- Feature Development: All features were checked out from the
staging
branch. - Merging: Features were merged back into
staging
. - Release: When ready to release,
staging
was merged intomain
, triggering a production deployment. - Hotfixes: If a bug was found in
main
, a hotfix branch was created frommain
, fixed, and then merged back into bothstaging
andmain
.
This workflow ensured stability and control, as any code merged into main
was deemed ready for production. However, with the shift to using GitHub, we sought to leverage its PR and code review capabilities to enhance our process further.
Transition to GitHub PR Workflow
With GitHub, we restructured our workflow to utilize PRs more effectively:
- Development Branch: We set
main
as our development branch. - Feature Branches: Features were checked out from
main
and developed. - PRs to Main: Developers created PRs to merge features back into
main
. - Automatic Deployment: Upon PR approval,
main
automatically deployed tostaging
. - Tagging for Production: Once a tag was created on
main
, it triggered an automatic deployment to production.
This new workflow integrated GitHub’s PR and code review features seamlessly. However, it introduced a significant challenge: handling hotfixes. Since main
was now our development branch, any hotfix merged into main
could inadvertently include unstable code, potentially affecting production.
Refining the Workflow
To address this issue, we made further modifications to our model while retaining the benefits of GitHub PRs:
- Branch Structure: We retained both
main
andstaging
branches. - PR to Staging: All developers were required to PR their changes to
staging
. - Releases: When ready to release, a PR from
staging
tomain
was created. - Hotfixes: In case of a hotfix, the fix was branched from
main
, PR’d to bothmain
andstaging
.
Although effective, this approach necessitated creating two PRs for each hotfix – one to main
and one to staging
. To simplify this process, we leveraged GitHub Actions to automate the synchronization of hotfixes across branches.
Automation with GitHub Actions
We created a GitHub Action using a bot account to automate our hotfix workflow:
- Hotfix PR: When a hotfix PR to
main
is accepted, the action checks outmain
to apatch
branch. - Automatic PR: The
patch
branch automatically creates a PR tostaging
. - Conflict Resolution: In case of conflicts, the bot’s PR allows manual conflict resolution on the
patch
branch before updating the PR tostaging
.
This automation ensures that our hotfixes are focused on main
, with staging
being automatically updated via a synchronized patch
branch. This approach maintains the integrity of our branches and simplifies the workflow for our developers.
GitHub Action Script
Below is the GitHub Action script we used to implement this workflow:
name: Pull Main
on:
push:
branches:
- main
jobs:
merge:
if: github.event.pull_request == null || github.event.pull_request.head.ref != 'staging'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
token: ${{ secrets.PAT_TOKEN }}
- name: Push a new branch
id: push_branch
run: |
git config --global user.name "${{ vars.INFR_AI_BOT_NAME }}"
git config --global user.email "${{ vars.INFR_AI_BOT_EMAIL }}"
echo "branch_name=pull-main-$GITHUB_SHA" >> "$GITHUB_OUTPUT"
git checkout -b pull-main-$GITHUB_SHA
git push origin pull-main-$GITHUB_SHA
- uses: actions/github-script@v7
env:
WORKING_BRANCH: ${{ steps.push_branch.outputs.branch_name }}
with:
github-token: ${{ secrets.PAT_TOKEN }}
script: |
github.rest.pulls.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: 'chore: pull main branch into staging',
head: process.env.WORKING_BRANCH,
base: 'staging',
body: 'Automatically generated pull request to merge changes from the main branch into the staging branch.'
})
Conclusion
By transitioning from GitFlow to GitHub’s PR workflow, we enhanced our development process, integrating modern code review practices. The automation with GitHub Actions further streamlined our workflow, allowing us to maintain stability and control across our branches. This journey underscores the importance of continually evolving our processes to leverage new tools and technologies effectively.