name: 'Setup Gordon' description: 'Install the Gordon CLI binary into the runner PATH' author: 'Gordon Contributors' branding: icon: 'download-cloud' color: 'blue' inputs: version: description: 'Gordon version to install (e.g. v2.0.0 or latest)' required: false default: 'latest' outputs: version: description: 'The version of Gordon that was installed' value: ${{ steps.install.outputs.version }} path: description: 'Path to the installed Gordon binary' value: ${{ steps.install.outputs.path }} runs: using: 'composite' steps: - name: Install Gordon id: install shell: bash env: GORDON_VERSION_INPUT: ${{ inputs.version }} run: | set -euo pipefail # Map RUNNER_OS to gordon OS identifier case "${RUNNER_OS}" in Linux) os="linux" ;; macOS) os="darwin" ;; *) echo "Unsupported OS: ${RUNNER_OS}" >&2; exit 1 ;; esac # Map RUNNER_ARCH to gordon arch identifier case "${RUNNER_ARCH}" in X64) arch="amd64" ;; ARM64) arch="arm64" ;; *) echo "Unsupported architecture: ${RUNNER_ARCH}" >&2; exit 1 ;; esac version="${GORDON_VERSION_INPUT}" if ! [[ "${version}" =~ ^(latest|v?[0-9]+\.[0-9]+\.[0-9]+([-+][0-9A-Za-z.-]+)?)$ ]]; then echo "Invalid Gordon version: ${version}" >&2 exit 1 fi # Resolve 'latest' to an actual tag via redirect URL if [ "${version}" = "latest" ]; then redirect_url="$(curl -fsSL -o /dev/null -w '%{redirect_url}' "https://github.com/bnema/gordon/releases/latest")" version="${redirect_url##*/}" if [ -z "${version}" ]; then echo "Failed to resolve latest Gordon version" >&2 exit 1 fi if ! [[ "${version}" =~ ^v?[0-9]+\.[0-9]+\.[0-9]+([-+][0-9A-Za-z.-]+)?$ ]]; then echo "Resolved invalid Gordon version: ${version}" >&2 exit 1 fi fi archive="gordon_${os}_${arch}.tar.gz" base_url="https://github.com/bnema/gordon/releases/download/${version}" url="${base_url}/${archive}" checksums_url="${base_url}/checksums.txt" work_dir="$(mktemp -d)" dest="${work_dir}/${archive}" checksums="${work_dir}/checksums.txt" extract_dir="${work_dir}/extract" install_path="/usr/local/bin/gordon" trap 'rm -rf "${work_dir}"' EXIT echo "Installing Gordon ${version} (${os}/${arch}) from ${url}" # Download the release archive and checksums curl -fsSL -o "${checksums}" "${checksums_url}" curl -fsSL -o "${dest}" "${url}" # Verify checksum before extraction archive_escaped="$(printf '%s\n' "${archive}" | sed 's/[.[\\*^$()+?{|]/\\\\&/g')" checksum_lines="$(grep -E "^[0-9a-fA-F]{64}[[:space:]]+\\*?${archive_escaped}$" "${checksums}" || true)" if [ "$(printf '%s\n' "${checksum_lines}" | sed '/^$/d' | wc -l | tr -d ' ')" != "1" ]; then echo "Expected exactly one checksum for ${archive} in checksums.txt" >&2 exit 1 fi expected="$(printf '%s\n' "${checksum_lines}" | awk '{print $1}')" if command -v sha256sum >/dev/null 2>&1; then actual="$(sha256sum "${dest}" | awk '{print $1}')" elif command -v shasum >/dev/null 2>&1; then actual="$(shasum -a 256 "${dest}" | awk '{print $1}')" else echo "Neither sha256sum nor shasum is available for checksum verification" >&2 exit 1 fi if [ "${expected}" != "${actual}" ]; then echo "Checksum verification failed for ${archive}" >&2 echo "Expected: ${expected}" >&2 echo "Actual: ${actual}" >&2 exit 1 fi # Extract just the gordon binary and reject symlinks/directories mkdir -p "${extract_dir}" tar -xzf "${dest}" -C "${extract_dir}" gordon binary="${extract_dir}/gordon" if [ ! -f "${binary}" ] || [ -L "${binary}" ]; then echo "Archive did not contain a regular Gordon binary" >&2 exit 1 fi # Install with explicit executable permissions and verify if [ -w "$(dirname "${install_path}")" ]; then install -m 0755 "${binary}" "${install_path}" else sudo install -m 0755 "${binary}" "${install_path}" fi gordon version # Set outputs echo "version=${version}" >> "${GITHUB_OUTPUT}" echo "path=${install_path}" >> "${GITHUB_OUTPUT}"