From 26d10ffc2ec7e658894203701bfa67f52f4fe4de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maxime=20Soul=C3=A9?= Date: Tue, 10 Nov 2020 23:18:40 +0100 Subject: [PATCH] feat: handle GITHUB_ENV and set GOROOT/GOPATH MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Maxime Soulé --- .github/workflows/test.yml | 111 ++++++++++++++++++++++++++++--------- README.md | 55 +++++++++++++++++- install-go.pl | 77 ++++++++++++++++++++----- 3 files changed, 200 insertions(+), 43 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index efc529d..882f8b4 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -28,37 +28,67 @@ jobs: perl -c install-go.pl - name: Environment - run: env - - - name: Test old version run: | - mkdir xxx - ./install-go.pl 1.15.1 xxx - ./xxx/go/bin/go version | tee xxx/go-version - fgrep -q go1.15.1 xxx/go-version - [ -s "$GITHUB_PATH" ] && cat $GITHUB_PATH - - - name: Test old version PATH - run: | - go version | fgrep go1.15.1 - rm -rf xxx + env | sort - name: Test GOROOT version run: | version=$(echo "$GOROOT" | perl -nE '/(\d+.\d+.\d+)/ and say $1') if [ -n "$version" ]; then mkdir xxx - ./install-go.pl $version xxx + ./install-go.pl -p -e $version xxx ./xxx/go/bin/go version | tee xxx/go-version fgrep -q go$version xxx/go-version - [ -s "$GITHUB_PATH" ] + if [ -s "$GITHUB_PATH" ]; then + echo "*** GITHUB_PATH file altered:" + cat $GITHUB_PATH + echo "--------------------" + false + fi + if [ -s "$GITHUB_ENV" ]; then + echo "*** GITHUB_ENV file altered:" + cat $GITHUB_ENV + echo "--------------------" + false + fi rm -rf xxx elif [ -z "$GOROOT" ]; then echo "GOROOT not available in environment" else - echo "Cannot find go version in GOROOT value: <$GOROOT>" + echo "*** Cannot find go version in GOROOT value: <$GOROOT>" + false + fi + + - name: Test old version + run: | + mkdir xxx + ./install-go.pl 1.15.1 xxx + ./xxx/go/bin/go version | tee xxx/go-version + fgrep -q go1.15.1 xxx/go-version + if [ ! -s "$GITHUB_PATH" ]; then + echo "*** GITHUB_PATH file is empty" + false + fi + if [ ! -s "$GITHUB_ENV" ]; then + echo "*** GITHUB_ENV file is empty" + false + fi + cat $GITHUB_ENV + + - name: Test just set PATH, GOROOT and GOPATH + run: | + env | sort + go version + go version | fgrep -q go1.15.1 + if [ -z "$GOROOT" ]; then + echo "*** GOROOT is empty" + false + fi + if ! echo "$GOPATH" | egrep -q 'xxx/go/gopath$'; then + echo "*** GOPATH incorrectly set: '$GOPATH'" false fi + rm -rf xxx - name: Test GOROOT_X_Y_X64 version with -p run: | @@ -71,23 +101,50 @@ jobs: ./install-go.pl -p $version xxx ./xxx/go/bin/go version | tee xxx/go-version fgrep -q go$version xxx/go-version - [ ! -s "$GITHUB_PATH" ] + if [ -s "$GITHUB_PATH" ]; then + echo "*** GITHUB_PATH file altered:" + cat $GITHUB_PATH + echo "--------------------" + false + fi + if [ ! -s "$GITHUB_ENV" ]; then + echo "*** GITHUB_ENV file is empty" + false + fi rm -rf xxx - - name: Test last version with --dont-alter-github-path + - name: Test last version with --dont-alter-github-path --dont-alter-github-env run: | mkdir xxx - ./install-go.pl --dont-alter-github-path 1.15.x xxx + ./install-go.pl --dont-alter-github-path --dont-alter-github-env 1.15.x xxx ./xxx/go/bin/go version | tee xxx/go-version fgrep -q go1.15. xxx/go-version - [ ! -s "$GITHUB_PATH" ] - rm -rf xxx + if [ -s "$GITHUB_PATH" ]; then + echo "*** GITHUB_PATH file altered:" + cat $GITHUB_PATH + echo "--------------------" + false + fi + if [ -s "$GITHUB_ENV" ]; then + echo "*** GITHUB_ENV file altered:" + cat $GITHUB_ENV + echo "--------------------" + false + fi - name: Test tip run: | - mkdir xxx - ./install-go.pl tip xxx - ./xxx/go/bin/go version | tee xxx/go-version - fgrep -q 'go version devel' xxx/go-version - [ -s "$GITHUB_PATH" ] - rm -rf xxx + mkdir zzz + ./install-go.pl tip zzz + ./zzz/go/bin/go version | tee zzz/go-version + fgrep -q 'go version devel' zzz/go-version + if [ ! -s "$GITHUB_PATH" ]; then + echo "*** GITHUB_PATH file is empty" + false + fi + if [ ! -s "$GITHUB_ENV" ]; then + echo "*** GITHUB_ENV file is empty" + false + fi + rm -rf zzz xxx + diff --git a/README.md b/README.md index bb007b5..9e123b7 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,11 @@ # install-go -Install any version of golang anywhere +Install any version of golang anywhere, even in a github action. + +No need to wait for the last version of go to be integrated in +`actions/setup-go` no need of any github action at all, even `tip` is +available out of the box. + ## Usage @@ -22,6 +27,35 @@ Tested on Linux (and Github unbuntu-latest), FreeBSD, Github macos-latest and windows-latest, for amd64 arch only. +### In a github action + +```yaml +jobs: + test: + strategy: + matrix: + go-version: [1.9.x, 1.10.x, 1.11.x, 1.12.x, 1.13.x, 1.14.x, 1.15.x, tip] + os: [ubuntu-latest, windows-latest, macos-latest] + + runs-on: ${{ matrix.os }} + + steps: + - name: Setup go + run: | + curl -sL https://raw.githubusercontent.com/maxatome/install-go/v2.0/install-go.pl | + perl - ${{ matrix.go-version }} $HOME/go + + - name: Checkout code + uses: actions/checkout@v2 + + - name: Testing + continue-on-error: ${{ matrix.go-version == 'tip' }} + run: | + go version + go test ./... # or whatever you want with go executable +``` + + ### Install last version of go 1.15 in current directory: ``` @@ -61,3 +95,22 @@ then Note that even if `~/my/path/go/bin/go` is the `gotip` executable at the end of installation, `tip` is compiled and installed in `~/sdk/gotip/`. + + +## How does it work? + +`install-go.pl` first checks if the requested version already exists +in its environment. + +If yes, it symlinks this version in the `INSTALLATION_DIR` directory. + +If no, it downloads the binary version from +[golang.org](https://golang.org/dl/), which is pretty fast. For the +`tip` case, it downloads then compiles it, so be prepared to have a +longer build due to this compilation stage. + + +## Real full example of use + +See [go-testdeep action](https://github.com/maxatome/go-testdeep/blob/master/.github/workflows/ci.yml), +only on linux but with linter and coverage steps. diff --git a/install-go.pl b/install-go.pl index 0e711c5..93546ba 100755 --- a/install-go.pl +++ b/install-go.pl @@ -9,8 +9,9 @@ use File::Spec; use Getopt::Long; -my $NO_GITHUB_PATH; -GetOptions('p|dont-alter-github-path' => \$NO_GITHUB_PATH) +my($NO_GITHUB_PATH, $NO_GITHUB_ENV); +GetOptions('p|dont-alter-github-path' => \$NO_GITHUB_PATH, + 'e|dont-alter-github-env' => \$NO_GITHUB_ENV) and (@ARGV == 1 or @ARGV == 2) or die <rel2abs($DESTDIR); @@ -70,8 +77,8 @@ # If go is already installed somewhere, no need to install it if ($goroot) { - install_tip("$goroot/bin/go", $DESTDIR); - export_path("$DESTDIR/go/bin"); + my $goroot_tip = install_tip($goroot, $DESTDIR); + export_env("$DESTDIR/go", $goroot_tip); exit 0; } @@ -84,10 +91,11 @@ # 1.15.x -> (1.15, 4) ($TARGET, my $last_minor) = resolve_target($TARGET); +my $goroot_env; link_go_if_available($TARGET, $last_minor, $DESTDIR) - or install_go(get_url($TARGET, $last_minor), $DESTDIR, $TIP); + or $goroot_env = install_go(get_url($TARGET, $last_minor), $DESTDIR, $TIP); -export_path("$DESTDIR/go/bin"); +export_env("$DESTDIR/go", $goroot_env); exit 0; @@ -160,8 +168,12 @@ sub link_go_if_available and -f -x "$value/bin/go") { say "Find already installed go version $full"; - rmdir "$dest_dir/go"; - symlink($value, "$dest_dir/go") or die "symlink($value, $dest_dir/go): $!\n"; + mkdir_p("$dest_dir/go"); + foreach my $subdir (qw(bin src pkg)) + { + symlink("$value/$subdir", "$dest_dir/go/$subdir") + or die "symlink($value/$subdir, $dest_dir/go/$subdir): $!\n"; + } say "go version $full symlinked and available as $dest_dir/go/bin/go"; return 1; } @@ -217,24 +229,30 @@ sub install_go exe("curl -s \Q$url\E | tar zxf - go/bin go/pkg go/src"); } + my $goroot_env; if ($tip) { - install_tip("$dest_dir/go/bin/go", $dest_dir); + my $goroot_env = install_tip("$dest_dir/go", $dest_dir); } else { say "go $version installed as $dest_dir/go/bin/go"; } + + return $goroot_env; } sub install_tip { - my($go, $dest_dir) = @_; + my($goroot, $dest_dir) = @_; my $gopath = "$dest_dir/go/gopath"; mkdir_p($gopath); { + my $go = "$goroot/bin/go"; + local $ENV{GOPATH} = $gopath; + local $ENV{GOROOT} = $goroot; exe($go, 'version'); exe($go, qw(get golang.org/dl/gotip)); } @@ -256,15 +274,44 @@ sub install_tip symlink($gotip, $final_go) or die "symlink($gotip, $final_go): $!\n"; say "go tip installed as $final_go"; + + return do + { + delete local $ENV{GOROOT}; + chomp(my $goroot_env = `$gotip env GOROOT`); + $goroot_env; + }; } -sub export_path +sub export_env { + my($goroot, $goroot_env) = @_; + + my $gopath; + if (not $NO_GITHUB_ENV + and $ENV{GITHUB_ENV} + and open(my $fh, '>>', $ENV{GITHUB_ENV})) + { + $goroot_env //= $goroot; + $gopath = "$goroot/gopath"; + mkdir_p($gopath); + print $fh <>', $ENV{GITHUB_PATH})) { - say $fh shift; + say $fh "$goroot/bin"; + if (defined $gopath) + { + mkdir_p("$gopath/bin"); + say $fh "$gopath/bin"; + } close $fh; } }