Compare commits

..

1 Commits

Author SHA1 Message Date
Victor Martinez
2f326e0d6e
Merge ef084a2719 into 21459d0b7b 2023-01-16 16:26:23 +00:00
47 changed files with 7463 additions and 6456 deletions

View File

@ -1,6 +0,0 @@
# Ignore list
/*
# Do not ignore these folders:
!__tests__/
!src/

View File

@ -1,51 +0,0 @@
// This is a reusable configuration file copied from https://github.com/actions/reusable-workflows/tree/main/reusable-configurations. Please don't make changes to this file as it's the subject of an automatic update.
module.exports = {
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:eslint-plugin-jest/recommended',
'eslint-config-prettier'
],
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint', 'eslint-plugin-node', 'eslint-plugin-jest'],
rules: {
'@typescript-eslint/no-require-imports': 'error',
'@typescript-eslint/no-non-null-assertion': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-empty-function': 'off',
'@typescript-eslint/ban-ts-comment': [
'error',
{
'ts-ignore': 'allow-with-description'
}
],
'no-console': 'error',
'yoda': 'error',
'prefer-const': [
'error',
{
destructuring: 'all'
}
],
'no-control-regex': 'off',
'no-constant-condition': ['error', {checkLoops: false}],
'node/no-extraneous-import': 'error'
},
overrides: [
{
files: ['**/*{test,spec}.ts'],
rules: {
'@typescript-eslint/no-unused-vars': 'off',
'jest/no-standalone-expect': 'off',
'jest/no-conditional-expect': 'off',
'no-console': 'off',
}
}
],
env: {
node: true,
es6: true,
'jest/globals': true
}
};

2
.gitattributes vendored
View File

