Delegate Promptkit releases to ReleaseKit

This commit is contained in:
2026-10-08 16:40:34 +00:00
parent 05082c6fdf
commit b1866946d1
8 changed files with 136 additions and 302 deletions

View File

@@ -1,126 +0,0 @@
#!/bin/sh
# Run local checks without publishing or changing files.
set -eu
cd "$(dirname "$0")/.."
go test -race -vet=off ./...
go vet ./...
python3 ./scripts/check-examples.py
unformatted=$(
git ls-files '*.go' |
while IFS= read -r go_file
do
gofmt -l "$go_file"
done
)
test -z "$unformatted"
python3 - <<'PY'
from pathlib import Path
import re
import subprocess
import sys
from urllib.parse import unquote
root = Path.cwd().resolve()
markdown_files = [
root / name
for name in subprocess.check_output(
["git", "ls-files", "*.md"], text=True
).splitlines()
]
link_pattern = re.compile(r"!?\[[^]]*\]\(([^)]+)\)")
heading_pattern = re.compile(r"^#{1,6}\s+(.+?)\s*#*\s*$")
scheme_pattern = re.compile(r"^[a-z][a-z0-9+.-]*:", re.IGNORECASE)
def markdown_lines(path):
in_fence = False
fence = ""
for line in path.read_text(encoding="utf-8").splitlines():
stripped = line.lstrip()
marker = stripped[:3]
if marker in {"```", "~~~"}:
if not in_fence:
in_fence = True
fence = marker
elif marker == fence:
in_fence = False
fence = ""
continue
if not in_fence:
yield line
anchor_cache = {}
def anchors(path):
if path in anchor_cache:
return anchor_cache[path]
found = set()
counts = {}
for line in markdown_lines(path):
match = heading_pattern.match(line)
if not match:
continue
heading = re.sub(r"<[^>]+>", "", match.group(1)).replace("`", "")
base = re.sub(r"[^\w\- ]", "", heading.lower()).replace(" ", "-")
count = counts.get(base, 0)
counts[base] = count + 1
found.add(base if count == 0 else f"{base}-{count}")
anchor_cache[path] = found
return found
failures = []
for source in markdown_files:
text = "\n".join(markdown_lines(source))
for match in link_pattern.finditer(text):
target = match.group(1).strip()
if target.startswith("<") and target.endswith(">"):
target = target[1:-1]
if scheme_pattern.match(target) or target.startswith("//"):
continue
path_text, separator, fragment = target.partition("#")
destination = source if not path_text else source.parent / unquote(path_text)
try:
destination = destination.resolve()
destination.relative_to(root)
except ValueError:
failures.append(f"{source.relative_to(root)}: escapes repository: {target}")
continue
if not destination.exists():
failures.append(f"{source.relative_to(root)}: missing target: {target}")
continue
if separator and destination.suffix.lower() == ".md":
fragment = unquote(fragment).lower()
if fragment not in anchors(destination):
failures.append(f"{source.relative_to(root)}: missing anchor: {target}")
if failures:
print("\n".join(failures), file=sys.stderr)
raise SystemExit(1)
PY
case "$(go env GOWORK)" in
''|off) ;;
*) printf '%s\n' 'an active Go workspace is not allowed' >&2; exit 1 ;;
esac
test -z "$(git ls-files go.work go.work.sum)"
test ! -e vendor
if grep -Eq '^[[:space:]]*replace([[:space:]]|\()' go.mod
then
printf '%s\n' 'go.mod contains a replacement' >&2
exit 1
fi
git diff --check
git diff --cached --check
credential_pattern='-----BEGIN ([A-Z0-9]+ )?PRIV''ATE KEY-----|AKI''A[0-9A-Z]{16}|gh[pousr]_[A-Za-z0-9]{36,}|sk-[A-Za-z0-9]{32,}'
if git grep -nEI -e "$credential_pattern" -- .
then
printf '%s\n' 'possible credential found' >&2
exit 1
fi

View File

@@ -1,57 +1,5 @@
#!/bin/sh
# Validate one committed candidate and publish only its selected annotated tag.
set -eu
cd "$(dirname "$0")/.."
release_version=${1:?usage: scripts/release.sh vMAJOR.MINOR.PATCH}
printf '%s\n' "$release_version" |
grep -Eq '^v(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)$'
release_commit=$(git rev-parse --verify 'HEAD^{commit}')
check_candidate() {
test "$(git branch --show-current)" = main
test -z "$(git status --porcelain)"
test "$(git rev-parse HEAD)" = "$release_commit"
git fetch origin main
test "$(git rev-parse refs/remotes/origin/main)" = "$release_commit"
if git show-ref --verify --quiet "refs/tags/$release_version"; then
printf '%s\n' "local tag already exists: $release_version" >&2
exit 1
fi
remote_refs=$(git ls-remote --tags origin "refs/tags/$release_version" "refs/tags/$release_version^{}")
test -z "$remote_refs"
}
check_candidate
python3 - "$release_version" <<'PY'
from pathlib import Path
import sys
version = sys.argv[1]
note = Path("docs/releases") / (version + ".md")
lines = note.read_text(encoding="utf-8").splitlines()
assert lines and lines[0] == "# Promptkit " + version, f"wrong release title: {note}"
headings = set()
fence = None
for line in lines:
marker = line.lstrip()[:3]
if marker in {"```", "~~~"}:
if fence is None:
fence = marker
elif fence == marker:
fence = None
elif fence is None:
headings.add(line)
for section in ("Summary", "Compatibility", "Upgrade", "Changes"):
assert "## " + section in headings, f"missing {section}: {note}"
PY
./scripts/release-check.sh
check_candidate
release_note=$(git show "$release_commit:docs/releases/$release_version.md")
printf '%s\n\nValidated commit: %s\n' "$release_note" "$release_commit" |
git tag --annotate --cleanup=verbatim "$release_version" --file - "$release_commit"
test "$(git cat-file -t "refs/tags/$release_version")" = tag
test "$(git rev-parse "refs/tags/$release_version^{commit}")" = "$release_commit"
git push origin "refs/tags/$release_version:refs/tags/$release_version"
printf '%s\n' "Released $release_version. No CI or module-availability wait is required."
exec ./scripts/releasekit.sh publish "$@"

View File

@@ -179,6 +179,7 @@ def prepare_repository(repository, remote, environment, module_bytes, version):
scripts = repository / "scripts"
scripts.mkdir(parents=True, exist_ok=True)
shutil.copy2(REPOSITORY_ROOT / "scripts/release.sh", scripts / "release.sh")
shutil.copy2(REPOSITORY_ROOT / "scripts/releasekit.sh", scripts / "releasekit.sh")
write_file(
scripts / "check-examples.py",
@@ -215,9 +216,9 @@ def prepare_repository(repository, remote, environment, module_bytes, version):
def verify_publication(repository, remote, temporary_root, environment, module_bytes, selected_go):
bootstrap = repository / "scripts/releasekit.sh"
publication = repository / "scripts/release.sh"
run(
[str(bootstrap), "publish", RELEASE_VERSION],
[str(publication), RELEASE_VERSION],
cwd=temporary_root,
environment=environment,
)
@@ -324,7 +325,7 @@ def verify_validation_failure(
)
result = execute(
[str(repository / "scripts/releasekit.sh"), "publish", FAILED_RELEASE_VERSION],
[str(repository / "scripts/release.sh"), FAILED_RELEASE_VERSION],
cwd=temporary_root,
environment=scenario_environment,
)