Settle the compatibility contract, the changelog and the changelog-cut Gitea release #17

Merged
lilleman merged 6 commits from worktree-versioning-contract into main 2026-09-16 20:20:01 +02:00
3 changed files with 18 additions and 13 deletions
Showing only changes of commit 16f2e96fe8 - Show all commits
+2 -2
View File
@@ -559,8 +559,8 @@ with no breaking change. From `v2` the module path carries `/vN`, so fences ship
batched into as few majors as possible.
[`testdata/shipped_shape.txt`](testdata/shipped_shape.txt) pins every path, each
category's format and the categories it reads, and each column's datatype and
nullability; a pull request that
template category's format, the categories each category reads, and each column's
datatype and nullability; a pull request that
changes it or `data/` adds its `CHANGELOG.md` entry, which CI checks. A removed,
renamed or retyped line is a major.
+11 -2
View File
@@ -12,7 +12,7 @@ import sys
import urllib.error
import urllib.request
HEADING = re.compile(r"^## \[([^\]]+)\].*?$\n(.*?)(?=^## \[|\Z)", re.M | re.S)
HEADING = re.compile(r"^## \[([^\]]+)\].*?$\n?(.*?)(?=^## \[|\Z)", re.M | re.S)
def request(path: str, data: dict | None = None):
@@ -45,7 +45,16 @@ def main() -> int:
except urllib.error.HTTPError as e:
if e.code != 404:
raise
release = request("releases", {"body": body, "name": tag, "tag_name": tag, "target_commitish": os.environ["SHA"]})
sha = os.environ["SHA"]
try:
at = request(f"tags/{tag}")["commit"]["sha"]
if at != sha:
print(f"{tag} exists at {at}, not {sha}; the version is burnt, bump the heading", file=sys.stderr)
return 1
except urllib.error.HTTPError as e:
if e.code != 404:
raise
release = request("releases", {"body": body, "name": tag, "tag_name": tag, "target_commitish": sha})
print(release["html_url"])
return 0
+5 -9
View File
@@ -10,9 +10,7 @@ import (
const shapePin = "testdata/shipped_shape.txt"
// TestShippedShapeIsPinned pins what a version promises about the shipped data (see
// the README's Versioning): every path, each category's format and the categories it
// reads, and each record column's datatype and nullability. REPIN=1 rewrites the pin.
// REPIN=1 rewrites the pin.
func TestShippedShapeIsPinned(t *testing.T) {
f, err := New(WithSeed(1))
if err != nil {
@@ -34,9 +32,6 @@ func TestShippedShapeIsPinned(t *testing.T) {
}
}
// shippedShape lists every path Fake accepts, one per line. A category carries the
// categories it references, a category-level template its format, and each of its
// columns its datatype and whether it may be null.
func shippedShape(f *Generator) string {
facts := map[string]string{}
var walk func(prefix string, n node)
@@ -108,10 +103,11 @@ func TestShippedShapeNamesReads(t *testing.T) {
f := newGenerator(t, writeData(t, map[string]string{
"a": `{"format":"{x}","x":["{/b}",{"format":"{/c.v}","weight":2}]}`,
"b": `"y"`,
"c": `{"format":"{v}","v":["z","w"]}`,
"d/pos": `["{/b}","q"]`,
"c": `{"format":"{v} {n}","n":[null,{"format":"{int(1,9)}","datatype":"integer"}],"v":["z","w"]}`,
"d/pos": `["{.q}","{/b}"]`,
"d/q": `"r"`,
}))
want := "a\tformat \"{x}\"\treads b c\na.x\tstring\nb\tformat \"y\"\nc\tformat \"{v}\"\nc.v\tstring\nd.pos\treads b\n"
want := "a\tformat \"{x}\"\treads b c\na.x\tstring\nb\tformat \"y\"\nc\tformat \"{v} {n}\"\nc.n\tinteger null\nc.v\tstring\nd.pos\treads b d.q\nd.q\tformat \"r\"\n"
if got := shippedShape(f); got != want {
t.Fatalf("shippedShape =\n%s\nwant\n%s", got, want)
}