diff --git a/CHANGELOG.md b/CHANGELOG.md index 35568c9..59dc1e9 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.9.0] - 2026-03-15 + +### Added +- `install.sh` script for downloading and installing prebuilt binaries with checksum verification + ## [0.8.0] - 2026-03-15 ### Added @@ -102,6 +107,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Initial release +[0.9.0]: https://github.com/gooddata/gooddata-goodmock/compare/v0.8.0...v0.9.0 [0.8.0]: https://github.com/gooddata/gooddata-goodmock/compare/v0.7.0...v0.8.0 [0.7.0]: https://github.com/gooddata/gooddata-goodmock/compare/v0.6.0...v0.7.0 [0.6.0]: https://github.com/gooddata/gooddata-goodmock/compare/v0.5.1...v0.6.0 diff --git a/README.md b/README.md index 7d041f7..8636c46 100644 --- a/README.md +++ b/README.md @@ -11,13 +11,30 @@ A lightweight, high-performance mock server written in Go, powered by [fasthttp] - Detailed mismatch logging (WireMock-style diagnostics) - Minimal Docker image (built from `scratch`) -## Installation +## Install + +```bash +# latest version +curl -fsSL https://raw.githubusercontent.com/gooddata/gooddata-goodmock/master/install.sh | sh + +# specific version +curl -fsSL https://raw.githubusercontent.com/gooddata/gooddata-goodmock/master/install.sh | sh -s v0.9.0 + +# custom install directory +curl -fsSL https://raw.githubusercontent.com/gooddata/gooddata-goodmock/master/install.sh | BINDIR=~/.local/bin sh +``` + +Or run locally: + +```bash +BINDIR=~/.local/bin ./install.sh v0.9.0 +``` ### Docker ```bash -docker build -t goodmock . -docker run -p 8080:8080 goodmock +docker pull gooddata/gooddata-goodmock:latest +docker run -p 8080:8080 gooddata/gooddata-goodmock:latest ``` ### Building from Source @@ -32,8 +49,10 @@ go build -o goodmock . ## Usage -``` +```bash goodmock +goodmock -v # print version +goodmock --version # print version ``` ### Modes diff --git a/VERSION b/VERSION index a3df0a6..ac39a10 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.8.0 +0.9.0 diff --git a/install.sh b/install.sh new file mode 100755 index 0000000..45b6fe5 --- /dev/null +++ b/install.sh @@ -0,0 +1,142 @@ +#!/bin/sh +set -e + +OWNER="gooddata" +REPO="gooddata-goodmock" +BINARY="goodmock" +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}"