From 9d7abfa15dcbf724d61766a7fc9c94955656adfd Mon Sep 17 00:00:00 2001 From: cyberdocs120 Date: Tue, 25 Aug 2026 07:06:32 +0100 Subject: [PATCH 1/2] fix(ci): retry the Stellar CLI download to survive CDN 503s (#119) The official action only retries the release CDN download over a ~25s window, which a multi-minute 503 outage can still blow past on the first cache-miss. Add scripts/install-stellar-cli.sh with exponential backoff and use it for the cache-miss install path in ci, smoke, and regression workflows. --- .github/workflows/ci.yml | 6 +-- .../workflows/testnet-deploy-regression.yml | 2 +- .github/workflows/testnet-smoke.yml | 2 +- scripts/install-stellar-cli.sh | 42 +++++++++++++++++++ 4 files changed, 46 insertions(+), 6 deletions(-) create mode 100755 scripts/install-stellar-cli.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 28a1a447..c73a4f2f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -40,7 +40,7 @@ jobs: - name: Install Stellar CLI if: steps.stellar-cli-cache.outputs.cache-hit != 'true' - uses: stellar/stellar-cli@v27.0.0 + run: bash scripts/install-stellar-cli.sh 27.0.0 # The install action puts ~/.local/bin on PATH itself; on a cache hit it is # skipped, so add the directory here too. @@ -106,9 +106,7 @@ jobs: - name: Install Stellar CLI ${{ matrix.stellar-version }} if: steps.stellar-cli-cache.outputs.cache-hit != 'true' - uses: stellar/stellar-cli@v27.0.0 - with: - version: ${{ matrix.stellar-version }} + run: bash scripts/install-stellar-cli.sh ${{ matrix.stellar-version }} - name: Add Stellar CLI to PATH run: echo "$HOME/.local/bin" >> "$GITHUB_PATH" diff --git a/.github/workflows/testnet-deploy-regression.yml b/.github/workflows/testnet-deploy-regression.yml index 46d4612b..f4b460f4 100644 --- a/.github/workflows/testnet-deploy-regression.yml +++ b/.github/workflows/testnet-deploy-regression.yml @@ -41,7 +41,7 @@ jobs: - name: Install Stellar CLI if: steps.stellar-cli-cache.outputs.cache-hit != 'true' - uses: stellar/stellar-cli@v27.0.0 + run: bash scripts/install-stellar-cli.sh 27.0.0 # The install action puts ~/.local/bin on PATH itself; on a cache hit it is # skipped, so add the directory here too. diff --git a/.github/workflows/testnet-smoke.yml b/.github/workflows/testnet-smoke.yml index 9dfd1b36..4c5a1c94 100644 --- a/.github/workflows/testnet-smoke.yml +++ b/.github/workflows/testnet-smoke.yml @@ -45,7 +45,7 @@ jobs: - name: Install Stellar CLI if: steps.stellar-cli-cache.outputs.cache-hit != 'true' - uses: stellar/stellar-cli@v27.0.0 + run: bash scripts/install-stellar-cli.sh 27.0.0 # The install action puts ~/.local/bin on PATH itself; on a cache hit it is # skipped, so add the directory here too. diff --git a/scripts/install-stellar-cli.sh b/scripts/install-stellar-cli.sh new file mode 100755 index 00000000..a49e84da --- /dev/null +++ b/scripts/install-stellar-cli.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash +# Install the Stellar CLI release binary with a resilient download. +# +# The official `stellar/stellar-cli` action only retries the CDN download a +# handful of times over ~25s, which a multi-minute 503 outage from the GitHub +# releases CDN can still blow past (see issue #119). When the binary is not +# already restored from `actions/cache`, this helper performs the same +# download with an exponential backoff that rides out much longer outages. +# +# Usage: install-stellar-cli.sh [os-arch-triple] +# version CLI version, with or without a leading "v" (e.g. 27.0.0) +# os-arch-triple target triple (default: x86_64-unknown-linux-gnu) +set -euo pipefail + +version_raw="${1:?Usage: install-stellar-cli.sh [os-arch-triple]}" +os_arch="${2:-x86_64-unknown-linux-gnu}" + +version="${version_raw#v}" +install_dir="$HOME/.local/bin" +mkdir -p "$install_dir" + +file="stellar-cli-${version}-${os_arch}.tar.gz" +url="https://github.com/stellar/stellar-cli/releases/download/v${version}/${file}" + +# Exponential backoff: 10s, 20s, 40s, 80s, 160s => ~5min of retries. +max_attempts=6 +delay=10 + +attempt=1 +until curl -fSL "$url" | tar xz -C "$install_dir"; do + if (( attempt >= max_attempts )); then + echo "error: failed to download ${url} after ${max_attempts} attempts" >&2 + exit 1 + fi + echo "warning: download of ${url} failed (attempt ${attempt}); retrying in ${delay}s" >&2 + sleep "$delay" + delay=$(( delay * 2 )) + attempt=$(( attempt + 1 )) +done + +binary="${install_dir}/stellar" +"${binary}" --version From 0f1b54eb02a24c28a31f69d600422cba4b1898e8 Mon Sep 17 00:00:00 2001 From: cyberdocs120 Date: Tue, 25 Aug 2026 17:49:09 +0100 Subject: [PATCH 2/2] fix(scripts): stage download to temp file before extraction, add chmod +x Addresses maintainer review on #119 CDN retry fix: - Replace curl | tar pipe with a two-step download-then-extract to prevent partial extractions in $install_dir on mid-stream connection drops - Add mktemp -d temp dir with trap cleanup so failed attempts leave no debris - Add explicit chmod +x after extraction for deterministic permissions across runner environments with varying umask/tar behaviour - Pass --retry 0 to curl to keep all retry logic in the shell backoff loop --- scripts/install-stellar-cli.sh | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/scripts/install-stellar-cli.sh b/scripts/install-stellar-cli.sh index a49e84da..6f10fe1c 100755 --- a/scripts/install-stellar-cli.sh +++ b/scripts/install-stellar-cli.sh @@ -22,12 +22,17 @@ mkdir -p "$install_dir" file="stellar-cli-${version}-${os_arch}.tar.gz" url="https://github.com/stellar/stellar-cli/releases/download/v${version}/${file}" +temp_dir="$(mktemp -d)" +trap 'rm -rf "$temp_dir"' EXIT + +archive_path="${temp_dir}/${file}" + # Exponential backoff: 10s, 20s, 40s, 80s, 160s => ~5min of retries. max_attempts=6 delay=10 attempt=1 -until curl -fSL "$url" | tar xz -C "$install_dir"; do +until curl -fSL --retry 0 "$url" -o "$archive_path"; do if (( attempt >= max_attempts )); then echo "error: failed to download ${url} after ${max_attempts} attempts" >&2 exit 1 @@ -38,5 +43,8 @@ until curl -fSL "$url" | tar xz -C "$install_dir"; do attempt=$(( attempt + 1 )) done +tar xzf "$archive_path" -C "$install_dir" +chmod +x "${install_dir}/stellar" + binary="${install_dir}/stellar" "${binary}" --version