mirror of
https://github.com/actions/setup-go.git
synced 2026-07-09 01:55:37 +00:00
Merge 9575d2a815 into 924ae3a1cd
This commit is contained in:
commit
f688984aea
@ -1,6 +0,0 @@
|
||||
# Ignore list
|
||||
/*
|
||||
|
||||
# Do not ignore these folders:
|
||||
!__tests__/
|
||||
!src/
|
||||
51
.eslintrc.js
51
.eslintrc.js
@ -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
|
||||
}
|
||||
};
|
||||
@ -10,7 +10,10 @@ allowed:
|
||||
- cc0-1.0
|
||||
- unlicense
|
||||
- 0bsd
|
||||
- blueoak-1.0.0
|
||||
|
||||
reviewed:
|
||||
npm:
|
||||
- "@actions/http-client"
|
||||
- "balanced-match"
|
||||
- "brace-expansion"
|
||||
BIN
.licenses/npm/@actions/cache.dep.yml
generated
BIN
.licenses/npm/@actions/cache.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/@actions/core.dep.yml
generated
BIN
.licenses/npm/@actions/core.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/@actions/exec.dep.yml
generated
BIN
.licenses/npm/@actions/exec.dep.yml
generated
Binary file not shown.
Binary file not shown.
BIN
.licenses/npm/@actions/glob-0.7.0.dep.yml
generated
Normal file
BIN
.licenses/npm/@actions/glob-0.7.0.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/@actions/http-client.dep.yml
generated
BIN
.licenses/npm/@actions/http-client.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/@actions/io.dep.yml
generated
BIN
.licenses/npm/@actions/io.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/@actions/tool-cache.dep.yml
generated
BIN
.licenses/npm/@actions/tool-cache.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/@azure/core-client.dep.yml
generated
BIN
.licenses/npm/@azure/core-client.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/@azure/core-http-compat.dep.yml
generated
BIN
.licenses/npm/@azure/core-http-compat.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/@azure/core-rest-pipeline.dep.yml
generated
BIN
.licenses/npm/@azure/core-rest-pipeline.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/@azure/core-xml.dep.yml
generated
BIN
.licenses/npm/@azure/core-xml.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/@azure/storage-blob.dep.yml
generated
BIN
.licenses/npm/@azure/storage-blob.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/@azure/storage-common.dep.yml
generated
BIN
.licenses/npm/@azure/storage-common.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/@typespec/ts-http-runtime.dep.yml
generated
BIN
.licenses/npm/@typespec/ts-http-runtime.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/anynum.dep.yml
generated
BIN
.licenses/npm/anynum.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/balanced-match-4.0.4.dep.yml
generated
Normal file
BIN
.licenses/npm/balanced-match-4.0.4.dep.yml
generated
Normal file
Binary file not shown.
Binary file not shown.
BIN
.licenses/npm/brace-expansion-5.0.6.dep.yml
generated
Normal file
BIN
.licenses/npm/brace-expansion-5.0.6.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/fast-xml-parser.dep.yml
generated
BIN
.licenses/npm/fast-xml-parser.dep.yml
generated
Binary file not shown.
Binary file not shown.
BIN
.licenses/npm/minimatch-10.2.5.dep.yml
generated
Normal file
BIN
.licenses/npm/minimatch-10.2.5.dep.yml
generated
Normal file
Binary file not shown.
BIN
.licenses/npm/path-expression-matcher.dep.yml
generated
BIN
.licenses/npm/path-expression-matcher.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/semver-6.3.1.dep.yml
generated
BIN
.licenses/npm/semver-6.3.1.dep.yml
generated
Binary file not shown.
BIN
.licenses/npm/strnum.dep.yml
generated
BIN
.licenses/npm/strnum.dep.yml
generated
Binary file not shown.
@ -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'
|
||||
};
|
||||
10
.prettierrc.json
Normal file
10
.prettierrc.json
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"printWidth": 80,
|
||||
"tabWidth": 2,
|
||||
"useTabs": false,
|
||||
"semi": true,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "none",
|
||||
"bracketSpacing": false,
|
||||
"arrowParens": "avoid"
|
||||
}
|
||||
@ -9,6 +9,11 @@ This action sets up a Go environment for use in GitHub Actions by:
|
||||
- Optionally caching Go modules and build outputs
|
||||
- Registering problem matchers for error output
|
||||
|
||||
## Breaking changes in V7
|
||||
|
||||
The V7 edition of the action includes:
|
||||
- **Migrated to ESM** to enable support for the latest `@actions/*` package versions.
|
||||
|
||||
## Breaking changes in V6
|
||||
|
||||
The V6 edition of the action includes:
|
||||
|
||||
@ -1,18 +1,65 @@
|
||||
import * as cache from '@actions/cache';
|
||||
import * as core from '@actions/core';
|
||||
import * as glob from '@actions/glob';
|
||||
import {jest, describe, it, expect, beforeEach, afterEach} from '@jest/globals';
|
||||
import fs from 'fs';
|
||||
|
||||
import * as cacheRestore from '../src/cache-restore';
|
||||
import * as cacheUtils from '../src/cache-utils';
|
||||
import {PackageManagerInfo} from '../src/package-managers';
|
||||
jest.unstable_mockModule('@actions/cache', () => ({
|
||||
saveCache: jest.fn(),
|
||||
restoreCache: jest.fn(),
|
||||
isFeatureAvailable: jest.fn()
|
||||
}));
|
||||
|
||||
jest.unstable_mockModule('@actions/glob', () => ({
|
||||
create: jest.fn(),
|
||||
hashFiles: jest.fn()
|
||||
}));
|
||||
|
||||
jest.unstable_mockModule('@actions/core', () => ({
|
||||
info: jest.fn(),
|
||||
warning: jest.fn(),
|
||||
debug: jest.fn(),
|
||||
error: jest.fn(),
|
||||
notice: jest.fn(),
|
||||
setFailed: jest.fn(),
|
||||
setOutput: jest.fn(),
|
||||
getInput: jest.fn(),
|
||||
getBooleanInput: jest.fn(),
|
||||
getMultilineInput: jest.fn(),
|
||||
addPath: jest.fn(),
|
||||
exportVariable: jest.fn(),
|
||||
saveState: jest.fn(),
|
||||
getState: jest.fn(),
|
||||
setSecret: jest.fn(),
|
||||
isDebug: jest.fn(() => false),
|
||||
startGroup: jest.fn(),
|
||||
endGroup: jest.fn(),
|
||||
group: jest.fn((_name: string, fn: () => Promise<unknown>) => fn()),
|
||||
toPlatformPath: jest.fn((p: string) => p),
|
||||
toWin32Path: jest.fn((p: string) => p),
|
||||
toPosixPath: jest.fn((p: string) => p)
|
||||
}));
|
||||
|
||||
// Import real cache-utils (with mocked @actions) before mocking it
|
||||
const realCacheUtils = await import('../src/cache-utils.js');
|
||||
|
||||
jest.unstable_mockModule('../src/cache-utils.js', () => ({
|
||||
...realCacheUtils,
|
||||
getCacheDirectoryPath: jest.fn()
|
||||
}));
|
||||
|
||||
const cache = await import('@actions/cache');
|
||||
const core = await import('@actions/core');
|
||||
const glob = await import('@actions/glob');
|
||||
const cacheRestore = await import('../src/cache-restore.js');
|
||||
const cacheUtils = await import('../src/cache-utils.js');
|
||||
import type {PackageManagerInfo} from '../src/package-managers.js';
|
||||
|
||||
describe('restoreCache', () => {
|
||||
let hashFilesSpy: jest.SpyInstance;
|
||||
let getCacheDirectoryPathSpy: jest.SpyInstance;
|
||||
let restoreCacheSpy: jest.SpyInstance;
|
||||
let infoSpy: jest.SpyInstance;
|
||||
let setOutputSpy: jest.SpyInstance;
|
||||
let hashFilesSpy: jest.Mock<typeof glob.hashFiles>;
|
||||
let getCacheDirectoryPathSpy: jest.Mock<
|
||||
typeof cacheUtils.getCacheDirectoryPath
|
||||
>;
|
||||
let restoreCacheSpy: jest.Mock<typeof cache.restoreCache>;
|
||||
let infoSpy: jest.Mock<typeof core.info>;
|
||||
let setOutputSpy: jest.Mock<typeof core.setOutput>;
|
||||
|
||||
const versionSpec = '1.13.1';
|
||||
const packageManager = 'default';
|
||||
@ -24,11 +71,15 @@ describe('restoreCache', () => {
|
||||
originalWorkspace = process.env.GITHUB_WORKSPACE;
|
||||
process.env.GITHUB_WORKSPACE = '/test/workspace';
|
||||
//Arrange
|
||||
hashFilesSpy = jest.spyOn(glob, 'hashFiles');
|
||||
getCacheDirectoryPathSpy = jest.spyOn(cacheUtils, 'getCacheDirectoryPath');
|
||||
restoreCacheSpy = jest.spyOn(cache, 'restoreCache');
|
||||
infoSpy = jest.spyOn(core, 'info');
|
||||
setOutputSpy = jest.spyOn(core, 'setOutput');
|
||||
hashFilesSpy = glob.hashFiles as jest.Mock<typeof glob.hashFiles>;
|
||||
getCacheDirectoryPathSpy = cacheUtils.getCacheDirectoryPath as jest.Mock<
|
||||
typeof cacheUtils.getCacheDirectoryPath
|
||||
>;
|
||||
restoreCacheSpy = cache.restoreCache as jest.Mock<
|
||||
typeof cache.restoreCache
|
||||
>;
|
||||
infoSpy = core.info as jest.Mock<typeof core.info>;
|
||||
setOutputSpy = core.setOutput as jest.Mock<typeof core.setOutput>;
|
||||
|
||||
getCacheDirectoryPathSpy.mockImplementation(
|
||||
(PackageManager: PackageManagerInfo) => {
|
||||
|
||||
@ -1,10 +1,41 @@
|
||||
import * as cache from '@actions/cache';
|
||||
import * as core from '@actions/core';
|
||||
import fs from 'fs';
|
||||
import {jest, describe, it, expect, beforeEach, afterEach} from '@jest/globals';
|
||||
|
||||
import {run} from '../src/cache-save';
|
||||
import * as cacheUtils from '../src/cache-utils';
|
||||
import {State} from '../src/constants';
|
||||
jest.unstable_mockModule('@actions/cache', () => ({
|
||||
saveCache: jest.fn(),
|
||||
restoreCache: jest.fn(),
|
||||
isFeatureAvailable: jest.fn()
|
||||
}));
|
||||
|
||||
jest.unstable_mockModule('@actions/core', () => ({
|
||||
info: jest.fn(),
|
||||
warning: jest.fn(),
|
||||
debug: jest.fn(),
|
||||
error: jest.fn(),
|
||||
setFailed: jest.fn(),
|
||||
getInput: jest.fn(),
|
||||
getBooleanInput: jest.fn(),
|
||||
getState: jest.fn(),
|
||||
saveState: jest.fn()
|
||||
}));
|
||||
|
||||
const realFs = (await import('fs')).default;
|
||||
const fsExports = {...realFs, existsSync: jest.fn()};
|
||||
jest.unstable_mockModule('fs', () => ({...fsExports, default: fsExports}));
|
||||
|
||||
// Import real cache-utils (with mocked @actions) before mocking it
|
||||
const realCacheUtils = await import('../src/cache-utils.js');
|
||||
|
||||
jest.unstable_mockModule('../src/cache-utils.js', () => ({
|
||||
...realCacheUtils,
|
||||
getCacheDirectoryPath: jest.fn()
|
||||
}));
|
||||
|
||||
const cache = await import('@actions/cache');
|
||||
const core = await import('@actions/core');
|
||||
const fs = (await import('fs')).default;
|
||||
const cacheUtils = await import('../src/cache-utils.js');
|
||||
const {run} = await import('../src/cache-save.js');
|
||||
const {State} = await import('../src/constants.js');
|
||||
|
||||
describe('cache-save', () => {
|
||||
const primaryKey = 'primary-key';
|
||||
@ -12,24 +43,28 @@ describe('cache-save', () => {
|
||||
let primaryKeyValue: string;
|
||||
let matchedKeyValue: string;
|
||||
|
||||
let getBooleanInputSpy: jest.SpyInstance;
|
||||
let getStateSpy: jest.SpyInstance;
|
||||
let infoSpy: jest.SpyInstance;
|
||||
let warningSpy: jest.SpyInstance;
|
||||
let debugSpy: jest.SpyInstance;
|
||||
let setFailedSpy: jest.SpyInstance;
|
||||
let saveCacheSpy: jest.SpyInstance;
|
||||
let getCacheDirectoryPathSpy: jest.SpyInstance;
|
||||
let existsSpy: jest.SpyInstance;
|
||||
let getBooleanInputSpy: jest.Mock<typeof core.getBooleanInput>;
|
||||
let getStateSpy: jest.Mock<typeof core.getState>;
|
||||
let infoSpy: jest.Mock<typeof core.info>;
|
||||
let warningSpy: jest.Mock<typeof core.warning>;
|
||||
let debugSpy: jest.Mock<typeof core.debug>;
|
||||
let setFailedSpy: jest.Mock<typeof core.setFailed>;
|
||||
let saveCacheSpy: jest.Mock<typeof cache.saveCache>;
|
||||
let getCacheDirectoryPathSpy: jest.Mock<
|
||||
typeof cacheUtils.getCacheDirectoryPath
|
||||
>;
|
||||
let existsSpy: jest.Mock<typeof fs.existsSync>;
|
||||
|
||||
beforeEach(() => {
|
||||
primaryKeyValue = primaryKey;
|
||||
matchedKeyValue = 'matched-key';
|
||||
|
||||
getBooleanInputSpy = jest.spyOn(core, 'getBooleanInput');
|
||||
getBooleanInputSpy = core.getBooleanInput as jest.Mock<
|
||||
typeof core.getBooleanInput
|
||||
>;
|
||||
getBooleanInputSpy.mockReturnValue(true);
|
||||
|
||||
getStateSpy = jest.spyOn(core, 'getState');
|
||||
getStateSpy = core.getState as jest.Mock<typeof core.getState>;
|
||||
getStateSpy.mockImplementation((key: string) => {
|
||||
if (key === State.CachePrimaryKey) {
|
||||
return primaryKeyValue;
|
||||
@ -40,32 +75,34 @@ describe('cache-save', () => {
|
||||
return '';
|
||||
});
|
||||
|
||||
infoSpy = jest.spyOn(core, 'info');
|
||||
infoSpy = core.info as jest.Mock<typeof core.info>;
|
||||
infoSpy.mockImplementation(() => undefined);
|
||||
|
||||
warningSpy = jest.spyOn(core, 'warning');
|
||||
warningSpy = core.warning as jest.Mock<typeof core.warning>;
|
||||
warningSpy.mockImplementation(() => undefined);
|
||||
|
||||
debugSpy = jest.spyOn(core, 'debug');
|
||||
debugSpy = core.debug as jest.Mock<typeof core.debug>;
|
||||
debugSpy.mockImplementation(() => undefined);
|
||||
|
||||
setFailedSpy = jest.spyOn(core, 'setFailed');
|
||||
setFailedSpy = core.setFailed as jest.Mock<typeof core.setFailed>;
|
||||
setFailedSpy.mockImplementation(() => undefined);
|
||||
|
||||
saveCacheSpy = jest.spyOn(cache, 'saveCache');
|
||||
saveCacheSpy = cache.saveCache as jest.Mock<typeof cache.saveCache>;
|
||||
saveCacheSpy.mockImplementation(() => Promise.resolve(0));
|
||||
|
||||
getCacheDirectoryPathSpy = jest.spyOn(cacheUtils, 'getCacheDirectoryPath');
|
||||
getCacheDirectoryPathSpy = cacheUtils.getCacheDirectoryPath as jest.Mock<
|
||||
typeof cacheUtils.getCacheDirectoryPath
|
||||
>;
|
||||
getCacheDirectoryPathSpy.mockImplementation(() =>
|
||||
Promise.resolve(['cache_directory_path', 'cache_directory_path'])
|
||||
);
|
||||
|
||||
existsSpy = jest.spyOn(fs, 'existsSync');
|
||||
existsSpy = fs.existsSync as jest.Mock<typeof fs.existsSync>;
|
||||
existsSpy.mockImplementation(() => true);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jest.restoreAllMocks();
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('does not save cache when the cache input is false', async () => {
|
||||
|
||||
@ -1,22 +1,60 @@
|
||||
import * as exec from '@actions/exec';
|
||||
import * as cache from '@actions/cache';
|
||||
import * as core from '@actions/core';
|
||||
import * as cacheUtils from '../src/cache-utils';
|
||||
import {PackageManagerInfo} from '../src/package-managers';
|
||||
import {jest, describe, it, expect, beforeEach, afterAll} from '@jest/globals';
|
||||
|
||||
jest.unstable_mockModule('@actions/exec', () => ({
|
||||
exec: jest.fn(),
|
||||
getExecOutput: jest.fn()
|
||||
}));
|
||||
|
||||
jest.unstable_mockModule('@actions/cache', () => ({
|
||||
saveCache: jest.fn(),
|
||||
restoreCache: jest.fn(),
|
||||
isFeatureAvailable: jest.fn()
|
||||
}));
|
||||
|
||||
jest.unstable_mockModule('@actions/core', () => ({
|
||||
info: jest.fn(),
|
||||
warning: jest.fn(),
|
||||
debug: jest.fn(),
|
||||
error: jest.fn(),
|
||||
notice: jest.fn(),
|
||||
setFailed: jest.fn(),
|
||||
setOutput: jest.fn(),
|
||||
getInput: jest.fn(),
|
||||
getBooleanInput: jest.fn(),
|
||||
getMultilineInput: jest.fn(),
|
||||
addPath: jest.fn(),
|
||||
exportVariable: jest.fn(),
|
||||
saveState: jest.fn(),
|
||||
getState: jest.fn(),
|
||||
setSecret: jest.fn(),
|
||||
isDebug: jest.fn(() => false),
|
||||
startGroup: jest.fn(),
|
||||
endGroup: jest.fn(),
|
||||
group: jest.fn((_name: string, fn: () => Promise<unknown>) => fn()),
|
||||
toPlatformPath: jest.fn((p: string) => p),
|
||||
toWin32Path: jest.fn((p: string) => p),
|
||||
toPosixPath: jest.fn((p: string) => p)
|
||||
}));
|
||||
|
||||
const exec = await import('@actions/exec');
|
||||
const cache = await import('@actions/cache');
|
||||
const core = await import('@actions/core');
|
||||
const cacheUtils = await import('../src/cache-utils.js');
|
||||
import type {PackageManagerInfo} from '../src/package-managers.js';
|
||||
|
||||
describe('getCommandOutput', () => {
|
||||
//Arrange
|
||||
const getExecOutputSpy = jest.spyOn(exec, 'getExecOutput');
|
||||
const getExecOutputSpy = exec.getExecOutput as jest.Mock<
|
||||
typeof exec.getExecOutput
|
||||
>;
|
||||
|
||||
it('should return trimmed stdout in case of successful exit code', async () => {
|
||||
//Arrange
|
||||
const stdoutResult = ' stdout ';
|
||||
const trimmedStdout = stdoutResult.trim();
|
||||
|
||||
getExecOutputSpy.mockImplementation((commandLine: string) => {
|
||||
return new Promise<exec.ExecOutput>(resolve => {
|
||||
resolve({exitCode: 0, stdout: stdoutResult, stderr: ''});
|
||||
});
|
||||
getExecOutputSpy.mockImplementation(async (commandLine: string) => {
|
||||
return {exitCode: 0, stdout: stdoutResult, stderr: ''};
|
||||
});
|
||||
|
||||
//Act + Assert
|
||||
@ -29,10 +67,8 @@ describe('getCommandOutput', () => {
|
||||
//Arrange
|
||||
const stderrResult = 'error message';
|
||||
|
||||
getExecOutputSpy.mockImplementation((commandLine: string) => {
|
||||
return new Promise<exec.ExecOutput>(resolve => {
|
||||
resolve({exitCode: 10, stdout: '', stderr: stderrResult});
|
||||
});
|
||||
getExecOutputSpy.mockImplementation(async (commandLine: string) => {
|
||||
return {exitCode: 10, stdout: '', stderr: stderrResult};
|
||||
});
|
||||
|
||||
//Act + Assert
|
||||
@ -70,7 +106,9 @@ describe('getPackageManagerInfo', () => {
|
||||
|
||||
describe('getCacheDirectoryPath', () => {
|
||||
//Arrange
|
||||
const getExecOutputSpy = jest.spyOn(exec, 'getExecOutput');
|
||||
const getExecOutputSpy = exec.getExecOutput as jest.Mock<
|
||||
typeof exec.getExecOutput
|
||||
>;
|
||||
|
||||
const validPackageManager: PackageManagerInfo = {
|
||||
dependencyFilePattern: 'go.mod',
|
||||
@ -79,10 +117,8 @@ describe('getCacheDirectoryPath', () => {
|
||||
|
||||
it('should return path to the cache folders which specified package manager uses', async () => {
|
||||
//Arrange
|
||||
getExecOutputSpy.mockImplementation((commandLine: string) => {
|
||||
return new Promise<exec.ExecOutput>(resolve => {
|
||||
resolve({exitCode: 0, stdout: 'path/to/cache/folder', stderr: ''});
|
||||
});
|
||||
getExecOutputSpy.mockImplementation(async (commandLine: string) => {
|
||||
return {exitCode: 0, stdout: 'path/to/cache/folder', stderr: ''};
|
||||
});
|
||||
|
||||
const expectedResult = ['path/to/cache/folder', 'path/to/cache/folder'];
|
||||
@ -95,16 +131,12 @@ describe('getCacheDirectoryPath', () => {
|
||||
|
||||
it('should return path to the cache folder if one command return empty str', async () => {
|
||||
//Arrange
|
||||
getExecOutputSpy.mockImplementationOnce((commandLine: string) => {
|
||||
return new Promise<exec.ExecOutput>(resolve => {
|
||||
resolve({exitCode: 0, stdout: 'path/to/cache/folder', stderr: ''});
|
||||
});
|
||||
getExecOutputSpy.mockImplementationOnce(async (commandLine: string) => {
|
||||
return {exitCode: 0, stdout: 'path/to/cache/folder', stderr: ''};
|
||||
});
|
||||
|
||||
getExecOutputSpy.mockImplementationOnce((commandLine: string) => {
|
||||
return new Promise<exec.ExecOutput>(resolve => {
|
||||
resolve({exitCode: 0, stdout: '', stderr: ''});
|
||||
});
|
||||
getExecOutputSpy.mockImplementationOnce(async (commandLine: string) => {
|
||||
return {exitCode: 0, stdout: '', stderr: ''};
|
||||
});
|
||||
|
||||
const expectedResult = ['path/to/cache/folder'];
|
||||
@ -116,10 +148,8 @@ describe('getCacheDirectoryPath', () => {
|
||||
});
|
||||
|
||||
it('should throw if the both commands return empty str', async () => {
|
||||
getExecOutputSpy.mockImplementation((commandLine: string) => {
|
||||
return new Promise<exec.ExecOutput>(resolve => {
|
||||
resolve({exitCode: 10, stdout: '', stderr: ''});
|
||||
});
|
||||
getExecOutputSpy.mockImplementation(async (commandLine: string) => {
|
||||
return {exitCode: 10, stdout: '', stderr: ''};
|
||||
});
|
||||
|
||||
//Act + Assert
|
||||
@ -129,10 +159,8 @@ describe('getCacheDirectoryPath', () => {
|
||||
});
|
||||
|
||||
it('should throw if the specified package name is invalid', async () => {
|
||||
getExecOutputSpy.mockImplementation((commandLine: string) => {
|
||||
return new Promise<exec.ExecOutput>(resolve => {
|
||||
resolve({exitCode: 10, stdout: '', stderr: 'Error message'});
|
||||
});
|
||||
getExecOutputSpy.mockImplementation(async (commandLine: string) => {
|
||||
return {exitCode: 10, stdout: '', stderr: 'Error message'};
|
||||
});
|
||||
|
||||
//Act + Assert
|
||||
@ -144,8 +172,10 @@ describe('getCacheDirectoryPath', () => {
|
||||
|
||||
describe('isCacheFeatureAvailable', () => {
|
||||
//Arrange
|
||||
const isFeatureAvailableSpy = jest.spyOn(cache, 'isFeatureAvailable');
|
||||
const warningSpy = jest.spyOn(core, 'warning');
|
||||
const isFeatureAvailableSpy = cache.isFeatureAvailable as jest.Mock<
|
||||
typeof cache.isFeatureAvailable
|
||||
>;
|
||||
const warningSpy = core.warning as jest.Mock<typeof core.warning>;
|
||||
|
||||
it('should return true when cache feature is available', () => {
|
||||
//Arrange
|
||||
@ -211,10 +241,9 @@ describe('isCacheFeatureAvailable', () => {
|
||||
});
|
||||
|
||||
describe('isGhes', () => {
|
||||
const pristineEnv = process.env;
|
||||
const pristineEnv = {...process.env};
|
||||
|
||||
beforeEach(() => {
|
||||
jest.resetModules();
|
||||
process.env = {...pristineEnv};
|
||||
});
|
||||
|
||||
|
||||
@ -1,17 +1,98 @@
|
||||
import * as core from '@actions/core';
|
||||
import * as io from '@actions/io';
|
||||
import * as tc from '@actions/tool-cache';
|
||||
import {
|
||||
jest,
|
||||
describe,
|
||||
it,
|
||||
expect,
|
||||
beforeAll,
|
||||
beforeEach,
|
||||
afterEach,
|
||||
afterAll
|
||||
} from '@jest/globals';
|
||||
import fs from 'fs';
|
||||
import cp from 'child_process';
|
||||
import osm, {type} from 'os';
|
||||
import path from 'path';
|
||||
import * as main from '../src/main';
|
||||
import * as im from '../src/installer';
|
||||
import * as httpm from '@actions/http-client';
|
||||
|
||||
import goJsonData from './data/golang-dl.json';
|
||||
import matchers from '../matchers.json';
|
||||
import goTestManifest from './data/versions-manifest.json';
|
||||
import goJsonData from './data/golang-dl.json' with {type: 'json'};
|
||||
import matchers from '../matchers.json' with {type: 'json'};
|
||||
import goTestManifest from './data/versions-manifest.json' with {type: 'json'};
|
||||
|
||||
import type {IGoVersion} from '../src/installer.js';
|
||||
import type {IToolRelease} from '@actions/tool-cache';
|
||||
|
||||
const httpClientGetJson = jest.fn();
|
||||
|
||||
const realCore = await import('@actions/core');
|
||||
|
||||
jest.unstable_mockModule('@actions/core', () => ({
|
||||
...realCore,
|
||||
getInput: jest.fn(),
|
||||
getBooleanInput: jest.fn(),
|
||||
info: jest.fn(),
|
||||
debug: jest.fn(),
|
||||
exportVariable: jest.fn()
|
||||
}));
|
||||
|
||||
const realOs = (await import('os')).default;
|
||||
const osPlatformMock = jest.fn();
|
||||
const osArchMock = jest.fn();
|
||||
const osExports = {
|
||||
...realOs,
|
||||
platform: osPlatformMock,
|
||||
arch: osArchMock
|
||||
};
|
||||
jest.unstable_mockModule('os', () => ({...osExports, default: osExports}));
|
||||
|
||||
const realPath = (await import('path')).default;
|
||||
const pathJoinMock = jest.fn();
|
||||
const pathExports = {
|
||||
...realPath,
|
||||
join: pathJoinMock
|
||||
};
|
||||
jest.unstable_mockModule('path', () => ({
|
||||
...pathExports,
|
||||
default: pathExports
|
||||
}));
|
||||
|
||||
jest.unstable_mockModule('@actions/io', () => ({
|
||||
which: jest.fn(),
|
||||
mkdirP: jest.fn(),
|
||||
rmRF: jest.fn(),
|
||||
mv: jest.fn(),
|
||||
cp: jest.fn()
|
||||
}));
|
||||
|
||||
const realTc = await import('@actions/tool-cache');
|
||||
|
||||
jest.unstable_mockModule('@actions/tool-cache', () => ({
|
||||
...realTc,
|
||||
find: jest.fn(),
|
||||
downloadTool: jest.fn(),
|
||||
extractTar: jest.fn(),
|
||||
extractZip: jest.fn(),
|
||||
cacheDir: jest.fn(),
|
||||
getManifestFromRepo: jest.fn()
|
||||
}));
|
||||
|
||||
const realHttp = await import('@actions/http-client');
|
||||
|
||||
jest.unstable_mockModule('@actions/http-client', () => ({
|
||||
...realHttp,
|
||||
HttpClient: jest.fn().mockImplementation(() => ({
|
||||
getJson: httpClientGetJson
|
||||
}))
|
||||
}));
|
||||
|
||||
jest.unstable_mockModule('../src/go-version-fetch.js', () => ({
|
||||
getVersionsDist: jest.fn()
|
||||
}));
|
||||
|
||||
const core = await import('@actions/core');
|
||||
const io = await import('@actions/io');
|
||||
const tc = await import('@actions/tool-cache');
|
||||
const vf = await import('../src/go-version-fetch.js');
|
||||
const main = await import('../src/main.js');
|
||||
const im = await import('../src/installer.js');
|
||||
const osm = (await import('os')).default;
|
||||
const path = (await import('path')).default;
|
||||
const matcherPattern = matchers.problemMatcher[0].pattern[0];
|
||||
const matcherRegExp = new RegExp(matcherPattern.regexp);
|
||||
const win32Join = path.win32.join;
|
||||
@ -23,32 +104,31 @@ describe('setup-go', () => {
|
||||
let inputs = {} as any;
|
||||
let os = {} as any;
|
||||
|
||||
let inSpy: jest.SpyInstance;
|
||||
let getBooleanInputSpy: jest.SpyInstance;
|
||||
let exportVarSpy: jest.SpyInstance;
|
||||
let findSpy: jest.SpyInstance;
|
||||
let cnSpy: jest.SpyInstance;
|
||||
let logSpy: jest.SpyInstance;
|
||||
let getSpy: jest.SpyInstance;
|
||||
let platSpy: jest.SpyInstance;
|
||||
let archSpy: jest.SpyInstance;
|
||||
let joinSpy: jest.SpyInstance;
|
||||
let dlSpy: jest.SpyInstance;
|
||||
let extractTarSpy: jest.SpyInstance;
|
||||
let extractZipSpy: jest.SpyInstance;
|
||||
let cacheSpy: jest.SpyInstance;
|
||||
let dbgSpy: jest.SpyInstance;
|
||||
let whichSpy: jest.SpyInstance;
|
||||
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 execFileSpy: jest.SpyInstance;
|
||||
let getManifestSpy: jest.SpyInstance;
|
||||
let getAllVersionsSpy: jest.SpyInstance;
|
||||
let httpmGetJsonSpy: jest.SpyInstance;
|
||||
let inSpy: jest.Mock<typeof core.getInput>;
|
||||
let getBooleanInputSpy: jest.Mock<typeof core.getBooleanInput>;
|
||||
let exportVarSpy: jest.Mock<typeof core.exportVariable>;
|
||||
let findSpy: jest.Mock;
|
||||
let cnSpy: jest.SpiedFunction<typeof process.stdout.write>;
|
||||
let logSpy: jest.Mock;
|
||||
let getSpy: jest.Mock;
|
||||
let platSpy: jest.Mock;
|
||||
let archSpy: jest.Mock;
|
||||
let joinSpy: jest.Mock<typeof path.join>;
|
||||
let dlSpy: jest.Mock;
|
||||
let extractTarSpy: jest.Mock;
|
||||
let extractZipSpy: jest.Mock;
|
||||
let cacheSpy: jest.Mock;
|
||||
let dbgSpy: jest.Mock;
|
||||
let whichSpy: jest.Mock;
|
||||
let existsSpy: jest.SpiedFunction<typeof fs.existsSync>;
|
||||
let readFileSpy: jest.SpiedFunction<typeof fs.readFileSync>;
|
||||
let mkdirpSpy: jest.Mock;
|
||||
let mkdirSpy: jest.SpiedFunction<typeof fs.mkdir>;
|
||||
let symlinkSpy: jest.SpiedFunction<typeof fs.symlinkSync>;
|
||||
let execSpy: jest.SpiedFunction<typeof cp.execSync>;
|
||||
let execFileSpy: jest.SpiedFunction<typeof cp.execFileSync>;
|
||||
let getManifestSpy: jest.Mock;
|
||||
let httpmGetJsonSpy: jest.Mock;
|
||||
|
||||
beforeAll(async () => {
|
||||
process.env['GITHUB_ENV'] = ''; // Stub out Environment file functionality so we can verify it writes to standard out (toolkit is backwards compatible)
|
||||
@ -59,17 +139,19 @@ describe('setup-go', () => {
|
||||
|
||||
// @actions/core
|
||||
inputs = {};
|
||||
inSpy = jest.spyOn(core, 'getInput');
|
||||
inSpy = core.getInput as jest.Mock<typeof core.getInput>;
|
||||
inSpy.mockImplementation(name => inputs[name]);
|
||||
getBooleanInputSpy = jest.spyOn(core, 'getBooleanInput');
|
||||
getBooleanInputSpy = core.getBooleanInput as jest.Mock<
|
||||
typeof core.getBooleanInput
|
||||
>;
|
||||
getBooleanInputSpy.mockImplementation(name => inputs[name]);
|
||||
exportVarSpy = jest.spyOn(core, 'exportVariable');
|
||||
exportVarSpy = core.exportVariable as jest.Mock<typeof core.exportVariable>;
|
||||
|
||||
// node
|
||||
os = {};
|
||||
platSpy = jest.spyOn(osm, 'platform');
|
||||
platSpy = osm.platform as jest.Mock;
|
||||
platSpy.mockImplementation(() => os['platform']);
|
||||
archSpy = jest.spyOn(osm, 'arch');
|
||||
archSpy = osm.arch as jest.Mock;
|
||||
archSpy.mockImplementation(() => os['arch']);
|
||||
execSpy = jest.spyOn(cp, 'execSync');
|
||||
execFileSpy = jest.spyOn(cp, 'execFileSync');
|
||||
@ -78,7 +160,7 @@ describe('setup-go', () => {
|
||||
});
|
||||
|
||||
// switch path join behaviour based on set os.platform
|
||||
joinSpy = jest.spyOn(path, 'join');
|
||||
joinSpy = path.join as jest.Mock<typeof path.join>;
|
||||
joinSpy.mockImplementation((...paths: string[]): string => {
|
||||
if (os['platform'] == 'win32') {
|
||||
return win32Join(...paths);
|
||||
@ -88,23 +170,22 @@ describe('setup-go', () => {
|
||||
});
|
||||
|
||||
// @actions/tool-cache
|
||||
findSpy = jest.spyOn(tc, 'find');
|
||||
dlSpy = jest.spyOn(tc, 'downloadTool');
|
||||
extractTarSpy = jest.spyOn(tc, 'extractTar');
|
||||
extractZipSpy = jest.spyOn(tc, 'extractZip');
|
||||
cacheSpy = jest.spyOn(tc, 'cacheDir');
|
||||
getSpy = jest.spyOn(im, 'getVersionsDist');
|
||||
getManifestSpy = jest.spyOn(tc, 'getManifestFromRepo');
|
||||
getAllVersionsSpy = jest.spyOn(im, 'getManifest');
|
||||
findSpy = tc.find as jest.Mock;
|
||||
dlSpy = tc.downloadTool as jest.Mock;
|
||||
extractTarSpy = tc.extractTar as jest.Mock;
|
||||
extractZipSpy = tc.extractZip as jest.Mock;
|
||||
cacheSpy = tc.cacheDir as jest.Mock;
|
||||
getSpy = vf.getVersionsDist as jest.Mock;
|
||||
getManifestSpy = tc.getManifestFromRepo as jest.Mock;
|
||||
|
||||
// httm
|
||||
httpmGetJsonSpy = jest.spyOn(httpm.HttpClient.prototype, 'getJson');
|
||||
httpmGetJsonSpy = httpClientGetJson;
|
||||
|
||||
// io
|
||||
whichSpy = jest.spyOn(io, 'which');
|
||||
whichSpy = io.which as jest.Mock;
|
||||
existsSpy = jest.spyOn(fs, 'existsSync');
|
||||
readFileSpy = jest.spyOn(fs, 'readFileSync');
|
||||
mkdirpSpy = jest.spyOn(io, 'mkdirP');
|
||||
mkdirpSpy = io.mkdirP as jest.Mock;
|
||||
|
||||
// fs
|
||||
mkdirSpy = jest.spyOn(fs, 'mkdir');
|
||||
@ -112,25 +193,16 @@ describe('setup-go', () => {
|
||||
symlinkSpy.mockImplementation(() => {});
|
||||
|
||||
// gets
|
||||
getManifestSpy.mockImplementation(() => <tc.IToolRelease[]>goTestManifest);
|
||||
getManifestSpy.mockImplementation(() => goTestManifest as IToolRelease[]);
|
||||
|
||||
// writes
|
||||
cnSpy = jest.spyOn(process.stdout, 'write');
|
||||
logSpy = jest.spyOn(core, 'info');
|
||||
dbgSpy = jest.spyOn(core, 'debug');
|
||||
getSpy.mockImplementation(() => <im.IGoVersion[] | null>goJsonData);
|
||||
cnSpy.mockImplementation(line => {
|
||||
// uncomment to debug
|
||||
// process.stderr.write('write:' + line + '\n');
|
||||
});
|
||||
logSpy.mockImplementation(line => {
|
||||
// uncomment to debug
|
||||
//process.stderr.write('log:' + line + '\n');
|
||||
});
|
||||
dbgSpy.mockImplementation(msg => {
|
||||
// uncomment to see debug output
|
||||
// process.stderr.write(msg + '\n');
|
||||
});
|
||||
logSpy = core.info as jest.Mock;
|
||||
dbgSpy = core.debug as jest.Mock;
|
||||
getSpy.mockImplementation(() => goJsonData as IGoVersion[] | null);
|
||||
cnSpy.mockImplementation(() => true);
|
||||
logSpy.mockImplementation(() => {});
|
||||
dbgSpy.mockImplementation(() => {});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
@ -138,6 +210,10 @@ describe('setup-go', () => {
|
||||
delete process.env[im.GOTOOLCHAIN_ENV_VAR];
|
||||
delete process.env['GO_DOWNLOAD_BASE_URL'];
|
||||
|
||||
// reset the exit code that core.setFailed sets on the error-path tests so
|
||||
// that a passing run does not leak a non-zero process exit code
|
||||
process.exitCode = 0;
|
||||
|
||||
//jest.resetAllMocks();
|
||||
jest.clearAllMocks();
|
||||
//jest.restoreAllMocks();
|
||||
@ -171,8 +247,10 @@ describe('setup-go', () => {
|
||||
});
|
||||
|
||||
it('should return manifest from raw URL if repo fetch fails', async () => {
|
||||
getManifestSpy.mockRejectedValue(new Error('Fetch failed'));
|
||||
httpmGetJsonSpy.mockResolvedValue({
|
||||
(getManifestSpy as jest.Mock<any>).mockRejectedValue(
|
||||
new Error('Fetch failed')
|
||||
);
|
||||
(httpmGetJsonSpy as jest.Mock<any>).mockResolvedValue({
|
||||
result: goTestManifest
|
||||
});
|
||||
const manifest = await im.getManifest(undefined);
|
||||
@ -211,7 +289,7 @@ describe('setup-go', () => {
|
||||
os.arch = 'x64';
|
||||
|
||||
// spec: 1.13.0 => 1.13
|
||||
const match: im.IGoVersion | undefined = await im.findMatch('1.13.0');
|
||||
const match: IGoVersion | undefined = await im.findMatch('1.13.0');
|
||||
expect(match).toBeDefined();
|
||||
const version: string = match ? match.version : '';
|
||||
expect(version).toBe('go1.13');
|
||||
@ -224,7 +302,7 @@ describe('setup-go', () => {
|
||||
os.arch = 'x64';
|
||||
|
||||
// spec: 1.13 => 1.13.7 (latest)
|
||||
const match: im.IGoVersion | undefined = await im.findMatch('1.13');
|
||||
const match: IGoVersion | undefined = await im.findMatch('1.13');
|
||||
expect(match).toBeDefined();
|
||||
const version: string = match ? match.version : '';
|
||||
expect(version).toBe('go1.13.7');
|
||||
@ -237,7 +315,7 @@ describe('setup-go', () => {
|
||||
os.arch = 'x64';
|
||||
|
||||
// spec: ^1.13.6 => 1.13.7
|
||||
const match: im.IGoVersion | undefined = await im.findMatch('^1.13.6');
|
||||
const match: IGoVersion | undefined = await im.findMatch('^1.13.6');
|
||||
expect(match).toBeDefined();
|
||||
const version: string = match ? match.version : '';
|
||||
expect(version).toBe('go1.13.7');
|
||||
@ -250,7 +328,7 @@ describe('setup-go', () => {
|
||||
os.arch = 'x32';
|
||||
|
||||
// spec: 1 => 1.13.7 (latest)
|
||||
const match: im.IGoVersion | undefined = await im.findMatch('1');
|
||||
const match: IGoVersion | undefined = await im.findMatch('1');
|
||||
expect(match).toBeDefined();
|
||||
const version: string = match ? match.version : '';
|
||||
expect(version).toBe('go1.13.7');
|
||||
@ -263,7 +341,7 @@ 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');
|
||||
const match: IGoVersion | undefined = await im.findMatch('1.14.0-rc.1');
|
||||
expect(match).toBeDefined();
|
||||
const version: string = match ? match.version : '';
|
||||
expect(version).toBe('go1.14rc1');
|
||||
@ -817,10 +895,9 @@ describe('setup-go', () => {
|
||||
getManifestSpy.mockImplementation(() => {
|
||||
throw new Error('Unable to download manifest');
|
||||
});
|
||||
httpmGetJsonSpy.mockRejectedValue(
|
||||
(httpmGetJsonSpy as jest.Mock<any>).mockRejectedValue(
|
||||
new Error('Unable to download manifest from raw URL')
|
||||
);
|
||||
getAllVersionsSpy.mockImplementationOnce(() => undefined);
|
||||
|
||||
dlSpy.mockImplementation(async () => '/some/temp/path');
|
||||
const toolPath = path.normalize('/cache/go/1.13.7/x64');
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import {isSelfHosted} from '../src/utils';
|
||||
import {describe, it, expect, beforeEach, afterEach} from '@jest/globals';
|
||||
import {isSelfHosted} from '../src/utils.js';
|
||||
|
||||
describe('utils', () => {
|
||||
describe('isSelfHosted', () => {
|
||||
|
||||
@ -1,38 +1,57 @@
|
||||
import fs from 'fs';
|
||||
import * as io from '@actions/io';
|
||||
import * as tc from '@actions/tool-cache';
|
||||
import {jest, describe, it, expect, beforeEach, afterEach} from '@jest/globals';
|
||||
import path from 'path';
|
||||
|
||||
const statSyncMock = jest.fn(() => ({
|
||||
isDirectory: () => true,
|
||||
isFile: () => true
|
||||
}));
|
||||
const readdirSyncMock = jest.fn(() => [] as any);
|
||||
const writeFileSyncMock = jest.fn();
|
||||
const mkdirMock = jest.fn();
|
||||
const symlinkSyncMock = jest.fn();
|
||||
|
||||
jest.unstable_mockModule('@actions/io', () => ({
|
||||
which: jest.fn(),
|
||||
mkdirP: jest.fn(() => Promise.resolve()),
|
||||
rmRF: jest.fn(() => Promise.resolve()),
|
||||
mv: jest.fn(() => Promise.resolve()),
|
||||
cp: jest.fn(() => Promise.resolve())
|
||||
}));
|
||||
|
||||
const realFs = (await import('fs')).default;
|
||||
const fsExports = {
|
||||
...realFs,
|
||||
statSync: statSyncMock,
|
||||
readdirSync: readdirSyncMock,
|
||||
writeFileSync: writeFileSyncMock,
|
||||
mkdir: mkdirMock,
|
||||
symlinkSync: symlinkSyncMock
|
||||
};
|
||||
jest.unstable_mockModule('fs', () => ({...fsExports, default: fsExports}));
|
||||
|
||||
const io = await import('@actions/io');
|
||||
const tc = await import('@actions/tool-cache');
|
||||
|
||||
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 rmRFSpy: jest.Mock;
|
||||
let mkdirPSpy: jest.Mock;
|
||||
let cpSpy: jest.Mock;
|
||||
|
||||
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');
|
||||
rmRFSpy = io.rmRF as jest.Mock;
|
||||
mkdirPSpy = io.mkdirP as jest.Mock;
|
||||
cpSpy = io.cp as jest.Mock;
|
||||
|
||||
// default implementations
|
||||
// @ts-ignore - not implement unused methods
|
||||
statSpy.mockImplementation(() => ({
|
||||
isDirectory: () => true
|
||||
statSyncMock.mockImplementation(() => ({
|
||||
isDirectory: () => true,
|
||||
isFile: () => true
|
||||
}));
|
||||
readdirSpy.mockImplementation(() => []);
|
||||
writeFileSpy.mockImplementation(() => {});
|
||||
mkdirSpy.mockImplementation(() => {});
|
||||
symlinkSpy.mockImplementation(() => {});
|
||||
readdirSyncMock.mockImplementation(() => []);
|
||||
writeFileSyncMock.mockImplementation(() => {});
|
||||
mkdirMock.mockImplementation(() => {});
|
||||
symlinkSyncMock.mockImplementation(() => {});
|
||||
rmRFSpy.mockImplementation(() => Promise.resolve());
|
||||
mkdirPSpy.mockImplementation(() => Promise.resolve());
|
||||
cpSpy.mockImplementation(() => Promise.resolve());
|
||||
|
||||
112520
dist/cache-save/index.js
vendored
112520
dist/cache-save/index.js
vendored
File diff suppressed because one or more lines are too long
3
dist/cache-save/package.json
vendored
Normal file
3
dist/cache-save/package.json
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"type": "module"
|
||||
}
|
||||
118189
dist/setup/index.js
vendored
118189
dist/setup/index.js
vendored
File diff suppressed because one or more lines are too long
3
dist/setup/package.json
vendored
Normal file
3
dist/setup/package.json
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"type": "module"
|
||||
}
|
||||
74
eslint.config.mjs
Normal file
74
eslint.config.mjs
Normal file
@ -0,0 +1,74 @@
|
||||
// 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.
|
||||
import js from '@eslint/js';
|
||||
import tsParser from '@typescript-eslint/parser';
|
||||
import tsPlugin from '@typescript-eslint/eslint-plugin';
|
||||
import jest from 'eslint-plugin-jest';
|
||||
import n from 'eslint-plugin-n';
|
||||
import prettier from 'eslint-config-prettier';
|
||||
import globals from 'globals';
|
||||
|
||||
export default [
|
||||
{
|
||||
ignores: ['**/*', '!src/**', '!__tests__/**']
|
||||
},
|
||||
js.configs.recommended,
|
||||
{
|
||||
files: ['**/*.ts'],
|
||||
languageOptions: {
|
||||
parser: tsParser,
|
||||
ecmaVersion: 2022,
|
||||
sourceType: 'module',
|
||||
globals: {
|
||||
...globals.node,
|
||||
...globals.es2015
|
||||
}
|
||||
},
|
||||
plugins: {
|
||||
'@typescript-eslint': tsPlugin,
|
||||
n
|
||||
},
|
||||
rules: {
|
||||
...tsPlugin.configs.recommended.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}],
|
||||
'no-undef': 'off',
|
||||
'no-useless-assignment': 'off',
|
||||
'n/no-extraneous-import': 'error'
|
||||
}
|
||||
},
|
||||
{
|
||||
files: ['**/*{test,spec}.ts'],
|
||||
plugins: {jest},
|
||||
languageOptions: {
|
||||
globals: {
|
||||
...globals.jest
|
||||
}
|
||||
},
|
||||
rules: {
|
||||
...jest.configs['flat/recommended'].rules,
|
||||
'@typescript-eslint/no-unused-vars': 'off',
|
||||
'jest/no-standalone-expect': 'off',
|
||||
'jest/no-conditional-expect': 'off',
|
||||
'no-console': 'off'
|
||||
}
|
||||
},
|
||||
prettier
|
||||
];
|
||||
@ -1,11 +0,0 @@
|
||||
module.exports = {
|
||||
clearMocks: true,
|
||||
moduleFileExtensions: ['js', 'ts'],
|
||||
testEnvironment: 'node',
|
||||
testMatch: ['**/*.test.ts'],
|
||||
testRunner: 'jest-circus/runner',
|
||||
transform: {
|
||||
'^.+\\.ts$': 'ts-jest'
|
||||
},
|
||||
verbose: true
|
||||
}
|
||||
24
jest.config.ts
Normal file
24
jest.config.ts
Normal file
@ -0,0 +1,24 @@
|
||||
export default {
|
||||
clearMocks: true,
|
||||
moduleFileExtensions: ['js', 'ts'],
|
||||
roots: ['<rootDir>'],
|
||||
testEnvironment: 'node',
|
||||
testMatch: ['**/*.test.ts'],
|
||||
transform: {
|
||||
'^.+\\.ts$': [
|
||||
'ts-jest',
|
||||
{
|
||||
useESM: true,
|
||||
diagnostics: {
|
||||
ignoreCodes: [151002]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
extensionsToTreatAsEsm: ['.ts'],
|
||||
transformIgnorePatterns: ['node_modules/(?!(@actions)/)'],
|
||||
moduleNameMapper: {
|
||||
'^(\\.{1,2}/.*)\\.js$': '$1'
|
||||
},
|
||||
verbose: true
|
||||
};
|
||||
4616
package-lock.json
generated
4616
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
62
package.json
62
package.json
@ -1,6 +1,7 @@
|
||||
{
|
||||
"name": "setup-go",
|
||||
"version": "6.5.0",
|
||||
"version": "7.0.0",
|
||||
"type": "module",
|
||||
"private": true,
|
||||
"description": "setup go action",
|
||||
"main": "lib/setup-go.js",
|
||||
@ -9,11 +10,11 @@
|
||||
},
|
||||
"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",
|
||||
"test": "jest --coverage",
|
||||
"format": "prettier --no-error-on-unmatched-pattern --write \"**/*.{ts,yml,yaml}\"",
|
||||
"format-check": "prettier --no-error-on-unmatched-pattern --check \"**/*.{ts,yml,yaml}\"",
|
||||
"lint": "eslint \"**/*.ts\"",
|
||||
"lint:fix": "eslint \"**/*.ts\" --fix",
|
||||
"test": "node --experimental-vm-modules ./node_modules/jest/bin/jest.js --runInBand --coverage",
|
||||
"pre-checkin": "npm run format && npm run lint:fix && npm run build && npm test"
|
||||
},
|
||||
"repository": {
|
||||
@ -28,31 +29,32 @@
|
||||
"author": "GitHub",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@actions/cache": "^5.1.0",
|
||||
"@actions/core": "^2.0.3",
|
||||
"@actions/exec": "^2.0.0",
|
||||
"@actions/glob": "^0.5.1",
|
||||
"@actions/http-client": "^3.0.2",
|
||||
"@actions/io": "^2.0.0",
|
||||
"@actions/tool-cache": "^3.0.1",
|
||||
"semver": "^7.7.3"
|
||||
"@actions/cache": "^6.1.0",
|
||||
"@actions/core": "^3.0.1",
|
||||
"@actions/exec": "^3.0.0",
|
||||
"@actions/glob": "^0.7.0",
|
||||
"@actions/http-client": "^4.0.1",
|
||||
"@actions/io": "^3.0.2",
|
||||
"@actions/tool-cache": "^4.0.0",
|
||||
"semver": "^7.8.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jest": "^29.5.14",
|
||||
"@types/node": "^25.9.3",
|
||||
"@types/semver": "^7.7.1",
|
||||
"@typescript-eslint/eslint-plugin": "^8.61.0",
|
||||
"@typescript-eslint/parser": "^8.61.0",
|
||||
"@vercel/ncc": "^0.38.1",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-config-prettier": "^10.1.8",
|
||||
"eslint-plugin-jest": "^29.0.1",
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"jest": "^29.7.0",
|
||||
"jest-circus": "^29.7.0",
|
||||
"nock": "^10.0.6",
|
||||
"prettier": "^2.8.4",
|
||||
"ts-jest": "^29.3.2",
|
||||
"typescript": "^5.8.3"
|
||||
"@eslint/js": "^10.0.1",
|
||||
"@jest/globals": "^30.4.1",
|
||||
"@types/node": "^26.0.0",
|
||||
"@types/semver": "^7.7.0",
|
||||
"@typescript-eslint/eslint-plugin": "^8.62.0",
|
||||
"@typescript-eslint/parser": "^8.62.0",
|
||||
"@vercel/ncc": "^0.44.0",
|
||||
"eslint": "^10.5.0",
|
||||
"eslint-config-prettier": "^10.0.0",
|
||||
"eslint-plugin-jest": "^29.15.2",
|
||||
"eslint-plugin-n": "^18.1.0",
|
||||
"globals": "^17.7.0",
|
||||
"jest": "^30.4.2",
|
||||
"nock": "^14.0.0",
|
||||
"prettier": "^3.8.4",
|
||||
"ts-jest": "^29.4.11",
|
||||
"typescript": "^6.0.3"
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,9 +4,9 @@ import * as glob from '@actions/glob';
|
||||
import path from 'path';
|
||||
import fs from 'fs';
|
||||
|
||||
import {State, Outputs} from './constants';
|
||||
import {PackageManagerInfo} from './package-managers';
|
||||
import {getCacheDirectoryPath, getPackageManagerInfo} from './cache-utils';
|
||||
import {State, Outputs} from './constants.js';
|
||||
import {PackageManagerInfo} from './package-managers.js';
|
||||
import {getCacheDirectoryPath, getPackageManagerInfo} from './cache-utils.js';
|
||||
|
||||
export const restoreCache = async (
|
||||
versionSpec: string,
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import * as core from '@actions/core';
|
||||
import * as cache from '@actions/cache';
|
||||
import fs from 'fs';
|
||||
import {State} from './constants';
|
||||
import {getCacheDirectoryPath, getPackageManagerInfo} from './cache-utils';
|
||||
import {State} from './constants.js';
|
||||
import {getCacheDirectoryPath, getPackageManagerInfo} from './cache-utils.js';
|
||||
|
||||
// Catch and log any unhandled exceptions. These exceptions can leak out of the uploadChunk method in
|
||||
// @actions/toolkit when a failed upload closes the file descriptor causing any in-process reads to
|
||||
|
||||
@ -1,7 +1,10 @@
|
||||
import * as cache from '@actions/cache';
|
||||
import * as core from '@actions/core';
|
||||
import * as exec from '@actions/exec';
|
||||
import {supportedPackageManagers, PackageManagerInfo} from './package-managers';
|
||||
import {
|
||||
supportedPackageManagers,
|
||||
PackageManagerInfo
|
||||
} from './package-managers.js';
|
||||
|
||||
export const getCommandOutput = async (toolCommand: string) => {
|
||||
let {stdout, stderr, exitCode} = await exec.getExecOutput(
|
||||
|
||||
13
src/go-version-fetch.ts
Normal file
13
src/go-version-fetch.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import * as httpm from '@actions/http-client';
|
||||
import type {IGoVersion} from './installer.js';
|
||||
|
||||
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', [], {
|
||||
allowRedirects: true,
|
||||
maxRedirects: 3
|
||||
});
|
||||
return (await http.getJson<IGoVersion[]>(dlUrl)).result;
|
||||
}
|
||||
@ -3,13 +3,14 @@ import * as core from '@actions/core';
|
||||
import * as path from 'path';
|
||||
import * as semver from 'semver';
|
||||
import * as httpm from '@actions/http-client';
|
||||
import * as sys from './system';
|
||||
import * as sys from './system.js';
|
||||
import crypto from 'crypto';
|
||||
import cp from 'child_process';
|
||||
import fs from 'fs';
|
||||
import os from 'os';
|
||||
import {StableReleaseAlias, isSelfHosted} from './utils';
|
||||
import {Architecture} from './types';
|
||||
import {StableReleaseAlias, isSelfHosted} from './utils.js';
|
||||
import {Architecture} from './types.js';
|
||||
import {getVersionsDist} from './go-version-fetch.js';
|
||||
|
||||
export const GOTOOLCHAIN_ENV_VAR = 'GOTOOLCHAIN';
|
||||
export const GOTOOLCHAIN_LOCAL_VAL = 'local';
|
||||
@ -167,12 +168,14 @@ export async function getGo(
|
||||
if (err instanceof tc.HTTPError && err.httpStatusCode === 404) {
|
||||
throw new Error(
|
||||
`The requested Go version ${versionSpec} is not available for platform ${osPlat}/${arch}. ` +
|
||||
`Download URL returned HTTP 404: ${downloadUrl}`
|
||||
`Download URL returned HTTP 404: ${downloadUrl}`,
|
||||
{cause: err}
|
||||
);
|
||||
}
|
||||
throw new Error(
|
||||
`Failed to download Go ${versionSpec} for platform ${osPlat}/${arch} ` +
|
||||
`from ${downloadUrl}: ${err}`
|
||||
`from ${downloadUrl}: ${err}`,
|
||||
{cause: err}
|
||||
);
|
||||
}
|
||||
} else {
|
||||
@ -218,7 +221,9 @@ export async function getGo(
|
||||
core.info('Install from dist');
|
||||
downloadPath = await installGoVersion(info, undefined, arch);
|
||||
} catch (err) {
|
||||
throw new Error(`Failed to download version ${versionSpec}: ${err}`);
|
||||
throw new Error(`Failed to download version ${versionSpec}: ${err}`, {
|
||||
cause: err
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -569,9 +574,7 @@ export async function findMatch(
|
||||
let result: IGoVersion | undefined;
|
||||
let match: IGoVersion | undefined;
|
||||
|
||||
const candidates: IGoVersion[] | null = await module.exports.getVersionsDist(
|
||||
dlUrl
|
||||
);
|
||||
const candidates: IGoVersion[] | null = await getVersionsDist(dlUrl);
|
||||
if (!candidates) {
|
||||
throw new Error(`golang download url did not return results`);
|
||||
}
|
||||
@ -607,17 +610,6 @@ export async function findMatch(
|
||||
return result;
|
||||
}
|
||||
|
||||
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', [], {
|
||||
allowRedirects: true,
|
||||
maxRedirects: 3
|
||||
});
|
||||
return (await http.getJson<IGoVersion[]>(dlUrl)).result;
|
||||
}
|
||||
|
||||
//
|
||||
// Convert the go version syntax into semver for semver matching
|
||||
// 1.13.1 => 1.13.1
|
||||
@ -686,9 +678,8 @@ async function resolveStableVersionDist(
|
||||
) {
|
||||
const archFilter = sys.getArch(arch);
|
||||
const platFilter = sys.getPlatform();
|
||||
const candidates: IGoVersion[] | null = await module.exports.getVersionsDist(
|
||||
GOLANG_DOWNLOAD_URL
|
||||
);
|
||||
const candidates: IGoVersion[] | null =
|
||||
await getVersionsDist(GOLANG_DOWNLOAD_URL);
|
||||
if (!candidates) {
|
||||
throw new Error(`golang download url did not return results`);
|
||||
}
|
||||
|
||||
15
src/main.ts
15
src/main.ts
@ -1,14 +1,15 @@
|
||||
import * as core from '@actions/core';
|
||||
import * as io from '@actions/io';
|
||||
import * as installer from './installer';
|
||||
import * as installer from './installer.js';
|
||||
import * as semver from 'semver';
|
||||
import path from 'path';
|
||||
import {restoreCache} from './cache-restore';
|
||||
import {isCacheFeatureAvailable} from './cache-utils';
|
||||
import {fileURLToPath} from 'url';
|
||||
import {restoreCache} from './cache-restore.js';
|
||||
import {isCacheFeatureAvailable} from './cache-utils.js';
|
||||
import cp from 'child_process';
|
||||
import fs from 'fs';
|
||||
import os from 'os';
|
||||
import {Architecture} from './types';
|
||||
import {Architecture} from './types.js';
|
||||
|
||||
export async function run() {
|
||||
try {
|
||||
@ -91,7 +92,11 @@ export async function run() {
|
||||
}
|
||||
|
||||
// add problem matchers
|
||||
const matchersPath = path.join(__dirname, '../..', 'matchers.json');
|
||||
const matchersPath = path.join(
|
||||
path.dirname(fileURLToPath(import.meta.url)),
|
||||
'../..',
|
||||
'matchers.json'
|
||||
);
|
||||
core.info(`##[add-matcher]${matchersPath}`);
|
||||
|
||||
// output the version actually being used
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
import {run} from './main';
|
||||
import {run} from './main.js';
|
||||
|
||||
run();
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import os from 'os';
|
||||
import {Architecture} from './types';
|
||||
import {Architecture} from './types.js';
|
||||
|
||||
export function getPlatform(): string {
|
||||
// darwin and linux match already
|
||||
|
||||
@ -2,8 +2,8 @@
|
||||
"compilerOptions": {
|
||||
/* Basic Options */
|
||||
// "incremental": true, /* Enable incremental compilation */
|
||||
"target": "es6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */
|
||||
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
|
||||
"target": "ES2022", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */
|
||||
"module": "NodeNext", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
|
||||
// "allowJs": true, /* Allow javascript files to be compiled. */
|
||||
// "checkJs": true, /* Report errors in .js files. */
|
||||
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
|
||||
@ -38,7 +38,7 @@
|
||||
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
|
||||
|
||||
/* Module Resolution Options */
|
||||
// "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
|
||||
// "moduleResolution": "NodeNext", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
|
||||
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
|
||||
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
|
||||
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
|
||||
@ -61,5 +61,5 @@
|
||||
// "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
|
||||
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
|
||||
},
|
||||
"exclude": ["node_modules", "**/*.test.ts"]
|
||||
"exclude": ["node_modules", "**/*.test.ts", "jest.config.ts"]
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user