Skip to content

chore(main): release 0.20.0 - #653

Open
github-actions[bot] wants to merge 1 commit into
mainfrom
release-please--branches--main--components--openstorage
Open

github-actions[bot] wants to merge 1 commit into
mainfrom
release-please--branches--main--components--openstorage

Conversation

@github-actions

@github-actions github-actions Bot commented Nov 2, 2026 •

Copy link
Copy Markdown

🤖 I have created a release beep boop

0.20.0 (2026-11-09)

⚠ BREAKING CHANGES

  • api: archive answers 422 for a repository that holds a symlink whose target is longer than 4,095 bytes, before any response byte, and the body names the symlink. Before, a target of 4,096 bytes up to about 1 MiB was in the archive, and a longer one cut the stream after its headers. To get the archive, pass the symlink in exclude_globs, or fetch the target with git.
  • api: diff-commit answers 400 invalid for a patch that gives a file a directory mode (new file mode 040000, or a mode change to 040000). Before, such a patch answered 412 no changes to commit, 409 conflict, or 200 with a commit that lacked the file.
  • api: diff-commit answers 400 invalid instead of 409 conflict for a patch that only git refuses (.git./x, git~1/x, a .gitmodules symlink, new mode 100664, a submodule patch without a commit or with a null commit). It answers 500 instead of 409 when git apply --cached fails for any other reason (a held index lock, a full disk, an unreadable index), and 500 instead of 400 when git fails while it parses the patch. A file name with a newline and a fatal: line makes git's message look like a server fault, so the client's own 400 or 409 then answers 500. A patch that makes git abort and a header without a file name answer 400 instead of 500.
  • api: the REST API answers a token that fails verification (malformed, bad signature, expired or unknown issuer) with 403 forbidden instead of 401 unauthorized. SDK 0.1.0 raises PermissionDeniedError instead of AuthenticationError for such a token. SDK 1.17.1 reports status 403 instead of 401, for example ApiError.status in TypeScript. A request without a Bearer token still gets 401.
  • api: a key store failure during REST token verification answers 403 authentication_unavailable instead of 401 (or instead of 403 forbidden for a fork source token; the Git and LFS transports keep 401; during a key store outage a caller with any well-formed token sees this 403 instead of 401), and unmatched /api/ paths answer problem bodies (404 route_not_found, or 405 method_not_allowed with Allow) instead of ServeMux's plain text.
  • api: merge failures no longer carry the result envelope. File conflicts answer 409 with upstream's MergeConflict body (error, conflict_type, conflict_paths, merge_base_sha), and every other merge failure answers the plain problem body. A non-fast-forward ff_only merge and a merge of unrelated histories answer 412 precondition_failed instead of 409. Note-write failures answer the plain problem body instead of the note envelope, except the 409 guard body. SDK 1.17.1 Go reads the note envelope only for application/json (util.go:154), so it now reports these note-write failures as a generic APIError instead of a RefUpdateError. I did not check the 1.17.1 TypeScript and Python clients.
  • api: commit-pack, diff-commit and restore-commit answer the failures for which upstream documents ProblemDetails with the plain problem body instead of the result envelope: 403 (ref policy, quota), 404, 429 and 500 on all three, and 400 and 409 on restore-commit. Merge's repository-not-found 404 and its 500 also answer the plain problem body. The 404s carry repository_not_found, branch_not_found or ref_not_found. SDK 1.17.1 Go reports these restore-commit failures as RefUpdateError with status 404 (or the HTTP status) and a generic message, and builds the commit-pack and diff-commit RefUpdateError with status failed. I did not check the 1.17.1 TypeScript and Python clients.
  • api: write routes (commit-pack, diff-commit, restore-commit, merge, notes, branches, tags) answer auth failures (401, 403), the REST rate limiter's 429 and the path-style alias 404 with the plain problem body instead of the result envelope, and so do the path-id git-credentials routes for every failure. SDK 1.17.1 Go builds the commit-pack, diff-commit and restore-commit RefUpdateError from that body with Status failed instead of unauthorized, forbidden, not_found or unavailable. I did not check the 1.17.1 TypeScript and Python clients.
  • api: a stale expected_target_sha or expected_head_sha on commit-pack, diff-commit and restore-commit, and a stale expected_notes_ref_sha or expected_ref_sha on POST .../notes and the DELETE .../notes body, now answer 409 with code: ref_guard_failed, guard, current_sha and result.status: conflict, instead of 412 precondition_failed. Go SDK 1.17.1 (code-storage-go) callers now get a RefUpdateError with status conflict on the three commit routes. On a note create they get an APIError with status 409 whose message is the raw body, because that SDK reads note bodies only for application/json. Go SDK 0.1.0 (github.com/pierrecomputer/sdk/go) callers get a RefGuardError on every form.
  • api: error bodies with problem members (code, detail, ...) are now sent as Content-Type: application/problem+json, as upstream documents. SDK 1.17.1 Go and TypeScript clients parse error JSON only for application/json, so their error message becomes the raw body text and the parsed body becomes a string. SDK 0.1.0 and the 1.17.1 Python client are not affected.

