Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ability to select to install matching version already available on the current image #19

Open
wants to merge 18 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions .github/workflows/e2e-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -481,3 +481,31 @@ jobs:
- name: Verify dotnet (higher version)
shell: pwsh
run: __tests__/verify-dotnet.ps1 -Patterns "^${{ matrix.lower-version }}$", "^${{ matrix.higher-version }}$"

test-version-already-installed:
runs-on: ${{ matrix.operating-system }}
strategy:
fail-fast: false
matrix:
operating-system: [ubuntu-latest, windows-latest, macos-latest]
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Clear toolcache
shell: pwsh
run: __tests__/clear-toolcache.ps1 ${{ runner.os }}
- name: Setup dotnet (first)
uses: ./
with:
dotnet-version: '6.0'
- name: Verify dotnet (first)
shell: pwsh
run: __tests__/verify-dotnet.ps1 -Patterns "^6.0"
- name: Setup dotnet (same major, any minor)
uses: ./
with:
dotnet-version: '6.x'
prefer-installed: true
- name: Verify dotnet (same major, any minor)
shell: pwsh
run: __tests__/verify-dotnet.ps1 -Patterns "^6.0"
79 changes: 79 additions & 0 deletions __tests__/dotnet-utils.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import * as dotnetUtils from '../src/dotnet-utils';
import * as exec from '@actions/exec';

