diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e1dd467..e8f6d46 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -216,8 +216,17 @@ jobs: # INSTALL_DIR inside the runner's temp, so there is no sudo prompt and # nothing to clean up. The default path is /usr/local/bin and that is # what the sudo fallback is for; this checks the installer, not sudo. + # /bin/bash explicitly, and the versions on the log, so which shell this + # ran under is a fact and not an assumption. macOS ships bash 3.2.57 - + # frozen in 2007 by its licence - where several things that work + # everywhere else do not. + - name: Which bash is being tested + run: | + /bin/bash --version | head -1 + bash --version | head -1 + - name: Run the installer - run: INSTALL_DIR="$RUNNER_TEMP/bin" bash scripts/install.sh + run: INSTALL_DIR="$RUNNER_TEMP/bin" /bin/bash scripts/install.sh - name: Run what it installed run: | @@ -233,7 +242,7 @@ jobs: - name: Install where the one-liner puts it run: | set -euo pipefail - bash scripts/install.sh + /bin/bash scripts/install.sh command -v nan nan --version @@ -247,12 +256,22 @@ jobs: GITHUB_TOKEN: "" run: | set -uo pipefail - out="$(REPO=helmcode/this-repo-does-not-exist bash scripts/install.sh 2>&1)" || true + out="$(REPO=helmcode/this-repo-does-not-exist /bin/bash scripts/install.sh 2>&1)" || true echo "$out" grep -q "could not work out the latest version" <<<"$out" || { echo "::error::the lookup failed without explaining itself" >&2 exit 1 } + # And it has to have failed for the reason it says. This step passed + # for a whole release while the script was dying on `auth[@]: unbound + # variable` two lines earlier - the bug produced the very message + # being grepped for, so the assertion was satisfied by the failure it + # existed to tell apart. A shell error in the output is never the + # expected path, whatever text follows it. + if grep -qiE "unbound variable|command not found|syntax error|bad substitution" <<<"$out"; then + echo "::error::the script hit a shell error, and the message that followed was not about the real cause" >&2 + exit 1 + fi # And the branch nobody had ever taken: a destination the user cannot # write to, where install_bin falls back to sudo. On a runner both @@ -266,7 +285,7 @@ jobs: sudo chmod 755 /opt/nan-sudo-test sudo chown root /opt/nan-sudo-test - INSTALL_DIR=/opt/nan-sudo-test/bin bash scripts/install.sh 2>&1 | tee out.txt + INSTALL_DIR=/opt/nan-sudo-test/bin /bin/bash scripts/install.sh 2>&1 | tee out.txt # It has to have actually taken that branch, not quietly succeeded. grep -q "retrying with sudo" out.txt || { diff --git a/internal/tui/tui.go b/internal/tui/tui.go index 679207c..1b300f0 100644 --- a/internal/tui/tui.go +++ b/internal/tui/tui.go @@ -2800,7 +2800,7 @@ func (m model) renderSetup(l layout) string { // ── about renderer ─────────────────────────────────────────────────────────── -const Version = "0.1.18" +const Version = "0.1.19" func renderAbout(l layout) string { var b strings.Builder diff --git a/scripts/install.ps1 b/scripts/install.ps1 index 29c269e..1b79c4a 100644 --- a/scripts/install.ps1 +++ b/scripts/install.ps1 @@ -118,7 +118,7 @@ function Get-LatestVersion { could not work out the latest version from the GitHub API it rate limits unauthenticated requests, so this is usually temporary wait a few minutes, or pick a version yourself: - & ([scriptblock]::Create((irm https://nan.builders/install.ps1))) -Version v0.1.18 + & ([scriptblock]::Create((irm https://nan.builders/install.ps1))) -Version v0.1.19 the releases are at https://github.com/$Repo/releases "@ } diff --git a/scripts/install.sh b/scripts/install.sh index 5d7e16a..ef5c44f 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -52,16 +52,24 @@ get_latest_version() { # A token if one is around. The unauthenticated API allows 60 requests an # hour per IP, which anyone behind a shared address - an office, a CI runner, # a phone tether - can be on the wrong side of through no fault of their own. - local auth=() + # + # Two branches and no array. macOS ships bash 3.2.57, frozen in 2007 by its + # licence, and there "${arr[@]}" on an EMPTY array under `set -u` is an + # unbound variable - fixed in bash 4.4, which no Mac has. That is not an edge + # case, it is every Mac: the script died on its first request and then blamed + # the GitHub rate limit for it. + # + # `|| true` on the pipeline, because the caller decides what an empty answer + # means. Without it `set -euo pipefail` kills the script where grep finds no + # tag_name - which is the rate-limited case - and the message explaining it + # never runs. + local url="https://api.github.com/repos/$REPO/releases/latest" local token="${GITHUB_TOKEN:-${GH_TOKEN:-}}" if [ -n "$token" ]; then - auth=(-H "Authorization: Bearer $token") + curl -sL -H "Authorization: Bearer $token" "$url" | grep '"tag_name"' | cut -d'"' -f4 || true + else + curl -sL "$url" | grep '"tag_name"' | cut -d'"' -f4 || true fi - # `|| true` on the pipeline, because the caller decides what an empty answer - # means. Without it `set -euo pipefail` kills the script where grep finds no - # tag_name - which is exactly the rate-limited case - and the careful message - # below never runs. It was written, and it was unreachable. - curl -sL "${auth[@]}" "https://api.github.com/repos/$REPO/releases/latest" | grep '"tag_name"' | cut -d'"' -f4 || true } # An unauthenticated GitHub API is rate limited per IP, so this call can come @@ -74,9 +82,9 @@ require_version() { return 0 fi err "could not work out the latest version from the GitHub API" - err "it rate limits unauthenticated requests, so this is usually temporary" + err "the usual cause is its rate limit on unauthenticated requests, which passes" err "wait a few minutes, or pick a version yourself:" - printf " VERSION=v0.1.18 curl -fsSL https://nan.builders/install | bash + printf " VERSION=v0.1.19 curl -fsSL https://nan.builders/install | bash " >&2 err "the releases are at https://github.com/$REPO/releases" exit 1