Branch, PR, and Merge Workflow¶
This page covers the full lifecycle of a change in projectMM: from creating a branch to merging, including CI requirements, CodeRabbit review, and how release branches differ from feature branches.
Branch naming¶
| Purpose | Pattern | Example |
|---|---|---|
| Feature or bug fix | short descriptive name | artnet-loopback-fix |
| Sprint work | release<N> or release<N>-sprint<M> |
Release02, release4-sprint8 |
| Hotfix | hotfix/<description> |
hotfix/wifi-crash |
Always branch from main. Never commit directly to main.
Release branches (any branch with release in the name) get extended CI: both ESP32 targets are built, firmware .bin files and the PC executable are uploaded as artifacts, and the docs are deployed to GitHub Pages. See CI behaviour by branch.
Opening a PR¶
- Create a branch from
main. - Make a first commit (even a skeleton is enough to open the PR early).
- Push and open a PR against
mainwith a short description of the goal. - CodeRabbit analyses the commits and generates a review automatically within a few minutes.
For non-trivial work, include a brief implementation plan in the PR description or as a top comment: what modules are touched, what the test strategy is, and what the footprint impact is expected to be.
PR title format: match the commit style used in this repo: a one-line summary that starts with the scope:
BrightnessModifier: fix brightness=0 not producing black output
Sprint 9: defVal sourcing confirmed + regression tests
Working on an open PR¶
Push additional commits as you work; GitHub keeps the PR up to date automatically. Do not force-push: it causes CodeRabbit review comments to disappear and makes the history harder to follow.
Addressing CodeRabbit feedback:
When a CodeRabbit comment leads to a change, use an emoji prefix in the commit title to signal the source:
| Emoji | Source |
|---|---|
| 🐰 | CodeRabbit suggestion |
| ✴️ | Claude Code generation |
| 🐱 | Mistral / other AI |
Example commit title: 🐰 remove redundant null check in WifiSta::startConnect
Addressing human review feedback: plain commit title is fine; reference the review comment if helpful.
Definition of done before merge¶
A PR is not ready to merge until every item below is checked. These match the standards checklist:
- [ ] All unit tests pass (
python3 deploy/unittest.py, 254/254 or higher). - [ ] PC build clean (
python3 deploy/build.py -target pc). - [ ] ESP32 build clean: at minimum
esp32dev; both targets for release work. - [ ] Every changed or added Module has a test in
tests/. - [ ] New tests are
behavioralorintegration(not justsmokeorformat). - [ ] Doc page added or updated for any user-facing change.
- [ ] No new
#ifdef ARDUINOinsidesrc/modules/(platform guards belong insrc/pal/). - [ ] Footprint delta reported by CI and within budget (see Footprint Budgeting).
- [ ]
Co-Authored-Bytrailer present if the commit was AI-generated.
For a new Module, also check the Module definition of done.
CI behaviour by branch¶
CI runs on every push and every PR targeting main.
| Job | main |
PR to main |
branch with release |
other branches |
|---|---|---|---|---|
| PC build + tests | yes | yes | yes | no |
| ESP32 esp32dev build | yes | yes | yes | no |
| ESP32 esp32s3_n16r8 build | no | no | yes | no |
| PC executable artifact | no | no | yes | no |
| ESP32 firmware artifacts | no | no | yes | no |
| Docs build | yes | yes | yes | no |
| Docs deploy (GitHub Pages) | yes | no | yes | no |
| Footprint report | yes | yes | yes | no |
CI is required to pass before merge. If a step fails, fix the root cause: do not skip hooks or disable checks.
Downloading firmware from a release branch:
After CI completes on a release branch, go to the GitHub Actions run, open the summary, and download the artifacts:
projectMM-pc-<branch>: the PC server executable (macOS)projectMM-esp32-<branch>: bothfirmware.binfiles (esp32dev + esp32s3_n16r8)
Merging¶
Who merges: any maintainer with write access, after at least one human approval and a green CodeRabbit summary.
How: squash-merge by default to keep main linear. The squash commit message should include the full Co-Authored-By trailers from the branch commits.
After merging:
- Delete the feature branch (GitHub offers this automatically after merge).
- For release branches, do not delete until the release doc (
docs/development/release-NN.md) is finalised.
Target lead time: aim for a week or less from opening to merge. Stale PRs accumulate conflicts and slow everyone down.
Hotfixes¶
For urgent fixes to main:
- Branch
hotfix/<description>frommain. - Fix, test, open PR, get a fast review.
- Merge and tag if the fix affects a released version.
Do not hotfix directly on main.
Release branches¶
Release branches (Release02, release4-sprint8, etc.) are longer-lived branches used during active sprint work. They follow the same rules as feature branches plus:
- Docs are deployed to GitHub Pages on every push, so reviewers can see the current state of the documentation without checking out the branch locally.
- Both ESP32 targets are built and both
.binartifacts are uploaded, ready for flashing to test hardware. - Sprint results, retrospectives, and the
release-NN.mddoc are updated on the branch before the final squash-merge tomain.
The CI branch filter includes both '*release*' and '*Release*' patterns because GitHub Actions glob matching is case-sensitive on Linux runners. The step conditionals use contains(github.ref_name, 'release') || contains(github.ref_name, 'Release') for the same reason. Branches named Release02 satisfy the '*Release*' pattern and the uppercase contains check.