Branching Strategy - opengovsg/GoGovSG GitHub Wiki

What are branching strategies?

Branching strategy is a methodology for a team to version control their application development lifecycle. Version control systems (Git in our case) are used alongside automated testing, code reviewing, vulnerability detection, and other CI/CD tools to help a team roll out features quickly and safely.

GoGov's approach

Branching

GoGov currently uses Gitflow as a branching strategy.

On a weekly basis (during maintenance, this interval can be longer), we fork a release-x.xx branch off of develop, where x.xx is the new version number of the application. Creating the branch starts the next release cycle, so no new features can be added after this point. Only bug fixes, documentation generation, and other release-oriented tasks go in this branch. At the same time, we also push the develop branch to the edge branch to build and push to our staging environment for tests.

During release, the release-<version_number> branch is merged into release, which is configured to build and push to our production environment. In addition, it should be merged back into develop to incorporate the documentation changes.

Only once it's proven stable, the release-<version_number> branch is merged into master so that master always reflects a production-ready state.

The diagram below shows a Gitflow setup similar to the one described above.

Merge strategy

Feature PRs are to be merged into the develop branch using squash and merge. This will make us lose visibility of the individual commits, making it harder to cherry pick or revert them. As such, PRs should do only one thing at a time, and we should avoid lumping multiple features into a single PR.

Release PRs from the release-<version_number> branch are strictly to be merged by merge commit only.

CI/ CD environment

We use GitHub Actions to manage our CI/ CD. Link to our GitHub Actions workflow.

Automated tests

Both unit and end-to-end tests currently run on every pull request within the virtual environment.

Vulnerability detection tools (Dependabot, Snyk, CodeQL)

We have vulnerability detection tools, Dependabot, Synk,and CodeQL running on our repository. CodeQL runs on every pull request to analyse the repository to verify that no vulnerable code is introduced, whereas both Dependabot and Synk focus on finding vulnerabilities in the external dependencies used by the repository.

Code reviewing

The develop, release, and master branches are all protected branches. PRs made to these branches require at least one approval (as well as all the tests to pass) before merge.

Manual tests

The edge branch is unprotected, and any pushes to edge will automatically build and deploy the application to our staging environment. If a developer wants to test out a new feature/ infrastructure/ migration or share any changes with designers/PM, they should test their changes out on staging environment by pushing to the edge branch.

Deployment

The edge and release branches are configured to deploy automatically to our staging and production environments respectively.

FAQ

I pushed my changes to staging but nothing is built on the staging environment. Why is this?

The edge branch deploys to our staging environment, not staging. We sometimes regret this choice of terminology too.

Why do we have a master branch if we don't use it for deployment?

As mentioned above, master always reflects a production-ready state, so we do not put our releases into master until they have proven stable.

Why Gitflow?

Using a dedicated branch to prepare releases makes it possible for one developer to polish the current release while another developer continues working on features for the next release.

More resources