From e459e92a3d2ae77f9a586ecfe7e919d7c65298bd Mon Sep 17 00:00:00 2001 From: Rob Ede Date: Sun, 9 Aug 2026 19:33:05 +0100 Subject: [PATCH] fix: use authenticated Homebrew tap checkout --- release-tools/test.bash | 21 +++++++++++++----- release-tools/update-homebrew-tap.py | 32 +++++++++++----------------- 2 files changed, 28 insertions(+), 25 deletions(-) diff --git a/release-tools/test.bash b/release-tools/test.bash index d2f0c1a..3d61295 100644 --- a/release-tools/test.bash +++ b/release-tools/test.bash @@ -160,10 +160,6 @@ shopt -s inherit_errexit if [[ "$*" == "diff --cached --quiet" || "$*" == *"diff --quiet --"* ]]; then exit 1 fi -if [[ "$*" == *"push --set-upstream origin release/homebrew-"* ]]; then - credential_helper="credential.helper=!${X52_GH} auth git-credential" - [[ "$*" == *"-c credential.helper= -c $credential_helper"* ]] -fi printf 'git' >>"$COMMAND_LOG" printf ' <%s>' "$@" >>"$COMMAND_LOG" printf '\n' >>"$COMMAND_LOG" @@ -293,7 +289,11 @@ grep -Fq 'assert_match "custom test", shell_output("#{bin}/demo-formula verify") grep -Fq '# x52-release-tools: begin macos artifacts' "$tap_root/Formula/demo-formula.rb" grep -Fq 'gh <--repo> <--base> <--head> ' "$command_log" grep -Fq 'git <-C> <'"$tap_root"'> <-m> ' "$command_log" -grep -Fq 'git <-c> <-c> <-C> <'"$tap_root"'> <--set-upstream> ' "$command_log" +grep -Fq 'git <-C> <'"$tap_root"'> <--set-upstream> ' "$command_log" +if grep -Fq 'gh ' "$command_log"; then + echo "Expected the updater to use the tap checkout's Git credentials" >&2 + exit 1 +fi x52-update-homebrew-tap \ --tag demo-v1.2.0 \ @@ -312,6 +312,17 @@ grep -Fq 'assert_match "manual test", shell_output("#{bin}/manual-demo verify")' grep -Fq '# x52-release-tools: begin macos artifacts' "$tap_root/Formula/manual-demo.rb" grep -Fq '# x52-release-tools: begin linux artifacts' "$tap_root/Formula/manual-demo.rb" +unset X52_HOMEBREW_TAP_DIRECTORY +if x52-update-homebrew-tap \ + --tag demo-v1.2.0 \ + --version 1.2.0 \ + --package manual-release \ + --source-repository example/manual >"$test_root/missing-tap-directory.log" 2>&1; then + echo "Expected a missing Homebrew tap checkout to fail" >&2 + exit 1 +fi +grep -Fq -- '--tap-directory or X52_HOMEBREW_TAP_DIRECTORY is required' "$test_root/missing-tap-directory.log" + cat >"$fixture_root/CHANGELOG.md" <<'EOF' # Changelog diff --git a/release-tools/update-homebrew-tap.py b/release-tools/update-homebrew-tap.py index 022a289..94452ae 100644 --- a/release-tools/update-homebrew-tap.py +++ b/release-tools/update-homebrew-tap.py @@ -58,11 +58,6 @@ def run(*command: str, cwd: Path | None = None, check: bool = True) -> subproces return result -def run_authenticated_git(git: str, gh: str, *command: str, check: bool = True) -> subprocess.CompletedProcess[str]: - credential_helper = f"!{shlex.quote(gh)} auth git-credential" - return run(git, "-c", "credential.helper=", "-c", f"credential.helper={credential_helper}", *command, check=check) - - def ruby_string(value: str) -> str: return json.dumps(value, ensure_ascii=False) @@ -263,28 +258,25 @@ def main() -> int: parser.add_argument("--source-repository", default=os.environ.get("GITHUB_REPOSITORY"), help="release repository") parser.add_argument("--tap", default=os.environ.get("X52_HOMEBREW_TAP_REPOSITORY", "x52dev/homebrew-tap"), help="Homebrew tap repository") parser.add_argument("--base", default="main", help="tap pull request base branch") - parser.add_argument("--tap-directory", default=os.environ.get("X52_HOMEBREW_TAP_DIRECTORY"), help=argparse.SUPPRESS) + parser.add_argument( + "--tap-directory", + default=os.environ.get("X52_HOMEBREW_TAP_DIRECTORY"), + help="existing Homebrew tap checkout with Git credentials; defaults to X52_HOMEBREW_TAP_DIRECTORY", + ) args = parser.parse_args() try: release = release_from_arguments(args) if not args.source_repository: raise UpdateError("--source-repository or GITHUB_REPOSITORY is required") + if not args.tap_directory: + raise UpdateError("--tap-directory or X52_HOMEBREW_TAP_DIRECTORY is required") formula_name = args.formula or args.package asset_prefix = args.asset_prefix or args.package log(f"Updating {formula_name} to {release.version} from {args.source_repository} release {release.tag}") - temporary_tap_directory = None - if args.tap_directory: - tap_directory = Path(args.tap_directory) - log(f"Using Homebrew tap checkout {tap_directory}") - else: - temporary_tap_directory = tempfile.TemporaryDirectory() - tap_directory = Path(temporary_tap_directory.name) / "homebrew-tap" - gh = os.environ.get("X52_GH", "gh") - git = os.environ.get("X52_GIT", "git") - log(f"Cloning Homebrew tap {args.tap}") - run_authenticated_git(git, gh, "clone", f"https://github.com/{args.tap}.git", str(tap_directory)) + tap_directory = Path(args.tap_directory) + log(f"Using Homebrew tap checkout {tap_directory}") formula = tap_directory / "Formula" / f"{formula_name}.rb" if not formula.is_file(): @@ -293,9 +285,9 @@ def main() -> int: git = os.environ.get("X52_GIT", "git") gh = os.environ.get("X52_GH", "gh") branch = f"release/homebrew-{formula_name}-{release.version}" - if run_authenticated_git(git, gh, "-C", str(tap_directory), "ls-remote", "--exit-code", "--heads", "origin", branch, check=False).returncode == 0: + if run(git, "-C", str(tap_directory), "ls-remote", "--exit-code", "--heads", "origin", branch, check=False).returncode == 0: log(f"Reusing tap branch {branch}") - run_authenticated_git(git, gh, "-C", str(tap_directory), "fetch", "origin", branch) + run(git, "-C", str(tap_directory), "fetch", "origin", branch) run(git, "-C", str(tap_directory), "switch", "--track", f"origin/{branch}") else: log(f"Creating tap branch {branch}") @@ -318,7 +310,7 @@ def main() -> int: run(git, "-C", str(tap_directory), "add", f"Formula/{formula_name}.rb") run(git, "-C", str(tap_directory), "commit", "-m", f"chore: update {formula_name} to {release.version}") log(f"Pushing tap branch {branch}") - run_authenticated_git(git, gh, "-C", str(tap_directory), "push", "--set-upstream", "origin", branch) + run(git, "-C", str(tap_directory), "push", "--set-upstream", "origin", branch) log(f"Creating pull request in {args.tap}") run(gh, "pr", "create", "--repo", args.tap, "--base", args.base, "--head", branch, "--title", f"chore: update {formula_name} to {release.version}", "--body", f"Automated update from {args.source_repository} release {release.tag}.") return 0