Features

  • api: base64 siblings for non-UTF-8 paths in files, diff, blame and grep responses (#721) (ccdd961)
  • api: filter GET /repos by prefix (upstream spec 34ac6de1) (#652) (86e6fe7)
  • api: send application/problem+json on problem bodies (#660) (3c6bfde)
  • api: send problem bodies and MergeConflict for merge and note-write failures (#670) (3c4b2b5)
  • api: send problem bodies for commit-write failures upstream documents as ProblemDetails (#669) (74c9684)
  • api: send problem bodies for write-route auth, rate-limit and alias failures (#663) (e0a48fb)
  • api: send route_not_found and authentication_unavailable (#672) (8638fa9)
  • api: serve GET/POST /api/repos and the tag-in-path delete that SDK 0.1.0 calls (#662) (2176fc1)
  • ref: write a scan-state row only when its generation is the expected one (#698) (1815795)

Bug Fixes

  • api: answer 404 or 400 for a git check only when git says no (#760) (b3add73)
  • api: answer a git-credentials repo_id of "org" with 404 instead of an assertion (#667) (8ebc5ee)
  • api: answer a token that fails verification with 403 forbidden (#674) (4e30915)
  • api: answer stale commit and notes guards with 409 ref_guard_failed (#661) (29688af)
  • api: cap diff-commit's patch, and read git apply's stderr as it streams (#778) (797dcd5)
  • api: clip long client values in git error names and log lines (#757) (44df4a4)
  • api: preview merge conflicts at paths longer than one git argument (#739) (a8b0e34)
  • api: put three rare diff-commit patch failures in the right status (#686) (a439727)
  • api: refuse a diff-commit patch that gives a file a directory mode (#722) (c94f17a)
  • api: refuse an archive that holds a symlink target over 4095 bytes (#756) (77efbe3)
  • api: restore only a commit, and answer 500 for one git cannot read (#771) (94f4341)
  • api: send target_branch and every RefUpdateResult member in commit-write results (#668) (50b4071)
  • auth: accept any non-empty sub and treat a token without repo as org-wide (#666) (137ba2c)
  • blob: list file-store keys in key order and add ListPagesAfter (#697) (093c231)
  • deps: bump github.com/jackc/pgx/v5 to v5.12.0 (#710) (caa296e)
  • deps: bump River to v0.51.1 (#720) (59cf665)
  • githttp: keep the hook's store errors off the pusher's screen and give them to the operator (#742) (9cdb2fa)
  • githttp: report a signature check that ends without a verdict as a failure (#765) (9c7aa98)
  • githttp: show the pusher only refusals from a hook (#755) (d9095f3)
  • gitlimit: keep only the tail of git's stderr in git errors (#759) (6d4b1bb)
  • gitlimit: signal only process groups whose leader is unreaped (#696) (50f97fd)
  • gitread: answer a diff with a type change (#784) (4a505d0)
  • gitread: decline a tree walk whose cat-file ended before the request (#774) (3c4337d)
  • gitread: report a failed git call in ResolveRef, never a missing ref (#749) (c4ce89f)
  • gitread: run blame and grep without the repository's attributes (#781) (5326d70)
  • image: bump alpine runtime base to 3.24.4 (apk-tools 3.0.9 security fix) (#711) (2b8f86b)
  • jobs: give the orphan sweep and LFS reclaim their own River queues (#691) (5279b5b)
  • jobs: give the repository purge its own budget in a sweep job (#692) (96a88ad)
  • jobs: never complete a sync job while its sync claim is held (#716) (d42b6c7)
  • jobs: requeue PostgreSQL lanes whose durable work has no River job (#726) (2c1c74f)
  • jobs: return the sweep job shortly after its context ends (#730) (bcb2444)
  • jobs: run each quarantine heal entry under its own deadline (#693) (570f2ae)
  • jobs: warn when a reclaim run is skipped and pin the guard's reset and order (#731) (cb51ae2)
  • keep only the tail of git's stderr in every git runner's error (#776) (50df23a)
  • list repos for a q or prefix of any length, and refuse NUL and invalid UTF-8 (#783) (e6be273)
  • ref: make ReplacePacks honor the purge fence (#704) (d7896ef)
  • refuse read paths outside the repository, and read blame and grep failures right (#772) (85b7d83)
  • run every git child without replacement objects (#777) (f6a8329)
  • s3wal: log the quarantine cause once and tighten the meta.json fuzz harness (#682) (1a93067)
  • scripts: keep tab stops when a Markdown container prefix is dropped (#751) (2c07fca)
  • scripts: lex JavaScript in the citation checker and stop where it is unsure (#723) (aa48d35)
  • scripts: read line ends, index flags and list items as their tools do (#738) (0b3a1e2)
  • serve: refuse an intent-recording ref update when the hook cannot wire its eventing (#724) (03cc9f2)
  • sync: hold the ref and record forward intent before a REST write's CAS (#737) (dc0dcfe)
  • sync: never lose a PostgreSQL forward between the ref CAS and its push run (#679) (faea6e1)
  • sync: record git forward intent before the CAS and refuse stale held snapshots (#678) (1996cc3)
  • sync: refuse stale held snapshots on PostgreSQL and restore River push runs (#762) (a0635de)
  • sync: run the worker's git without replacement objects (#779) (ffd0e9f)

Performance Improvements

  • api: resume a recursive files page at its cursor (#715) (3ad97da)
  • gitread: join a git call's output once (#750) (df18c1b)
  • meta: lower a repo list filter once per query on PostgreSQL (#785) (3ceb600)

This PR was generated with Release Please. See documentation.

@github-actions
github-actions Bot force-pushed the release-please--branches--main--components--openstorage branch 21 times, most recently from 4b2411b to d1f710f Compare November 6, 2026 08:37
@github-actions
github-actions Bot force-pushed the release-please--branches--main--components--openstorage branch 7 times, most recently from db774df to 55f8e5f Compare November 6, 2026 13:39
@github-actions
github-actions Bot force-pushed the release-please--branches--main--components--openstorage branch 28 times, most recently from 540e1f1 to 0c9cfd0 Compare November 9, 2026 09:48
@github-actions
github-actions Bot force-pushed the release-please--branches--main--components--openstorage branch from 0c9cfd0 to 1eff3cf Compare November 9, 2026 15:55

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants