pyronear / pyronear/pyro-engine
Harden branch protection: required status checks are empty on develop and main
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 19
- Forks
- 8
- PR merge metrics
- No merged PRs in 30d
Description
Context
On 2026-08-14 a history-rewriting force-push (git push --force --all) rewrote every branch in this repository. develop was rejected by its protection rule and survived, which is the only reason the canonical history still exists. Everything else was rewritten: 20 branches lost their common ancestor with develop, 286 GPG signatures were stripped, and the 4 open PRs whose head branch lived in this repo were auto-closed by GitHub (a PR with no merge base has no computable diff).
Recovery was only possible because one contributor's local clone still held the pre-rewrite objects. There is no server-side reflog to fall back on.
The incident has been cleaned up. This issue is about the gaps it exposed, not the cleanup. To be studied after the summer, none of this is urgent.
Current state
develop force=false del=false reviews=1 required_checks=[] <- empty
main force=false del=false reviews=1 required_checks=[] <- empty
gh-pages force=true del=false reviews=none required_checks=none
main and gh-pages were unprotected until 2026-08-17 and are now covered.
Proposals, ranked by value
1. Fill in the required status checks
This is the only real gap, and it is unrelated to force-pushes. requiresStatusChecks is true on both develop and main but requiredStatusCheckContexts is empty, so the gate is decorative: a PR can be merged with the whole CI red. Seven workflows run on every PR and not one of them blocks a merge.
Suggested contexts (verified to run on pull requests):
ruffmypypytest (ubuntu-latest, 3.11)headers (ubuntu-latest)
Deliberately excluded: Build and Push pyronear/* only run on push, never on PRs, so requiring them would block every merge permanently. codecov-upload and see-page-build-payload are flaky.
Open question: whether to also require build (ubuntu-latest, 3.11) and the docker job. They are slower and would add several minutes per merge.
2. Replace the two duplicated rules with a single ruleset
develop and main are currently two separate legacy branch-protection rules with identical settings, which will drift the first time someone edits one and forgets the other. A single repository ruleset targeting both is the modern mechanism and keeps them in sync by construction.
3. Document the two things that turned this into a repo-wide incident
Worth a short section in CONTRIBUTING.md:
- Never
git push --force --all. This flag is what escalated a local mistake into everyone's problem: it pushes every branch at once, without showing which ones. Push one named branch at a time and read the output. - History rewriting is for secrets, oversized blobs, legal removals and repo splits. It is never worth it for cosmetics. To fix commit attribution for an email address, add the address to your GitHub account instead: it corrects retroactively across the whole history without touching a single commit.
- The correct recovery after a rewrite is to re-clone, not
git pulland notgit rebase. Rebasing a branch that has lost its common ancestor replays the entire history.
4. Same audit on pyro-api
pyronear/pyro-api has the mirror-image version of gap 1: it does require 5 checks (pytest, pytest-client, client (ubuntu-latest, 3.11), docker, end-to-end), but ruff, ty, headers and precommit-hooks run without being required, so a PR can merge with lint, types and license headers red. It also has a Code Quality Copilot review ruleset sitting at enforcement: disabled, which should be either enabled or deleted.
Explicitly not proposed
- Do not block force-pushes on
gh-pages.docs.ymldeploys viaJamesIves/github-pages-deploy-actionwithCLEAN: trueand an SSH deploy key. That push has to rewrite the branch and cannot satisfy a review requirement. Blocking it breaks every docs deploy, silently. Deletion protection is enough there. - Do not block force-pushes repository-wide. Contributors need to force-push their own PR branches to rebase.
- Do not require commit signatures. Real cost for volunteer contributors, no benefit against the failure mode seen here.
isAdminEnforcedis currentlyfalse, so admins bypass all of the above. That is a deliberate trade-off for a small team that occasionally needs to hotfix during fire season. Worth a conscious decision rather than a silent default, but changing it is not recommended.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reviewing the branch-protection settings for develop and main and the pull-request workflows that provide ruff, mypy, pytest, headers, build, and docker checks. The scope still needs a decision among required checks, a combined ruleset, CONTRIBUTING.md documentation, and the pyro-api audit; done should be defined after selecting one of these proposals.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- github, github-actions
- Domain
- ci-cd, devops, security
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 38/100