From 4a66dc76b11acea87f470bcc979f9a289074b887 Mon Sep 17 00:00:00 2001 From: Mehdi ABAAKOUK Date: Wed, 17 Jun 2026 22:31:52 +0200 Subject: [PATCH] feat: install mergify-cli from prebuilt release binary Replace the Python + uv install path (`uv tool install mergify-cli`) with the mergify-cli prebuilt binary, installed via the CLI's own `install.sh` installer. Why delegate to install.sh rather than re-implement the download/verify: - install.sh owns platform detection, asset naming, and SHA256SUMS verification, so the action doesn't duplicate that logic or have to track it when the asset naming changes (it already changed once between releases). - For a pinned version we fetch install.sh from that release tag (its asset naming matches the binary it installs); for `latest`/empty we fetch it from `main` and let the installer resolve the latest release. Details: - Fetch install.sh (tag or main), run it with MERGIFY_VERSION + MERGIFY_INSTALL_DIR, add the dir to $GITHUB_PATH. - The `mergify_cli_version` output is read back from `mergify --version` (the binary reports its real version), accurate for both pinned and `latest`. - Default bumped to 2026.6.16.1, the first release with prebuilt binaries + install.sh under the canonical versioned asset naming. - Renovate datasource moved pypi -> github-releases (Mergifyio/mergify-cli, pep440). - CI test-install is a matrix over the target triples install.sh supports (linux/macos, x86_64 + aarch64). install.sh currently supports Linux and macOS only; Windows is picked up automatically once install.sh ships a Windows path. BREAKING CHANGE: the `python_version` input is removed (no Python is used) and the action no longer provisions Python/uv on PATH as a side effect. Fixes MRGFY-7660 Change-Id: If70ad03ddf01ec196f051fef6489b68904d02b20 --- .github/workflows/ci.yaml | 26 ++++++++++++--- README.md | 16 +++++---- action.yml | 69 +++++++++++++++++++++------------------ renovate.json | 9 ++--- 4 files changed, 75 insertions(+), 45 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index e742121..5660f69 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -61,7 +61,21 @@ jobs: test-install: timeout-minutes: 5 - runs-on: ubuntu-24.04 + # One runner per target triple install.sh supports, so every detection + + # extraction path is exercised: linux+macos on both x86_64 and aarch64. + # (Windows is added once install.sh ships a Windows path.) + strategy: + fail-fast: false + matrix: + os: + - ubuntu-24.04 # x86_64-unknown-linux-gnu + - ubuntu-24.04-arm # aarch64-unknown-linux-gnu + - macos-15-intel # x86_64-apple-darwin + - macos-15 # aarch64-apple-darwin + runs-on: ${{ matrix.os }} + defaults: + run: + shell: bash steps: - name: Checkout 🛎️ uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 @@ -69,13 +83,17 @@ jobs: - name: Install pinned mergify-cli id: pinned uses: ./ + with: + mergify_cli_version: 2026.6.16.1 - name: Assert pinned install env: VERSION: ${{ steps.pinned.outputs.mergify_cli_version }} run: | - test -n "$VERSION" - mergify --version + # Compare against the literal requested version (not the action's own + # readback), so a regression that installs the wrong version fails CI. + test "$VERSION" = "2026.6.16.1" + test "$(mergify --version | awk '{print $NF}')" = "2026.6.16.1" - name: Install latest mergify-cli id: latest @@ -88,7 +106,7 @@ jobs: VERSION: ${{ steps.latest.outputs.mergify_cli_version }} run: | test -n "$VERSION" - mergify --version + test "$(mergify --version | awk '{print $NF}')" = "$VERSION" all-greens: if: ${{ !cancelled() }} diff --git a/README.md b/README.md index 6976f80..296218e 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,15 @@ # setup-cli -GitHub Action to install the [Mergify CLI](https://pypi.org/project/mergify-cli/) +GitHub Action to install the [Mergify CLI](https://github.com/Mergifyio/mergify-cli) (`mergify-cli`) with version pinning and Renovate autoupdate. -It sets up Python, installs `uv`, then installs `mergify-cli` (pinned by default, -`latest` supported) and exposes the resolved version as an output. +It installs the prebuilt `mergify` binary via the mergify-cli `install.sh` +installer, which downloads the binary from the GitHub release and verifies it +against the release `SHA256SUMS`. For a pinned version the installer is fetched +from that release tag; `latest` uses `main`. The action then puts the binary on +`PATH` and exposes the installed version as an output. Pinned by default, +`latest` supported. No Python or toolchain is required; Linux and macOS are +supported. More information on https://mergify.com @@ -35,8 +40,7 @@ Pin a specific `mergify-cli` version, or install the latest one: | Input | Type | Required | Default | Description | | --- | --- | --- | --- | --- | -| `mergify_cli_version` | string | false | `2026.6.8.1` | Version of mergify-cli to install. Use `latest` to install the latest released version without pinning. | -| `python_version` | string | false | `3.14` | Python version to set up for the install (passed to actions/setup-python). | +| `mergify_cli_version` | string | false | `2026.6.16.1` | Version of mergify-cli to install. Use `latest` to install the latest released version without pinning. | @@ -44,4 +48,4 @@ Pin a specific `mergify-cli` version, or install the latest one: | Output | Description | | --- | --- | -| `mergify_cli_version` | The `mergify-cli` version that was installed. Resolved from the installed package metadata, so it reflects the real version even when `latest` or an empty input was requested. | +| `mergify_cli_version` | The `mergify-cli` version that was installed. Read back from the installed binary, so it reflects the real version even when `latest` or an empty input was requested. | diff --git a/action.yml b/action.yml index 5e14c59..691690a 100644 --- a/action.yml +++ b/action.yml @@ -1,5 +1,5 @@ name: Setup Mergify CLI -description: Install the Mergify CLI (mergify-cli) with version pinning. +description: Install the Mergify CLI (mergify-cli) prebuilt binary with version pinning. author: Mergify branding: icon: terminal @@ -9,48 +9,55 @@ inputs: description: | Version of mergify-cli to install. Use `latest` to install the latest released version without pinning. - # renovate: datasource=pypi depName=mergify-cli - default: 2026.6.8.1 - python_version: - description: Python version to set up for the install (passed to actions/setup-python). - default: "3.14" + # renovate: datasource=github-releases depName=Mergifyio/mergify-cli versioning=pep440 + default: 2026.6.16.1 outputs: mergify_cli_version: description: | - The mergify-cli version that was installed. Resolved from the installed - package metadata, so it reflects the real version even when `latest` or an - empty input was requested. + The mergify-cli version that was installed. Read back from the installed + binary, so it reflects the real version even when `latest` or an empty + input was requested. value: ${{ steps.install.outputs.mergify_cli_version }} runs: using: composite steps: - - name: Setup Python 🔧 - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 - with: - python-version: ${{ inputs.python_version }} - - - name: Install uv - uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0 - with: - # mergify is too small to benefit + there is no version lock (so no cache key either) - enable-cache: false - - name: Install mergify-cli id: install shell: bash env: MERGIFY_CLI_VERSION: ${{ inputs.mergify_cli_version }} run: | - if [ -z "$MERGIFY_CLI_VERSION" ] || [ "$MERGIFY_CLI_VERSION" = "latest" ]; then - # --upgrade implies --refresh, so uv re-resolves against PyPI and - # installs the newest release even on persistent self-hosted runners - # where an older mergify-cli is already cached. - uv tool install --upgrade mergify-cli + set -euo pipefail + + REPO="Mergifyio/mergify-cli" + + die() { echo "::error::$1" >&2; exit 1; } + + # For a pinned version, fetch the installer from that release tag (its + # asset naming matches the binary it installs); for `latest`/empty, + # fetch it from `main` and let the installer resolve the latest release. + if [ -z "${MERGIFY_CLI_VERSION}" ] || [ "${MERGIFY_CLI_VERSION}" = "latest" ]; then + ref="main" else - uv tool install "mergify-cli==$MERGIFY_CLI_VERSION" + ref="${MERGIFY_CLI_VERSION}" fi - mergify --version - # `mergify --version` may print a placeholder while versioning becomes - # Rust-native, so read the resolved version from the package metadata. - installed=$(uv tool list | awk '/^mergify-cli /{print $2}' | sed 's/^v//') - echo "mergify_cli_version=$installed" >> "$GITHUB_OUTPUT" + + bindir="${RUNNER_TEMP}/mergify-cli-bin" + + # Install via the CLI's own installer: it owns platform detection, asset + # naming, and SHA256SUMS verification, so we don't duplicate (or have to + # track) any of that. MERGIFY_VERSION forwards the requested version; an + # empty/`latest` value lets the installer resolve the latest release. + # install.sh supports Linux and macOS only. + tmp=$(mktemp -d) + trap 'rm -rf "${tmp}"' EXIT + curl -fsSL "https://raw.githubusercontent.com/${REPO}/${ref}/install.sh" -o "${tmp}/install.sh" \ + || die "failed to fetch install.sh (ref ${ref})" + MERGIFY_VERSION="${MERGIFY_CLI_VERSION}" MERGIFY_INSTALL_DIR="${bindir}" sh "${tmp}/install.sh" + + # Expose the binary to later steps and read the version back from it + # (the binary reports its real version) for the action output. + echo "${bindir}" >> "${GITHUB_PATH}" + installed=$("${bindir}/mergify" --version | awk '{print $NF}') + [ -n "${installed}" ] || die "could not read installed mergify-cli version" + echo "mergify_cli_version=${installed}" >> "${GITHUB_OUTPUT}" diff --git a/renovate.json b/renovate.json index 6865721..3d91408 100644 --- a/renovate.json +++ b/renovate.json @@ -11,8 +11,8 @@ "lockFileMaintenance": { "enabled": true }, "packageRules": [ { - "matchDatasources": ["pypi"], - "matchPackageNames": ["mergify-cli"], + "matchDatasources": ["github-releases"], + "matchPackageNames": ["Mergifyio/mergify-cli"], "minimumReleaseAge": "2 days" }, { @@ -40,8 +40,9 @@ "matchStrings": [ "\\| `mergify_cli_version` \\| string \\| \\w+ \\| `(?[^`]+)` \\|" ], - "datasourceTemplate": "pypi", - "depNameTemplate": "mergify-cli" + "datasourceTemplate": "github-releases", + "depNameTemplate": "Mergifyio/mergify-cli", + "versioningTemplate": "pep440" }, { "description": "Bump the self-referenced action version pinned in the README usage example on each new setup-cli release.",