From 9afa15778575e6c384925ac4e5fad48905d75be1 Mon Sep 17 00:00:00 2001 From: mdvanes <4253562+mdvanes@users.noreply.github.com> Date: Thu, 4 Jun 2026 06:58:12 +0200 Subject: [PATCH] fix: update Homebrew formula to use PyYAML 6.0.3 and automate versioning --- .github/workflows/publish.yml | 43 +++++++++++++++++ docs/architecture/homebrew-publish-plan.md | 54 +++++++++++++++++++--- 2 files changed, 90 insertions(+), 7 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 543b1c3..1273c2a 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -246,9 +246,48 @@ jobs: print("ERROR: sha256 mismatch between PyPI metadata and downloaded tarball.", file=sys.stderr) sys.exit(1) + # Resolve the latest PyYAML release satisfying >=6.0.3. + def parse_ver(v): + try: + return tuple(int(x) for x in v.split(".")) + except ValueError: + return (0,) + + pyyaml_json_url = "https://pypi.org/pypi/PyYAML/json" + with urllib.request.urlopen(pyyaml_json_url) as response: + pyyaml_meta = json.load(response) + + pyyaml_min = (6, 0, 3) + pyyaml_candidates = [ + v for v in pyyaml_meta.get("releases", {}) + if not any(c in v for c in ("a", "b", "rc", "dev")) + and parse_ver(v) >= pyyaml_min + ] + if not pyyaml_candidates: + print("ERROR: no PyYAML release satisfying >=6.0.3 found on PyPI.", file=sys.stderr) + sys.exit(1) + + pyyaml_version = max(pyyaml_candidates, key=parse_ver) + pyyaml_release_assets = pyyaml_meta["releases"][pyyaml_version] + pyyaml_sdist = next( + (item for item in pyyaml_release_assets if item.get("packagetype") == "sdist"), + None, + ) + if pyyaml_sdist is None: + print(f"ERROR: no sdist found for PyYAML {pyyaml_version}.", file=sys.stderr) + sys.exit(1) + + pyyaml_url = pyyaml_sdist["url"] + pyyaml_sha = pyyaml_sdist.get("digests", {}).get("sha256", "") + if not pyyaml_sha: + print(f"ERROR: PyPI metadata did not provide a sha256 for PyYAML {pyyaml_version}.", file=sys.stderr) + sys.exit(1) + with open(os.environ["GITHUB_OUTPUT"], "a", encoding="utf-8") as output: output.write(f"sdist_url={sdist_url}\n") output.write(f"sdist_sha256={local_sha}\n") + output.write(f"pyyaml_url={pyyaml_url}\n") + output.write(f"pyyaml_sha256={pyyaml_sha}\n") PY env: GITHUB_REF_NAME: ${{ github.event.release.tag_name }} @@ -259,6 +298,8 @@ jobs: RELEASE_VERSION: ${{ github.event.release.tag_name }} SDIST_URL: ${{ steps.verify_sdist.outputs.sdist_url }} SDIST_SHA256: ${{ steps.verify_sdist.outputs.sdist_sha256 }} + PYYAML_URL: ${{ steps.verify_sdist.outputs.pyyaml_url }} + PYYAML_SHA256: ${{ steps.verify_sdist.outputs.pyyaml_sha256 }} run: | python - <<'PY' import hmac @@ -270,6 +311,8 @@ jobs: "version": os.environ["RELEASE_VERSION"], "sdist_url": os.environ["SDIST_URL"], "sha256": os.environ["SDIST_SHA256"], + "pyyaml_url": os.environ["PYYAML_URL"], + "pyyaml_sha256": os.environ["PYYAML_SHA256"], } secret = os.environ.get("HOMEBREW_TAP_DISPATCH_SECRET", "") diff --git a/docs/architecture/homebrew-publish-plan.md b/docs/architecture/homebrew-publish-plan.md index 719485c..9549750 100644 --- a/docs/architecture/homebrew-publish-plan.md +++ b/docs/architecture/homebrew-publish-plan.md @@ -120,8 +120,8 @@ class Vstack < Formula depends_on "python@3.11" resource "pyyaml" do - url "https://files.pythonhosted.org/packages/source/P/PyYAML/PyYAML-6.0.2.tar.gz" - sha256 "" + url "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz" + sha256 "d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f" end def install @@ -244,11 +244,51 @@ jobs: - name: Update formula version and sha256 shell: bash run: | - VERSION="${{ github.event.client_payload.version }}" - SHA256="${{ github.event.client_payload.sha256 }}" - URL="${{ github.event.client_payload.sdist_url }}" - sed -i "s|url \".*\"|url \"${URL}\"|" Formula/vstack.rb - sed -i "s|sha256 \".*\"|sha256 \"${SHA256}\"|" Formula/vstack.rb + python3 - <<'PY' + import re + import os + + url = os.environ["SDIST_URL"] + sha256 = os.environ["SDIST_SHA256"] + pyyaml_url = os.environ["PYYAML_URL"] + pyyaml_sha = os.environ["PYYAML_SHA256"] + + with open("Formula/vstack.rb") as f: + content = f.read() + + # Replace top-level vstack sdist url (first url line only). + content = re.sub( + r'(^ url ")[^"]*(")' , + rf'\g<1>{url}\2', + content, count=1, flags=re.MULTILINE, + ) + # Replace top-level vstack sha256 (first sha256 line only). + content = re.sub( + r'^ sha256 "[0-9a-f]+"', + f' sha256 "{sha256}"', + content, count=1, flags=re.MULTILINE, + ) + # Replace pyyaml resource url. + content = re.sub( + r'(resource "pyyaml" do\n url ")[^"]*(")' , + rf'\g<1>{pyyaml_url}\2', + content, + ) + # Replace pyyaml resource sha256. + content = re.sub( + r'(resource "pyyaml" do\n url "[^"]*"\n sha256 ")[0-9a-f]+(")', + rf'\g<1>{pyyaml_sha}\2', + content, + ) + + with open("Formula/vstack.rb", "w") as f: + f.write(content) + PY + env: + SDIST_URL: ${{ github.event.client_payload.sdist_url }} + SDIST_SHA256: ${{ github.event.client_payload.sha256 }} + PYYAML_URL: ${{ github.event.client_payload.pyyaml_url }} + PYYAML_SHA256: ${{ github.event.client_payload.pyyaml_sha256 }} - name: Commit and push run: | git config user.name "vstack-release-bot"