Skip to content

Branching Strategy

This document defines the standard branching strategy used across software engineering projects.

Polk County’s Software Engineering Team uses GitHub Flow as the default branching model. GitHub Flow is a lightweight workflow centered around short-lived feature branches, pull requests, and frequent integration into the main branch.

This strategy supports rapid iteration, continuous integration, and a stable deployment-ready main branch.

---
config:
  theme: base
  gitGraph:
    showCommitLabel: false
---
gitGraph
   commit
   branch "feature 1"
   branch "feature 2"
   checkout "feature 1"
   commit
   commit
   checkout main
   merge "feature 1" tag: "v0.1.0"
   checkout "feature 2"
   commit
   commit
   checkout main
   merge "feature 2" tag: "v0.2.0"
   branch "hotfix"
   commit
   checkout main
   merge "hotfix" tag: "v0.2.1"
   branch "feature 3"
   commit
   commit
   commit
   checkout main
   merge "feature 3" tag: "v1.0.0"

The following principles apply to all repositories using the GitHub Flow branching strategy:

  • Keep main in a deployable state. It contains the latest stable version of the codebase.
  • No direct commits are made to main. All changes go through feature branches and pull requests.
  • Each new feature, bug fix, or improvement is developed in a separate branch created from main.
  • Open a pull request for all changes before merging.
  • Use peer review and automated validation as part of the merge process.
  • Automated checks should pass before a pull request is merged.
  • Prefer small, incremental changes over large, long-lived branches.
  • Squash merge pull requests to maintain a clean commit history.
  • Delete branches after merging to keep the repository clean.

The standard GitHub Flow process is:

  1. Create a branch from main

    Use a short-lived branch for the change.

  2. Make and commit changes

    Keep commits focused and descriptive, following the Conventional Commits standard.

  3. Push the branch to GitHub

    Publish the branch so a pull request can be opened.

  4. Open a pull request

    Describe the purpose of the change and any relevant context.

  5. Run automated checks

    CI workflows should validate the proposed changes.

  6. Complete review

    Address reviewer feedback and confirm readiness to merge.

  7. Merge into main

    Merge only after approval and successful validation.

    Squash merging is preferred to maintain a clean history.

  8. Delete the branch

    Remove the short-lived branch after merge.

Branch names should clearly describe the purpose of the work.

Recommended patterns include:

  • feat/short-description
  • fix/short-description
  • chore/short-description
  • docs/short-description

Examples:

  • feat/add-permit-search
  • fix/handle-null-api-response
  • chore/update-dependencies
  • docs/update-onboarding-guide

Use lowercase letters and hyphens for readability and consistency.

All changes to shared branches should be introduced through pull requests.

Pull requests should:

  • Clearly describe what changed
  • Explain why the change was made
  • Reference related issues or tickets when applicable
  • Remain focused in scope
  • Be reviewed before merging
  • Pass all required automated checks

Pull requests are the primary checkpoint for collaboration, validation, and quality control.

For detailed expectations regarding pull request size, reviewer responsibilities, and approval requirements, see the code review standards.

Repositories should use automated workflows to validate changes before merging.

Typical checks include:

  • Linting and formatting checks
  • Unit and integration tests
  • Build verification
  • Static code analysis and security scans

A pull request should not be merged until required checks have completed successfully.

Branches should be kept short-lived to reduce merge conflicts and simplify review.

To support this:

  • Start new work from the latest main
  • Merge frequently
  • Avoid bundling unrelated changes together
  • Break large efforts into smaller pull requests when possible

Long-lived branches increase the risk of drift, review complexity, and integration problems.

The following practices should be avoided:

  • Direct commits to main
  • Long-lived feature branches
  • Large pull requests with unrelated changes
  • Skipping pull request review
  • Merging with failing automated checks
  • Reusing old branches for new work