From 53e2d16911e4677e80c8dfdf8d7a7bebcc70aa47 Mon Sep 17 00:00:00 2001 From: Martin Najemi Date: Fri, 13 Feb 2026 13:07:26 +0100 Subject: [PATCH] chore: Create install script Risk: low JIRA: STL-2317 --- CHANGELOG.md | 6 +++ README.md | 20 ++++++++ VERSION | 2 +- install.sh | 142 +++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 169 insertions(+), 1 deletion(-) create mode 100755 install.sh diff --git a/CHANGELOG.md b/CHANGELOG.md index 823a959..23e5366 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.0] - 2026-02-13 + +### Added +- `install.sh` script for downloading and installing standalone binaries with SHA-256 verification + ## [0.2.5] - 2026-02-13 ### Changed @@ -53,6 +58,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Multi-stage Docker build - Automated vendor upgrade workflow +[0.3.0]: https://github.com/gooddata/gooddata-goodchanges/compare/v0.2.5...v0.3.0 [0.2.5]: https://github.com/gooddata/gooddata-goodchanges/compare/v0.2.4...v0.2.5 [0.2.4]: https://github.com/gooddata/gooddata-goodchanges/compare/v0.2.3...v0.2.4 [0.2.3]: https://github.com/gooddata/gooddata-goodchanges/compare/v0.2.2...v0.2.3 diff --git a/README.md b/README.md index 6b8f15a..7041206 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,25 @@ Granular change detection for Rush monorepos. Analyzes code changes at the AST level to determine which library exports are affected by a pull request, then propagates taint through the workspace dependency graph to identify which e2e test targets need to run. +## Install + +```bash +# latest version +curl -fsSL https://raw.githubusercontent.com/gooddata/gooddata-goodchanges/master/install.sh | sh + +# specific version +curl -fsSL https://raw.githubusercontent.com/gooddata/gooddata-goodchanges/master/install.sh | sh -s v0.2.5 + +# custom install directory +curl -fsSL https://raw.githubusercontent.com/gooddata/gooddata-goodchanges/master/install.sh | BINDIR=~/.local/bin sh +``` + +Or run locally: + +```bash +BINDIR=~/.local/bin ./install.sh v0.2.5 +``` + ## How it works 1. Finds the merge base commit (comparison point) @@ -219,6 +238,7 @@ internal/ rush.go # Rush config, dependency graph, project configs tsparse/ tsparse.go # TypeScript parser (imports, exports, symbols) +install.sh # Standalone binary installer vendor-tsgo.sh # Vendor script for typescript-go TSGO_COMMIT # Pinned typescript-go commit hash Dockerfile # Multi-stage Docker build diff --git a/VERSION b/VERSION index 28af839..9325c3c 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.2.5 \ No newline at end of file +0.3.0 \ No newline at end of file diff --git a/install.sh b/install.sh new file mode 100755 index 0000000..e906c68 --- /dev/null +++ b/install.sh @@ -0,0 +1,142 @@ +#!/bin/sh +set -e + +OWNER="gooddata" +REPO="gooddata-goodchanges" +BINARY="goodchanges" +BINDIR="${BINDIR:-/usr/local/bin}" + +usage() { + cat <&2; exit 1 ;; + esac + echo "$os" +} + +detect_arch() { + arch=$(uname -m) + case "$arch" in + x86_64|amd64) arch="amd64" ;; + arm64|aarch64) arch="arm64" ;; + *) echo "error: unsupported architecture: $arch" >&2; exit 1 ;; + esac + echo "$arch" +} + +# --- resolve version --- + +resolve_version() { + if [ -n "${1:-}" ]; then + echo "$1" + return + fi + # GitHub redirects /releases/latest to the latest tag; grab it from the JSON response + tag=$(curl -sSL "https://api.github.com/repos/${OWNER}/${REPO}/releases/latest" \ + | grep '"tag_name"' | head -1 | sed 's/.*"tag_name": *"//;s/".*//') + if [ -z "$tag" ]; then + echo "error: could not determine latest release" >&2 + exit 1 + fi + echo "$tag" +} + +# --- download helpers --- + +download() { + if command -v curl >/dev/null 2>&1; then + curl -fsSL -o "$1" "$2" + elif command -v wget >/dev/null 2>&1; then + wget -qO "$1" "$2" + else + echo "error: curl or wget required" >&2 + exit 1 + fi +} + +verify_checksum() { + target="$1" + checksum_file="$2" + want=$(cut -d ' ' -f 1 < "$checksum_file") + if command -v sha256sum >/dev/null 2>&1; then + got=$(sha256sum "$target" | cut -d ' ' -f 1) + elif command -v shasum >/dev/null 2>&1; then + got=$(shasum -a 256 "$target" | cut -d ' ' -f 1) + else + echo "error: no sha256 tool found (need sha256sum or shasum), cannot verify download" >&2 + exit 1 + fi + if [ "$want" != "$got" ]; then + echo "error: checksum mismatch" >&2 + echo " expected: $want" >&2 + echo " got: $got" >&2 + exit 1 + fi +} + +# --- main --- + +OS=$(detect_os) +ARCH=$(detect_arch) +VERSION=$(resolve_version "${1:-}") + +case "$OS" in + windows) ext="zip" ;; + *) ext="tar.gz" ;; +esac + +asset="${BINARY}-${OS}-${ARCH}.${ext}" +base_url="https://github.com/${OWNER}/${REPO}/releases/download/${VERSION}" + +tmpdir=$(mktemp -d) +trap 'rm -rf "$tmpdir"' EXIT + +echo "Installing ${BINARY} ${VERSION} (${OS}/${ARCH})..." + +download "${tmpdir}/${asset}" "${base_url}/${asset}" +download "${tmpdir}/${asset}.sha256" "${base_url}/${asset}.sha256" +verify_checksum "${tmpdir}/${asset}" "${tmpdir}/${asset}.sha256" + +# extract +case "$ext" in + tar.gz) tar -xzf "${tmpdir}/${asset}" -C "$tmpdir" ;; + zip) unzip -oq "${tmpdir}/${asset}" -d "$tmpdir" ;; +esac + +# install +mkdir -p "$BINDIR" 2>/dev/null || sudo mkdir -p "$BINDIR" +srcname="${BINARY}-${OS}-${ARCH}" +binexe="${BINARY}" +[ "$OS" = "windows" ] && srcname="${srcname}.exe" && binexe="${binexe}.exe" + +mv "${tmpdir}/${srcname}" "${BINDIR}/${binexe}" 2>/dev/null \ + || sudo mv "${tmpdir}/${srcname}" "${BINDIR}/${binexe}" + +echo "Installed ${BINDIR}/${binexe}"