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
stagingbranch. - Merging: Features were merged back into
staging. - Release: When ready to release,
stagingwas 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 bothstagingandmain.
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
mainas our development branch. - Feature Branches: Features were checked out from
mainand developed. - PRs to Main: Developers created PRs to merge features back into
main. - Automatic Deployment: Upon PR approval,
mainautomatically 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
mainandstagingbranches. - PR to Staging: All developers were required to PR their changes to
staging. - Releases: When ready to release, a PR from
stagingtomainwas created. - Hotfixes: In case of a hotfix, the fix was branched from
main, PR’d to bothmainandstaging.
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
mainis accepted, the action checks outmainto apatchbranch. - Automatic PR: The
patchbranch automatically creates a PR tostaging. - Conflict Resolution: In case of conflicts, the bot’s PR allows manual conflict resolution on the
patchbranch 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.