Development Workflow
Standardize how code moves from local work to production safely.
Recommended approach
Use an extended GitHub Flow with short-lived feature branches, automated checks, and tag-based releases.
Default flow
- Break work into small pull requests.
- Require review before merge.
- Gate merge with CI checks (
types,lint,tests). - Deploy frequently to non-production environments.
- Promote using explicit release approval.
Git flow (branches and releases)
Branch rules
mainis the integration branch for all completed work.- Every merge to
mainis continuously deployed to staging. - Work is done on short-lived
feature/*branches. feature/*->mainmerge happens only after review and required CI checks pass.- Release branch is created from a tagged commit on
main:release/<version>. - Hotfixes for that release are applied on
release/<version>and also merged back tomain. - A GitHub Release created from the tag triggers production deployment.
Illustration
feature/task-a ──┐
feature/task-b ──┼── PR + review + CI ──> main ──(continuous deploy)──> staging
feature/task-c ──┘
│
├── tag: v1.4.0 ──> release/v1.4.0
│ │
│ └── hotfixes
│ │
│ └── merge/cherry-pick back to main
│
└── GitHub Release from tag v1.4.0 ──> production deployImplementation checklist
- Enforce branch protection on main branches.
- Enforce branch protection on
release/*branches. - Require at least one reviewer for application changes.
- Run at minimum: type check, lint, unit tests, and integration/smoke/e2e checks.
- Require status checks before merge to
mainandrelease/*. - Ensure staging deployment is triggered on every merge to
main. - Ensure production deployment is triggered only from GitHub Release/tag flow.
- Add release notes to each production deploy.
- Track incidents and feed action items into backlog.
Common pitfalls
- Long-lived branches causing integration pain.
- CI checks that are optional in practice.
- Missing ownership for failed pipelines.