diff --git a/root/update.go b/root/update.go index c402bb1..6438494 100644 --- a/root/update.go +++ b/root/update.go @@ -90,14 +90,14 @@ func FetchLatestVersion() (string, error) { func IsNewer(current, latest string) bool { c := strings.TrimPrefix(current, "v") l := strings.TrimPrefix(latest, "v") - + channel := config.Get().Updater.Channel // dev builds or empty versions never trigger an update if c == "" || c == "dev" || l == "" || l == "dev" { return false } // nightly builds are never shown as stable update targets - if config.Get().Updater.Channel != "nightly" && strings.Contains(l, "-nightly.") { + if channel != "nightly" && strings.Contains(l, "-nightly.") { return false } @@ -124,6 +124,10 @@ func IsNewer(current, latest string) bool { } } + if channel == "nightly" && strings.Contains(l, "-nightly.") && c != l { + return true + } + // if all parts are equal, the one with more parts is newer (e.g. 1.0.1 > 1.0) return len(lParts) > len(cParts) } @@ -245,9 +249,17 @@ var updateCmd = &cobra.Command{ // download and replace the binary using the install script installScript := "https://raw.githubusercontent.com/versenilvis/iris/main/scripts/install.sh" - fmt.Printf("running: curl -sSL %s | sh\n\n", installScript) + command := "curl -sSL " + installScript + " | sh" + runningPrefix := "" + if config.Get().Updater.Channel == "nightly" { + runningPrefix = fmt.Sprintf("IRIS_RELEASE_TAG=%s ", latest) + } + fmt.Printf("running: %s%s\n\n", runningPrefix, command) - cmdRun := exec.Command("sh", "-c", "curl -sSL "+installScript+" | sh") + cmdRun := exec.Command("sh", "-c", command) + if config.Get().Updater.Channel == "nightly" { + cmdRun.Env = append(os.Environ(), "IRIS_RELEASE_TAG="+latest) + } cmdRun.Stdout = os.Stdout cmdRun.Stderr = os.Stderr cmdRun.Stdin = os.Stdin diff --git a/root/update_test.go b/root/update_test.go index 29af684..9e30a36 100644 --- a/root/update_test.go +++ b/root/update_test.go @@ -10,27 +10,41 @@ import ( ) func TestIsNewer(t *testing.T) { + originalConfig := config.Get() + t.Cleanup(func() { + config.Init(originalConfig) + }) + tests := []struct { current string latest string + channel string want bool }{ - {"v1.0.0", "v1.0.1", true}, - {"v1.0.1", "v1.0.0", false}, - {"v1.0.0", "v1.0.0", false}, - {"v1.2.3", "v1.2.4", true}, - {"v1.2.0", "v1.1.9", false}, - {"dev", "v1.0.0", false}, // dev never updates - {"v1.0.0", "dev", false}, - {"", "v1.0.0", false}, - {"v1.0.0", "v1.1.0-nightly.8cb1f47", false}, // nightly never triggers update - {"v1.1.0-nightly.abc", "v1.2.0", true}, // but if you are on nightly, you can update to stable + {"v1.0.0", "v1.0.1", "stable", true}, + {"v1.0.1", "v1.0.0", "stable", false}, + {"v1.0.0", "v1.0.0", "stable", false}, + {"v1.2.3", "v1.2.4", "stable", true}, + {"v1.2.0", "v1.1.9", "stable", false}, + {"dev", "v1.0.0", "stable", false}, // dev never updates + {"v1.0.0", "dev", "stable", false}, + {"", "v1.0.0", "stable", false}, + {"v1.0.0", "v1.1.0-nightly.8cb1f47", "stable", false}, // nightly never triggers update + {"v1.1.0-nightly.abc", "v1.2.0", "stable", true}, // but if you are on nightly, you can update to stable + {"v1.1.0-nightly.abc", "v1.1.0-nightly.def", "nightly", true}, // nightly can update to newer nightly + {"v1.1.0-nightly.abc", "v1.1.0-nightly.abc", "nightly", false}, // same nightly is not newer } for _, tt := range tests { - if got := IsNewer(tt.current, tt.latest); got != tt.want { - t.Errorf("IsNewer(%q, %q) = %v; want %v", tt.current, tt.latest, got, tt.want) - } + t.Run(tt.current+"_"+tt.latest+"_"+tt.channel, func(t *testing.T) { + cfg := config.DefaultConfig() + cfg.Updater.Channel = tt.channel + config.Init(cfg) + + if got := IsNewer(tt.current, tt.latest); got != tt.want { + t.Errorf("IsNewer(%q, %q, %q) = %v; want %v", tt.current, tt.latest, tt.channel, got, tt.want) + } + }) } } diff --git a/scripts/install.sh b/scripts/install.sh index 77e7689..6caa45e 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -5,6 +5,7 @@ REPO="versenilvis/iris" BIN_DIR="${BIN_DIR:-/usr/local/bin}" # allow overriding the GitHub API base URL for local testing IRIS_API_URL="${IRIS_API_URL:-https://api.github.com}" +IRIS_RELEASE_TAG="${IRIS_RELEASE_TAG:-}" main() { echo "Installing iris..." @@ -123,18 +124,22 @@ get_arch() { get_download_url() { arch="$1" + release_path="/releases/latest" + if [ -n "${IRIS_RELEASE_TAG}" ]; then + release_path="/releases/tags/${IRIS_RELEASE_TAG}" + fi if command -v curl >/dev/null 2>&1; then http_response=$(curl -sL -w "\n%{http_code}" \ ${GITHUB_TOKEN:+-H "Authorization: Bearer ${GITHUB_TOKEN}"} \ - "${IRIS_API_URL}/repos/${REPO}/releases/latest") + "${IRIS_API_URL}/repos/${REPO}${release_path}") http_code=$(echo "${http_response}" | tail -1) releases=$(echo "${http_response}" | sed '$d') elif command -v wget >/dev/null 2>&1; then tmp_headers=$(mktemp) releases=$(wget -S -qO- \ ${GITHUB_TOKEN:+--header "Authorization: Bearer ${GITHUB_TOKEN}"} \ - "${IRIS_API_URL}/repos/${REPO}/releases/latest" 2>"$tmp_headers" || true) + "${IRIS_API_URL}/repos/${REPO}${release_path}" 2>"$tmp_headers" || true) http_code=$(grep "HTTP/" "$tmp_headers" | tail -1 | sed -e 's/^[[:space:]]*//' | cut -d' ' -f2) [ -z "${http_code}" ] && http_code="000" rm -f "$tmp_headers"