From b5c04b7698e3e1bc206e640b32d77e07a3edfc47 Mon Sep 17 00:00:00 2001 From: Anand Pant Date: Tue, 21 Apr 2026 09:02:50 -0500 Subject: [PATCH 1/4] feat: add meshix-cli formula --- Formula/meshix-cli.rb | 34 ++++++++++ Formula/osyrra.rb | 8 +-- Formula/tabex.rb | 8 +-- README.md | 12 ++-- docs/setup.md | 27 +++++--- scripts/update-formulae.sh | 10 ++- scripts/update-meshix-cli.sh | 119 +++++++++++++++++++++++++++++++++++ scripts/validate-formulae.sh | 8 +++ 8 files changed, 204 insertions(+), 22 deletions(-) create mode 100644 Formula/meshix-cli.rb create mode 100755 scripts/update-meshix-cli.sh diff --git a/Formula/meshix-cli.rb b/Formula/meshix-cli.rb new file mode 100644 index 0000000..75fc792 --- /dev/null +++ b/Formula/meshix-cli.rb @@ -0,0 +1,34 @@ +class MeshixCli < Formula + desc "Meshix CLI for run inspection and generation workflows" + homepage "https://github.com/shpitdev/meshix-observability" + version "0.0.1" + license :cannot_represent + depends_on arch: :arm64 + + on_macos do + on_arm do + url "https://github.com/shpitdev/meshix-observability/releases/download/v0.0.1/meshix-cli_v0.0.1_darwin_arm64.tar.gz" + sha256 "01e42197ff960a8f6033f80178800f8ede31bb8e18e276f705abc72b17ba7426" + end + end + + def install + bin.install "meshix-cli" + end + + def caveats + <<~EOS + Package-manager installs provide the stable meshix-cli command only. + Start with: + meshix-cli --help + + For a checkout-linked dev command, install meshix-cli-dev from a local checkout. + EOS + end + + test do + output = shell_output("#{bin}/meshix-cli --help") + assert_match "meshix-cli", output + assert_match "architecture", output + end +end diff --git a/Formula/osyrra.rb b/Formula/osyrra.rb index 18a51f1..a03d27e 100644 --- a/Formula/osyrra.rb +++ b/Formula/osyrra.rb @@ -62,16 +62,16 @@ def curl(*args, print_stdout: true, **options) class Osyrra < Formula desc "Osyrra silent email worker and operator TUI" homepage "https://github.com/shpitdev/osyrra" - version "0.0.2" + version "0.0.3" license :cannot_represent depends_on arch: :arm64 on_macos do on_arm do - url "https://api.github.com/repos/shpitdev/osyrra/releases/assets/400635105", + url "https://api.github.com/repos/shpitdev/osyrra/releases/assets/401514991", using: OsyrraGitHubReleaseDownloadStrategy, - resolved_basename: "osyrra_v0.0.2_darwin_arm64.tar.gz" - sha256 "feabb71c64519e9b9ffa85dc3846a36064944a21220f6840e9196b945c426d06" + resolved_basename: "osyrra_v0.0.3_darwin_arm64.tar.gz" + sha256 "c0e7e0c547f5744d74158018fe29cfa27c3bbac2ca0e511fa5784467202ee213" end end diff --git a/Formula/tabex.rb b/Formula/tabex.rb index 1177f47..96b1ad4 100644 --- a/Formula/tabex.rb +++ b/Formula/tabex.rb @@ -62,16 +62,16 @@ def curl(*args, print_stdout: true, **options) class Tabex < Formula desc "Tabex CLI for browser session, capture, and page inspection" homepage "https://github.com/shpitdev/tabex" - version "0.0.4" + version "0.0.5" license :cannot_represent depends_on arch: :arm64 on_macos do on_arm do - url "https://api.github.com/repos/shpitdev/tabex/releases/assets/401429381", + url "https://api.github.com/repos/shpitdev/tabex/releases/assets/401540246", using: TabexGitHubReleaseDownloadStrategy, - resolved_basename: "tabex_v0.0.4_darwin_arm64.tar.gz" - sha256 "8e5bdf30d9a57d34fec3bbb8973041dd1f8df821325652d1d16f40083f98b666" + resolved_basename: "tabex_v0.0.5_darwin_arm64.tar.gz" + sha256 "e4a7477b220fbb31e21cf818e88be56e013dfbf3fe2b70bc862171287275e80f" end end diff --git a/README.md b/README.md index 1c6a5f2..cb9753b 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ This repo is the tap source of truth. Formulae are updated by repo-owned scripts | Formula | Upstream | Notes | |---|---|---| +| `meshix-cli` | `shpitdev/meshix-observability` GitHub Releases | Public darwin arm64 release asset fetched from GitHub Releases. No extra GitHub auth is required for install. | | `tabex` | `shpitdev/tabex` GitHub Releases | Private darwin arm64 release asset fetched through the GitHub Releases API. The formula reads `HOMEBREW_GITHUB_API_TOKEN`, `GH_TOKEN`, `GITHUB_TOKEN`, or `SHPIT_GH_TOKEN`, and falls back to `gh auth token` when available. | | `osyrra` | `shpitdev/osyrra` GitHub Releases | Private darwin arm64 release asset fetched through the GitHub Releases API. Same auth path as `tabex`. | @@ -22,11 +23,14 @@ Once the GitHub repo exists as `shpitdev/homebrew-tap`: ```bash brew tap shpitdev/tap +brew install shpitdev/tap/meshix-cli brew install shpitdev/tap/tabex brew install shpitdev/tap/osyrra ``` -If `gh` is not installed or not logged in locally, run installs with an explicit token: +`meshix-cli` is public, so it installs without any extra GitHub token. + +If `gh` is not installed or not logged in locally, run the private-package installs with an explicit token: ```bash HOMEBREW_GITHUB_API_TOKEN="$(gh auth token)" brew install shpitdev/tap/tabex @@ -43,9 +47,9 @@ That saves browser config, installs or updates the managed Chrome extension loca ## Current Limitation -- Both formulae are macOS arm64 only. The upstream releases do not ship a `darwin_amd64` asset today; add one upstream and the updater scripts can gain an `on_intel` block. -- Both upstreams are private repos, so this tap is SHPIT-internal until release assets become public. -- Automation can read those releases with the `SHPIT_GH_TOKEN` secret. +- All current formulae are macOS arm64 only. The upstream releases do not ship a `darwin_amd64` asset today; add one upstream and the updater scripts can gain an `on_intel` block where appropriate. +- `tabex` and `osyrra` still come from private upstream repos, so those install paths remain SHPIT-internal until their release assets become public. +- Automation reads the private `tabex` and `osyrra` releases with the `SHPIT_GH_TOKEN` secret. `meshix-cli` does not need that secret because its upstream release is public. ## Local Usage diff --git a/docs/setup.md b/docs/setup.md index cacf701..eaa9c91 100644 --- a/docs/setup.md +++ b/docs/setup.md @@ -17,7 +17,7 @@ Result: - branch and PR creation use the repo `GITHUB_TOKEN` - private SHPIT formula refreshes work only if the repo can read `SHPIT_GH_TOKEN` - there is no separate publish workflow because the tap repo itself is the distribution surface -- upstream `tabex` and `osyrra` release workflows can also trigger this workflow automatically with `gh workflow run version-bumps.yml`, but that depends on `SHPIT_WORKFLOW_DISPATCH_TOKEN` being available in their Depot CI repo secrets +- upstream `meshix-observability`, `tabex`, and `osyrra` release workflows can also trigger this workflow automatically with `gh workflow run version-bumps.yml`, but that depends on `SHPIT_WORKFLOW_DISPATCH_TOKEN` being available in their producer-repo Depot CI secrets ## GitHub UI Links @@ -27,7 +27,7 @@ Result: ## SHPIT_GH_TOKEN -Create the secret (org-level or repo-level) with access to read private releases on `shpitdev/tabex` and `shpitdev/osyrra`. An org-level secret with `selected` visibility works well if you consume it from multiple repos. +Create the secret (org-level or repo-level) with access to read private releases on `shpitdev/tabex` and `shpitdev/osyrra`. An org-level secret with `selected` visibility works well if you consume it from multiple repos. `meshix-cli` does not need this secret because `shpitdev/meshix-observability` publishes public releases. Attach it to this repo with: @@ -47,12 +47,16 @@ Create a fine-grained PAT that can trigger workflow dispatches in: Store that PAT as the GitHub org secret `SHPIT_WORKFLOW_DISPATCH_TOKEN` with `selected` visibility for these producer repos: +- `shpitdev/meshix-observability` - `shpitdev/tabex` - `shpitdev/osyrra` Those producer release workflows run in Depot CI, so GitHub org secrets are not enough on their own. Mirror the same secret into Depot for each producer repo with one of these paths: ```bash +cd /home/anandpant/Development/shpitdev/meshix/meshix-observability +depot ci migrate secrets-and-vars -y + cd /home/anandpant/Development/shpitdev/tabex depot ci migrate secrets-and-vars -y @@ -63,6 +67,7 @@ depot ci migrate secrets-and-vars -y Or add the Depot secrets directly: ```bash +depot ci secrets add SHPIT_WORKFLOW_DISPATCH_TOKEN --repo shpitdev/meshix-observability depot ci secrets add SHPIT_WORKFLOW_DISPATCH_TOKEN --repo shpitdev/tabex depot ci secrets add SHPIT_WORKFLOW_DISPATCH_TOKEN --repo shpitdev/osyrra ``` @@ -78,11 +83,13 @@ If you are logged into GitHub locally with `gh auth login`, you can run: That uses your local GitHub CLI session for private release access. -For local `brew install shpitdev/tap/tabex`, the formula uses the same auth path: +For local installs: -- it first checks `HOMEBREW_GITHUB_API_TOKEN`, `GH_TOKEN`, `GITHUB_TOKEN`, and `SHPIT_GH_TOKEN` -- if none are set, it falls back to `gh auth token` -- in headless environments, prefer `HOMEBREW_GITHUB_API_TOKEN="$(gh auth token)" brew install ...` +- `brew install shpitdev/tap/meshix-cli` uses the public release asset and does not require any extra token +- `brew install shpitdev/tap/tabex` and `brew install shpitdev/tap/osyrra` use the private-auth path: + - they first check `HOMEBREW_GITHUB_API_TOKEN`, `GH_TOKEN`, `GITHUB_TOKEN`, and `SHPIT_GH_TOKEN` + - if none are set, they fall back to `gh auth token` + - in headless environments, prefer `HOMEBREW_GITHUB_API_TOKEN="$(gh auth token)" brew install ...` For `tabex`, the formula caveat currently points users at: @@ -94,15 +101,17 @@ That is intentional. `v0.0.4` is the first stable release that ships the source- ## Package-Manager Install Behavior -Both private formulae use install-side GitHub auth: +`meshix-cli` uses the public GitHub release download path, so it behaves like a normal public Homebrew formula. + +The private formulae (`tabex` and `osyrra`) use install-side GitHub auth: - they check `HOMEBREW_GITHUB_API_TOKEN`, `GH_TOKEN`, `GITHUB_TOKEN`, and `SHPIT_GH_TOKEN` - if no token env var is present, they fall back to `gh auth token` -Both `tabex` and `osyrra` are macOS arm64 only today. An Intel Mac install will fail with an architecture guard until the upstream release adds a `darwin_amd64` asset and the formulae gain an `on_intel` block. +All current SHPIT formulae are macOS arm64 only today. An Intel Mac install will fail with an architecture guard until the upstream release adds a `darwin_amd64` asset and the relevant formula gains an `on_intel` block. ## Recommended Follow-Up 1. Confirm `SHPIT_GH_TOKEN` is attached to this repo. -2. Validate real `brew install shpitdev/tap/tabex` and `brew install shpitdev/tap/osyrra` flows on a macOS arm64 machine with a user who has access to the private upstream repos. +2. Validate real `brew install shpitdev/tap/meshix-cli`, `brew install shpitdev/tap/tabex`, and `brew install shpitdev/tap/osyrra` flows on a macOS arm64 machine. 3. Keep the package-manager caveats aligned with the upstream installers when shell or setup UX changes. diff --git a/scripts/update-formulae.sh b/scripts/update-formulae.sh index af14252..2972853 100755 --- a/scripts/update-formulae.sh +++ b/scripts/update-formulae.sh @@ -8,13 +8,14 @@ if (($# == 0)); then fi if [[ "$1" == "auto" ]]; then - formulae=() + formulae=(meshix-cli) if [[ -n "${SHPIT_GH_TOKEN:-}" || -z "${GITHUB_ACTIONS:-}" ]]; then formulae+=(tabex) formulae+=(osyrra) fi elif [[ "$1" == "all" ]]; then formulae=( + meshix-cli tabex osyrra ) @@ -24,6 +25,13 @@ fi for formula in "${formulae[@]}"; do case "${formula}" in + meshix-cli) + if [[ "$1" == "auto" ]]; then + "${repo_root}/scripts/update-meshix-cli.sh" --optional + else + "${repo_root}/scripts/update-meshix-cli.sh" + fi + ;; tabex) if [[ "$1" == "auto" ]]; then "${repo_root}/scripts/update-tabex.sh" --optional diff --git a/scripts/update-meshix-cli.sh b/scripts/update-meshix-cli.sh new file mode 100755 index 0000000..6e3787d --- /dev/null +++ b/scripts/update-meshix-cli.sh @@ -0,0 +1,119 @@ +#!/usr/bin/env bash +set -euo pipefail + +optional=false +if (($# > 1)); then + echo "usage: $0 [--optional]" >&2 + exit 1 +fi +if (($# == 1)); then + if [[ "$1" != "--optional" ]]; then + echo "usage: $0 [--optional]" >&2 + exit 1 + fi + optional=true +fi + +repo_root="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)" +formula_path="${repo_root}/Formula/meshix-cli.rb" +repo="shpitdev/meshix-observability" + +verify_sha256() { + local expected="$1" + local file="$2" + local actual + + if command -v shasum >/dev/null 2>&1; then + actual="$(shasum -a 256 "${file}" | awk '{print $1}')" + elif command -v sha256sum >/dev/null 2>&1; then + actual="$(sha256sum "${file}" | awk '{print $1}')" + else + echo "Unable to verify SHA-256: neither shasum nor sha256sum is available." >&2 + exit 1 + fi + + if [[ "${actual}" != "${expected}" ]]; then + echo "SHA-256 mismatch for ${file}: expected ${expected}, got ${actual}." >&2 + exit 1 + fi +} + +release_json="$(gh api "repos/${repo}/releases/latest")" +version="$(jq -r '.tag_name | ltrimstr("v")' <<<"${release_json}")" +arm64_json="$(jq -c ' + .assets + | map(select(.name | test("_darwin_arm64\\.tar\\.gz$"))) + | first +' <<<"${release_json}")" + +arm64_asset="$(jq -r '.name // empty' <<<"${arm64_json}")" +arm64_sha="$(jq -r '.digest // empty' <<<"${arm64_json}")" + +if [[ -z "${arm64_asset}" || "${arm64_asset}" == "null" ]]; then + if [[ "${optional}" == "true" ]]; then + echo "Skipping meshix-cli: latest release is missing a darwin arm64 archive." >&2 + exit 0 + fi + echo "meshix-cli latest release is missing a darwin arm64 archive" >&2 + exit 1 +fi + +if [[ -z "${arm64_sha}" || "${arm64_sha}" == "null" ]]; then + if [[ "${optional}" == "true" ]]; then + echo "Skipping meshix-cli: latest release is missing a darwin arm64 digest." >&2 + exit 0 + fi + echo "meshix-cli latest release is missing a darwin arm64 digest" >&2 + exit 1 +fi + +arm64_sha="${arm64_sha#sha256:}" + +tmpdir="$(mktemp -d)" +trap 'rm -rf "${tmpdir}"' EXIT + +gh release download "v${version}" --repo "${repo}" \ + --pattern "${arm64_asset}" --dir "${tmpdir}" --clobber >/dev/null + +( + cd "${tmpdir}" + verify_sha256 "${arm64_sha}" "${arm64_asset}" + tar -tzf "${arm64_asset}" | grep -qx "meshix-cli_v${version}_darwin_arm64/meshix-cli" +) + +cat > "${formula_path}" < Date: Tue, 21 Apr 2026 14:44:58 -0500 Subject: [PATCH 2/4] fix: use authenticated meshix formula updates --- .github/workflows/version-bumps.yml | 5 ++ Formula/meshix-cli.rb | 65 +++++++++++++++- README.md | 11 ++- docs/setup.md | 16 ++-- scripts/update-meshix-cli.sh | 115 +++++++++++++++++++++++++--- scripts/validate-formulae.sh | 4 +- 6 files changed, 189 insertions(+), 27 deletions(-) diff --git a/.github/workflows/version-bumps.yml b/.github/workflows/version-bumps.yml index f5a00fb..256790d 100644 --- a/.github/workflows/version-bumps.yml +++ b/.github/workflows/version-bumps.yml @@ -2,6 +2,10 @@ name: version-bumps on: workflow_dispatch: + inputs: + meshix_cli_version: + description: Optional Meshix CLI release tag to pin for this run (for example v0.0.2) + required: false schedule: - cron: '41 6 * * *' @@ -15,6 +19,7 @@ jobs: env: GH_TOKEN: ${{ github.token }} SHPIT_GH_TOKEN: ${{ secrets.SHPIT_GH_TOKEN }} + MESHIX_CLI_VERSION: ${{ github.event.inputs.meshix_cli_version || '' }} UPDATE_BRANCH: automation/version-bumps steps: - name: Checkout diff --git a/Formula/meshix-cli.rb b/Formula/meshix-cli.rb index 75fc792..8267407 100644 --- a/Formula/meshix-cli.rb +++ b/Formula/meshix-cli.rb @@ -1,3 +1,64 @@ +class MeshixCliGitHubReleaseDownloadStrategy < CurlDownloadStrategy + def initialize(url, name, version, **meta) + @resolved_basename = meta.delete(:resolved_basename) + @github_token = resolve_github_token + + if @github_token.nil? || @github_token.empty? + raise CurlDownloadStrategyError.new( + url, + [ + "GitHub authentication is required to download the private meshix-cli release asset.", + "Set HOMEBREW_GITHUB_API_TOKEN, GH_TOKEN, GITHUB_TOKEN, or SHPIT_GH_TOKEN,", + "or log in with gh auth login." + ].join(" ") + ) + end + + meta[:headers] ||= [] + meta[:headers] << "Accept: application/octet-stream" + meta[:headers] << "Authorization: Bearer #{@github_token}" + super + end + + private + + def resolve_github_token + %w[HOMEBREW_GITHUB_API_TOKEN GH_TOKEN GITHUB_TOKEN SHPIT_GH_TOKEN].each do |key| + value = ENV[key]&.strip + return value unless value.nil? || value.empty? + end + + [ + "#{HOMEBREW_PREFIX}/bin/gh", + "/opt/homebrew/bin/gh", + "/usr/local/bin/gh", + "gh" + ].uniq.each do |gh| + next if gh != "gh" && !File.executable?(gh) + + value = Utils.safe_popen_read(gh, "auth", "token").strip + return value unless value.empty? + rescue ErrorDuringExecution, Errno::ENOENT + next + end + + nil + end + + def resolve_url_basename_time_file_size(url, timeout: nil) + resolved_url, _, last_modified, file_size, content_type, is_redirection = super + [resolved_url, @resolved_basename, last_modified, file_size, content_type, is_redirection] + end + + def curl_output(*args, **options) + super(*args, secrets: [@github_token], **options) + end + + def curl(*args, print_stdout: true, **options) + super(*args, print_stdout: print_stdout, secrets: [@github_token], **options) + end +end + class MeshixCli < Formula desc "Meshix CLI for run inspection and generation workflows" homepage "https://github.com/shpitdev/meshix-observability" @@ -7,7 +68,9 @@ class MeshixCli < Formula on_macos do on_arm do - url "https://github.com/shpitdev/meshix-observability/releases/download/v0.0.1/meshix-cli_v0.0.1_darwin_arm64.tar.gz" + url "https://api.github.com/repos/shpitdev/meshix-observability/releases/assets/391763692", + using: MeshixCliGitHubReleaseDownloadStrategy, + resolved_basename: "meshix-cli_v0.0.1_darwin_arm64.tar.gz" sha256 "01e42197ff960a8f6033f80178800f8ede31bb8e18e276f705abc72b17ba7426" end end diff --git a/README.md b/README.md index cb9753b..de4c1bd 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ This repo is the tap source of truth. Formulae are updated by repo-owned scripts | Formula | Upstream | Notes | |---|---|---| -| `meshix-cli` | `shpitdev/meshix-observability` GitHub Releases | Public darwin arm64 release asset fetched from GitHub Releases. No extra GitHub auth is required for install. | +| `meshix-cli` | `shpitdev/meshix-observability` GitHub Releases | Private darwin arm64 release asset fetched through the GitHub Releases API. The formula reads `HOMEBREW_GITHUB_API_TOKEN`, `GH_TOKEN`, `GITHUB_TOKEN`, or `SHPIT_GH_TOKEN`, and falls back to `gh auth token` when available. | | `tabex` | `shpitdev/tabex` GitHub Releases | Private darwin arm64 release asset fetched through the GitHub Releases API. The formula reads `HOMEBREW_GITHUB_API_TOKEN`, `GH_TOKEN`, `GITHUB_TOKEN`, or `SHPIT_GH_TOKEN`, and falls back to `gh auth token` when available. | | `osyrra` | `shpitdev/osyrra` GitHub Releases | Private darwin arm64 release asset fetched through the GitHub Releases API. Same auth path as `tabex`. | @@ -28,11 +28,10 @@ brew install shpitdev/tap/tabex brew install shpitdev/tap/osyrra ``` -`meshix-cli` is public, so it installs without any extra GitHub token. - -If `gh` is not installed or not logged in locally, run the private-package installs with an explicit token: +If `gh` is not installed or not logged in locally, run installs with an explicit token: ```bash +HOMEBREW_GITHUB_API_TOKEN="$(gh auth token)" brew install shpitdev/tap/meshix-cli HOMEBREW_GITHUB_API_TOKEN="$(gh auth token)" brew install shpitdev/tap/tabex HOMEBREW_GITHUB_API_TOKEN="$(gh auth token)" brew install shpitdev/tap/osyrra ``` @@ -48,8 +47,8 @@ That saves browser config, installs or updates the managed Chrome extension loca ## Current Limitation - All current formulae are macOS arm64 only. The upstream releases do not ship a `darwin_amd64` asset today; add one upstream and the updater scripts can gain an `on_intel` block where appropriate. -- `tabex` and `osyrra` still come from private upstream repos, so those install paths remain SHPIT-internal until their release assets become public. -- Automation reads the private `tabex` and `osyrra` releases with the `SHPIT_GH_TOKEN` secret. `meshix-cli` does not need that secret because its upstream release is public. +- `meshix-cli`, `tabex`, and `osyrra` currently come from private upstream repos, so these install paths remain SHPIT-internal until their release assets become public. +- Automation reads those private releases with the `SHPIT_GH_TOKEN` secret. ## Local Usage diff --git a/docs/setup.md b/docs/setup.md index eaa9c91..40d0fe0 100644 --- a/docs/setup.md +++ b/docs/setup.md @@ -27,7 +27,7 @@ Result: ## SHPIT_GH_TOKEN -Create the secret (org-level or repo-level) with access to read private releases on `shpitdev/tabex` and `shpitdev/osyrra`. An org-level secret with `selected` visibility works well if you consume it from multiple repos. `meshix-cli` does not need this secret because `shpitdev/meshix-observability` publishes public releases. +Create the secret (org-level or repo-level) with access to read private releases on `shpitdev/meshix-observability`, `shpitdev/tabex`, and `shpitdev/osyrra`. An org-level secret with `selected` visibility works well if you consume it from multiple repos. Attach it to this repo with: @@ -83,13 +83,11 @@ If you are logged into GitHub locally with `gh auth login`, you can run: That uses your local GitHub CLI session for private release access. -For local installs: +For local installs, all three SHPIT formulae (`meshix-cli`, `tabex`, and `osyrra`) use the same private-auth path: -- `brew install shpitdev/tap/meshix-cli` uses the public release asset and does not require any extra token -- `brew install shpitdev/tap/tabex` and `brew install shpitdev/tap/osyrra` use the private-auth path: - - they first check `HOMEBREW_GITHUB_API_TOKEN`, `GH_TOKEN`, `GITHUB_TOKEN`, and `SHPIT_GH_TOKEN` - - if none are set, they fall back to `gh auth token` - - in headless environments, prefer `HOMEBREW_GITHUB_API_TOKEN="$(gh auth token)" brew install ...` +- they first check `HOMEBREW_GITHUB_API_TOKEN`, `GH_TOKEN`, `GITHUB_TOKEN`, and `SHPIT_GH_TOKEN` +- if none are set, they fall back to `gh auth token` +- in headless environments, prefer `HOMEBREW_GITHUB_API_TOKEN="$(gh auth token)" brew install ...` For `tabex`, the formula caveat currently points users at: @@ -101,9 +99,7 @@ That is intentional. `v0.0.4` is the first stable release that ships the source- ## Package-Manager Install Behavior -`meshix-cli` uses the public GitHub release download path, so it behaves like a normal public Homebrew formula. - -The private formulae (`tabex` and `osyrra`) use install-side GitHub auth: +All three current SHPIT formulae use install-side GitHub auth: - they check `HOMEBREW_GITHUB_API_TOKEN`, `GH_TOKEN`, `GITHUB_TOKEN`, and `SHPIT_GH_TOKEN` - if no token env var is present, they fall back to `gh auth token` diff --git a/scripts/update-meshix-cli.sh b/scripts/update-meshix-cli.sh index 6e3787d..8fcbb09 100755 --- a/scripts/update-meshix-cli.sh +++ b/scripts/update-meshix-cli.sh @@ -17,6 +17,7 @@ fi repo_root="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)" formula_path="${repo_root}/Formula/meshix-cli.rb" repo="shpitdev/meshix-observability" +requested_version="${MESHIX_CLI_VERSION:-latest}" verify_sha256() { local expected="$1" @@ -38,7 +39,34 @@ verify_sha256() { fi } -release_json="$(gh api "repos/${repo}/releases/latest")" +resolve_release_json() { + local version="$1" + local endpoint + + if [[ -z "${version}" || "${version}" == "latest" ]]; then + endpoint="repos/${repo}/releases/latest" + else + if [[ "${version}" != v* ]]; then + version="v${version}" + fi + endpoint="repos/${repo}/releases/tags/${version}" + fi + + if [[ -n "${SHPIT_GH_TOKEN:-}" ]]; then + GH_TOKEN="${SHPIT_GH_TOKEN}" gh api "${endpoint}" + elif [[ -n "${GITHUB_ACTIONS:-}" ]]; then + if [[ "${optional}" == "true" ]]; then + echo "Skipping meshix-cli: SHPIT_GH_TOKEN is not configured in GitHub Actions." >&2 + exit 0 + fi + echo "SHPIT_GH_TOKEN is required in GitHub Actions to read the private meshix-cli release." >&2 + exit 1 + else + gh api "${endpoint}" + fi +} + +release_json="$(resolve_release_json "${requested_version}")" version="$(jq -r '.tag_name | ltrimstr("v")' <<<"${release_json}")" arm64_json="$(jq -c ' .assets @@ -47,23 +75,24 @@ arm64_json="$(jq -c ' ' <<<"${release_json}")" arm64_asset="$(jq -r '.name // empty' <<<"${arm64_json}")" +arm64_api_url="$(jq -r '.url // empty' <<<"${arm64_json}")" arm64_sha="$(jq -r '.digest // empty' <<<"${arm64_json}")" -if [[ -z "${arm64_asset}" || "${arm64_asset}" == "null" ]]; then +if [[ -z "${arm64_asset}" || "${arm64_asset}" == "null" || -z "${arm64_api_url}" || "${arm64_api_url}" == "null" ]]; then if [[ "${optional}" == "true" ]]; then - echo "Skipping meshix-cli: latest release is missing a darwin arm64 archive." >&2 + echo "Skipping meshix-cli: release is missing a darwin arm64 archive." >&2 exit 0 fi - echo "meshix-cli latest release is missing a darwin arm64 archive" >&2 + echo "meshix-cli release is missing a darwin arm64 archive" >&2 exit 1 fi if [[ -z "${arm64_sha}" || "${arm64_sha}" == "null" ]]; then if [[ "${optional}" == "true" ]]; then - echo "Skipping meshix-cli: latest release is missing a darwin arm64 digest." >&2 + echo "Skipping meshix-cli: release is missing a darwin arm64 digest." >&2 exit 0 fi - echo "meshix-cli latest release is missing a darwin arm64 digest" >&2 + echo "meshix-cli release is missing a darwin arm64 digest" >&2 exit 1 fi @@ -72,8 +101,13 @@ arm64_sha="${arm64_sha#sha256:}" tmpdir="$(mktemp -d)" trap 'rm -rf "${tmpdir}"' EXIT -gh release download "v${version}" --repo "${repo}" \ - --pattern "${arm64_asset}" --dir "${tmpdir}" --clobber >/dev/null +if [[ -n "${SHPIT_GH_TOKEN:-}" ]]; then + GH_TOKEN="${SHPIT_GH_TOKEN}" gh release download "v${version}" --repo "${repo}" \ + --pattern "${arm64_asset}" --dir "${tmpdir}" --clobber >/dev/null +else + gh release download "v${version}" --repo "${repo}" \ + --pattern "${arm64_asset}" --dir "${tmpdir}" --clobber >/dev/null +fi ( cd "${tmpdir}" @@ -82,6 +116,67 @@ gh release download "v${version}" --repo "${repo}" \ ) cat > "${formula_path}" < Date: Tue, 21 Apr 2026 14:47:13 -0500 Subject: [PATCH 3/4] fix: skip meshix formula bumps without release access --- scripts/update-meshix-cli.sh | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/scripts/update-meshix-cli.sh b/scripts/update-meshix-cli.sh index 8fcbb09..a5ef4e1 100755 --- a/scripts/update-meshix-cli.sh +++ b/scripts/update-meshix-cli.sh @@ -42,6 +42,7 @@ verify_sha256() { resolve_release_json() { local version="$1" local endpoint + local output="" if [[ -z "${version}" || "${version}" == "latest" ]]; then endpoint="repos/${repo}/releases/latest" @@ -53,7 +54,16 @@ resolve_release_json() { fi if [[ -n "${SHPIT_GH_TOKEN:-}" ]]; then - GH_TOKEN="${SHPIT_GH_TOKEN}" gh api "${endpoint}" + if output="$(GH_TOKEN="${SHPIT_GH_TOKEN}" gh api "${endpoint}" 2>/dev/null)"; then + printf '%s' "${output}" + return 0 + fi + if [[ -n "${GITHUB_ACTIONS:-}" && "${optional}" == "true" ]]; then + echo "Skipping meshix-cli: SHPIT_GH_TOKEN does not currently grant release access to ${repo}." >&2 + exit 0 + fi + echo "SHPIT_GH_TOKEN could not read the private meshix-cli release in ${repo}." >&2 + exit 1 elif [[ -n "${GITHUB_ACTIONS:-}" ]]; then if [[ "${optional}" == "true" ]]; then echo "Skipping meshix-cli: SHPIT_GH_TOKEN is not configured in GitHub Actions." >&2 From fdbe4afe159d11ee6bea541c151a1b1c33283999 Mon Sep 17 00:00:00 2001 From: Anand Pant Date: Tue, 21 Apr 2026 15:06:01 -0500 Subject: [PATCH 4/4] fix: make meshix formula validation deterministic --- scripts/update-meshix-cli.sh | 13 +++++++++---- scripts/validate-formulae.sh | 4 ++++ 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/scripts/update-meshix-cli.sh b/scripts/update-meshix-cli.sh index a5ef4e1..5922bae 100755 --- a/scripts/update-meshix-cli.sh +++ b/scripts/update-meshix-cli.sh @@ -60,23 +60,28 @@ resolve_release_json() { fi if [[ -n "${GITHUB_ACTIONS:-}" && "${optional}" == "true" ]]; then echo "Skipping meshix-cli: SHPIT_GH_TOKEN does not currently grant release access to ${repo}." >&2 - exit 0 + printf '__SKIP__' + return 0 fi echo "SHPIT_GH_TOKEN could not read the private meshix-cli release in ${repo}." >&2 - exit 1 + return 1 elif [[ -n "${GITHUB_ACTIONS:-}" ]]; then if [[ "${optional}" == "true" ]]; then echo "Skipping meshix-cli: SHPIT_GH_TOKEN is not configured in GitHub Actions." >&2 - exit 0 + printf '__SKIP__' + return 0 fi echo "SHPIT_GH_TOKEN is required in GitHub Actions to read the private meshix-cli release." >&2 - exit 1 + return 1 else gh api "${endpoint}" fi } release_json="$(resolve_release_json "${requested_version}")" +if [[ "${release_json}" == "__SKIP__" ]]; then + exit 0 +fi version="$(jq -r '.tag_name | ltrimstr("v")' <<<"${release_json}")" arm64_json="$(jq -c ' .assets diff --git a/scripts/validate-formulae.sh b/scripts/validate-formulae.sh index 485d66c..acfd06e 100755 --- a/scripts/validate-formulae.sh +++ b/scripts/validate-formulae.sh @@ -42,6 +42,10 @@ trap 'rm -rf "${tmpdir}"' EXIT cp -a "${repo_root}/." "${tmpdir}/repo" ( cd "${tmpdir}/repo" + if [[ -z "${MESHIX_CLI_VERSION:-}" && -f Formula/meshix-cli.rb ]]; then + MESHIX_CLI_VERSION="$(sed -n 's/^ version "\([^"]*\)"$/\1/p' Formula/meshix-cli.rb | head -n 1)" + export MESHIX_CLI_VERSION + fi ./scripts/update-formulae.sh auto )