From 227fd5ea9fd958c3fc89f6721f5ed004b3e7838d Mon Sep 17 00:00:00 2001 From: Chris Busillo Date: Mon, 25 May 2026 21:01:32 -0400 Subject: [PATCH] chore(release): remove legacy GitHub release helpers --- code-rs/scripts/create_github_release | 313 ----------------------- code-rs/scripts/create_github_release.sh | 102 -------- code-rs/tui/src/chatwidget.rs | 2 +- 3 files changed, 1 insertion(+), 416 deletions(-) delete mode 100755 code-rs/scripts/create_github_release delete mode 100755 code-rs/scripts/create_github_release.sh diff --git a/code-rs/scripts/create_github_release b/code-rs/scripts/create_github_release deleted file mode 100755 index 3962c639a53d..000000000000 --- a/code-rs/scripts/create_github_release +++ /dev/null @@ -1,313 +0,0 @@ -#!/usr/bin/env python3 - -import argparse -import base64 -import json -import re -import subprocess -import sys - - -REPO = "openai/codex" -BRANCH_REF = "heads/main" -CARGO_TOML_PATH = "code-rs/Cargo.toml" - - -def parse_args(argv: list[str]) -> argparse.Namespace: - parser = argparse.ArgumentParser(description="Publish a tagged Codex release.") - parser.add_argument( - "-n", - "--dry-run", - action="store_true", - help="Print the version that would be used and exit before making changes.", - ) - - group = parser.add_mutually_exclusive_group() - group.add_argument( - "--publish-alpha", - action="store_true", - help="Publish the next alpha release for the upcoming minor version.", - ) - group.add_argument( - "--publish-release", - action="store_true", - help="Publish the next stable release by bumping the minor version.", - ) - parser.add_argument( - "--emergency-version-override", - help="Publish a specific version because tag was created for the previous release but it never succeeded. Value should be semver, e.g., `0.43.0-alpha.9`.", - ) - - args = parser.parse_args(argv[1:]) - if not ( - args.publish_alpha - or args.publish_release - or args.emergency_version_override - ): - parser.error( - "Must specify --publish-alpha, --publish-release, or --emergency-version-override." - ) - return args - - -def main(argv: list[str]) -> int: - args = parse_args(argv) - try: - if args.emergency_version_override: - version = args.emergency_version_override - else: - version = determine_version(args) - print(f"Publishing version {version}") - if args.dry_run: - return 0 - - print("Fetching branch head...") - base_commit = get_branch_head() - print(f"Base commit: {base_commit}") - print("Fetching commit tree...") - base_tree = get_commit_tree(base_commit) - print(f"Base tree: {base_tree}") - print("Fetching Cargo.toml...") - current_contents = fetch_file_contents(base_commit) - print("Updating version...") - updated_contents = replace_version(current_contents, version) - print("Creating blob...") - blob_sha = create_blob(updated_contents) - print(f"Blob SHA: {blob_sha}") - print("Creating tree...") - tree_sha = create_tree(base_tree, blob_sha) - print(f"Tree SHA: {tree_sha}") - print("Creating commit...") - commit_sha = create_commit(version, tree_sha, base_commit) - print(f"Commit SHA: {commit_sha}") - print("Creating tag...") - tag_sha = create_tag(version, commit_sha) - print(f"Tag SHA: {tag_sha}") - print("Creating tag ref...") - create_tag_ref(version, tag_sha) - print("Done.") - except ReleaseError as error: - print(f"ERROR: {error}", file=sys.stderr) - return 1 - return 0 - - -class ReleaseError(RuntimeError): - pass - - -def run_gh_api(endpoint: str, *, method: str = "GET", payload: dict | None = None) -> dict: - print(f"Running gh api {method} {endpoint}") - command = [ - "gh", - "api", - endpoint, - "--method", - method, - "-H", - "Accept: application/vnd.github+json", - ] - json_payload = None - if payload is not None: - json_payload = json.dumps(payload) - print(f"Payload: {json_payload}") - command.extend(["-H", "Content-Type: application/json", "--input", "-"]) - result = subprocess.run(command, text=True, capture_output=True, input=json_payload) - if result.returncode != 0: - message = result.stderr.strip() or result.stdout.strip() or "gh api call failed" - raise ReleaseError(message) - try: - return json.loads(result.stdout or "{}") - except json.JSONDecodeError as error: - raise ReleaseError("Failed to parse response from gh api.") from error - - -def get_branch_head() -> str: - response = run_gh_api(f"/repos/{REPO}/git/refs/{BRANCH_REF}") - try: - return response["object"]["sha"] - except KeyError as error: - raise ReleaseError("Unable to determine branch head.") from error - - -def get_commit_tree(commit_sha: str) -> str: - response = run_gh_api(f"/repos/{REPO}/git/commits/{commit_sha}") - try: - return response["tree"]["sha"] - except KeyError as error: - raise ReleaseError("Commit response missing tree SHA.") from error - - -def fetch_file_contents(ref_sha: str) -> str: - response = run_gh_api(f"/repos/{REPO}/contents/{CARGO_TOML_PATH}?ref={ref_sha}") - try: - encoded_content = response["content"].replace("\n", "") - encoding = response.get("encoding", "") - except KeyError as error: - raise ReleaseError("Failed to fetch Cargo.toml contents.") from error - - if encoding != "base64": - raise ReleaseError(f"Unexpected Cargo.toml encoding: {encoding}") - - try: - return base64.b64decode(encoded_content).decode("utf-8") - except (ValueError, UnicodeDecodeError) as error: - raise ReleaseError("Failed to decode Cargo.toml contents.") from error - - -def replace_version(contents: str, version: str) -> str: - updated, matches = re.subn( - r'^version = "[^"]+"', f'version = "{version}"', contents, count=1, flags=re.MULTILINE - ) - if matches != 1: - raise ReleaseError("Unable to update version in Cargo.toml.") - return updated - - -def create_blob(content: str) -> str: - response = run_gh_api( - f"/repos/{REPO}/git/blobs", - method="POST", - payload={"content": content, "encoding": "utf-8"}, - ) - try: - return response["sha"] - except KeyError as error: - raise ReleaseError("Blob creation response missing SHA.") from error - - -def create_tree(base_tree_sha: str, blob_sha: str) -> str: - response = run_gh_api( - f"/repos/{REPO}/git/trees", - method="POST", - payload={ - "base_tree": base_tree_sha, - "tree": [ - { - "path": CARGO_TOML_PATH, - "mode": "100644", - "type": "blob", - "sha": blob_sha, - } - ], - }, - ) - try: - return response["sha"] - except KeyError as error: - raise ReleaseError("Tree creation response missing SHA.") from error - - -def create_commit(version: str, tree_sha: str, parent_sha: str) -> str: - response = run_gh_api( - f"/repos/{REPO}/git/commits", - method="POST", - payload={ - "message": f"Release {version}", - "tree": tree_sha, - "parents": [parent_sha], - }, - ) - try: - return response["sha"] - except KeyError as error: - raise ReleaseError("Commit creation response missing SHA.") from error - - -def create_tag(version: str, commit_sha: str) -> str: - tag_name = f"rust-v{version}" - response = run_gh_api( - f"/repos/{REPO}/git/tags", - method="POST", - payload={ - "tag": tag_name, - "message": f"Release {version}", - "object": commit_sha, - "type": "commit", - }, - ) - try: - return response["sha"] - except KeyError as error: - raise ReleaseError("Tag creation response missing SHA.") from error - - -def create_tag_ref(version: str, tag_sha: str) -> None: - tag_ref = f"refs/tags/rust-v{version}" - run_gh_api( - f"/repos/{REPO}/git/refs", - method="POST", - payload={"ref": tag_ref, "sha": tag_sha}, - ) - - -def determine_version(args: argparse.Namespace) -> str: - latest_version = get_latest_release_version() - major, minor, patch = parse_semver(latest_version) - next_minor_version = format_version(major, minor + 1, patch) - - if args.publish_release: - return next_minor_version - - alpha_prefix = f"{next_minor_version}-alpha." - releases = list_releases() - highest_alpha = 0 - found_alpha = False - for release in releases: - tag = release.get("tag_name", "") - candidate = strip_tag_prefix(tag) - if candidate and candidate.startswith(alpha_prefix): - suffix = candidate[len(alpha_prefix) :] - try: - alpha_number = int(suffix) - except ValueError: - continue - highest_alpha = max(highest_alpha, alpha_number) - found_alpha = True - - if found_alpha: - return f"{alpha_prefix}{highest_alpha + 1}" - return f"{alpha_prefix}1" - - -def get_latest_release_version() -> str: - response = run_gh_api(f"/repos/{REPO}/releases/latest") - tag = response.get("tag_name") - version = strip_tag_prefix(tag) - if not version: - raise ReleaseError("Latest release tag has unexpected format.") - return version - - -def list_releases() -> list[dict]: - response = run_gh_api(f"/repos/{REPO}/releases?per_page=100") - if not isinstance(response, list): - raise ReleaseError("Unexpected response when listing releases.") - return response - - -def strip_tag_prefix(tag: str | None) -> str | None: - if not tag: - return None - prefix = "rust-v" - if not tag.startswith(prefix): - return None - return tag[len(prefix) :] - - -def parse_semver(version: str) -> tuple[int, int, int]: - parts = version.split(".") - if len(parts) != 3: - raise ReleaseError(f"Unexpected version format: {version}") - try: - return int(parts[0]), int(parts[1]), int(parts[2]) - except ValueError as error: - raise ReleaseError(f"Version components must be integers: {version}") from error - - -def format_version(major: int, minor: int, patch: int) -> str: - return f"{major}.{minor}.{patch}" - - -if __name__ == "__main__": - sys.exit(main(sys.argv)) diff --git a/code-rs/scripts/create_github_release.sh b/code-rs/scripts/create_github_release.sh deleted file mode 100755 index df3719bc436a..000000000000 --- a/code-rs/scripts/create_github_release.sh +++ /dev/null @@ -1,102 +0,0 @@ -#!/bin/bash - -set -euo pipefail - -# This script creates a GitHub release by tagging the current commit. -# The GitHub Actions workflow will handle updating the version in Cargo.toml during build. -# -# Usage: -# ./scripts/create_github_release.sh 0.1.0 -# ./scripts/create_github_release.sh 0.1.0-alpha.4 -# -# If no version is specified, a timestamp-based version will be used. - -# Change to the root of the repository (two levels up from scripts dir). -cd "$(dirname "${BASH_SOURCE[0]}")/../.." - -# Cancel if there are uncommitted changes. -if ! git diff --quiet || ! git diff --cached --quiet || [ -n "$(git ls-files --others --exclude-standard)" ]; then - echo "ERROR: You have uncommitted or untracked changes." >&2 - echo " Please commit or stash your changes before creating a release." >&2 - exit 1 -fi - -# Fail if in a detached HEAD state. -CURRENT_BRANCH=$(git symbolic-ref --short -q HEAD 2>/dev/null || true) -if [ -z "${CURRENT_BRANCH:-}" ]; then - echo "ERROR: Could not determine the current branch (detached HEAD?)." >&2 - echo " Please run this script from a checked-out branch." >&2 - exit 1 -fi - -# Ensure we are on the 'main' branch before proceeding. -if [ "${CURRENT_BRANCH}" != "main" ]; then - echo "ERROR: Releases must be created from the 'main' branch (current: '${CURRENT_BRANCH}')." >&2 - echo " Please switch to 'main' and try again." >&2 - exit 1 -fi - -# Ensure the current local commit on 'main' is present on 'origin/main'. -# This guarantees we only create releases from commits that are already on -# the canonical repository. -if ! git fetch --quiet origin main; then - echo "ERROR: Failed to fetch 'origin/main'. Ensure the 'origin' remote is configured and reachable." >&2 - exit 1 -fi - -if ! git merge-base --is-ancestor HEAD origin/main; then - echo "ERROR: Your local 'main' HEAD commit is not present on 'origin/main'." >&2 - echo " Please push your commits first (git push origin main) or check out a commit on 'origin/main'." >&2 - exit 1 -fi - -# Determine version -if [ $# -ge 1 ]; then - VERSION="$1" -else - VERSION=$(printf '0.0.%d' "$(date +%y%m%d%H%M)") -fi - -# Validate version format -if ! [[ "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-(alpha|beta)(\.[0-9]+)?)?$ ]]; then - echo "ERROR: Invalid version format: $VERSION" >&2 - echo " Expected format: X.Y.Z or X.Y.Z-alpha.N or X.Y.Z-beta.N" >&2 - exit 1 -fi - -TAG="rust-v$VERSION" - -# Check if tag already exists -if git rev-parse "$TAG" >/dev/null 2>&1; then - echo "ERROR: Tag $TAG already exists." >&2 - echo " Please choose a different version." >&2 - exit 1 -fi - -echo "Creating release for version: $VERSION" -echo "Tag: $TAG" -echo "" -echo "The GitHub Actions workflow will:" -echo " 1. Update version in Cargo.toml to $VERSION" -echo " 2. Build binaries with the correct version embedded" -echo " 3. Create a GitHub release with artifacts" -echo "" -read -p "Continue? (y/N) " -n 1 -r -echo -if [[ ! $REPLY =~ ^[Yy]$ ]]; then - echo "Aborted." - exit 1 -fi - -# Create and push the tag -git tag -a "$TAG" -m "Release $VERSION" -git push origin "refs/tags/$TAG" - -echo "" -echo "✅ Tag $TAG pushed successfully!" -echo "" -echo "📦 The release workflow has been triggered." -echo " View progress at: https://github.com/${GITHUB_REPOSITORY:-$(git remote get-url origin | sed 's/.*github.com[:/]\(.*\)\.git/\1/')}/actions" -echo "" -echo "Once the workflow completes, the release will be available at:" -echo " https://github.com/${GITHUB_REPOSITORY:-$(git remote get-url origin | sed 's/.*github.com[:/]\(.*\)\.git/\1/')}/releases/tag/$TAG" diff --git a/code-rs/tui/src/chatwidget.rs b/code-rs/tui/src/chatwidget.rs index cf6b71107066..81af4444976a 100644 --- a/code-rs/tui/src/chatwidget.rs +++ b/code-rs/tui/src/chatwidget.rs @@ -16442,7 +16442,7 @@ impl ChatWidget<'_> { "streaming preview: validating release artifacts…", "streaming preview: preparing announcement copy…", ], - "**Release rehearsal:**\n\n1. Run `./scripts/create_github_release.sh --dry-run`.\n2. Capture artifact hashes in the notes.\n3. Schedule follow-up validation in automation.\n\n```bash\n./scripts/create_github_release.sh 1.2.3 --dry-run\n```", + "**Release rehearsal:**\n\n1. Run `./build-fast.sh`.\n2. Merge the release metadata PR if one is opened.\n3. Watch the protected `Release` workflow publish GitHub Release assets.\n\n```bash\nscripts/wait-for-gh-run.sh --workflow Release --branch main\n```", vec![ (vec!["git", "--no-pager", "diff", "--stat"], " src/lib.rs | 10 ++++++----\n 1 file changed, 6 insertions(+), 4 deletions(-)\n"), (vec!["ls", "-1"], "Cargo.lock\nREADME.md\nsrc\ntarget\n"),