feat(sync): report upstream commits landed since the latest downstream release - #71
Merged
Merged
Conversation
…m release Rebasing the Django fork branches with `dbx sync --all-branches` aligns them with upstream's current tip, which says nothing about whether the *released* backend contains those commits. A security fix backported to Django's stable/5.2.x the day after django-mongodb-backend 5.2.4 shipped is on the fork branch, in CI, and absent from every installed copy of the backend — and nothing in the sync output said so. After the sync (and the ci_rerun step), each mapped branch is now compared against the highest release tag of the same series in the group's new `release_repo`, and the commits upstream has that the release does not are listed, each labelled with the Django dev cycle it was backported from (parsed from `Backport of <sha> from main.` and located against the stable/X.Y.x fork points on main). The release series is derived from the branch name (mongodb-5.2.x -> the highest 5.2.<patch> tag), so adding a release branch needs no report config. Tags are fetched in the release repo first, since a stale clone would silently over-report commits as new. Best-effort throughout: an unset release_repo, an un-cloned release repo, or a git error warns and skips rather than failing the sync. Pass --no-backport-report to skip it; it also runs under --dry-run. Found on first run: stable/6.0.x is 25 commits and four CVEs ahead of backend 6.0.4, and stable/6.1.x is 6 commits ahead of 6.1.0. Also carries a pre-existing working-tree note in repo-management.rst about `dbx clone` skipping the upstream worktree quietly (follow-up to #70).
aclark4life
added a commit
that referenced
this pull request
Aug 26, 2026
…hores (#73) The report added in #71 listed every upstream commit that landed after the matching downstream release as one flat run of lines, which on the first real run meant reading 25 commits on stable/6.0.x to notice that four of them were CVE fixes. That is triage work the tool can do: Django's stable branches follow a tight commit-subject convention, so the commits sort themselves. Each commit is now bucketed by subject -- security (`Fixed CVE-YYYY-NNNNN`), fixes (`Fixed #NNNNN`), chores (version bumps, stub release notes, translation updates, `Refs #NNNNN` follow-ups), and unclassified -- and printed in that order under a summary line. Chores are hidden behind a count; `--all` lists them, `--security-only` narrows to the CVE fixes, and `--all` wins when both are passed. Security is a sort order rather than a filter by default, since a plain `Fixed #NNNNN` can be release-worthy too. Two deliberate choices about being wrong. `Added CVE-x, CVE-y to security archive.` names CVEs but only edits a docs page, so it is matched as a chore before anything keying off "CVE" -- otherwise it inflates the count that is supposed to mean "cut a release now". And the chore patterns stay narrow: anything unrecognised lands in `unclassified` and stays visible, so a change in upstream's conventions surfaces as unclassified commits rather than quietly filing real fixes as noise. The summary line counts len(commits) independently of the buckets, so the total still moves if the patterns stop matching. This is presentation only -- it does not make the report more correct. "New" is still committer date against the release tag.
aclark4life
added a commit
that referenced
this pull request
Aug 26, 2026
… branch (#74) Assembling the next "Backports for 5.2.5 LTS" PR -- the successor to INTPYTHON-528 Backports for 5.2.4 LTS (#607) -- means finding commits on django-mongodb-backend's main that are not yet on 5.2.x. Nothing in dbx answered that. The release-gap report added in #71/#73 looks like it should, but it compares the *Django fork* against a released *backend* tag, so it never opens the backend's own branches: wrong repos, wrong pair. `dbx backports <repo>` compares a repo's main against each of its X.Y.x release branches and lists what has not made it across, bounded by that branch's latest release tag. The window is the whole design. Since the 5.2.x branch point, 164 commits are missing from 5.2.x -- 82 after filtering release chores, and nearly all of those are feature work that the supported-versions policy forbids on an LTS branch. Since the 5.2.4 tag there is one. The older commits are not candidates: they were already triaged when #607 was assembled, and were either taken or deliberately skipped. The window is also load-bearing for correctness. Backports get squashed into a single commit, so the main commits they carried keep their own patch-ids and `git log --cherry-mark` recognises only 6 of the 164 as already present. Bounding by the tag sidesteps that, because everything the squash carried predates it. The cost is that a fix missed before the last release stays hidden, so --since and --all widen the window for that hunt. Branches with no release tag (5.1.x, 5.0.x) are skipped rather than falling back to the branch point, which dumped 262 and 290 lines of commits that were never candidates. Eligibility is left to the reader. Only security fixes and data-loss bugs belong on LTS branches per the backend's release-process.rst, and no commit subject marks those. The documented signal is the PR description, but roughly 4 of the last 60 merged PRs follow it and there is no backport label, so keying off it would report an empty list and look authoritative. Release chores are filtered (version bumps including ticket-prefixed ones, dependency bumps, SBOM, stub notes, release prep, and "Update to Django X.Y", which is the opposite of a backport); everything else is shown. Moves latest_release_tag/classify_commit/git_out into utils/release.py so the two commands share them instead of importing across command modules. sync.py is refactor-only.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
dbx sync django --all-branchesrebases each fork branch onto upstream, which keeps the fork current but says nothing about whether the released backend contains those commits. A CVE backported to Django'sstable/5.2.xthe day after django-mongodb-backend 5.2.4 shipped is on the fork branch, in CI, and absent from every installed copy of the backend — and nothing in the sync output surfaced that.What
After the branch sync (and the
ci_rerunstep), each mapped branch is compared against the highest release tag of the same series in the group's newrelease_repo, and the delta is listed with each commit labelled by the Django dev cycle it was backported from:How it works:
mongodb-5.2.x→5.2. Adding a release branch needs no report config.5.2.<patch>tag inrelease_repo, compared numerically so 5.2.10 beats 5.2.4.Backport of <sha> from main., then locate the source sha against thestable/X.Y.xfork points onmain; past all of them means the in-development cycle (read fromdjango/__init__.pyonmain). Cached per sha.A
[6.2 cycle]label on astable/5.2.xcommit is expected — authored during 6.2 development, backported to 5.2. Unannotated commits (version bumps, release chores) are still listed as[unannotated].Findings on first run
stable/5.2.x— clean; backend 5.2.4 (2026-08-24) is current. Tracked in INTPYTHON-1077.stable/6.0.x— 25 commits ahead of backend 6.0.4, including CVE-2026-15307 / 15337 / 15830 / 15920 and Django 6.0.8.stable/6.1.x— 6 commits ahead of backend 6.1.0, including #37259.Notes
release_repo, un-cloned release repo, or a git error warns and skips rather than failing the sync.--no-backport-reportopts out. The report also runs under--dry-run.[repo.groups.django.release_repo]+get_release_repo()accessor.Testing
dbx sync django --all-branches --dry-run.Docs
docs/features/django-fork.rst— new "Spotting upstream fixes released after the backend" section.docs/features/repo-management.rst—--no-backport-reportflag and therelease_repokey.