Files
promptkit/scripts/test-release.py

164 lines
7.4 KiB
Python
Raw Permalink Normal View History

"""Check Promptkit's launcher and release profile using a disposable local remote.
ReleaseKit owns the detailed publication, validation, and delivery algorithms.
These fixtures protect this repository's launcher and release-profile wiring.
"""
import json
import os
import shutil
import subprocess
import sys
import tempfile
import textwrap
from pathlib import Path
REPOSITORY_ROOT = Path(__file__).resolve().parent.parent
RELEASEKIT_MODULE = "go.maximumdirect.net/releasekit"
RELEASE_VERSION = "v0.0.1"
FAILED_VERSION = "v0.0.2"
def run(command, directory, environment, status=0):
result = subprocess.run(
command, cwd=directory, env=environment, text=True, capture_output=True
)
if result.returncode != status:
raise RuntimeError(
f"{' '.join(map(str, command))}: status {result.returncode}, want {status}"
f"\nstdout:\n{result.stdout}\nstderr:\n{result.stderr}"
)
return result.stdout
def git(repository, environment, *arguments):
return run(["git", "-C", str(repository), *arguments], repository.parent, environment).strip()
def write(path, contents):
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(textwrap.dedent(contents).lstrip("\n"), encoding="utf-8")
def prepare_fixture(root, environment, module_bytes):
repository, remote = root / "checkout", root / "origin.git"
run(["git", "init", "--bare", "--initial-branch=main", str(remote)], root, environment)
run(["git", "init", "--initial-branch=main", str(repository)], root, environment)
git(repository, environment, "config", "user.name", "Promptkit Fixture")
git(repository, environment, "config", "user.email", "fixture@example.invalid")
git(repository, environment, "remote", "add", "origin", str(remote))
for name, contents in module_bytes.items():
(repository / name).write_bytes(contents)
for name in ("release.sh", "releasekit.sh"):
destination = repository / "scripts" / name
destination.parent.mkdir(exist_ok=True)
shutil.copy2(REPOSITORY_ROOT / "scripts" / name, destination)
shutil.copy2(REPOSITORY_ROOT / "releasekit.json", repository / "releasekit.json")
shutil.copy2(REPOSITORY_ROOT / ".gitignore", repository / ".gitignore")
write(repository / f"docs/releases/{RELEASE_VERSION}.md", f"# Promptkit {RELEASE_VERSION}\n\nFixture.\n")
write(repository / "fixture_test.go", """
package fixture
import (
"fmt"
"os"
"runtime"
"testing"
)
func TestSelectedSuite(t *testing.T) {
if !raceEnabled {
t.Fatal("profile did not select the race detector")
}
file, err := os.OpenFile(os.Getenv("FIXTURE_SUITE_MARKER"), os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0600)
if err != nil { t.Fatal(err) }
defer file.Close()
if _, err := fmt.Fprintln(file, runtime.Version()); err != nil { t.Fatal(err) }
}
""")
for name, tag, enabled in (("race", "race", "true"), ("norace", "!race", "false")):
write(repository / f"{name}.go", f"//go:build {tag}\n\npackage fixture\n\nconst raceEnabled = {enabled}\n")
run(["gofmt", "-w", "fixture_test.go", "race.go", "norace.go"], repository, environment)
git(repository, environment, "add", ".")
git(repository, environment, "commit", "-m", "Add release wiring fixture")
git(repository, environment, "push", "origin", "main")
return repository, remote
def verify_bootstrap(repository, root, environment, selected_go):
selected_version = run(
["go", "list", "-mod=readonly", "-m", "-f", "{{.Version}}", RELEASEKIT_MODULE],
repository, environment,
).strip()
launcher = str(repository / "scripts/releasekit.sh")
version = run([launcher, "version"], root, environment).strip()
if version != f"releasekit {selected_version}":
raise RuntimeError(f"launcher used an unexpected tool: {version}")
tool_path = run(
["go", "tool", "-n", f"{RELEASEKIT_MODULE}/cmd/releasekit"],
repository, environment,
).strip()
build_info = run(["go", "version", "-m", tool_path], root, environment)
if selected_go not in build_info.splitlines()[0]:
raise RuntimeError("launcher did not build with the selected local Go")
if f"\tmod\t{RELEASEKIT_MODULE}\t{selected_version}\t" not in build_info:
raise RuntimeError("launcher did not use the module-selected ReleaseKit")
run([launcher, "unknown"], root, environment, status=2)
def verify_publication(repository, remote, root, environment, profile, selected_go):
if (repository / profile["delivery"]["token_file"]).exists():
raise RuntimeError("source-publication fixture must have no delivery token")
publication = str(repository / "scripts/release.sh")
run([publication, RELEASE_VERSION], root, environment)
candidate = git(repository, environment, "rev-parse", "HEAD")
if git(remote, environment, "rev-parse", f"refs/tags/{RELEASE_VERSION}^{{}}") != candidate:
raise RuntimeError("launcher did not publish the intended candidate")
suite = Path(environment["FIXTURE_SUITE_MARKER"]).read_text().splitlines()
if suite != [selected_go]:
raise RuntimeError(f"profile did not run the selected suite: {suite}")
run([publication, FAILED_VERSION], root, environment, status=1)
run(
["git", "-C", str(remote), "show-ref", "--verify", "--quiet", f"refs/tags/{FAILED_VERSION}"],
root, environment, status=1,
)
def verify_token_guard(repository, environment, profile):
2026-11-02 14:10:37 +00:00
token_path = profile["delivery"]["token_file"]
git(repository, environment, "check-ignore", "--no-index", token_path)
if token_path not in profile["validation"].get("forbidden_files", []):
raise RuntimeError("delivery token path is not selected for committed-file protection")
def main():
environment = dict(os.environ, GOTOOLCHAIN="local", GOWORK="off",
GOPROXY="off", GONOPROXY="none", GOSUMDB="off")
profile = json.loads((REPOSITORY_ROOT / "releasekit.json").read_text())
environment.pop(profile["delivery"].get("token_env", "RELEASEKIT_GITEA_TOKEN"), None)
module_bytes = {name: (REPOSITORY_ROOT / name).read_bytes() for name in ("go.mod", "go.sum")}
try:
selected_go = run(["go", "env", "GOVERSION"], REPOSITORY_ROOT, environment).strip()
with tempfile.TemporaryDirectory(prefix="promptkit-release-fixture-") as directory:
root = Path(directory)
environment.update(FIXTURE_SUITE_MARKER=str(root / "suite"))
repository, remote = prepare_fixture(root, environment, module_bytes)
verify_bootstrap(repository, root, environment, selected_go)
verify_publication(repository, remote, root, environment, profile, selected_go)
verify_token_guard(repository, environment, profile)
if any((repository / name).read_bytes() != contents for name, contents in module_bytes.items()):
raise RuntimeError("release commands changed module metadata")
if git(repository, environment, "status", "--porcelain", "--untracked-files=all"):
raise RuntimeError("release commands left unexpected worktree changes")
except (OSError, RuntimeError) as error:
print(error, file=sys.stderr)
return 1
print("Promptkit release wiring checks passed")
return 0
if __name__ == "__main__":
raise SystemExit(main())