Add and configure ESLint and update configuration for Prettier (#458)

* Add ESLint config and update Prettier

* Update test files

* Rebuild action

* Update docs

* Update licenses

* Update tsconfig

* Rebuild action

* Update tsconfig.json

* Fix console.time calls

* Rebuild action

* Rebuild action on Linux
This commit is contained in:
Ivan 2023-03-09 14:49:35 +02:00 committed by GitHub
parent ea15b3b99c
commit 0de5c66fc0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
55 changed files with 4402 additions and 1317 deletions

6
.eslintignore Normal file
View File

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

49
.eslintrc.js Normal file
View File

@ -0,0 +1,49 @@
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-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}]
},
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
}
};

1
.gitattributes vendored
View File

@ -1,3 +1,4 @@
* text=auto eol=lf
dist/index.js -diff -merge
dist/index.js linguist-generated=true
.licenses/** -diff linguist-generated=true

View File

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

View File

@ -14,4 +14,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

@ -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

@ -151,7 +151,6 @@ jobs:
exit 1
fi
- name: Check files to cache on ubuntu-latest
if: matrix.os == 'ubuntu-latest'
run: |

View File

@ -86,7 +86,7 @@ jobs:
if ($content -notlike '*maven*') {
throw "settings.xml file is not overwritten"
}
test-publishing-skip-overwrite:
name: settings.xml is not overwritten if flag is false
runs-on: ${{ matrix.os }}
@ -150,4 +150,4 @@ jobs:
$path = Join-Path $env:RUNNER_TEMP "settings.xml"
if (-not (Test-Path $path)) {
throw "settings.xml file is not found in expected location"
}
}

View File

@ -11,7 +11,7 @@ on:
paths-ignore:
- '**.md'
schedule:
- cron: '0 */12 * * *'
- cron: '0 */12 * * *'
workflow_dispatch:
jobs:
setup-java-major-versions:
@ -21,21 +21,29 @@ jobs:
fail-fast: false
matrix:
os: [macos-latest, windows-latest, ubuntu-latest]
distribution: ['temurin', 'adopt', 'adopt-openj9', 'zulu', 'liberica', 'microsoft', 'corretto' ] # internally 'adopt-hotspot' is the same as 'adopt'
distribution: [
'temurin',
'adopt',
'adopt-openj9',
'zulu',
'liberica',
'microsoft',
'corretto'
] # internally 'adopt-hotspot' is the same as 'adopt'
version: ['8', '11', '16']
exclude:
- distribution: microsoft
version: 8
- distribution: microsoft
version: 8
include:
- distribution: oracle
os: macos-latest
version: 17
- distribution: oracle
os: windows-latest
version: 19
- distribution: oracle
os: ubuntu-latest
version: 19
- distribution: oracle
os: macos-latest
version: 17
- distribution: oracle
os: windows-latest
version: 19
- distribution: oracle
os: ubuntu-latest
version: 19
steps:
- name: Checkout
uses: actions/checkout@v3
@ -59,13 +67,13 @@ jobs:
os: [macos-latest, windows-latest, ubuntu-latest]
distribution: ['temurin', 'zulu', 'liberica']
version:
- '11.0'
- '8.0.302'
- '16.0.2+7'
- '11.0'
- '8.0.302'
- '16.0.2+7'
include:
- distribution: oracle
os: ubuntu-latest
version: '19.0.1'
- distribution: oracle
os: ubuntu-latest
version: '19.0.1'
steps:
- name: Checkout
uses: actions/checkout@v3
@ -262,7 +270,7 @@ jobs:
fail-fast: false
matrix:
os: [macos-latest, windows-latest, ubuntu-latest]
distribution: ['temurin', 'microsoft', 'corretto' ]
distribution: ['temurin', 'microsoft', 'corretto']
steps:
- name: Checkout
uses: actions/checkout@v3
@ -287,7 +295,7 @@ jobs:
fail-fast: false
matrix:
os: [macos-latest, windows-latest, ubuntu-latest]
distribution: ['temurin', 'zulu', 'liberica', 'microsoft', 'corretto' ]
distribution: ['temurin', 'zulu', 'liberica', 'microsoft', 'corretto']
steps:
- name: Checkout
uses: actions/checkout@v3
@ -311,7 +319,7 @@ jobs:
fail-fast: false
matrix:
os: [macos-latest, windows-latest, ubuntu-latest]
distribution: [ 'adopt', 'adopt-openj9', 'zulu' ]
distribution: ['adopt', 'adopt-openj9', 'zulu']
steps:
- name: Checkout
uses: actions/checkout@v3
@ -335,7 +343,7 @@ jobs:
fail-fast: false
matrix:
os: [macos-latest, windows-latest, ubuntu-latest]
distribution: ['adopt', 'zulu', 'liberica' ]
distribution: ['adopt', 'zulu', 'liberica']
steps:
- name: Checkout
uses: actions/checkout@v3

View File

@ -21,9 +21,9 @@ jobs:
name: releaseNewActionVersion
runs-on: ubuntu-latest
steps:
- name: Update the ${{ env.TAG_NAME }} tag
id: update-major-tag
uses: actions/publish-action@v0.2.2
with:
source-tag: ${{ env.TAG_NAME }}
slack-webhook: ${{ secrets.SLACK_WEBHOOK }}
- name: Update the ${{ env.TAG_NAME }} tag
id: update-major-tag
uses: actions/publish-action@v0.2.2
with:
source-tag: ${{ env.TAG_NAME }}
slack-webhook: ${{ secrets.SLACK_WEBHOOK }}

