Skip to content

Commit

Permalink
Merge pull request #3 from maxatome/env
Browse files Browse the repository at this point in the history
feat: handle GITHUB_ENV and set GOROOT/GOPATH
  • Loading branch information
maxatome authored Nov 23, 2020
2 parents 086089b + 26d10ff commit e0a5d60
Show file tree
Hide file tree
Showing 3 changed files with 200 additions and 43 deletions.
111 changes: 84 additions & 27 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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: |
Expand All @@ -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
55 changes: 54 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -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

Expand All @@ -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:
```
Expand Down Expand Up @@ -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.
77 changes: 62 additions & 15 deletions install-go.pl
Original file line number Diff line number Diff line change
Expand Up @@ -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 <<EOU;
usage: $0 [-p|--dont-alter-github-path] GO_VERSION [INSTALL_DIR]
Expand All @@ -22,9 +23,15 @@
INSTALL_DIR defaults to .
By default, if GITHUB_PATH environment variable exists *AND*
references a writable file, INSTALL_DIR/go/bin is automatically
appended to this file.
references a writable file, INSTALL_DIR/go/bin and
INSTALL_DIR/go/gopath/bin (aka \$GOPATH/bin except if -e or no
GITHUB_ENV) are automatically appended to this file.
-p or --dont-alter-github-path option disables this behavior.
By default, if GITHUB_ENV environment variable exists *AND* references
a writable file, GOROOT and GOPATH are set respectively to "" and
INSTALL_DIR/go/gopath.
-e or --dont-alter-github-env option disables this behavior.
EOU


Expand All @@ -37,7 +44,7 @@
or die "$DESTDIR directory is not writable\n";

defined glob("$DESTDIR/go/*")
and die "$DESTDIR/go directory already exists and not empty\n";
and die "$DESTDIR/go directory already exists and is not empty\n";

$DESTDIR = File::Spec::->rel2abs($DESTDIR);

Expand Down Expand Up @@ -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;
}

Expand All @@ -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;

Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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));
}
Expand All @@ -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 <<EOF;
GOROOT=$goroot_env
GOPATH=$gopath
EOF
close $fh;
}

if (not $NO_GITHUB_PATH
and $ENV{GITHUB_PATH}
and open(my $fh, '>>', $ENV{GITHUB_PATH}))
{
say $fh shift;
say $fh "$goroot/bin";
if (defined $gopath)
{
mkdir_p("$gopath/bin");
say $fh "$gopath/bin";
}
close $fh;
}
}
Expand Down

0 comments on commit e0a5d60

Please sign in to comment.