diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index eb42634..3db4aae 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,9 +1,10 @@ name: ci on: push: + branches: [ main ] workflow_dispatch: pull_request: - types: [opened, synchronize, reopened] + types: [ opened, synchronize, reopened ] jobs: cibuild: name: cibuild @@ -32,6 +33,8 @@ jobs: run: shell: bash steps: + - run: env + - run: go env - uses: actions/checkout@v3.3.0 - run: script/bootstrap - run: script/test diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml index d252165..23b324c 100644 --- a/.github/workflows/integration.yml +++ b/.github/workflows/integration.yml @@ -1,9 +1,10 @@ name: integration on: push: + branches: [ main ] workflow_dispatch: pull_request: - types: [opened, synchronize, reopened] + types: [ opened, synchronize, reopened ] jobs: install_go_tip: name: install tip diff --git a/src/install-go b/src/install-go index 0d35fd3..7e6db22 100755 --- a/src/install-go +++ b/src/install-go @@ -2,6 +2,7 @@ # required global vars: # RUNNER_TOOL_CACHE # provided by action +# GITHUB_OUTPUT # provided by action # # optional vars: # INSTALL_GO_FORCE # set to non-empty to force the install @@ -37,7 +38,9 @@ GITHUB_PATH="${GITHUB_PATH:-/dev/null}" add_to_github_path "$target_dir/bin" PATH="$(add_to_system_path "$target_dir/bin")" -gopath=$(go env GOPATH) +go_exec="$target_dir/bin/$(exe_name go)" + +gopath=$("$go_exec" env GOPATH) mkdir -p "$gopath/bin" add_to_github_path "$gopath/bin" @@ -46,7 +49,7 @@ PATH="$(add_to_system_path "$gopath/bin")" unset GOROOT if [ -n "$INSTALL_GO_TIP" ]; then - GO111MODULE=off go get golang.org/dl/gotip + GO111MODULE=off "$go_exec" get golang.org/dl/gotip "$gopath/bin/$(exe_name gotip)" download rm -rf "$tip_target_dir" mkdir -p "$(dirname "$tip_target_dir")" @@ -54,6 +57,7 @@ if [ -n "$INSTALL_GO_TIP" ]; then add_to_github_path "$tip_target_dir/bin" PATH="$(add_to_system_path "$tip_target_dir/bin")" + go_exec="$tip_target_dir/bin/$(exe_name go)" fi govars='GOCACHE @@ -62,8 +66,8 @@ GOPATH GOROOT GOTOOLDIR' -echo "GOROOT=$(go env GOROOT)" >> "$GITHUB_ENV" +echo "GOROOT=$("$go_exec" env GOROOT)" >> "$GITHUB_ENV" for var in $govars; do - echo "$var=$(go env "$var")" >> "$GITHUB_OUTPUT" + echo "$var=$("$go_exec" env "$var")" >> "$GITHUB_OUTPUT" done diff --git a/src/lib b/src/lib index d0833ee..f9435d0 100755 --- a/src/lib +++ b/src/lib @@ -70,7 +70,7 @@ download_go_url() { } install_go() { - local go_version="$1" + local go_version="${1#go}" local target_dir="$2" debug_out "installing go $go_version to $target_dir" rm -rf "$target_dir" @@ -160,8 +160,6 @@ select_local_version() { select_remote_version() { local constraint="$1" local versions="$2" - # shellcheck disable=SC2001 - versions="$(echo "$versions" | sed 's/^go//g')" if got="$(select_go_version "$constraint" "$versions")"; then echo "$got" && return @@ -172,7 +170,7 @@ select_remote_version() { return fi - echo "$versions" | ./src/"semver-select" --go -c "$constraint" -n 1 -i - + echo "$versions" | ./src/"semver-select" --orig --go -c "$constraint" -n 1 -i - } # uses semver-select to convert a go version to semver diff --git a/src/lib.pl b/src/lib.pl index c7b7800..2fc1c6d 100644 --- a/src/lib.pl +++ b/src/lib.pl @@ -2,24 +2,17 @@ use strict; use warnings; -my $exp = qr/^(x|\d+)(\.(x|\d+)(\.(x|\d+))?)?(\w+)?$/; +my $exp = qr/^(?:go)?(?x|\d+)(?:\.(?x|\d+)(?:\.(?x|\d+))?)?(?\w+)?$/; sub parse_go_version { my $ver = shift; return unless $ver =~ m/$exp/; - my $major = $1; - my $minor = $3; - my $patch = $5; - my $pre_release = $6; - $major = 0 unless $major; - $minor = 0 unless $minor; - $patch = 0 unless $patch; - $pre_release = "" unless $pre_release; my $result = { - major => $major, - minor => $minor, - patch => $patch, - pre_release => $pre_release + original => $&, + major => $+{major} || 0, + minor => $+{minor} || 0, + patch => $+{patch} || 0, + pre_release => $+{pre_release} || "" }; return unless is_valid_go_version_pattern($result); return $result; @@ -45,7 +38,7 @@ sub go_version_greater { # false if a is a pre-release and b isn't return 0 if $$a{"pre_release"} ne "" && $$b{"pre_release"} eq ""; - # true if a's preview is asciibetical ahead of b's + # true if a's pre-release is asciibetical ahead of b's return 1 if $$a{"pre_release"} gt $$b{"pre_release"}; return 0; } @@ -67,34 +60,6 @@ () return 1; } -sub go_version_string { - my $v = shift; - my $major_v = $$v{"major"}; - my $minor_v = $$v{"minor"}; - my $patch_v = $$v{"patch"}; - - # For 1.21 and above with no pre-release, always return major.minor.patch - if ( $major_v > 1 || ( $major_v == 1 && $minor_v >= 21 ) ) { - if ( $$v{"pre_release"} eq "" ) { - return "$major_v.$minor_v.$patch_v"; - } - } - - $patch_v = "" if $patch_v == 0; - $minor_v = "" if $minor_v == 0 && $patch_v eq ""; - my $st = "$$v{'major'}"; - if ( $minor_v ne "" ) { - $st = "$st.$minor_v"; - } - if ( $patch_v ne "" ) { - $st = "$st.$patch_v"; - } - if ( $$v{"pre_release"} ) { - $st = "$st$$v{'pre_release'}"; - } - return $st; -} - sub go_version_pattern_match { my $pattern = shift; my $ver = shift; @@ -106,10 +71,4 @@ sub go_version_pattern_match { return 1; } -sub exit_err() { - my $msg = shift; - print "$msg\n"; - exit 1; -} - 1; diff --git a/src/lib_test.pl b/src/lib_test.pl index cf3625e..8fe4bfb 100755 --- a/src/lib_test.pl +++ b/src/lib_test.pl @@ -36,19 +36,5 @@ sub parse_and_match { ok( parse_and_match( "1.2.x", "1.2.3" ) == 1 ); ok( parse_and_match( "1.2.x", "1.2.3beta1" ) == 0 ); -sub test_go_version_string { - my $in = shift; - my $p = parse_go_version($in); - ok( go_version_string($p) eq $in, "test_go_version_string $in" ); -} - -test_go_version_string "1.2.3"; -test_go_version_string "1"; -test_go_version_string "0"; -test_go_version_string "1.0.1"; -test_go_version_string "1.1"; -test_go_version_string "1.1beta1"; -test_go_version_string "1beta1"; - done_testing(); diff --git a/src/lib_test.sh b/src/lib_test.sh index 7ef23dd..da03300 100755 --- a/src/lib_test.sh +++ b/src/lib_test.sh @@ -93,47 +93,47 @@ test_select_go_version() { do_test_select_go_version "" "1.2.3" do_test_select_go_version "1.21.0" "1.21.x" "1.21.0" do_test_select_go_version "1.21.0" "1.21" "1.21.0" - do_test_select_go_version "1.20" "1.20.x" "1.20.0" + do_test_select_go_version "go1.20" "1.20.x" "go1.20" } test_select_remote_version() { - versions='1.15.7 -1.15.6 -1.14.3 -1.15.6 -1.15.5 -1.15.4 -1.15.3 -1.15.2 -1.15.1 -1.15 -1.14.3 -1.14.2 -1.14.1 -1.14 -1.13.3 -1.13.2 -1.13.1 -1.13 -1.3.3 -1.3.2 -1.3.1 -1.3 -1.2.2 -1 -1.16beta1 -1.16rc1' - - tests='*;1.15.7 + versions='go1.15.7 +go1.15.6 +go1.14.3 +go1.15.6 +go1.15.5 +go1.15.4 +go1.15.3 +go1.15.2 +go1.15.1 +go1.15 +go1.14.3 +go1.14.2 +go1.14.1 +go1.14 +go1.13.3 +go1.13.2 +go1.13.1 +go1.13 +go1.3.3 +go1.3.2 +go1.3.1 +go1.3 +go1.2.2 +go1 +go1.16beta1 +go1.16rc1' + + tests='*;go1.15.7 1.17.x; 1.16.x; -1.15;1.15 -1.15.x;1.15.7 -^1;1.15.7 +1.15;go1.15 +1.15.x;go1.15.7 +^1;go1.15.7 ^1.15.999; -1.13.x;1.13.3 -1.16beta1;1.16beta1 -x;1.15.7' +1.13.x;go1.13.3 +1.16beta1;go1.16beta1 +x;go1.15.7' for td in $tests; do input="$(echo "$td" | cut -d ';' -f1)" diff --git a/src/run b/src/run index ec3cd01..391a60e 100755 --- a/src/run +++ b/src/run @@ -2,11 +2,19 @@ # required global vars: # RUNNER_TOOL_CACHE # provided by action +# RUNNER_WORKSPACE # provided by action +# GITHUB_ACTION_PATH # provided by action +# GITHUB_OUTPUT # provided by action # # optional vars: # GO_VERSION= version constraint # GO_VERSION_FILE= path to go.mod or go.work -# INSTALL_GO_FORCE # set to non-empty to force the install +# INSTALL_GO_FORCE # set to non-empty to force the install +# IGNORE_LOCAL_GO # set to non-empty to ignore local go installations +# +# for testing: +# VERSIONS_URL # override the url used to get the list of known versions +# SKIP_MATCHER # don't issue the add-matcher command because it breaks when running tests on windows set -e [ -n "$DEBUG" ] && set -x @@ -15,6 +23,8 @@ CDPATH="" cd -- "$(dirname -- "$0")/.." . src/lib +VERSIONS_URL="${VERSIONS_URL:-https://raw.githubusercontent.com/WillAbides/goreleases/main/versions.txt}" + debug_out starting run export INSTALL_GO_TIP @@ -49,25 +59,25 @@ mkdir -p "$go_tool_cache" if [ -z "$IGNORE_LOCAL_GO" ]; then lv="$(select_local_version "$constraint" "$install_parent")" - target_dir="$install_parent/$lv/x64" + target_dir="$install_parent/${lv#go}/x64" fi if [ -z "$IGNORE_LOCAL_GO" ] && [ -z "$lv" ]; then lv="$(select_local_version "$constraint" "$go_tool_cache")" - target_dir="$go_tool_cache/$lv/x64" + target_dir="$go_tool_cache/${lv#go}/x64" fi if [ -z "$lv" ]; then if is_precise_version "$constraint"; then lv="$constraint" - target_dir="$install_parent/$lv/x64" + target_dir="$install_parent/${lv#go}/x64" fi fi if [ -z "$lv" ]; then - known_versions="$(curl --retry 4 -s --fail 'https://raw.githubusercontent.com/WillAbides/goreleases/main/versions.txt')" + known_versions="$(curl --retry 4 -s --fail "$VERSIONS_URL")" lv="$(select_remote_version "$constraint" "$known_versions")" - target_dir="$install_parent/$lv/x64" + target_dir="$install_parent/${lv#go}/x64" fi if [ -z "$lv" ]; then @@ -75,6 +85,6 @@ if [ -z "$lv" ]; then exit 1 fi -echo "::add-matcher::$GITHUB_ACTION_PATH/matchers.json" +[ -n "$SKIP_MATCHER" ] || echo "::add-matcher::$GITHUB_ACTION_PATH/matchers.json" src/install-go "$lv" "$target_dir" "$install_parent/tip/x64" diff --git a/src/run_test_long.sh b/src/run_test_long.sh new file mode 100755 index 0000000..5c7a0c3 --- /dev/null +++ b/src/run_test_long.sh @@ -0,0 +1,74 @@ +#!/bin/bash + +set -e + +CDPATH="" cd -- "$(dirname -- "$0")/.." + +setUp() { + . src/lib +} + +# Nothing special about this one. It just happens to be HEAD of main when writing this. +# Most recent version is go1.21rc4 +STABLE_VERSIONS_URL="https://raw.githubusercontent.com/WillAbides/goreleases/077db58ac86a8a2fb63c90817090e132eded0f3d/versions.txt" + +do_test_run() { + tmp_dir="$SHUNIT_TMPDIR"/test_run + rm -rf -- "$tmp_dir" + mkdir -p -- "$tmp_dir" + export RUNNER_TEMP="$tmp_dir/runner_temp" + export RUNNER_TOOL_CACHE="$tmp_dir/runner_tool_cache" + export RUNNER_WORKSPACE="$tmp_dir/runner_workspace" + export GITHUB_OUTPUT="$tmp_dir/github_output" + export GITHUB_ACTION_PATH="$PWD" + export VERSIONS_URL="$STABLE_VERSIONS_URL" + export SKIP_MATCHER=1 + export IGNORE_LOCAL_GO=1 + export GOROOT="" + ./src/run + WANT_GOROOT="$RUNNER_WORKSPACE/setup-go-faster/go/$WANT_VERSION/x64" + if [ "$(goos)" = "windows" ]; then + # Windows is trickier because of how it translates paths. + # Just check that is has the right suffix. + WANT_GOROOT="setup-go-faster\\go\\$WANT_VERSION\\x64" + fi + assertContains "$(grep '^GOROOT=' "$GITHUB_OUTPUT")" "$WANT_GOROOT" +} + +test_run_1_15_x() { + GO_VERSION="1.15.x" \ + WANT_VERSION="1.15.15" \ + do_test_run +} + +test_run_star() { + GO_VERSION="*" \ + WANT_VERSION="1.20.7" \ + do_test_run +} + +test_run_1_16rc1() { + GO_VERSION="1.16rc1" \ + WANT_VERSION="1.16rc1" \ + do_test_run +} + +test_run_1_21rc4() { + GO_VERSION="1.21rc4" \ + WANT_VERSION="1.21rc4" \ + do_test_run +} + +test_go_mod() { + GO_VERSION_FILE="$SHUNIT_TMPDIR"/test_go_mod/go.mod + mkdir -p -- "$(dirname -- "$GO_VERSION_FILE")" + echo " +module foo +go 1.20.7 // the go version +" > "$GO_VERSION_FILE" + GO_VERSION_FILE="$GO_VERSION_FILE" \ + WANT_VERSION="1.20.7" \ + do_test_run +} + +. ./external/shunit2 diff --git a/src/select_go_version.pl b/src/select_go_version.pl index 246fe1d..3c2d449 100755 --- a/src/select_go_version.pl +++ b/src/select_go_version.pl @@ -10,9 +10,16 @@ my $usage = "usage: echo | select_go_version.pl pattern"; my $pat_arg = shift; -exit_err($usage) unless $pat_arg; +unless ($pat_arg) { + print "$usage\n"; + exit 1; +} + my $pat = parse_go_version($pat_arg); -exit_err("invalid pattern: $pat_arg") unless $pat; +unless ($pat) { + print "invalid pattern: $pat_arg\n"; + exit 1; +} my $max; @@ -26,4 +33,5 @@ } exit 1 unless $max; -print go_version_string($max) . "\n"; + +print $$max{"original"} . "\n"; diff --git a/src/semver-select b/src/semver-select index 73fdf76..70de7b0 100755 --- a/src/semver-select +++ b/src/semver-select @@ -5,24 +5,9 @@ set -e CDPATH="" cd -- "$(dirname -- "$0")/.." -goos() { - case "$RUNNER_OS" in - macOS) - echo "darwin" - ;; - Linux) - echo "linux" - ;; - Windows) - echo "windows" - ;; - *) - uname -s | tr '[:upper:]' '[:lower:]' - ;; - esac -} +. src/lib -target_version="0.3.0" +target_version="0.4.0" bin_path="./bin/semver-select" [ "$(goos)" = "windows" ] && bin_path+=".exe"