Repository navigation
chore(changelog): one file per entry in changelog.d/ — merges stop conflicting - #196
Merged
Merged
Conversation
…nflicting Every PR inserted its entry directly under `## [Unreleased]`, the same line each time, so each merge left every other open PR CONFLICTING, and GitHub runs no pull_request workflows on a conflicting PR. Since 2026-09-01, 47 of 72 merged PRs touched CHANGELOG.md. 22 of them needed the take-out / merge / put-back dance (66 extra commits), and 54-58% of PR CI runs were cancelled by the re-pushes. New entries go in changelog.d/<YYYY-MM-DD>-<topic>.md, one each, in the house style (first line `### Type — headline`). scripts/changelog.py folds them in newest first below a pointer under [Unreleased]. `--release X.Y.Z` also cuts the version heading in the release-prep PR. docs/development.md step 1 now runs it, and a new step checks changelog.d/ is empty before tagging. tests/test_changelog_fragments.py checks fragment names and first lines. It fails, saying what to do instead, when an entry is inserted at the top of CHANGELOG.md, and it covers fold, release and refusal on temp files. Re-running `--release X.Y.Z` after a late merge adds the entry under the heading already cut. An older or empty release is refused. Anything in changelog.d/ that isn't a regular YYYY-MM-DD-<topic>.md file is refused too (links, other extensions); a BOM or CRLF from Windows editors is normalised. Not chosen: - .gitattributes `merge=union`: GitHub's server-side merges (merge button, mergeability, update-branch) don't apply repository merge drivers. git reverted reading attributes from HEAD in bare repos (51441e6). It would not run for API commits either. - Generated release notes only: release.yml already attaches GitHub's PR-title list. As a replacement it loses most of the content (rationale, operator actions) and the copy inside the signed tarball. - towncrier / scriv: they name and group entries differently from the house style, and add a dependency for about 50 lines of logic. The existing [Unreleased] entries stay where they are and move under the next version at release. Fragments go through the hooks' and scope guard's content scans (CHANGELOG.md is exempt), which is the safer direction. Verified: full suite 1667 passed / 80 skipped; a release fold dry-run on a copy of main's CHANGELOG; ruff check + format clean; gitleaks and the pre-commit scope guard clean. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MrChengLen
added a commit
that referenced
this pull request
Oct 6, 2026
…HS256-only pip-audit started failing the required lint-and-test job on every PR: python-jose 3.5.0 is affected by CVE-2026-85394 (GHSA-3qf3-8w2g-rqmx, CRITICAL / CVSS 9.1). It is an incomplete fix for CVE-2024-33663: the HMAC key check rejects PEM- and SSH-formatted public keys but not DER ones, so a verifier that checks tokens with a public key and also accepts HS256 accepts a token signed with that public key. No fixed release exists; 3.5.0 (May 2025) is the latest and upstream has been quiet since. Not reachable here, confirmed by a security review against origin/main. FileMorph has no asymmetric key. Every token is verified in one place (`_decode`, app/core/tokens.py) with the symmetric JWT_SECRET and algorithms=["HS256"]. python-jose takes the key only from that argument, never from a kid/jwk/jku header, and there is no JWKS, OIDC or SSO code. Per docs/patch-policy.md (no upgrade available), the ID goes on the --ignore-vuln list with the reasoning next to the step, a review date (2026-11-05, and at each release) and the exit conditions: migrate off python-jose before any SSO work (that also ends PYSEC-2026-1325), or an upstream fix. docs/security-overview.md lists it as the third accepted advisory. A new guard, test_cve_2026_85394_ignore_still_holds, fails CI if a second JWT verify path appears while the ignore is still in ci.yml. Mutation-checked: an extra jwt.decode under app/ turns it red. The changelog entry is a changelog.d/ fragment; the fragment tooling lands with #196. Verified: full suite 1652 passed / 79 skipped; local pip-audit on requirements.lock with CI's flags: no known vulnerabilities, 4 ignored; ruff clean; gitleaks and the pre-commit scope guard clean. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MrChengLen
added a commit
that referenced
this pull request
Oct 6, 2026
…e merge base Since #196 each entry is its own file in changelog.d/, and a guard fails when an entry is inserted at the top of CHANGELOG.md. CHANGELOG.md goes back to the merge base's bytes, so this PR no longer touches it, and the entry moves unchanged to changelog.d/2026-10-06-pillow-heif-docs.md. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
Every PR added its changelog entry directly under
## [Unreleased], on the same line each time. So every merge made all other open PRs CONFLICTING, and GitHub runs nopull_requestworkflows on a conflicting PR.Since 2026-09-01:
CHANGELOG.md.main.How it works now
changelog.d/<YYYY-MM-DD>-<topic>.md, in the house style (first line### Fixed — headline, then paragraphs). New files never conflict.python scripts/changelog.pymoves the files intoCHANGELOG.mdbelow the pointer, newest first, and deletes them.python scripts/changelog.py --release X.Y.Zin the release-prep PR also cuts## [X.Y.Z] — <date>(docs/development.md, steps 1 and 3). If a PR merges late, running the same command again adds its entry under the heading already cut. An older or empty release is refused.tests/test_changelog_fragments.py, inside the requiredlint-and-test. It checks names and first lines, and fails with the fix spelled out when an entry lands at the top ofCHANGELOG.md. It also tests fold, release and refusal on temp files.The 79 entries already under
[Unreleased]stay where they are and move under the next version at release.Not chosen
merge=unionin.gitattributes. GitHub's server-side merges (merge button, mergeability, update-branch) don't apply repository merge drivers, and git itself stopped reading attributes from HEAD in bare repositories (git51441e6). It would also never run for API commits.release.ymlalready attaches GitHub's PR-title list. As a replacement, it drops most of the content (rationale, operator actions) and the copy inside the signed tarball.Notes
CHANGELOG.md, fragments go through the hooks' and the scope guard's content scans. That is the safer direction;changelog.d/README.mdsays to describe ops-only names instead of spelling them out.CHANGELOG.mdentry converts with a single commit: setCHANGELOG.mdback to its merge-base bytes and add the entry, unchanged, as a fragment.shipskill) switch to fragments as soon as this merges. They are not part of the repo.Verification
changelog.d/paths pinned as scanned intest_hook_allowlist_regression.py.CHANGELOG.md: the fragment lands under a new## [1.2.0] — <date>above the existing[Unreleased]entries, and the pointer stays.🤖 Generated with Claude Code