Ran: ``` ./codex-rs/scripts/create_github_release 0.31.0-alpha.1 ``` which appeared to work as expected: - workflow https://github.com/openai/codex/actions/runs/17508403922 - release https://github.com/openai/codex/releases/tag/rust-v0.31.0-alpha.1 --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/openai/codex/pull/3228). * #3231 * #3230 * __->__ #3228 * #3226
106 lines
3.1 KiB
Python
Executable File
106 lines
3.1 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
import argparse
|
|
import re
|
|
import subprocess
|
|
import sys
|
|
import tempfile
|
|
from pathlib import Path
|
|
|
|
|
|
def parse_args(argv: list[str]) -> argparse.Namespace:
|
|
parser = argparse.ArgumentParser(description="Create a tagged Codex release.")
|
|
parser.add_argument(
|
|
"version",
|
|
help="Version string used for Cargo.toml and the Git tag (e.g. 0.1.0-alpha.4).",
|
|
)
|
|
return parser.parse_args(argv[1:])
|
|
|
|
|
|
def main(argv: list[str]) -> int:
|
|
args = parse_args(argv)
|
|
try:
|
|
with tempfile.TemporaryDirectory() as temp_dir:
|
|
repo_dir = Path(temp_dir) / "codex"
|
|
clone_repository(repo_dir)
|
|
branch = current_branch(repo_dir)
|
|
create_release(args.version, branch, repo_dir)
|
|
except ReleaseError as error:
|
|
print(f"ERROR: {error}", file=sys.stderr)
|
|
return 1
|
|
return 0
|
|
|
|
|
|
def current_branch(repo_dir: Path) -> str:
|
|
result = run_git(
|
|
repo_dir,
|
|
["symbolic-ref", "--short", "-q", "HEAD"],
|
|
capture_output=True,
|
|
check=False,
|
|
)
|
|
branch = result.stdout.strip()
|
|
if result.returncode != 0 or not branch:
|
|
raise ReleaseError("Could not determine the current branch (detached HEAD?).")
|
|
return branch
|
|
|
|
|
|
def update_version(version: str, cargo_toml: Path) -> None:
|
|
content = cargo_toml.read_text(encoding="utf-8")
|
|
new_content, matches = re.subn(
|
|
r'^version = "[^"]+"', f'version = "{version}"', content, count=1, flags=re.MULTILINE
|
|
)
|
|
if matches != 1:
|
|
raise ReleaseError("Unable to update version in Cargo.toml.")
|
|
cargo_toml.write_text(new_content, encoding="utf-8")
|
|
|
|
|
|
def create_release(version: str, branch: str, repo_dir: Path) -> None:
|
|
tag = f"rust-v{version}"
|
|
run_git(repo_dir, ["checkout", "-b", tag])
|
|
try:
|
|
update_version(version, repo_dir / "codex-rs" / "Cargo.toml")
|
|
run_git(repo_dir, ["add", "codex-rs/Cargo.toml"])
|
|
run_git(repo_dir, ["commit", "-m", f"Release {version}"])
|
|
run_git(repo_dir, ["tag", "-a", tag, "-m", f"Release {version}"])
|
|
run_git(repo_dir, ["push", "origin", f"refs/tags/{tag}"])
|
|
finally:
|
|
run_git(repo_dir, ["checkout", branch])
|
|
|
|
|
|
def clone_repository(destination: Path) -> None:
|
|
result = subprocess.run(
|
|
["gh", "repo", "clone", "openai/codex", str(destination), "--", "--depth", "1"],
|
|
text=True,
|
|
)
|
|
if result.returncode != 0:
|
|
raise ReleaseError("Failed to clone openai/codex using gh.")
|
|
|
|
|
|
class ReleaseError(RuntimeError):
|
|
pass
|
|
|
|
|
|
def run_git(
|
|
repo_dir: Path,
|
|
args: list[str],
|
|
*,
|
|
capture_output: bool = False,
|
|
check: bool = True,
|
|
) -> subprocess.CompletedProcess:
|
|
result = subprocess.run(
|
|
["git", *args],
|
|
cwd=repo_dir,
|
|
text=True,
|
|
capture_output=capture_output,
|
|
)
|
|
if check and result.returncode != 0:
|
|
stderr = result.stderr.strip() if result.stderr else ""
|
|
stdout = result.stdout.strip() if result.stdout else ""
|
|
message = stderr if stderr else stdout
|
|
raise ReleaseError(message or f"git {' '.join(args)} failed")
|
|
return result
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main(sys.argv))
|