describe('dotnet-utils', () => {
describe('matchVersionToList', () => {
it('matches all versions with all syntaxes correctly', () => {
expect(
dotnetUtils.matchVersionToList('3.1', ['3.1.201', '6.0.402'])
).toEqual('3.1.201');
expect(
dotnetUtils.matchVersionToList('3.1.x', ['3.1.201', '6.0.402'])
).toEqual('3.1.201');
expect(
dotnetUtils.matchVersionToList('3', ['3.1.201', '6.0.402'])
).toEqual('3.1.201');
expect(
dotnetUtils.matchVersionToList('3.x', ['3.1.201', '6.0.402'])
).toEqual('3.1.201');
expect(
dotnetUtils.matchVersionToList('6.0.4xx', ['3.1.201', '6.0.402'])
).toEqual('6.0.402');
});

it('returns undefined if no version is matched', () => {
expect(
dotnetUtils.matchVersionToList('6.0.5xx', ['3.1.201', '6.0.403'])
).toEqual(undefined);
expect(dotnetUtils.matchVersionToList('6.0.5xx', [])).toEqual(undefined);
});

it("returns the first version if 'x' or '*' version is provided", () => {
expect(
dotnetUtils.matchVersionToList('x', ['3.1.201', '6.0.403'])
).toEqual('3.1.201');
expect(
dotnetUtils.matchVersionToList('*', ['3.1.201', '6.0.403'])
).toEqual('3.1.201');
});

it('returns undefined if empty version list is provided', () => {
expect(dotnetUtils.matchVersionToList('6.0.4xx', [])).toEqual(undefined);
});
});

describe('listSdks', () => {
const execSpy = jest.spyOn(exec, 'getExecOutput');

it('correctly parses versions from output and sorts them from newest to oldest', async () => {
const stdout = `
2.2.207 [C:\\Users\\User_Name\\AppData\\Local\\Microsoft\\dotnet\\sdk]
6.0.413 [C:\\Users\\User_Name\\AppData\\Local\\Microsoft\\dotnet\\sdk]
6.0.414 [C:\\Users\\User_Name\\AppData\\Local\\Microsoft\\dotnet\\sdk]
`;

execSpy.mockImplementationOnce(() =>
Promise.resolve({stdout, exitCode: 0, stderr: ''})
);
expect(await dotnetUtils.listSdks()).toEqual([
'6.0.414',
'6.0.413',
'2.2.207'
]);
});

it('returns empty array if exit code is not 0', async () => {
execSpy.mockImplementationOnce(() =>
Promise.resolve({stdout: '', exitCode: 1, stderr: 'arbitrary error'})
);
expect(await dotnetUtils.listSdks()).toEqual([]);
});

it('returns empty array on error', async () => {
execSpy.mockImplementationOnce(() =>
Promise.reject(new Error('arbitrary error'))
);
expect(await dotnetUtils.listSdks()).toEqual([]);
});
});
});
57 changes: 48 additions & 9 deletions __tests__/installer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ describe('installer tests', () => {
const inputQuality = '' as QualityOptions;
const errorMessage = 'fictitious error message!';

const resolvedVersion = await new installer.DotnetVersionResolver(
inputVersion
).createDotnetVersion();

getExecOutputSpy.mockImplementation(() => {
return Promise.resolve({
exitCode: 1,
Expand All @@ -51,7 +55,7 @@ describe('installer tests', () => {
});

const dotnetInstaller = new installer.DotnetCoreInstaller(
inputVersion,
resolvedVersion,
inputQuality
);
await expect(dotnetInstaller.installDotnet()).rejects.toThrow(
Expand All @@ -63,6 +67,11 @@ describe('installer tests', () => {
const inputVersion = '3.1.100';
const inputQuality = '' as QualityOptions;
const stdout = `Fictitious dotnet version ${inputVersion} is installed`;

const resolvedVersion = await new installer.DotnetVersionResolver(
inputVersion
).createDotnetVersion();

getExecOutputSpy.mockImplementation(() => {
return Promise.resolve({
exitCode: 0,
Expand All @@ -73,7 +82,7 @@ describe('installer tests', () => {
maxSatisfyingSpy.mockImplementation(() => inputVersion);

const dotnetInstaller = new installer.DotnetCoreInstaller(
inputVersion,
resolvedVersion,
inputQuality
);
const installedVersion = await dotnetInstaller.installDotnet();
Expand All @@ -86,6 +95,10 @@ describe('installer tests', () => {
const inputQuality = '' as QualityOptions;
const stdout = `Fictitious dotnet version ${inputVersion} is installed`;

const resolvedVersion = await new installer.DotnetVersionResolver(
inputVersion
).createDotnetVersion();

getExecOutputSpy.mockImplementation(() => {
return Promise.resolve({
exitCode: 0,
Expand All @@ -96,7 +109,7 @@ describe('installer tests', () => {
maxSatisfyingSpy.mockImplementation(() => inputVersion);

const dotnetInstaller = new installer.DotnetCoreInstaller(
inputVersion,
resolvedVersion,
inputQuality
);

Expand All @@ -123,6 +136,11 @@ describe('installer tests', () => {
const inputVersion = '6.0.300';
const inputQuality = 'ga' as QualityOptions;
const stdout = `Fictitious dotnet version ${inputVersion} is installed`;

const resolvedVersion = await new installer.DotnetVersionResolver(
inputVersion
).createDotnetVersion();

getExecOutputSpy.mockImplementation(() => {
return Promise.resolve({
exitCode: 0,
Expand All @@ -133,7 +151,7 @@ describe('installer tests', () => {
maxSatisfyingSpy.mockImplementation(() => inputVersion);

const dotnetInstaller = new installer.DotnetCoreInstaller(
inputVersion,
resolvedVersion,
inputQuality
);

Expand All @@ -149,6 +167,10 @@ describe('installer tests', () => {
const inputQuality = 'ga' as QualityOptions;
const stdout = `Fictitious dotnet version 3.1.100 is installed`;

const resolvedVersion = await new installer.DotnetVersionResolver(
inputVersion
).createDotnetVersion();

getExecOutputSpy.mockImplementation(() => {
return Promise.resolve({
exitCode: 0,
Expand All @@ -159,7 +181,7 @@ describe('installer tests', () => {
maxSatisfyingSpy.mockImplementation(() => inputVersion);

const dotnetInstaller = new installer.DotnetCoreInstaller(
inputVersion,
resolvedVersion,
inputQuality
);

Expand All @@ -173,6 +195,10 @@ describe('installer tests', () => {
each(['6', '6.0', '6.0.x', '6.0.*', '6.0.X']).test(
`should supply 'quality' argument to the installation script if quality input is set and version (%s) is not in A.B.C syntax`,
async inputVersion => {
const resolvedVersion = await new installer.DotnetVersionResolver(
inputVersion
).createDotnetVersion();

const inputQuality = 'ga' as QualityOptions;
const exitCode = 0;
const stdout = `Fictitious dotnet version 6.0.0 is installed`;
Expand All @@ -186,7 +212,7 @@ describe('installer tests', () => {
maxSatisfyingSpy.mockImplementation(() => inputVersion);

const dotnetInstaller = new installer.DotnetCoreInstaller(
inputVersion,
resolvedVersion,
inputQuality
);

Expand Down Expand Up @@ -216,6 +242,11 @@ describe('installer tests', () => {
const inputQuality = '' as QualityOptions;
const exitCode = 0;
const stdout = `Fictitious dotnet version 6.0.0 is installed`;

const resolvedVersion = await new installer.DotnetVersionResolver(
inputVersion
).createDotnetVersion();

getExecOutputSpy.mockImplementation(() => {
return Promise.resolve({
exitCode: exitCode,
Expand All @@ -226,7 +257,7 @@ describe('installer tests', () => {
maxSatisfyingSpy.mockImplementation(() => inputVersion);

const dotnetInstaller = new installer.DotnetCoreInstaller(
inputVersion,
resolvedVersion,
inputQuality
);

Expand Down Expand Up @@ -257,6 +288,10 @@ describe('installer tests', () => {
const inputQuality = '' as QualityOptions;
const stdout = `Fictitious dotnet version ${inputVersion} is installed`;

const resolvedVersion = await new installer.DotnetVersionResolver(
inputVersion
).createDotnetVersion();

getExecOutputSpy.mockImplementation(() => {
return Promise.resolve({
exitCode: 0,
Expand All @@ -267,7 +302,7 @@ describe('installer tests', () => {
maxSatisfyingSpy.mockImplementation(() => inputVersion);

const dotnetInstaller = new installer.DotnetCoreInstaller(
inputVersion,
resolvedVersion,
inputQuality
);

Expand Down Expand Up @@ -295,6 +330,10 @@ describe('installer tests', () => {
const inputQuality = '' as QualityOptions;
const stdout = `Fictitious dotnet version 6.0.0 is installed`;

const resolvedVersion = await new installer.DotnetVersionResolver(
inputVersion
).createDotnetVersion();

getExecOutputSpy.mockImplementation(() => {
return Promise.resolve({
exitCode: 0,
Expand All @@ -305,7 +344,7 @@ describe('installer tests', () => {
maxSatisfyingSpy.mockImplementation(() => inputVersion);

const dotnetInstaller = new installer.DotnetCoreInstaller(
inputVersion,
resolvedVersion,
inputQuality
);

Expand Down
4 changes: 4 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ inputs:
description: 'Optional SDK version(s) to use. If not provided, will install global.json version when available. Examples: 2.2.104, 3.1, 3.1.x, 3.x, 6.0.2xx'
dotnet-quality:
description: 'Optional quality of the build. The possible values are: daily, signed, validated, preview, ga.'
prefer-installed:
description: 'Optional flag to prefer an already installed version of the SDK (when partial version syntax is used). If not provided, latest version with specified quality will be installed.'
required: false
default: false
global-json-file:
description: 'Optional global.json location, if your global.json isn''t located in the root of the repo.'
source-url:
Expand Down
Loading
Loading