26
.licenses/npm/semver-7.3.8.dep.yml generated Normal file
View File

@ -0,0 +1,26 @@
---
name: semver
version: 7.3.8
type: npm
summary: The semantic version parser used by npm.
homepage:
license: isc
licenses:
- sources: LICENSE
text: |
The ISC License
Copyright (c) Isaac Z. Schlueter and Contributors
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
notices: []

7
.prettierignore Normal file
View File

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

10
.prettierrc.js Normal file
View File

@ -0,0 +1,10 @@
module.exports = {
printWidth: 80,
tabWidth: 2,
useTabs: false,
semi: true,
singleQuote: true,
trailingComma: 'none',
bracketSpacing: false,
arrowParens: 'avoid'
};

View File

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

View File

@ -1,11 +1,11 @@
import io = require('@actions/io');
import fs = require('fs');
import path = require('path');
import * as io from '@actions/io';
import * as core from '@actions/core';
import * as fs from 'fs';
import * as path from 'path';
import os from 'os';
import * as auth from '../src/auth';
import { M2_DIR, MVN_SETTINGS_FILE } from '../src/constants';
import {M2_DIR, MVN_SETTINGS_FILE} from '../src/constants';
const m2Dir = path.join(__dirname, M2_DIR);
const settingsFile = path.join(m2Dir, MVN_SETTINGS_FILE);
@ -42,7 +42,13 @@ describe('auth tests', () => {
const altSettingsFile = path.join(altHome, MVN_SETTINGS_FILE);
await io.rmRF(altHome); // ensure it doesn't already exist
await auth.createAuthenticationSettings(id, username, password, altHome, true);
await auth.createAuthenticationSettings(
id,
username,
password,
altHome,
true
);
expect(fs.existsSync(m2Dir)).toBe(false);
expect(fs.existsSync(settingsFile)).toBe(false);
@ -61,11 +67,19 @@ describe('auth tests', () => {
const username = 'UNAME';
const password = 'TOKEN';
await auth.createAuthenticationSettings(id, username, password, m2Dir, true);
await auth.createAuthenticationSettings(
id,
username,
password,
m2Dir,
true
);
expect(fs.existsSync(m2Dir)).toBe(true);
expect(fs.existsSync(settingsFile)).toBe(true);
expect(fs.readFileSync(settingsFile, 'utf-8')).toEqual(auth.generate(id, username, password));
expect(fs.readFileSync(settingsFile, 'utf-8')).toEqual(
auth.generate(id, username, password)
);
}, 100000);
it('creates settings.xml with additional configuration', async () => {
@ -74,7 +88,14 @@ describe('auth tests', () => {
const password = 'TOKEN';
const gpgPassphrase = 'GPG';
await auth.createAuthenticationSettings(id, username, password, m2Dir, true, gpgPassphrase);
await auth.createAuthenticationSettings(
id,
username,
password,
m2Dir,
true,
gpgPassphrase
);
expect(fs.existsSync(m2Dir)).toBe(true);
expect(fs.existsSync(settingsFile)).toBe(true);
@ -88,16 +109,24 @@ describe('auth tests', () => {
const username = 'USERNAME';
const password = 'PASSWORD';
fs.mkdirSync(m2Dir, { recursive: true });
fs.mkdirSync(m2Dir, {recursive: true});
fs.writeFileSync(settingsFile, 'FAKE FILE');
expect(fs.existsSync(m2Dir)).toBe(true);
expect(fs.existsSync(settingsFile)).toBe(true);
await auth.createAuthenticationSettings(id, username, password, m2Dir, true);
await auth.createAuthenticationSettings(
id,
username,
password,
m2Dir,
true
);
expect(fs.existsSync(m2Dir)).toBe(true);
expect(fs.existsSync(settingsFile)).toBe(true);
expect(fs.readFileSync(settingsFile, 'utf-8')).toEqual(auth.generate(id, username, password));
expect(fs.readFileSync(settingsFile, 'utf-8')).toEqual(
auth.generate(id, username, password)
);
}, 100000);
it('does not overwrite existing settings.xml files', async () => {
@ -105,12 +134,18 @@ describe('auth tests', () => {
const username = 'USERNAME';
const password = 'PASSWORD';
fs.mkdirSync(m2Dir, { recursive: true });
fs.mkdirSync(m2Dir, {recursive: true});
fs.writeFileSync(settingsFile, 'FAKE FILE');
expect(fs.existsSync(m2Dir)).toBe(true);
expect(fs.existsSync(settingsFile)).toBe(true);
await auth.createAuthenticationSettings(id, username, password, m2Dir, false);
await auth.createAuthenticationSettings(
id,
username,
password,
m2Dir,
false
);
expect(fs.existsSync(m2Dir)).toBe(true);
expect(fs.existsSync(settingsFile)).toBe(true);
@ -159,6 +194,8 @@ describe('auth tests', () => {
</servers>
</settings>`;
expect(auth.generate(id, username, password, gpgPassphrase)).toEqual(expectedSettings);
expect(auth.generate(id, username, password, gpgPassphrase)).toEqual(
expectedSettings
);
});
});

View File

@ -1,7 +1,7 @@
import { mkdtempSync } from 'fs';
import { tmpdir } from 'os';
import { join } from 'path';
import { restore, save } from '../src/cache';
import {mkdtempSync} from 'fs';
import {tmpdir} from 'os';
import {join} from 'path';
import {restore, save} from '../src/cache';
import * as fs from 'fs';
import * as os from 'os';
import * as core from '@actions/core';
@ -68,17 +68,21 @@ describe('dependency cache', () => {
beforeEach(() => {
spyCacheRestore = jest
.spyOn(cache, 'restoreCache')
.mockImplementation((paths: string[], primaryKey: string) => Promise.resolve(undefined));
.mockImplementation((paths: string[], primaryKey: string) =>
Promise.resolve(undefined)
);
spyWarning.mockImplementation(() => null);
});
it('throws error if unsupported package manager specified', () => {
return expect(restore('ant')).rejects.toThrowError('unknown package manager specified: ant');
return expect(restore('ant')).rejects.toThrow(
'unknown package manager specified: ant'
);
});
describe('for maven', () => {
it('throws error if no pom.xml found', async () => {
await expect(restore('maven')).rejects.toThrowError(
await expect(restore('maven')).rejects.toThrow(
`No file in ${projectRoot(
workspace
)} matched to [**/pom.xml], make sure you have checked out the target repository`
@ -88,14 +92,14 @@ describe('dependency cache', () => {
createFile(join(workspace, 'pom.xml'));
await restore('maven');
expect(spyCacheRestore).toBeCalled();
expect(spyWarning).not.toBeCalled();
expect(spyInfo).toBeCalledWith('maven cache is not found');
expect(spyCacheRestore).toHaveBeenCalled();
expect(spyWarning).not.toHaveBeenCalled();
expect(spyInfo).toHaveBeenCalledWith('maven cache is not found');
});
});
describe('for gradle', () => {
it('throws error if no build.gradle found', async () => {
await expect(restore('gradle')).rejects.toThrowError(
await expect(restore('gradle')).rejects.toThrow(
`No file in ${projectRoot(
workspace
)} matched to [**/*.gradle*,**/gradle-wrapper.properties,buildSrc/**/Versions.kt,buildSrc/**/Dependencies.kt,gradle/*.versions.toml], make sure you have checked out the target repository`
@ -105,26 +109,26 @@ describe('dependency cache', () => {
createFile(join(workspace, 'build.gradle'));
await restore('gradle');
expect(spyCacheRestore).toBeCalled();
expect(spyWarning).not.toBeCalled();
expect(spyInfo).toBeCalledWith('gradle cache is not found');
expect(spyCacheRestore).toHaveBeenCalled();
expect(spyWarning).not.toHaveBeenCalled();
expect(spyInfo).toHaveBeenCalledWith('gradle cache is not found');
});
it('downloads cache based on build.gradle.kts', async () => {
createFile(join(workspace, 'build.gradle.kts'));
await restore('gradle');
expect(spyCacheRestore).toBeCalled();
expect(spyWarning).not.toBeCalled();
expect(spyInfo).toBeCalledWith('gradle cache is not found');
expect(spyCacheRestore).toHaveBeenCalled();
expect(spyWarning).not.toHaveBeenCalled();
expect(spyInfo).toHaveBeenCalledWith('gradle cache is not found');
});
it('downloads cache based on libs.versions.toml', async () => {
createDirectory(join(workspace, 'gradle'));
createFile(join(workspace, 'gradle', 'libs.versions.toml'));
await restore('gradle');
expect(spyCacheRestore).toBeCalled();
expect(spyWarning).not.toBeCalled();
expect(spyInfo).toBeCalledWith('gradle cache is not found');
expect(spyCacheRestore).toHaveBeenCalled();
expect(spyWarning).not.toHaveBeenCalled();
expect(spyInfo).toHaveBeenCalledWith('gradle cache is not found');
});
});
it('downloads cache based on buildSrc/Versions.kt', async () => {
@ -132,13 +136,13 @@ describe('dependency cache', () => {
createFile(join(workspace, 'buildSrc', 'Versions.kt'));
await restore('gradle');
expect(spyCacheRestore).toBeCalled();
expect(spyWarning).not.toBeCalled();
expect(spyInfo).toBeCalledWith('gradle cache is not found');
expect(spyCacheRestore).toHaveBeenCalled();
expect(spyWarning).not.toHaveBeenCalled();
expect(spyInfo).toHaveBeenCalledWith('gradle cache is not found');
});
describe('for sbt', () => {
it('throws error if no build.sbt found', async () => {
await expect(restore('sbt')).rejects.toThrowError(
await expect(restore('sbt')).rejects.toThrow(
`No file in ${projectRoot(
workspace
)} matched to [**/*.sbt,**/project/build.properties,**/project/**.{scala,sbt}], make sure you have checked out the target repository`
@ -148,9 +152,9 @@ describe('dependency cache', () => {
createFile(join(workspace, 'build.sbt'));
await restore('sbt');
expect(spyCacheRestore).toBeCalled();
expect(spyWarning).not.toBeCalled();
expect(spyInfo).toBeCalledWith('sbt cache is not found');
expect(spyCacheRestore).toHaveBeenCalled();
expect(spyWarning).not.toHaveBeenCalled();
expect(spyInfo).toHaveBeenCalledWith('sbt cache is not found');
});
});
});
@ -163,12 +167,16 @@ describe('dependency cache', () => {
beforeEach(() => {
spyCacheSave = jest
.spyOn(cache, 'saveCache')
.mockImplementation((paths: string[], key: string) => Promise.resolve(0));
.mockImplementation((paths: string[], key: string) =>
Promise.resolve(0)
);
spyWarning.mockImplementation(() => null);
});
it('throws error if unsupported package manager specified', () => {
return expect(save('ant')).rejects.toThrowError('unknown package manager specified: ant');
return expect(save('ant')).rejects.toThrow(
'unknown package manager specified: ant'
);
});
it('save with -1 cacheId , should not fail workflow', async () => {
@ -176,10 +184,12 @@ describe('dependency cache', () => {
createStateForMissingBuildFile();
await save('maven');
expect(spyCacheSave).toBeCalled();
expect(spyWarning).not.toBeCalled();
expect(spyInfo).toBeCalled();
expect(spyInfo).toBeCalledWith(expect.stringMatching(/^Cache saved with the key:.*/));
expect(spyCacheSave).toHaveBeenCalled();
expect(spyWarning).not.toHaveBeenCalled();
expect(spyInfo).toHaveBeenCalled();
expect(spyInfo).toHaveBeenCalledWith(
expect.stringMatching(/^Cache saved with the key:.*/)
);
});
it('saves with error from toolkit, should fail workflow', async () => {
@ -189,31 +199,37 @@ describe('dependency cache', () => {
createStateForMissingBuildFile();
expect.assertions(1);
await expect(save('maven')).rejects.toEqual(new cache.ValidationError('Validation failed'));
await expect(save('maven')).rejects.toEqual(
new cache.ValidationError('Validation failed')
);
});
describe('for maven', () => {
it('uploads cache even if no pom.xml found', async () => {
createStateForMissingBuildFile();
await save('maven');
expect(spyCacheSave).toBeCalled();
expect(spyWarning).not.toBeCalled();
expect(spyCacheSave).toHaveBeenCalled();
expect(spyWarning).not.toHaveBeenCalled();
});
it('does not upload cache if no restore run before', async () => {
createFile(join(workspace, 'pom.xml'));
await save('maven');
expect(spyCacheSave).not.toBeCalled();
expect(spyWarning).toBeCalledWith('Error retrieving key from state.');
expect(spyCacheSave).not.toHaveBeenCalled();
expect(spyWarning).toHaveBeenCalledWith(
'Error retrieving key from state.'
);
});
it('uploads cache', async () => {
createFile(join(workspace, 'pom.xml'));
createStateForSuccessfulRestore();
await save('maven');
expect(spyCacheSave).toBeCalled();
expect(spyWarning).not.toBeCalled();
expect(spyInfo).toBeCalledWith(expect.stringMatching(/^Cache saved with the key:.*/));
expect(spyCacheSave).toHaveBeenCalled();
expect(spyWarning).not.toHaveBeenCalled();
expect(spyInfo).toHaveBeenCalledWith(
expect.stringMatching(/^Cache saved with the key:.*/)
);
});
});
describe('for gradle', () => {
@ -221,33 +237,39 @@ describe('dependency cache', () => {
createStateForMissingBuildFile();
await save('gradle');
expect(spyCacheSave).toBeCalled();
expect(spyWarning).not.toBeCalled();
expect(spyCacheSave).toHaveBeenCalled();
expect(spyWarning).not.toHaveBeenCalled();
});
it('does not upload cache if no restore run before', async () => {
createFile(join(workspace, 'build.gradle'));
await save('gradle');
expect(spyCacheSave).not.toBeCalled();
expect(spyWarning).toBeCalledWith('Error retrieving key from state.');
expect(spyCacheSave).not.toHaveBeenCalled();
expect(spyWarning).toHaveBeenCalledWith(
'Error retrieving key from state.'
);
});
it('uploads cache based on build.gradle', async () => {
createFile(join(workspace, 'build.gradle'));
createStateForSuccessfulRestore();
await save('gradle');
expect(spyCacheSave).toBeCalled();
expect(spyWarning).not.toBeCalled();
expect(spyInfo).toBeCalledWith(expect.stringMatching(/^Cache saved with the key:.*/));
expect(spyCacheSave).toHaveBeenCalled();
expect(spyWarning).not.toHaveBeenCalled();
expect(spyInfo).toHaveBeenCalledWith(
expect.stringMatching(/^Cache saved with the key:.*/)
);
});
it('uploads cache based on build.gradle.kts', async () => {
createFile(join(workspace, 'build.gradle.kts'));
createStateForSuccessfulRestore();
await save('gradle');
expect(spyCacheSave).toBeCalled();
expect(spyWarning).not.toBeCalled();
expect(spyInfo).toBeCalledWith(expect.stringMatching(/^Cache saved with the key:.*/));
expect(spyCacheSave).toHaveBeenCalled();
expect(spyWarning).not.toHaveBeenCalled();
expect(spyInfo).toHaveBeenCalledWith(
expect.stringMatching(/^Cache saved with the key:.*/)
);
});
it('uploads cache based on buildSrc/Versions.kt', async () => {
createDirectory(join(workspace, 'buildSrc'));
@ -255,33 +277,39 @@ describe('dependency cache', () => {
createStateForSuccessfulRestore();
await save('gradle');
expect(spyCacheSave).toBeCalled();
expect(spyWarning).not.toBeCalled();
expect(spyInfo).toBeCalledWith(expect.stringMatching(/^Cache saved with the key:.*/));
expect(spyCacheSave).toHaveBeenCalled();
expect(spyWarning).not.toHaveBeenCalled();
expect(spyInfo).toHaveBeenCalledWith(
expect.stringMatching(/^Cache saved with the key:.*/)
);
});
});
describe('for sbt', () => {
it('uploads cache even if no build.sbt found', async () => {
createStateForMissingBuildFile();
await save('sbt');
expect(spyCacheSave).toBeCalled();
expect(spyWarning).not.toBeCalled();
expect(spyCacheSave).toHaveBeenCalled();
expect(spyWarning).not.toHaveBeenCalled();
});
it('does not upload cache if no restore run before', async () => {
createFile(join(workspace, 'build.sbt'));
await save('sbt');
expect(spyCacheSave).not.toBeCalled();
expect(spyWarning).toBeCalledWith('Error retrieving key from state.');
expect(spyCacheSave).not.toHaveBeenCalled();
expect(spyWarning).toHaveBeenCalledWith(
'Error retrieving key from state.'
);
});
it('uploads cache', async () => {
createFile(join(workspace, 'build.sbt'));
createStateForSuccessfulRestore();
await save('sbt');
expect(spyCacheSave).toBeCalled();
expect(spyWarning).not.toBeCalled();
expect(spyInfo).toBeCalledWith(expect.stringMatching(/^Cache saved with the key:.*/));
expect(spyCacheSave).toHaveBeenCalled();
expect(spyWarning).not.toHaveBeenCalled();
expect(spyInfo).toHaveBeenCalledWith(
expect.stringMatching(/^Cache saved with the key:.*/)
);
});
});
});

View File

@ -1,4 +1,4 @@
import { run as cleanup } from '../src/cleanup-java';
import {run as cleanup} from '../src/cleanup-java';
import * as core from '@actions/core';
import * as cache from '@actions/cache';
import * as util from '../src/util';
@ -38,8 +38,8 @@ describe('cleanup', () => {
return name === 'cache' ? 'gradle' : '';
});
await cleanup();
expect(spyCacheSave).toBeCalled();
expect(spyWarning).not.toBeCalled();
expect(spyCacheSave).toHaveBeenCalled();
expect(spyWarning).not.toHaveBeenCalled();
});
it('does not fail even though the save process throws error', async () => {
@ -50,7 +50,7 @@ describe('cleanup', () => {
return name === 'cache' ? 'gradle' : '';
});
await cleanup();
expect(spyCacheSave).toBeCalled();
expect(spyCacheSave).toHaveBeenCalled();
});
});

View File

@ -1,11 +1,14 @@
import { HttpClient } from '@actions/http-client';
import { AdoptDistribution, AdoptImplementation } from '../../src/distributions/adopt/installer';
import { JavaInstallerOptions } from '../../src/distributions/base-models';
import {HttpClient} from '@actions/http-client';
import {IAdoptAvailableVersions} from '../../src/distributions/adopt/models';
import {
AdoptDistribution,
AdoptImplementation
} from '../../src/distributions/adopt/installer';
import {JavaInstallerOptions} from '../../src/distributions/base-models';
import os from 'os';
let manifestData = require('../data/adopt.json') as [];
import manifestData from '../data/adopt.json';
describe('getAvailableVersions', () => {
let spyHttpClient: jest.SpyInstance;
@ -27,42 +30,82 @@ describe('getAvailableVersions', () => {
it.each([
[
{ version: '11', architecture: 'x64', packageType: 'jdk', checkLatest: false },
{
version: '11',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
},
AdoptImplementation.Hotspot,
'os=mac&architecture=x64&image_type=jdk&release_type=ga&jvm_impl=hotspot&page_size=20&page=0'
],
[
{ version: '11', architecture: 'x86', packageType: 'jdk', checkLatest: false },
{
version: '11',
architecture: 'x86',
packageType: 'jdk',
checkLatest: false
},
AdoptImplementation.Hotspot,
'os=mac&architecture=x86&image_type=jdk&release_type=ga&jvm_impl=hotspot&page_size=20&page=0'
],
[
{ version: '11', architecture: 'x64', packageType: 'jre', checkLatest: false },
{
version: '11',
architecture: 'x64',
packageType: 'jre',
checkLatest: false
},
AdoptImplementation.Hotspot,
'os=mac&architecture=x64&image_type=jre&release_type=ga&jvm_impl=hotspot&page_size=20&page=0'
],
[
{ version: '11-ea', architecture: 'x64', packageType: 'jdk', checkLatest: false },
{
version: '11-ea',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
},
AdoptImplementation.Hotspot,
'os=mac&architecture=x64&image_type=jdk&release_type=ea&jvm_impl=hotspot&page_size=20&page=0'
],
[
{ version: '11', architecture: 'x64', packageType: 'jdk', checkLatest: false },
{
version: '11',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
},
AdoptImplementation.OpenJ9,
'os=mac&architecture=x64&image_type=jdk&release_type=ga&jvm_impl=openj9&page_size=20&page=0'
],
[
{ version: '11', architecture: 'x86', packageType: 'jdk', checkLatest: false },
{
version: '11',
architecture: 'x86',
packageType: 'jdk',
checkLatest: false
},
AdoptImplementation.OpenJ9,
'os=mac&architecture=x86&image_type=jdk&release_type=ga&jvm_impl=openj9&page_size=20&page=0'
],
[
{ version: '11', architecture: 'x64', packageType: 'jre', checkLatest: false },
{
version: '11',
architecture: 'x64',
packageType: 'jre',
checkLatest: false
},
AdoptImplementation.OpenJ9,
'os=mac&architecture=x64&image_type=jre&release_type=ga&jvm_impl=openj9&page_size=20&page=0'
],
[
{ version: '11-ea', architecture: 'x64', packageType: 'jdk', checkLatest: false },
{
version: '11-ea',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
},
AdoptImplementation.OpenJ9,
'os=mac&architecture=x64&image_type=jdk&release_type=ea&jvm_impl=openj9&page_size=20&page=0'
]
@ -74,7 +117,8 @@ describe('getAvailableVersions', () => {
expectedParameters
) => {
const distribution = new AdoptDistribution(installerOptions, impl);
const baseUrl = 'https://api.adoptopenjdk.net/v3/assets/version/%5B1.0,100.0%5D';
const baseUrl =
'https://api.adoptopenjdk.net/v3/assets/version/%5B1.0,100.0%5D';
const expectedUrl = `${baseUrl}?project=jdk&vendor=adoptopenjdk&heap_size=normal&sort_method=DEFAULT&sort_order=DESC&${expectedParameters}`;
distribution['getPlatformOption'] = () => 'mac';
@ -91,12 +135,12 @@ describe('getAvailableVersions', () => {
.mockReturnValueOnce({
statusCode: 200,
headers: {},
result: manifestData
result: manifestData as any
})
.mockReturnValueOnce({
statusCode: 200,
headers: {},
result: manifestData
result: manifestData as any
})
.mockReturnValueOnce({
statusCode: 200,
@ -105,7 +149,12 @@ describe('getAvailableVersions', () => {
});
const distribution = new AdoptDistribution(
{ version: '11', architecture: 'x64', packageType: 'jdk', checkLatest: false },
{
version: '11',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
},
AdoptImplementation.Hotspot
);
const availableVersions = await distribution['getAvailableVersions']();
@ -122,7 +171,12 @@ describe('getAvailableVersions', () => {
'find right toolchain folder',
(impl: AdoptImplementation, packageType: string, expected: string) => {
const distribution = new AdoptDistribution(
{ version: '11', architecture: 'x64', packageType: packageType, checkLatest: false },
{
version: '11',
architecture: 'x64',
packageType: packageType,
checkLatest: false
},
impl
);
@ -148,8 +202,12 @@ describe('getAvailableVersions', () => {
const expectedParameters = `os=mac&architecture=${distroArch}&image_type=jdk&release_type=ga&jvm_impl=hotspot&page_size=20&page=0`;
const distribution = new AdoptDistribution(installerOptions, AdoptImplementation.Hotspot);
const baseUrl = 'https://api.adoptopenjdk.net/v3/assets/version/%5B1.0,100.0%5D';
const distribution = new AdoptDistribution(
installerOptions,
AdoptImplementation.Hotspot
);
const baseUrl =
'https://api.adoptopenjdk.net/v3/assets/version/%5B1.0,100.0%5D';
const expectedUrl = `${baseUrl}?project=jdk&vendor=adoptopenjdk&heap_size=normal&sort_method=DEFAULT&sort_order=DESC&${expectedParameters}`;
distribution['getPlatformOption'] = () => 'mac';
@ -176,43 +234,63 @@ describe('findPackageForDownload', () => {
['15.0.1+9.1', '15.0.1+9.1']
])('version is resolved correctly %s -> %s', async (input, expected) => {
const distribution = new AdoptDistribution(
{ version: '11', architecture: 'x64', packageType: 'jdk', checkLatest: false },
{
version: '11',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
},
AdoptImplementation.Hotspot
);
distribution['getAvailableVersions'] = async () => manifestData;
distribution['getAvailableVersions'] = async () => manifestData as any;
const resolvedVersion = await distribution['findPackageForDownload'](input);
expect(resolvedVersion.version).toBe(expected);
});
it('version is found but binaries list is empty', async () => {
const distribution = new AdoptDistribution(
{ version: '11', architecture: 'x64', packageType: 'jdk', checkLatest: false },
{
version: '11',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
},
AdoptImplementation.Hotspot
);
distribution['getAvailableVersions'] = async () => manifestData;
await expect(distribution['findPackageForDownload']('9.0.8')).rejects.toThrowError(
/Could not find satisfied version for SemVer */
);
distribution['getAvailableVersions'] = async () => manifestData as any;
await expect(
distribution['findPackageForDownload']('9.0.8')
).rejects.toThrow(/Could not find satisfied version for SemVer */);
});
it('version is not found', async () => {
const distribution = new AdoptDistribution(
{ version: '11', architecture: 'x64', packageType: 'jdk', checkLatest: false },
{
version: '11',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
},
AdoptImplementation.Hotspot
);
distribution['getAvailableVersions'] = async () => manifestData;
await expect(distribution['findPackageForDownload']('7.x')).rejects.toThrowError(
distribution['getAvailableVersions'] = async () => manifestData as any;
await expect(distribution['findPackageForDownload']('7.x')).rejects.toThrow(
/Could not find satisfied version for SemVer */
);
});
it('version list is empty', async () => {
const distribution = new AdoptDistribution(
{ version: '11', architecture: 'x64', packageType: 'jdk', checkLatest: false },
{
version: '11',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
},
AdoptImplementation.Hotspot
);
distribution['getAvailableVersions'] = async () => [];
await expect(distribution['findPackageForDownload']('11')).rejects.toThrowError(
await expect(distribution['findPackageForDownload']('11')).rejects.toThrow(
/Could not find satisfied version for SemVer */
);
});

View File

@ -5,7 +5,7 @@ import * as util from '../../src/util';
import path from 'path';
import * as semver from 'semver';
import { JavaBase } from '../../src/distributions/base-installer';
import {JavaBase} from '../../src/distributions/base-installer';
import {
JavaDownloadRelease,
JavaInstallerOptions,
@ -19,14 +19,23 @@ class EmptyJavaBase extends JavaBase {
super('Empty', installerOptions);
}
protected async downloadTool(javaRelease: JavaDownloadRelease): Promise<JavaInstallerResults> {
protected async downloadTool(
javaRelease: JavaDownloadRelease
): Promise<JavaInstallerResults> {
return {
version: '11.0.9',
path: path.join('toolcache', this.toolcacheFolderName, '11.0.9', this.architecture)
path: path.join(
'toolcache',
this.toolcacheFolderName,
'11.0.9',
this.architecture
)
};
}
protected async findPackageForDownload(range: string): Promise<JavaDownloadRelease> {
protected async findPackageForDownload(
range: string
): Promise<JavaDownloadRelease> {
const availableVersion = '11.0.9';
if (!semver.satisfies(availableVersion, range)) {
throw new Error('Available version not found');
@ -60,44 +69,111 @@ describe('findInToolcache', () => {
it.each([
[
{ version: '11', architecture: 'x64', packageType: 'jdk', checkLatest: false },
{ version: actualJavaVersion, path: javaPath }
{
version: '11',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
},
{version: actualJavaVersion, path: javaPath}
],
[
{ version: '11.0', architecture: 'x64', packageType: 'jdk', checkLatest: false },
{ version: actualJavaVersion, path: javaPath }
{
version: '11.0',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
},
{version: actualJavaVersion, path: javaPath}
],
[
{ version: '11.0.8', architecture: 'x64', packageType: 'jdk', checkLatest: false },
{ version: actualJavaVersion, path: javaPath }
{
version: '11.0.8',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
},
{version: actualJavaVersion, path: javaPath}
],
[
{ version: '11', architecture: 'x64', packageType: 'jdk', checkLatest: true },
{ version: actualJavaVersion, path: javaPath }
{
version: '11',
architecture: 'x64',
packageType: 'jdk',
checkLatest: true
},
{version: actualJavaVersion, path: javaPath}
],
[
{ version: '11.0', architecture: 'x64', packageType: 'jdk', checkLatest: true },
{ version: actualJavaVersion, path: javaPath }
{
version: '11.0',
architecture: 'x64',
packageType: 'jdk',
checkLatest: true
},
{version: actualJavaVersion, path: javaPath}
],
[
{ version: '11.0.8', architecture: 'x64', packageType: 'jdk', checkLatest: true },
{ version: actualJavaVersion, path: javaPath }
{
version: '11.0.8',
architecture: 'x64',
packageType: 'jdk',
checkLatest: true
},
{version: actualJavaVersion, path: javaPath}
],
[{ version: '11', architecture: 'x64', packageType: 'jre', checkLatest: false }, null],
[{ version: '8', architecture: 'x64', packageType: 'jdk', checkLatest: false }, null],
[{ version: '11', architecture: 'x86', packageType: 'jdk', checkLatest: false }, null],
[{ version: '11', architecture: 'x86', packageType: 'jre', checkLatest: false }, null]
[
{
version: '11',
architecture: 'x64',
packageType: 'jre',
checkLatest: false
},
null
],
[
{
version: '8',
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
},
null
],
[
{
version: '11',
architecture: 'x86',
packageType: 'jdk',
checkLatest: false
},
null
],
[
{
version: '11',
architecture: 'x86',
packageType: 'jre',
checkLatest: false
},
null
]
])(`should find java for path %s -> %s`, (input, expected) => {
spyTcFindAllVersions.mockReturnValue([actualJavaVersion]);
spyGetToolcachePath.mockImplementation(
(toolname: string, javaVersion: string, architecture: string) => {
const semverVersion = new semver.Range(javaVersion);
if (path.basename(javaPath) !== architecture || !javaPath.includes(toolname)) {
if (
path.basename(javaPath) !== architecture ||
!javaPath.includes(toolname)
) {
return '';
}
return semver.satisfies(actualJavaVersion, semverVersion) ? javaPath : '';
return semver.satisfies(actualJavaVersion, semverVersion)
? javaPath
: '';
}
);
mockJavaBase = new EmptyJavaBase(input);
@ -105,52 +181,63 @@ describe('findInToolcache', () => {
});
it.each([
['11', { version: '11.0.3+2', versionInPath: '11.0.3-2' }],
['11.0', { version: '11.0.3+2', versionInPath: '11.0.3-2' }],
['11.0.1', { version: '11.0.1', versionInPath: '11.0.1' }],
['11.0.3', { version: '11.0.3+2', versionInPath: '11.0.3-2' }],
['15', { version: '15.0.2+4', versionInPath: '15.0.2-4' }],
['x', { version: '15.0.2+4', versionInPath: '15.0.2-4' }],
['x-ea', { version: '17.4.4', versionInPath: '17.4.4-ea' }],
['11-ea', { version: '11.3.3+5.2.1231421', versionInPath: '11.3.3-ea.5.2.1231421' }],
['11.2-ea', { version: '11.2.1', versionInPath: '11.2.1-ea' }],
['11.2.1-ea', { version: '11.2.1', versionInPath: '11.2.1-ea' }]
])('should choose correct java from tool-cache for input %s', (input, expected) => {
spyTcFindAllVersions.mockReturnValue([
'17.4.4-ea',
'11.0.2',
'15.0.2-4',
'11.0.3-2',
'11.2.1-ea',
'11.3.2-ea',
'11.3.2-ea.5',
'11.3.3-ea.5.2.1231421',
'12.3.2-0',
'11.0.1'
]);
spyGetToolcachePath.mockImplementation(
(toolname: string, javaVersion: string, architecture: string) =>
`/hostedtoolcache/${toolname}/${javaVersion}/${architecture}`
);
mockJavaBase = new EmptyJavaBase({
version: input,
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
});
const foundVersion = mockJavaBase['findInToolcache']();
expect(foundVersion).toEqual({
version: expected.version,
path: `/hostedtoolcache/Java_Empty_jdk/${expected.versionInPath}/x64`
});
});
['11', {version: '11.0.3+2', versionInPath: '11.0.3-2'}],
['11.0', {version: '11.0.3+2', versionInPath: '11.0.3-2'}],
['11.0.1', {version: '11.0.1', versionInPath: '11.0.1'}],
['11.0.3', {version: '11.0.3+2', versionInPath: '11.0.3-2'}],
['15', {version: '15.0.2+4', versionInPath: '15.0.2-4'}],
['x', {version: '15.0.2+4', versionInPath: '15.0.2-4'}],
['x-ea', {version: '17.4.4', versionInPath: '17.4.4-ea'}],
[
'11-ea',
{version: '11.3.3+5.2.1231421', versionInPath: '11.3.3-ea.5.2.1231421'}
],
['11.2-ea', {version: '11.2.1', versionInPath: '11.2.1-ea'}],
['11.2.1-ea', {version: '11.2.1', versionInPath: '11.2.1-ea'}]
])(
'should choose correct java from tool-cache for input %s',
(input, expected) => {
spyTcFindAllVersions.mockReturnValue([
'17.4.4-ea',
'11.0.2',
'15.0.2-4',
'11.0.3-2',
'11.2.1-ea',
'11.3.2-ea',
'11.3.2-ea.5',
'11.3.3-ea.5.2.1231421',
'12.3.2-0',
'11.0.1'
]);
spyGetToolcachePath.mockImplementation(
(toolname: string, javaVersion: string, architecture: string) =>
`/hostedtoolcache/${toolname}/${javaVersion}/${architecture}`
);
mockJavaBase = new EmptyJavaBase({
version: input,
architecture: 'x64',
packageType: 'jdk',
checkLatest: false
});
const foundVersion = mockJavaBase['findInToolcache']();
expect(foundVersion).toEqual({
version: expected.version,
path: `/hostedtoolcache/Java_Empty_jdk/${expected.versionInPath}/x64`
});
}
);
});
describe('setupJava', () => {
const actualJavaVersion = '11.0.9';
const installedJavaVersion = '11.0.8';
const javaPath = path.join('Java_Empty_jdk', installedJavaVersion, 'x86');
const javaPathInstalled = path.join('toolcache', 'Java_Empty_jdk', actualJavaVersion, 'x86');
const javaPathInstalled = path.join(
'toolcache',
'Java_Empty_jdk',
actualJavaVersion,
'x86'
);
let mockJavaBase: EmptyJavaBase;
@ -168,11 +255,16 @@ describe('setupJava', () => {
(toolname: string, javaVersion: string, architecture: string) => {
const semverVersion = new semver.Range(javaVersion);
if (path.basename(javaPath) !== architecture || !javaPath.includes(toolname)) {
if (
path.basename(javaPath) !== architecture ||
!javaPath.includes(toolname)
) {
return '';
}
return semver.satisfies(installedJavaVersion, semverVersion) ? javaPath : '';
return semver.satisfies(installedJavaVersion, semverVersion)
? javaPath
: '';
}
);