@ -1,2 +1,2 @@
* text=auto eol=lf
* text=auto
.licenses/** -diff linguist-generated=true

View File

@ -1 +1 @@
blank_issues_enabled: false
blank_issues_enabled: false

View File

@ -13,4 +13,4 @@ on:
jobs:
call-basic-validation:
name: Basic validation
uses: actions/reusable-workflows/.github/workflows/basic-validation.yml@main
uses: actions/reusable-workflows/.github/workflows/basic-validation.yml@main

View File

@ -14,4 +14,4 @@ on:
jobs:
call-check-dist:
name: Check dist/
uses: actions/reusable-workflows/.github/workflows/check-dist.yml@main
uses: actions/reusable-workflows/.github/workflows/check-dist.yml@main

View File

@ -2,13 +2,13 @@ name: CodeQL analysis
on:
push:
branches: [main]
branches: [ main ]
pull_request:
branches: [main]
branches: [ main ]
schedule:
- cron: '0 3 * * 0'
jobs:
call-codeQL-analysis:
name: CodeQL analysis
uses: actions/reusable-workflows/.github/workflows/codeql-analysis.yml@main
name: CodeQL analysis
uses: actions/reusable-workflows/.github/workflows/codeql-analysis.yml@main

View File

@ -11,4 +11,4 @@ on:
jobs:
call-licensed:
name: Licensed
uses: actions/reusable-workflows/.github/workflows/licensed.yml@main
uses: actions/reusable-workflows/.github/workflows/licensed.yml@main

View File

@ -1,11 +0,0 @@
name: Update configuration files
on:
schedule:
- cron: '0 3 * * 0'
workflow_dispatch:
jobs:
call-update-configuration-files:
name: Update configuration files
uses: actions/reusable-workflows/.github/workflows/update-config-files.yml@main

View File

@ -42,7 +42,7 @@ jobs:
go-version: oldstable
- name: Verify Go
run: go version
aliases-arch:
runs-on: ${{ matrix.os }}
strategy:
@ -52,8 +52,8 @@ jobs:
version: [stable, oldstable]
architecture: [x64, x32]
exclude:
- os: macos-latest
architecture: x32
- os: macos-latest
architecture: x32
steps:
- uses: actions/checkout@v3
- name: Setup Go ${{ matrix.version }} ${{ matrix.architecture }}

View File

@ -1,114 +0,0 @@
name: Validate Windows installation
on:
push:
branches:
- main
paths-ignore:
- '**.md'
pull_request:
paths-ignore:
- '**.md'
jobs:
create-link-if-not-default:
runs-on: windows-latest
name: 'Validate if symlink is created'
strategy:
matrix:
cache: [false, true]
go: [1.20.1]
steps:
- uses: actions/checkout@v3
- name: 'Setup ${{ matrix.cache }}, cache: ${{ matrix.go }}'
uses: ./
with:
go-version: ${{ matrix.go }}
cache: ${{ matrix.cache }}
- name: 'Drive C: should have zero size link'
run: |
du -m -s 'C:\hostedtoolcache\windows\go\${{ matrix.go }}\x64'
# make sure drive c: contains only a link
size=$(du -m -s 'C:\hostedtoolcache\windows\go\${{ matrix.go }}\x64'|cut -f1 -d$'\t')
if [ $size -ne 0 ];then
echo 'Size of the link created on drive c: must be 0'
exit 1
fi
shell: bash
# Drive D: is small, take care the action does not eat up the space
- name: 'Drive D: space usage should be below 1G'
run: |
du -m -s 'D:\hostedtoolcache\windows\go\${{ matrix.go }}\x64'
size=$(du -m -s 'D:\hostedtoolcache\windows\go\${{ matrix.go }}\x64'|cut -f1 -d$'\t')
# make sure archive does not take lot of space
if [ $size -gt 999 ];then
echo 'Size of installed on drive d: go is too big';
exit 1
fi
shell: bash
# make sure the Go installation has not been changed to the end user
- name: Test paths and environments
run: |
echo $PATH
which go
go version
go env
if [ $(which go) != '/c/hostedtoolcache/windows/go/${{ matrix.go }}/x64/bin/go' ];then
echo 'which go should return "/c/hostedtoolcache/windows/go/${{ matrix.go }}/x64/bin/go"'
exit 1
fi
if [ $(go env GOROOT) != 'C:\hostedtoolcache\windows\go\${{ matrix.go }}\x64' ];then
echo 'go env GOROOT should return "C:\hostedtoolcache\windows\go\${{ matrix.go }}\x64"'
exit 1
fi
shell: bash
find-default-go:
name: 'Find default go version'
runs-on: windows-latest
outputs:
version: ${{ steps.goversion.outputs.version }}
steps:
- run: |
version=`go env GOVERSION|sed s/^go//`
echo "default go version: $version"
echo "version=$version" >> "$GITHUB_OUTPUT"
id: goversion
shell: bash
dont-create-link-if-default:
name: 'Validate if symlink is not created for default go'
runs-on: windows-latest
needs: find-default-go
strategy:
matrix:
cache: [false, true]
steps:
- uses: actions/checkout@v3
- name: 'Setup default go, cache: ${{ matrix.cache }}'
uses: ./
with:
go-version: ${{ needs.find-default-go.outputs.version }}
cache: ${{ matrix.cache }}
- name: 'Drive C: should have Go installation, cache: ${{ matrix.cache}}'
run: |
size=$(du -m -s 'C:\hostedtoolcache\windows\go\${{ needs.find-default-go.outputs.version }}\x64'|cut -f1 -d$'\t')
if [ $size -eq 0 ];then
echo 'Size of the hosted go installed on drive c: must be above zero'
exit 1
fi
shell: bash
- name: 'Drive D: should not have Go installation, cache: ${{ matrix.cache}}'
run: |
if [ -e 'D:\hostedtoolcache\windows\go\${{ needs.find-default-go.outputs.version }}\x64' ];then
echo 'D:\hostedtoolcache\windows\go\${{ needs.find-default-go.outputs.version }}\x64 should not exist for hosted version of go';
exit 1
fi
shell: bash

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
.licenses/npm/psl.dep.yml generated Normal file

Binary file not shown.

BIN
.licenses/npm/punycode.dep.yml generated Normal file

Binary file not shown.

Binary file not shown.

BIN
.licenses/npm/tough-cookie-3.0.1.dep.yml generated Normal file

Binary file not shown.

BIN
.licenses/npm/tough-cookie-4.0.0.dep.yml generated Normal file

Binary file not shown.

Binary file not shown.

BIN
.licenses/npm/universalify.dep.yml generated Normal file

Binary file not shown.

Binary file not shown.

View File

@ -1,7 +0,0 @@
# Ignore list
/*
# Do not ignore these folders:
!__tests__/
!.github/
!src/

View File

@ -1,11 +0,0 @@
// This is a reusable configuration file copied from https://github.com/actions/reusable-workflows/tree/main/reusable-configurations. Please don't make changes to this file as it's the subject of an automatic update.
module.exports = {
printWidth: 80,
tabWidth: 2,
useTabs: false,
semi: true,
singleQuote: true,
trailingComma: 'none',
bracketSpacing: false,
arrowParens: 'avoid'
};

11
.prettierrc.json Normal file
View File

@ -0,0 +1,11 @@
{
"printWidth": 80,
"tabWidth": 2,
"useTabs": false,
"semi": true,
"singleQuote": true,
"trailingComma": "none",
"bracketSpacing": false,
"arrowParens": "avoid",
"parser": "typescript"
}

149
README.md
View File

@ -8,16 +8,6 @@ This action sets up a go environment for use in actions by:
- Optionally downloading and caching a version of Go by version and adding to `PATH`.
- Registering problem matchers for error output.
# V4
The V4 edition of the action offers:
- Enabled caching by default
The action will try to enable caching unless the `cache` input is explicitly set to false.
Please see "[Caching dependency files and build outputs](https://github.com/actions/setup-go#caching-dependency-files-and-build-outputs)" for more information.
# V3
The V3 edition of the action offers:
@ -29,21 +19,16 @@ The V3 edition of the action offers:
- stable and oldstable aliases
- Bug Fixes (including issues around version matching and semver)
The action will first check the local cache for a version match. If a version is not found locally, it will pull it from
the `main` branch of the [go-versions](https://github.com/actions/go-versions/blob/main/versions-manifest.json)
repository. On miss or failure, it will fall back to downloading directly
from [go dist](https://storage.googleapis.com/golang). To change the default behavior, please use
the [check-latest input](#check-latest-version).
The action will first check the local cache for a version match. If a version is not found locally, it will pull it from the `main` branch of the [go-versions](https://github.com/actions/go-versions/blob/main/versions-manifest.json) repository. On miss or failure, it will fall back to downloading directly from [go dist](https://storage.googleapis.com/golang). To change the default behavior, please use the [check-latest input](#check-latest-version).
**Note:** The `setup-go` action uses executable binaries which are built by Golang side. The action does not build
golang from source code.
**Note:** The `setup-go` action uses executable binaries which are built by Golang side. The action does not build golang from source code.
Matching by [semver spec](https://github.com/npm/node-semver):
```yaml
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v4
- uses: actions/setup-go@v3
with:
go-version: '^1.13.1' # The Go version to download (if necessary) and use.
- run: go version
@ -52,25 +37,18 @@ steps:
```yaml
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v4
- uses: actions/setup-go@v3
with:
go-version: '>=1.17.0'
- run: go version
```
> **Note**: Due to the peculiarities of YAML parsing, it is recommended to wrap the version in single quotation marks:
>
> ```yaml
> go-version: '1.20'
> ```
>
> The recommendation is based on the YAML parser's behavior, which interprets non-wrapped values as numbers and, in the case of version 1.20, trims it down to 1.2, which may not be very obvious.
Matching an unstable pre-release:
```yaml
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v4
- uses: actions/setup-go@v3
with:
go-version: '1.18.0-rc.1' # The Go version to download (if necessary) and use.
- run: go version
@ -79,7 +57,7 @@ steps:
```yaml
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v4
- uses: actions/setup-go@v3
with:
go-version: '1.16.0-beta.1' # The Go version to download (if necessary) and use.
- run: go version
@ -94,28 +72,25 @@ See [action.yml](action.yml)
```yaml
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v4
- uses: actions/setup-go@v3
with:
go-version: '1.16.1' # The Go version to download (if necessary) and use.
- run: go run hello.go
```
## Check latest version
The `check-latest` flag defaults to `false`. Use the default or set `check-latest` to `false` if you prefer stability
and if you want to ensure a specific Go version is always used.
The `check-latest` flag defaults to `false`. Use the default or set `check-latest` to `false` if you prefer stability and if you want to ensure a specific Go version is always used.
If `check-latest` is set to `true`, the action first checks if the cached version is the latest one. If the locally
cached version is not the most up-to-date, a Go version will then be downloaded. Set `check-latest` to `true` if you
want the most up-to-date Go version to always be used.
If `check-latest` is set to `true`, the action first checks if the cached version is the latest one. If the locally cached version is not the most up-to-date, a Go version will then be downloaded. Set `check-latest` to `true` if you want the most up-to-date Go version to always be used.
> Setting `check-latest` to `true` has performance implications as downloading Go versions is slower than using cached
> versions.
> Setting `check-latest` to `true` has performance implications as downloading Go versions is slower than using cached versions.
```yaml
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v4
- uses: actions/setup-go@v3
with:
go-version: '1.14'
check-latest: true
@ -124,19 +99,16 @@ steps:
## Using stable/oldstable aliases
If `stable` is provided, action will get the latest stable version from
the [`go-versions`](https://github.com/actions/go-versions/blob/main/versions-manifest.json) repository manifest.
If `stable` is provided, action will get the latest stable version from the [`go-versions`](https://github.com/actions/go-versions/blob/main/versions-manifest.json) repository manifest.
If `oldstable` is provided, when current release is 1.19.x, action will resolve version as 1.18.x, where x is the latest
patch release.
If `oldstable` is provided, when current release is 1.19.x, action will resolve version as 1.18.x, where x is the latest patch release.
**Note:** using these aliases will result in same version as using corresponding minor release with `check-latest` input
set to `true`
**Note:** using these aliases will result in same version as using corresponding minor release with `check-latest` input set to `true`
```yaml
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v4
- uses: actions/setup-go@v3
with:
go-version: 'stable'
- run: go run hello.go
@ -145,7 +117,7 @@ steps:
```yaml
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v4
- uses: actions/setup-go@v3
with:
go-version: 'oldstable'
- run: go run hello.go
@ -153,25 +125,31 @@ steps:
## Caching dependency files and build outputs:
The action has a built-in functionality for caching and restoring go modules and build outputs. It
uses [toolkit/cache](https://github.com/actions/toolkit/tree/main/packages/cache) under the hood but requires less configuration settings.
The `cache` input is optional, and caching is turned on by default.
The action has a built-in functionality for caching and restoring go modules and build outputs. It uses [actions/cache](https://github.com/actions/cache) under the hood but requires less configuration settings. The `cache` input is optional, and caching is turned off by default.
The action defaults to search for the dependency file - go.sum in the repository root, and uses its hash as a part of
the cache key. Use `cache-dependency-path` input for cases when multiple dependency files are used, or they are located
in different subdirectories.
If some problem that prevents success caching happens then the action issues the warning in the log and continues the execution of the pipeline.
**Caching in monorepos**
The action defaults to search for the dependency file - go.sum in the repository root, and uses its hash as a part of the cache key. Use `cache-dependency-path` input for cases when multiple dependency files are used, or they are located in different subdirectories.
**Caching without specifying dependency file path**
```yaml
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v4
- uses: actions/setup-go@v3
with:
go-version: '1.17'
check-latest: true
cache: true
- run: go run hello.go
```
**Caching in monorepos**
```yaml
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v3
with:
go-version: '1.17'
check-latest: true
cache: true
cache-dependency-path: subdir/go.sum
- run: go run hello.go
```
@ -179,37 +157,21 @@ steps:
If both the `go-version` and the `go-version-file` inputs are provided then the `go-version` input is used.
If the file contains only major and minor (e.g. 1.18) tags, the action will search for the latest available patch version
sequentially in the runner's directory with the cached tools, in the [version-manifest.json](https://github.com/actions/go-versions/blob/main/versions-manifest.json)
file or at the go servers.
If the file contains only major and minor (e.g. 1.18) tags, the action will search for the latest available patch version sequentially in the runner's directory with the cached tools, in the [version-manifest.json](https://github.com/actions/go-versions/blob/main/versions-manifest.json) file or at the go servers.
### If the go.mod or .tool-versions files
### If the go.mod file
The `go-version-file` input accepts a path to a `go.mod` file, [.tool-versions](https://asdf-vm.com/manage/configuration.html#tool-versions) file or a `go.work` file that contains the version of Go to be used by a project.
As the `go.mod` file contains only major and minor (e.g. 1.18) tags, the action will follow the above-mentioned approach.
The `go-version-file` input accepts a path to a `go.mod` file or a `go.work` file that contains the version of Go to be used by a project. As the `go.mod` file contains only major and minor (e.g. 1.18) tags, the action will follow the above-mentioned approach.
> The action will search for the `go.mod` file relative to the repository root
```yaml
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v4
with:
go-version-file: 'path/to/go.mod'
- run: go version
```
The `go-version` output contains the resolved Golang version from the `go.mod` file.
> The action will search for the `.tool-versions` file relative to the repository root
```yaml
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v4
with:
go-version-file: '.tool-versions'
- run: go version
- uses: actions/checkout@v3
- uses: actions/setup-go@v3
with:
go-version-file: 'path/to/go.mod'
- run: go version
```
### If a different file
@ -240,7 +202,7 @@ jobs:
steps:
- uses: actions/checkout@v3
- name: Setup go
uses: actions/setup-go@v4
uses: actions/setup-go@v3
with:
go-version: ${{ matrix.go }}
- run: go run hello.go
@ -253,35 +215,22 @@ The `go-version` input supports the following syntax:
- Specific versions: `1.15`, `1.16.1`, `1.17.0-rc.2`, `1.16.0-beta.1`
- SemVer's version range syntax: `^1.13.1`, `>=1.18.0-rc.1`
For more information about semantic versioning, please refer to [semver](https://github.com/npm/node-semver)
documentation.
For more information about semantic versioning, please refer to [semver](https://github.com/npm/node-semver) documentation.
## Using `setup-go` on GHES
`setup-go` comes pre-installed on the appliance with GHES if Actions is enabled. When dynamically downloading Go
distributions, `setup-go` downloads distributions from [`actions/go-versions`](https://github.com/actions/go-versions)
on github.com (outside of the appliance). These calls to `actions/go-versions` are made via unauthenticated requests,
which are limited
to [60 requests per hour per IP](https://docs.github.com/en/rest/overview/resources-in-the-rest-api#rate-limiting). If
more requests are made within the time frame, then you will start to see rate-limit errors during downloading that looks
like: `##[error]API rate limit exceeded for...`. After that error the action will try to download versions directly
from https://storage.googleapis.com/golang, but it also can have rate limit so it's better to put token.
`setup-go` comes pre-installed on the appliance with GHES if Actions is enabled. When dynamically downloading Go distributions, `setup-go` downloads distributions from [`actions/go-versions`](https://github.com/actions/go-versions) on github.com (outside of the appliance). These calls to `actions/go-versions` are made via unauthenticated requests, which are limited to [60 requests per hour per IP](https://docs.github.com/en/rest/overview/resources-in-the-rest-api#rate-limiting). If more requests are made within the time frame, then you will start to see rate-limit errors during downloading that looks like: `##[error]API rate limit exceeded for...`. After that error the action will try to download versions directly from https://storage.googleapis.com/golang, but it also can have rate limit so it's better to put token.
To get a higher rate limit, you
can [generate a personal access token on github.com](https://github.com/settings/tokens/new) and pass it as the `token`
input for the action:
To get a higher rate limit, you can [generate a personal access token on github.com](https://github.com/settings/tokens/new) and pass it as the `token` input for the action:
```yaml
uses: actions/setup-go@v4
uses: actions/setup-go@v3
with:
token: ${{ secrets.GH_DOTCOM_TOKEN }}
go-version: '1.18'
go-version: 1.18
```
If the runner is not able to access github.com, any Go versions requested during a workflow run must come from the
runner's tool cache.
See "[Setting up the tool cache on self-hosted runners without internet access](https://docs.github.com/en/enterprise-server@3.2/admin/github-actions/managing-access-to-actions-from-githubcom/setting-up-the-tool-cache-on-self-hosted-runners-without-internet-access)"
for more information.
If the runner is not able to access github.com, any Go versions requested during a workflow run must come from the runner's tool cache. See "[Setting up the tool cache on self-hosted runners without internet access](https://docs.github.com/en/enterprise-server@3.2/admin/github-actions/managing-access-to-actions-from-githubcom/setting-up-the-tool-cache-on-self-hosted-runners-without-internet-access)" for more information.
# License

View File

@ -8,14 +8,14 @@ import {PackageManagerInfo} from '../src/package-managers';
describe('restoreCache', () => {
//Arrange
const hashFilesSpy = jest.spyOn(glob, 'hashFiles');
const getCacheDirectoryPathSpy = jest.spyOn(
let hashFilesSpy = jest.spyOn(glob, 'hashFiles');
let getCacheDirectoryPathSpy = jest.spyOn(
cacheUtils,
'getCacheDirectoryPath'
);
const restoreCacheSpy = jest.spyOn(cache, 'restoreCache');
const infoSpy = jest.spyOn(core, 'info');
const setOutputSpy = jest.spyOn(core, 'setOutput');
let restoreCacheSpy = jest.spyOn(cache, 'restoreCache');
let infoSpy = jest.spyOn(core, 'info');
let setOutputSpy = jest.spyOn(core, 'setOutput');
const versionSpec = '1.13.1';
const packageManager = 'default';
@ -40,13 +40,13 @@ describe('restoreCache', () => {
});
//Act + Assert
await expect(async () => {
expect(async () => {
await cacheRestore.restoreCache(
versionSpec,
packageManager,
cacheDependencyPath
);
}).rejects.toThrow(
}).rejects.toThrowError(
'Some specified paths were not resolved, unable to cache dependencies.'
);
});
@ -71,7 +71,7 @@ describe('restoreCache', () => {
packageManager,
cacheDependencyPath
);
expect(infoSpy).toHaveBeenCalledWith(`Cache is not found`);
expect(infoSpy).toBeCalledWith(`Cache is not found`);
});
it('should set output if cache hit is occured', async () => {
@ -94,6 +94,6 @@ describe('restoreCache', () => {
packageManager,
cacheDependencyPath
);
expect(setOutputSpy).toHaveBeenCalledWith('cache-hit', true);
expect(setOutputSpy).toBeCalledWith('cache-hit', true);
});
});

View File

@ -6,7 +6,7 @@ import {PackageManagerInfo} from '../src/package-managers';
describe('getCommandOutput', () => {
//Arrange
const getExecOutputSpy = jest.spyOn(exec, 'getExecOutput');
let getExecOutputSpy = jest.spyOn(exec, 'getExecOutput');
it('should return trimmed stdout in case of successful exit code', async () => {
//Arrange
@ -36,7 +36,7 @@ describe('getCommandOutput', () => {
});
//Act + Assert
await expect(async () => {
expect(async () => {
await cacheUtils.getCommandOutput('command');
}).rejects.toThrow();
});
@ -62,7 +62,7 @@ describe('getPackageManagerInfo', () => {
const packageManagerName = 'invalidName';
//Act + Assert
await expect(async () => {
expect(async () => {
await cacheUtils.getPackageManagerInfo(packageManagerName);
}).rejects.toThrow();
});
@ -70,7 +70,7 @@ describe('getPackageManagerInfo', () => {
describe('getCacheDirectoryPath', () => {
//Arrange
const getExecOutputSpy = jest.spyOn(exec, 'getExecOutput');
let getExecOutputSpy = jest.spyOn(exec, 'getExecOutput');
const validPackageManager: PackageManagerInfo = {
dependencyFilePattern: 'go.sum',
@ -123,7 +123,7 @@ describe('getCacheDirectoryPath', () => {
});
//Act + Assert
await expect(async () => {
expect(async () => {
await cacheUtils.getCacheDirectoryPath(validPackageManager);
}).rejects.toThrow();
});
@ -136,7 +136,7 @@ describe('getCacheDirectoryPath', () => {
});
//Act + Assert
await expect(async () => {
expect(async () => {
await cacheUtils.getCacheDirectoryPath(validPackageManager);
}).rejects.toThrow();
});
@ -144,8 +144,8 @@ describe('getCacheDirectoryPath', () => {
describe('isCacheFeatureAvailable', () => {
//Arrange
const isFeatureAvailableSpy = jest.spyOn(cache, 'isFeatureAvailable');
const warningSpy = jest.spyOn(core, 'warning');
let isFeatureAvailableSpy = jest.spyOn(cache, 'isFeatureAvailable');
let warningSpy = jest.spyOn(core, 'warning');
it('should return true when cache feature is available', () => {
//Arrange
@ -153,14 +153,16 @@ describe('isCacheFeatureAvailable', () => {
return true;
});
let functionResult;
//Act
const functionResult = cacheUtils.isCacheFeatureAvailable();
functionResult = cacheUtils.isCacheFeatureAvailable();
//Assert
expect(functionResult).toBeTruthy();
});
it('should warn when cache feature is unavailable and GHES is not used', () => {
it('should warn when cache feature is unavailable and GHES is not used ', () => {
//Arrange
isFeatureAvailableSpy.mockImplementation(() => {
return false;
@ -168,7 +170,7 @@ describe('isCacheFeatureAvailable', () => {
process.env['GITHUB_SERVER_URL'] = 'https://github.com';
const warningMessage =
let warningMessage =
'The runner was not able to contact the cache service. Caching will be skipped';
//Act
@ -186,8 +188,10 @@ describe('isCacheFeatureAvailable', () => {
process.env['GITHUB_SERVER_URL'] = 'https://github.com';
let functionResult;
//Act
const functionResult = cacheUtils.isCacheFeatureAvailable();
functionResult = cacheUtils.isCacheFeatureAvailable();
//Assert
expect(functionResult).toBeFalsy();
@ -201,7 +205,7 @@ describe('isCacheFeatureAvailable', () => {
process.env['GITHUB_SERVER_URL'] = 'https://nongithub.com';
const warningMessage =
let warningMessage =
'Cache action is only supported on GHES version >= 3.5. If you are on version >=3.5 Please check with GHES admin if Actions cache service is enabled or not.';
//Act + Assert

View File

@ -3,20 +3,18 @@ import * as io from '@actions/io';
import * as tc from '@actions/tool-cache';
import fs from 'fs';
import cp from 'child_process';
import osm, {type} from 'os';
import osm from 'os';
import path from 'path';
import * as main from '../src/main';
import * as im from '../src/installer';
import goJsonData from './data/golang-dl.json';
import matchers from '../matchers.json';
import goTestManifest from './data/versions-manifest.json';
const matcherPattern = matchers.problemMatcher[0].pattern[0];
const matcherRegExp = new RegExp(matcherPattern.regexp);
const win32Join = path.win32.join;
const posixJoin = path.posix.join;
jest.setTimeout(10000);
let goJsonData = require('./data/golang-dl.json');
let matchers = require('../matchers.json');
let goTestManifest = require('./data/versions-manifest.json');
let matcherPattern = matchers.problemMatcher[0].pattern[0];
let matcherRegExp = new RegExp(matcherPattern.regexp);
let win32Join = path.win32.join;
let posixJoin = path.posix.join;
describe('setup-go', () => {
let inputs = {} as any;
@ -41,8 +39,6 @@ describe('setup-go', () => {
let existsSpy: jest.SpyInstance;
let readFileSpy: jest.SpyInstance;
let mkdirpSpy: jest.SpyInstance;
let mkdirSpy: jest.SpyInstance;
let symlinkSpy: jest.SpyInstance;
let execSpy: jest.SpyInstance;
let getManifestSpy: jest.SpyInstance;
let getAllVersionsSpy: jest.SpyInstance;
@ -96,11 +92,6 @@ describe('setup-go', () => {
readFileSpy = jest.spyOn(fs, 'readFileSync');
mkdirpSpy = jest.spyOn(io, 'mkdirP');
// fs
mkdirSpy = jest.spyOn(fs, 'mkdir');
symlinkSpy = jest.spyOn(fs, 'symlinkSync');
symlinkSpy.mockImplementation(() => {});
// gets
getManifestSpy.mockImplementation(() => <tc.IToolRelease[]>goTestManifest);
@ -142,7 +133,7 @@ describe('setup-go', () => {
os.platform = 'darwin';
os.arch = 'x64';
const match = await im.getInfoFromManifest('1.9.7', true, 'mocktoken');
let match = await im.getInfoFromManifest('1.9.7', true, 'mocktoken');
expect(match).toBeDefined();
expect(match!.resolvedVersion).toBe('1.9.7');
expect(match!.type).toBe('manifest');
@ -155,7 +146,7 @@ describe('setup-go', () => {
os.platform = 'linux';
os.arch = 'x64';
const match = await im.getInfoFromManifest('1.9.7', true, 'mocktoken');
let match = await im.getInfoFromManifest('1.9.7', true, 'mocktoken');
expect(match).toBeDefined();
expect(match!.resolvedVersion).toBe('1.9.7');
expect(match!.type).toBe('manifest');
@ -168,7 +159,7 @@ describe('setup-go', () => {
os.platform = 'win32';
os.arch = 'x64';
const match = await im.getInfoFromManifest('1.9.7', true, 'mocktoken');
let match = await im.getInfoFromManifest('1.9.7', true, 'mocktoken');
expect(match).toBeDefined();
expect(match!.resolvedVersion).toBe('1.9.7');
expect(match!.type).toBe('manifest');
@ -182,11 +173,11 @@ describe('setup-go', () => {
os.arch = 'x64';
// spec: 1.13.0 => 1.13
const match: im.IGoVersion | undefined = await im.findMatch('1.13.0');
let match: im.IGoVersion | undefined = await im.findMatch('1.13.0');
expect(match).toBeDefined();
const version: string = match ? match.version : '';
let version: string = match ? match.version : '';
expect(version).toBe('go1.13');
const fileName = match ? match.files[0].filename : '';
let fileName = match ? match.files[0].filename : '';
expect(fileName).toBe('go1.13.darwin-amd64.tar.gz');
});
@ -195,11 +186,11 @@ describe('setup-go', () => {
os.arch = 'x64';
// spec: 1.13 => 1.13.7 (latest)
const match: im.IGoVersion | undefined = await im.findMatch('1.13');
let match: im.IGoVersion | undefined = await im.findMatch('1.13');
expect(match).toBeDefined();
const version: string = match ? match.version : '';
let version: string = match ? match.version : '';
expect(version).toBe('go1.13.7');
const fileName = match ? match.files[0].filename : '';
let fileName = match ? match.files[0].filename : '';
expect(fileName).toBe('go1.13.7.linux-amd64.tar.gz');
});
@ -208,11 +199,11 @@ describe('setup-go', () => {
os.arch = 'x64';
// spec: ^1.13.6 => 1.13.7
const match: im.IGoVersion | undefined = await im.findMatch('^1.13.6');
let match: im.IGoVersion | undefined = await im.findMatch('^1.13.6');
expect(match).toBeDefined();
const version: string = match ? match.version : '';
let version: string = match ? match.version : '';
expect(version).toBe('go1.13.7');
const fileName = match ? match.files[0].filename : '';
let fileName = match ? match.files[0].filename : '';
expect(fileName).toBe('go1.13.7.linux-amd64.tar.gz');
});
@ -221,11 +212,11 @@ describe('setup-go', () => {
os.arch = 'x32';
// spec: 1 => 1.13.7 (latest)
const match: im.IGoVersion | undefined = await im.findMatch('1');
let match: im.IGoVersion | undefined = await im.findMatch('1');
expect(match).toBeDefined();
const version: string = match ? match.version : '';
let version: string = match ? match.version : '';
expect(version).toBe('go1.13.7');
const fileName = match ? match.files[0].filename : '';
let fileName = match ? match.files[0].filename : '';
expect(fileName).toBe('go1.13.7.windows-386.zip');
});
@ -234,11 +225,11 @@ describe('setup-go', () => {
os.arch = 'x64';
// spec: 1.14, stable=false => go1.14rc1
const match: im.IGoVersion | undefined = await im.findMatch('1.14.0-rc.1');
let match: im.IGoVersion | undefined = await im.findMatch('1.14.0-rc.1');
expect(match).toBeDefined();
const version: string = match ? match.version : '';
let version: string = match ? match.version : '';
expect(version).toBe('go1.14rc1');
const fileName = match ? match.files[0].filename : '';
let fileName = match ? match.files[0].filename : '';
expect(fileName).toBe('go1.14rc1.linux-amd64.tar.gz');
});
@ -246,7 +237,7 @@ describe('setup-go', () => {
inputs['go-version'] = '1.13.0';
inputs.stable = 'true';
const toolPath = path.normalize('/cache/go/1.13.0/x64');
let toolPath = path.normalize('/cache/go/1.13.0/x64');
findSpy.mockImplementation(() => toolPath);
await main.run();
@ -258,7 +249,7 @@ describe('setup-go', () => {
inSpy.mockImplementation(name => inputs[name]);
const toolPath = path.normalize('/cache/go/1.13.0/x64');
let toolPath = path.normalize('/cache/go/1.13.0/x64');
findSpy.mockImplementation(() => toolPath);
await main.run();
@ -269,10 +260,10 @@ describe('setup-go', () => {
inputs['go-version'] = '1.13.0';
inSpy.mockImplementation(name => inputs[name]);
const toolPath = path.normalize('/cache/go/1.13.0/x64');
let toolPath = path.normalize('/cache/go/1.13.0/x64');
findSpy.mockImplementation(() => toolPath);
const vars: {[key: string]: string} = {};
let vars: {[key: string]: string} = {};
exportVarSpy.mockImplementation((name: string, val: string) => {
vars[name] = val;
});
@ -285,10 +276,10 @@ describe('setup-go', () => {
inputs['go-version'] = '1.8';
inSpy.mockImplementation(name => inputs[name]);
const toolPath = path.normalize('/cache/go/1.8.0/x64');
let toolPath = path.normalize('/cache/go/1.8.0/x64');
findSpy.mockImplementation(() => toolPath);
const vars: {[key: string]: string} = {};
let vars: {[key: string]: string} = {};
exportVarSpy.mockImplementation((name: string, val: string) => {
vars[name] = val;
});
@ -302,7 +293,7 @@ describe('setup-go', () => {
it('finds a version of go already in the cache', async () => {
inputs['go-version'] = '1.13.0';
const toolPath = path.normalize('/cache/go/1.13.0/x64');
let toolPath = path.normalize('/cache/go/1.13.0/x64');
findSpy.mockImplementation(() => toolPath);
await main.run();
@ -311,16 +302,16 @@ describe('setup-go', () => {
it('finds a version in the cache and adds it to the path', async () => {
inputs['go-version'] = '1.13.0';
const toolPath = path.normalize('/cache/go/1.13.0/x64');
let toolPath = path.normalize('/cache/go/1.13.0/x64');
findSpy.mockImplementation(() => toolPath);
await main.run();
const expPath = path.join(toolPath, 'bin');
let expPath = path.join(toolPath, 'bin');
expect(cnSpy).toHaveBeenCalledWith(`::add-path::${expPath}${osm.EOL}`);
});
it('handles unhandled error and reports error', async () => {
const errMsg = 'unhandled error message';
let errMsg = 'unhandled error message';
inputs['go-version'] = '1.13.0';
findSpy.mockImplementation(() => {
@ -338,12 +329,12 @@ describe('setup-go', () => {
findSpy.mockImplementation(() => '');
dlSpy.mockImplementation(() => '/some/temp/path');
const toolPath = path.normalize('/cache/go/1.13.0/x64');
let toolPath = path.normalize('/cache/go/1.13.0/x64');
extractTarSpy.mockImplementation(() => '/some/other/temp/path');
cacheSpy.mockImplementation(() => toolPath);
await main.run();
const expPath = path.join(toolPath, 'bin');
let expPath = path.join(toolPath, 'bin');
expect(dlSpy).toHaveBeenCalled();
expect(extractTarSpy).toHaveBeenCalled();
@ -361,12 +352,12 @@ describe('setup-go', () => {
dlSpy.mockImplementation(() => 'C:\\temp\\some\\path');
extractZipSpy.mockImplementation(() => 'C:\\temp\\some\\other\\path');
const toolPath = path.normalize('C:\\cache\\go\\1.13.0\\x64');
let toolPath = path.normalize('C:\\cache\\go\\1.13.0\\x64');
cacheSpy.mockImplementation(() => toolPath);
await main.run();
const expPath = path.win32.join(toolPath, 'bin');
let expPath = path.win32.join(toolPath, 'bin');
expect(dlSpy).toHaveBeenCalledWith(
'https://storage.googleapis.com/golang/go1.13.1.windows-amd64.zip',
'C:\\temp\\go1.13.1.windows-amd64.zip',
@ -393,25 +384,25 @@ describe('setup-go', () => {
os.platform = 'linux';
os.arch = 'x64';
const versionSpec = '1.12.16';
let versionSpec = '1.12.16';
inputs['go-version'] = versionSpec;
inputs['token'] = 'faketoken';
const expectedUrl =
let expectedUrl =
'https://github.com/actions/go-versions/releases/download/1.12.16-20200616.20/go-1.12.16-linux-x64.tar.gz';
// ... but not in the local cache
findSpy.mockImplementation(() => '');
dlSpy.mockImplementation(async () => '/some/temp/path');
const toolPath = path.normalize('/cache/go/1.12.16/x64');
let toolPath = path.normalize('/cache/go/1.12.16/x64');
extractTarSpy.mockImplementation(async () => '/some/other/temp/path');
cacheSpy.mockImplementation(async () => toolPath);
await main.run();
const expPath = path.join(toolPath, 'bin');
let expPath = path.join(toolPath, 'bin');
expect(dlSpy).toHaveBeenCalled();
expect(extractTarSpy).toHaveBeenCalled();
@ -430,25 +421,25 @@ describe('setup-go', () => {
os.platform = 'linux';
os.arch = 'x64';
const versionSpec = '1.12';
let versionSpec = '1.12';
inputs['go-version'] = versionSpec;
inputs['token'] = 'faketoken';
const expectedUrl =
let expectedUrl =
'https://github.com/actions/go-versions/releases/download/1.12.17-20200616.21/go-1.12.17-linux-x64.tar.gz';
// ... but not in the local cache
findSpy.mockImplementation(() => '');
dlSpy.mockImplementation(async () => '/some/temp/path');
const toolPath = path.normalize('/cache/go/1.12.17/x64');
let toolPath = path.normalize('/cache/go/1.12.17/x64');
extractTarSpy.mockImplementation(async () => '/some/other/temp/path');
cacheSpy.mockImplementation(async () => toolPath);
await main.run();
const expPath = path.join(toolPath, 'bin');
let expPath = path.join(toolPath, 'bin');
expect(dlSpy).toHaveBeenCalled();
expect(extractTarSpy).toHaveBeenCalled();
@ -467,7 +458,7 @@ describe('setup-go', () => {
os.platform = 'linux';
os.arch = 'x64';
const versionSpec = '1.12.14';
let versionSpec = '1.12.14';
inputs['go-version'] = versionSpec;
inputs['token'] = 'faketoken';
@ -476,13 +467,13 @@ describe('setup-go', () => {
findSpy.mockImplementation(() => '');
dlSpy.mockImplementation(async () => '/some/temp/path');
const toolPath = path.normalize('/cache/go/1.12.14/x64');
let toolPath = path.normalize('/cache/go/1.12.14/x64');
extractTarSpy.mockImplementation(async () => '/some/other/temp/path');
cacheSpy.mockImplementation(async () => toolPath);
await main.run();
const expPath = path.join(toolPath, 'bin');
let expPath = path.join(toolPath, 'bin');
expect(logSpy).toHaveBeenCalledWith('Setup go version spec 1.12.14');
expect(findSpy).toHaveBeenCalled();
expect(logSpy).toHaveBeenCalledWith('Attempting to download 1.12.14...');
@ -498,7 +489,7 @@ describe('setup-go', () => {
});
it('reports a failed download', async () => {
const errMsg = 'unhandled download message';
let errMsg = 'unhandled download message';
os.platform = 'linux';
os.arch = 'x64';
@ -519,7 +510,7 @@ describe('setup-go', () => {
whichSpy.mockImplementation(async () => {
return '';
});
const added = await main.addBinToPath();
let added = await main.addBinToPath();
expect(added).toBeFalsy();
});
@ -537,8 +528,8 @@ describe('setup-go', () => {
return false;
});
const added = await main.addBinToPath();
expect(added).toBeTruthy();
let added = await main.addBinToPath();
expect(added).toBeTruthy;
});
interface Annotation {
@ -552,9 +543,9 @@ describe('setup-go', () => {
// problem matcher regex pattern tests
function testMatch(line: string): Annotation {
const annotation = <Annotation>{};
let annotation = <Annotation>{};
const match = matcherRegExp.exec(line);
let match = matcherRegExp.exec(line);
if (match) {
annotation.line = parseInt(match[matcherPattern.line], 10);
annotation.column = parseInt(match[matcherPattern.column], 10);
@ -566,8 +557,8 @@ describe('setup-go', () => {
}
it('matches on relative unix path', async () => {
const line = './main.go:13:2: undefined: fmt.Printl';
const annotation = testMatch(line);
let line = './main.go:13:2: undefined: fmt.Printl';
let annotation = testMatch(line);
expect(annotation).toBeDefined();
expect(annotation.line).toBe(13);
expect(annotation.column).toBe(2);
@ -576,8 +567,8 @@ describe('setup-go', () => {
});
it('matches on unix path up the tree', async () => {
const line = '../main.go:13:2: undefined: fmt.Printl';
const annotation = testMatch(line);
let line = '../main.go:13:2: undefined: fmt.Printl';
let annotation = testMatch(line);
expect(annotation).toBeDefined();
expect(annotation.line).toBe(13);
expect(annotation.column).toBe(2);
@ -586,8 +577,8 @@ describe('setup-go', () => {
});
it('matches on unix path down the tree', async () => {
const line = 'foo/main.go:13:2: undefined: fmt.Printl';
const annotation = testMatch(line);
let line = 'foo/main.go:13:2: undefined: fmt.Printl';
let annotation = testMatch(line);
expect(annotation).toBeDefined();
expect(annotation.line).toBe(13);
expect(annotation.column).toBe(2);
@ -596,8 +587,8 @@ describe('setup-go', () => {
});
it('matches on rooted unix path', async () => {
const line = '/assert.go:4:1: missing return at end of function';
const annotation = testMatch(line);
let line = '/assert.go:4:1: missing return at end of function';
let annotation = testMatch(line);
expect(annotation).toBeDefined();
expect(annotation.line).toBe(4);
expect(annotation.column).toBe(1);
@ -606,8 +597,8 @@ describe('setup-go', () => {
});
it('matches on unix path with spaces', async () => {
const line = ' ./assert.go:5:2: missing return at end of function ';
const annotation = testMatch(line);
let line = ' ./assert.go:5:2: missing return at end of function ';
let annotation = testMatch(line);
expect(annotation).toBeDefined();
expect(annotation.line).toBe(5);
expect(annotation.column).toBe(2);
@ -616,8 +607,8 @@ describe('setup-go', () => {
});
it('matches on unix path with tabs', async () => {
const line = '\t./assert.go:5:2: missing return at end of function ';
const annotation = testMatch(line);
let line = '\t./assert.go:5:2: missing return at end of function ';
let annotation = testMatch(line);
expect(annotation).toBeDefined();
expect(annotation.line).toBe(5);
expect(annotation.column).toBe(2);
@ -626,8 +617,8 @@ describe('setup-go', () => {
});
it('matches on relative windows path', async () => {
const line = '.\\main.go:13:2: undefined: fmt.Printl';
const annotation = testMatch(line);
let line = '.\\main.go:13:2: undefined: fmt.Printl';
let annotation = testMatch(line);
expect(annotation).toBeDefined();
expect(annotation.line).toBe(13);
expect(annotation.column).toBe(2);
@ -636,8 +627,8 @@ describe('setup-go', () => {
});
it('matches on windows path up the tree', async () => {
const line = '..\\main.go:13:2: undefined: fmt.Printl';
const annotation = testMatch(line);
let line = '..\\main.go:13:2: undefined: fmt.Printl';
let annotation = testMatch(line);
expect(annotation).toBeDefined();
expect(annotation.line).toBe(13);
expect(annotation.column).toBe(2);
@ -739,7 +730,7 @@ describe('setup-go', () => {
os.platform = 'linux';
os.arch = 'x64';
const versionSpec = '1.13';
let versionSpec = '1.13';
inputs['go-version'] = versionSpec;
inputs['check-latest'] = true;
@ -750,13 +741,13 @@ describe('setup-go', () => {
findSpy.mockImplementation(() => '');
dlSpy.mockImplementation(async () => '/some/temp/path');
const toolPath = path.normalize('/cache/go/1.13.7/x64');
let toolPath = path.normalize('/cache/go/1.13.7/x64');
extractTarSpy.mockImplementation(async () => '/some/other/temp/path');
cacheSpy.mockImplementation(async () => toolPath);
await main.run();
const expPath = path.join(toolPath, 'bin');
let expPath = path.join(toolPath, 'bin');
expect(dlSpy).toHaveBeenCalled();
expect(extractTarSpy).toHaveBeenCalled();
@ -776,7 +767,7 @@ describe('setup-go', () => {
os.platform = 'linux';
os.arch = 'x64';
const versionSpec = '1.13';
let versionSpec = '1.13';
process.env['GITHUB_PATH'] = '';
@ -793,13 +784,13 @@ describe('setup-go', () => {
getAllVersionsSpy.mockImplementationOnce(() => undefined);
dlSpy.mockImplementation(async () => '/some/temp/path');
const toolPath = path.normalize('/cache/go/1.13.7/x64');
let toolPath = path.normalize('/cache/go/1.13.7/x64');
extractTarSpy.mockImplementation(async () => '/some/other/temp/path');
cacheSpy.mockImplementation(async () => toolPath);
await main.run();
const expPath = path.join(toolPath, 'bin');
let expPath = path.join(toolPath, 'bin');
expect(logSpy).toHaveBeenCalledWith(
`Failed to resolve version ${versionSpec} from manifest`
@ -919,7 +910,7 @@ use .
inputs['go-version'] = version;
inputs['architecture'] = arch;
const expectedUrl =
let expectedUrl =
platform === 'win32'
? `https://github.com/actions/go-versions/releases/download/${version}/go-${version}-${platform}-${arch}.${fileExtension}`
: `https://storage.googleapis.com/golang/go${version}.${osSpec}-${arch}.${fileExtension}`;
@ -928,7 +919,7 @@ use .
findSpy.mockImplementation(() => '');
dlSpy.mockImplementation(async () => '/some/temp/path');
const toolPath = path.normalize(`/cache/go/${version}/${arch}`);
let toolPath = path.normalize(`/cache/go/${version}/${arch}`);
cacheSpy.mockImplementation(async () => toolPath);
await main.run();
@ -953,7 +944,7 @@ use .
findSpy.mockImplementation(() => '');
dlSpy.mockImplementation(async () => '/some/temp/path');
const toolPath = path.normalize(`/cache/go/${alias}/${arch}`);
let toolPath = path.normalize(`/cache/go/${alias}/${arch}`);
cacheSpy.mockImplementation(async () => toolPath);
await main.run();

View File

@ -1,62 +0,0 @@
import fs from 'fs';
import * as io from '@actions/io';
import * as tc from '@actions/tool-cache';
import path from 'path';
describe('Windows performance workaround', () => {
let mkdirSpy: jest.SpyInstance;
let symlinkSpy: jest.SpyInstance;
let statSpy: jest.SpyInstance;
let readdirSpy: jest.SpyInstance;
let writeFileSpy: jest.SpyInstance;
let rmRFSpy: jest.SpyInstance;
let mkdirPSpy: jest.SpyInstance;
let cpSpy: jest.SpyInstance;
let runnerToolCache: string | undefined;
beforeEach(() => {
mkdirSpy = jest.spyOn(fs, 'mkdir');
symlinkSpy = jest.spyOn(fs, 'symlinkSync');
statSpy = jest.spyOn(fs, 'statSync');
readdirSpy = jest.spyOn(fs, 'readdirSync');
writeFileSpy = jest.spyOn(fs, 'writeFileSync');
rmRFSpy = jest.spyOn(io, 'rmRF');
mkdirPSpy = jest.spyOn(io, 'mkdirP');
cpSpy = jest.spyOn(io, 'cp');
// default implementations
// @ts-ignore - not implement unused methods
statSpy.mockImplementation(() => ({
isDirectory: () => true
}));
readdirSpy.mockImplementation(() => []);
writeFileSpy.mockImplementation(() => {});
mkdirSpy.mockImplementation(() => {});
symlinkSpy.mockImplementation(() => {});
rmRFSpy.mockImplementation(() => Promise.resolve());
mkdirPSpy.mockImplementation(() => Promise.resolve());
cpSpy.mockImplementation(() => Promise.resolve());
runnerToolCache = process.env['RUNNER_TOOL_CACHE'];
});
afterEach(() => {
jest.clearAllMocks();
process.env['RUNNER_TOOL_CACHE'] = runnerToolCache;
});
// cacheWindowsToolkitDir depends on implementation of tc.cacheDir
// with the assumption that target dir is passed by RUNNER_TOOL_CACHE environment variable
// Make sure the implementation has not been changed
it('addExecutablesToCache should depend on env[RUNNER_TOOL_CACHE]', async () => {
process.env['RUNNER_TOOL_CACHE'] = '/faked-hostedtoolcache1';
const cacheDir1 = await tc.cacheDir('/qzx', 'go', '1.2.3', 'arch');
expect(cacheDir1).toBe(
path.join('/', 'faked-hostedtoolcache1', 'go', '1.2.3', 'arch')
);
process.env['RUNNER_TOOL_CACHE'] = '/faked-hostedtoolcache2';
const cacheDir2 = await tc.cacheDir('/qzx', 'go', '1.2.3', 'arch');
expect(cacheDir2).toBe(
path.join('/', 'faked-hostedtoolcache2', 'go', '1.2.3', 'arch')
);
});
});

View File

@ -3,18 +3,18 @@ description: 'Setup a Go environment and add it to the PATH'
author: 'GitHub'
inputs:
go-version:
description: 'The Go version to download (if necessary) and use. Supports semver spec and ranges. Be sure to enclose this option in single quotation marks.'
description: 'The Go version to download (if necessary) and use. Supports semver spec and ranges.'
go-version-file:
description: 'Path to the go.mod or go.work file.'
check-latest:
description: 'Set this option to true if you want the action to always check for the latest available version that satisfies the version spec'
default: false
token:
description: Used to pull Go distributions from go-versions. Since there's a default, this is typically not supplied by the user. When running this action on github.com, the default value is sufficient. When running on GHES, you can pass a personal access token for github.com if you are experiencing rate limiting.
description: Used to pull node distributions from go-versions. Since there's a default, this is typically not supplied by the user. When running this action on github.com, the default value is sufficient. When running on GHES, you can pass a personal access token for github.com if you are experiencing rate limiting.
default: ${{ github.server_url == 'https://github.com' && github.token || '' }}
cache:
description: Used to specify whether caching is needed. Set to true, if you'd like to enable caching.
default: true
default: false
cache-dependency-path:
description: 'Used to specify the path to a dependency file - go.sum'
architecture:

5112
dist/cache-save/index.js vendored

File diff suppressed because one or more lines are too long

5230
dist/setup/index.js vendored

File diff suppressed because one or more lines are too long

View File

@ -52,7 +52,7 @@ Pull requests are the easiest way to contribute changes to git repos at GitHub.
- Please check that no one else has already created a pull request with these changes
- Use a "feature branch" for your changes. That separates the changes in the pull request from your other changes and makes it easy to edit/amend commits in the pull request
- **Run `pre-checkin` script to format, lint, build and test changes**
- **Run `pre-checkin` script to format, build and test changes**
- Make sure your changes are well formatted and that all tests are passing
- If your pull request is connected to an open issue, please, leave a link to this issue in the `Related issue:` section
- If you later need to add new commits to the pull request, you can simply commit the changes to the local branch and then push them. The pull request gets automatically updated
@ -61,7 +61,6 @@ Pull requests are the easiest way to contribute changes to git repos at GitHub.
- To implement new features or fix bugs, you need to make changes to the `.ts` files, which are located in the `src` folder
- To comply with the code style, **you need to run the `format` script**
- To lint the code, **you need to run the `lint:fix` script**
- To transpile source code to `javascript` we use [NCC](https://github.com/vercel/ncc). **It is very important to run the `build` script after making changes**, otherwise your changes will not get into the final `javascript` build
- You can also start formatting, building code, and testing with a single `pre-checkin` command

2700
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,17 +1,16 @@
{
"name": "setup-go",
"version": "4.0.0",
"version": "3.3.0",
"private": true,
"description": "setup go action",
"main": "lib/setup-go.js",
"scripts": {
"build": "tsc && ncc build -o dist/setup src/setup-go.ts && ncc build -o dist/cache-save src/cache-save.ts",
"format": "prettier --no-error-on-unmatched-pattern --config ./.prettierrc.js --write \"**/*.{ts,yml,yaml}\"",
"format-check": "prettier --no-error-on-unmatched-pattern --config ./.prettierrc.js --check \"**/*.{ts,yml,yaml}\"",
"lint": "eslint --config ./.eslintrc.js \"**/*.ts\"",
"lint:fix": "eslint --config ./.eslintrc.js \"**/*.ts\" --fix",
"format": "prettier --write **/*.ts",
"format-check": "prettier --check **/*.ts",
"lint": "echo \"Fake command that does nothing. It is used in reusable workflows\"",
"test": "jest --coverage",
"pre-checkin": "npm run format && npm run lint:fix && npm run build && npm test"
"pre-checkin": "npm run format && npm run build && npm test"
},
"repository": {
"type": "git",
@ -25,30 +24,24 @@
"author": "GitHub",
"license": "MIT",
"dependencies": {
"@actions/cache": "^3.2.1",
"@actions/cache": "^3.0.0",
"@actions/core": "^1.10.0",
"@actions/exec": "^1.1.0",
"@actions/glob": "^0.2.0",
"@actions/http-client": "^2.0.1",
"@actions/io": "^1.0.2",
"@actions/tool-cache": "^1.5.5",
"semver": "^6.3.1"
"semver": "^6.1.1"
},
"devDependencies": {
"@types/jest": "^27.0.2",
"@types/node": "^16.11.25",
"@types/semver": "^6.0.0",
"@typescript-eslint/eslint-plugin": "^5.54.0",
"@typescript-eslint/parser": "^5.54.0",
"@vercel/ncc": "^0.33.4",
"eslint": "^8.35.0",
"eslint-config-prettier": "^8.6.0",
"eslint-plugin-jest": "^27.2.1",
"eslint-plugin-node": "^11.1.0",
"jest": "^27.2.5",
"jest-circus": "^27.2.5",
"nock": "^10.0.6",
"prettier": "^2.8.4",
"prettier": "^1.17.1",
"ts-jest": "^27.0.5",
"typescript": "^4.3.3"
}

View File

@ -29,9 +29,7 @@ export const restoreCache = async (
);
}
const linuxVersion =
process.env.RUNNER_OS === 'Linux' ? `${process.env.ImageOS}-` : '';
const primaryKey = `setup-go-${platform}-${linuxVersion}go-${versionSpec}-${fileHash}`;
const primaryKey = `setup-go-${platform}-go-${versionSpec}-${fileHash}`;
core.debug(`primary key is ${primaryKey}`);
core.saveState(State.CachePrimaryKey, primaryKey);
@ -50,7 +48,7 @@ export const restoreCache = async (
};
const findDependencyFile = (packageManager: PackageManagerInfo) => {
const dependencyFile = packageManager.dependencyFilePattern;
let dependencyFile = packageManager.dependencyFilePattern;
const workspace = process.env.GITHUB_WORKSPACE!;
const rootContent = fs.readdirSync(workspace);

View File

@ -23,7 +23,7 @@ export async function run() {
if (typeof error === 'string') {
message = error;
}
core.warning(message);
core.setFailed(message);
}
}
@ -59,13 +59,6 @@ const cachePackages = async () => {
);
}
if (!primaryKey) {
core.info(
'Primary key was not generated. Please check the log messages above for more errors or information'
);
return;
}
if (primaryKey === state) {
core.info(
`Cache hit occurred on the primary key ${primaryKey}, not saving cache.`

View File

@ -34,23 +34,13 @@ export const getPackageManagerInfo = async (packageManager: string) => {
export const getCacheDirectoryPath = async (
packageManagerInfo: PackageManagerInfo
) => {
const pathOutputs = await Promise.allSettled(
packageManagerInfo.cacheFolderCommandList.map(async command =>
const pathList = await Promise.all(
packageManagerInfo.cacheFolderCommandList.map(command =>
getCommandOutput(command)
)
);
const results = pathOutputs.map(item => {
if (item.status === 'fulfilled') {
return item.value;
} else {
core.info(`[warning]getting cache directory path failed: ${item.reason}`);
}
return '';
});
const cachePaths = results.filter(item => item);
const cachePaths = pathList.filter(item => item);
if (!cachePaths.length) {
throw new Error(`Could not get cache folder paths.`);

View File

@ -37,7 +37,7 @@ export async function getGo(
arch = os.arch()
) {
let manifest: tc.IToolRelease[] | undefined;
const osPlat: string = os.platform();
let osPlat: string = os.platform();
if (
versionSpec === StableReleaseAlias.Stable ||
@ -83,7 +83,8 @@ export async function getGo(
}
// check cache
const toolPath = tc.find('go', versionSpec, arch);
let toolPath: string;
toolPath = tc.find('go', versionSpec, arch);
// If not found in cache, download
if (toolPath) {
core.info(`Found in cache @ ${toolPath}`);
@ -164,64 +165,6 @@ async function resolveVersionFromManifest(
}
}
// for github hosted windows runner handle latency of OS drive
// by avoiding write operations to C:
async function cacheWindowsDir(
extPath: string,
tool: string,
version: string,
arch: string
): Promise<string | false> {
if (os.platform() !== 'win32') return false;
// make sure the action runs in the hosted environment
if (
process.env['RUNNER_ENVIRONMENT'] !== 'github-hosted' &&
process.env['AGENT_ISSELFHOSTED'] === '1'
)
return false;
const defaultToolCacheRoot = process.env['RUNNER_TOOL_CACHE'];
if (!defaultToolCacheRoot) return false;
if (!fs.existsSync('d:\\') || !fs.existsSync('c:\\')) return false;
const actualToolCacheRoot = defaultToolCacheRoot
.replace('C:', 'D:')
.replace('c:', 'd:');
// make toolcache root to be on drive d:
process.env['RUNNER_TOOL_CACHE'] = actualToolCacheRoot;
const actualToolCacheDir = await tc.cacheDir(extPath, tool, version, arch);
// create a link from c: to d:
const defaultToolCacheDir = actualToolCacheDir.replace(
actualToolCacheRoot,
defaultToolCacheRoot
);
fs.mkdirSync(path.dirname(defaultToolCacheDir), {recursive: true});
fs.symlinkSync(actualToolCacheDir, defaultToolCacheDir, 'junction');
core.info(`Created link ${defaultToolCacheDir} => ${actualToolCacheDir}`);
// make outer code to continue using toolcache as if it were installed on c:
// restore toolcache root to default drive c:
process.env['RUNNER_TOOL_CACHE'] = defaultToolCacheRoot;
return defaultToolCacheDir;
}
async function addExecutablesToToolCache(
extPath: string,
info: IGoVersionInfo,
arch: string
): Promise<string> {
const tool = 'go';
const version = makeSemver(info.resolvedVersion);
return (
(await cacheWindowsDir(extPath, tool, version, arch)) ||
(await tc.cacheDir(extPath, tool, version, arch))
);
}
async function installGoVersion(
info: IGoVersionInfo,
auth: string | undefined,
@ -244,10 +187,14 @@ async function installGoVersion(
}
core.info('Adding to the cache ...');
const toolCacheDir = await addExecutablesToToolCache(extPath, info, arch);
core.info(`Successfully cached go to ${toolCacheDir}`);
return toolCacheDir;
const cachedDir = await tc.cacheDir(
extPath,
'go',
makeSemver(info.resolvedVersion),
arch
);
core.info(`Successfully cached go to ${cachedDir}`);
return cachedDir;
}
export async function extractGoArchive(archivePath: string): Promise<string> {
@ -299,12 +246,13 @@ async function getInfoFromDist(
versionSpec: string,
arch: string
): Promise<IGoVersionInfo | null> {
const version: IGoVersion | undefined = await findMatch(versionSpec, arch);
let version: IGoVersion | undefined;
version = await findMatch(versionSpec, arch);
if (!version) {
return null;
}
const downloadUrl = `https://storage.googleapis.com/golang/${version.files[0].filename}`;
let downloadUrl: string = `https://storage.googleapis.com/golang/${version.files[0].filename}`;
return <IGoVersionInfo>{
type: 'dist',
@ -318,14 +266,14 @@ export async function findMatch(
versionSpec: string,
arch = os.arch()
): Promise<IGoVersion | undefined> {
const archFilter = sys.getArch(arch);
const platFilter = sys.getPlatform();
let archFilter = sys.getArch(arch);
let platFilter = sys.getPlatform();
let result: IGoVersion | undefined;
let match: IGoVersion | undefined;
const dlUrl = 'https://golang.org/dl/?mode=json&include=all';
const candidates: IGoVersion[] | null = await module.exports.getVersionsDist(
const dlUrl: string = 'https://golang.org/dl/?mode=json&include=all';
let candidates: IGoVersion[] | null = await module.exports.getVersionsDist(
dlUrl
);
if (!candidates) {
@ -334,8 +282,8 @@ export async function findMatch(
let goFile: IGoVersionFile | undefined;
for (let i = 0; i < candidates.length; i++) {
const candidate: IGoVersion = candidates[i];
const version = makeSemver(candidate.version);
let candidate: IGoVersion = candidates[i];
let version = makeSemver(candidate.version);
core.debug(`check ${version} satisfies ${versionSpec}`);
if (semver.satisfies(version, versionSpec)) {
@ -367,7 +315,7 @@ export async function getVersionsDist(
dlUrl: string
): Promise<IGoVersion[] | null> {
// this returns versions descending so latest is first
const http: httpm.HttpClient = new httpm.HttpClient('setup-go', [], {
let http: httpm.HttpClient = new httpm.HttpClient('setup-go', [], {
allowRedirects: true,
maxRedirects: 3
});
@ -383,9 +331,9 @@ export async function getVersionsDist(
export function makeSemver(version: string): string {
version = version.replace('go', '');
version = version.replace('beta', '-beta.').replace('rc', '-rc.');
const parts = version.split('-');
let parts = version.split('-');
const semVersion = semver.coerce(parts[0])?.version;
let semVersion = semver.coerce(parts[0])?.version;
if (!semVersion) {
throw new Error(
`The version: ${version} can't be changed to SemVer notation`
@ -421,10 +369,10 @@ export function parseGoVersionFile(versionFilePath: string): string {
}
async function resolveStableVersionDist(versionSpec: string, arch: string) {
const archFilter = sys.getArch(arch);
const platFilter = sys.getPlatform();
const dlUrl = 'https://golang.org/dl/?mode=json&include=all';
const candidates: IGoVersion[] | null = await module.exports.getVersionsDist(
let archFilter = sys.getArch(arch);
let platFilter = sys.getPlatform();
const dlUrl: string = 'https://golang.org/dl/?mode=json&include=all';
let candidates: IGoVersion[] | null = await module.exports.getVersionsDist(
dlUrl
);
if (!candidates) {

View File

@ -27,8 +27,8 @@ export async function run() {
}
if (versionSpec) {
const token = core.getInput('token');
const auth = !token ? undefined : `token ${token}`;
let token = core.getInput('token');
let auth = !token ? undefined : `token ${token}`;
const checkLatest = core.getBooleanInput('check-latest');
@ -51,31 +51,15 @@ export async function run() {
core.exportVariable('GOROOT', installDir);
}
let added = await addBinToPath();
core.debug(`add bin ${added}`);
core.info(`Successfully set up Go version ${versionSpec}`);
} else {
core.info(
'[warning]go-version input was not specified. The action will try to use pre-installed version.'
);
}
const added = await addBinToPath();
core.debug(`add bin ${added}`);
const goPath = await io.which('go');
const goVersion = (cp.execSync(`${goPath} version`) || '').toString();
if (cache && isCacheFeatureAvailable()) {
const packageManager = 'default';
const cacheDependencyPath = core.getInput('cache-dependency-path');
try {
await restoreCache(
parseGoVersion(goVersion),
packageManager,
cacheDependencyPath
);
} catch (error) {
core.warning(`Restore cache failed: ${error.message}`);
}
await restoreCache(versionSpec, packageManager, cacheDependencyPath);
}
// add problem matchers
@ -83,12 +67,14 @@ export async function run() {
core.info(`##[add-matcher]${matchersPath}`);
// output the version actually being used
let goPath = await io.which('go');
let goVersion = (cp.execSync(`${goPath} version`) || '').toString();
core.info(goVersion);
core.setOutput('go-version', parseGoVersion(goVersion));
core.startGroup('go env');
const goEnv = (cp.execSync(`${goPath} env`) || '').toString();
let goEnv = (cp.execSync(`${goPath} env`) || '').toString();
core.info(goEnv);
core.endGroup();
} catch (error) {
@ -98,16 +84,16 @@ export async function run() {
export async function addBinToPath(): Promise<boolean> {
let added = false;
const g = await io.which('go');
let g = await io.which('go');
core.debug(`which go :${g}:`);
if (!g) {
core.debug('go not in the path');
return added;
}
const buf = cp.execSync('go env GOPATH');
let buf = cp.execSync('go env GOPATH');
if (buf.length > 1) {
const gp = buf.toString().trim();
let gp = buf.toString().trim();
core.debug(`go env GOPATH :${gp}:`);
if (!fs.existsSync(gp)) {
// some of the hosted images have go install but not profile dir
@ -115,7 +101,7 @@ export async function addBinToPath(): Promise<boolean> {
await io.mkdirP(gp);
}
const bp = path.join(gp, 'bin');
let bp = path.join(gp, 'bin');
if (!fs.existsSync(bp)) {
core.debug(`creating ${bp}`);
await io.mkdirP(bp);

View File

@ -1,4 +1,4 @@
import os from 'os';
const os = require('os');
export function getPlatform(): string {
// darwin and linux match already

View File

@ -46,7 +46,6 @@
// "types": [], /* Type declaration files to be included in compilation. */
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
"esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
"resolveJsonModule": true, /* Allows importing modules with a '.json' extension, which is a common practice in node projects. */
"sourceMap": true,
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */