Skip to content

Commit

Permalink
Merge pull request #428 from akv-platform/add-latest-patch-syntax
Browse files Browse the repository at this point in the history
Add latest patch syntax
  • Loading branch information
marko-zivic-93 committed May 24, 2023
2 parents 5fdecd2 + b891376 commit aa983c5
Show file tree
Hide file tree
Showing 8 changed files with 318 additions and 138 deletions.
46 changes: 46 additions & 0 deletions .github/workflows/e2e-tests.yml
Expand Up @@ -133,6 +133,27 @@ jobs:
shell: pwsh
run: __tests__/verify-dotnet.ps1 -Patterns "^2.2", "^3.1"

test-ABCxx-syntax:
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 6.0.4xx
uses: ./
with:
dotnet-version: '6.0.4xx'
- name: Verify dotnet
shell: pwsh
run: __tests__/verify-dotnet.ps1 -Patterns "^6\.0\.4\d{2}"

test-setup-with-wildcard:
runs-on: ${{ matrix.operating-system }}
strategy:
Expand Down Expand Up @@ -183,6 +204,31 @@ jobs:
shell: pwsh
run: __tests__/verify-dotnet.ps1 -Patterns "^2.2", "^3.1"

test-setup-global-json-only:
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: Write global.json
shell: bash
run: |
mkdir subdirectory
echo '{"sdk":{"version": "2.2.207","rollForward": "latestFeature"}}' > ./subdirectory/global.json
- name: Setup dotnet
uses: ./
with:
global-json-file: ./subdirectory/global.json
- name: Verify dotnet
shell: pwsh
run: __tests__/verify-dotnet.ps1 -Patterns "^2.2"

test-setup-with-dotnet-quality:
runs-on: ${{ matrix.operating-system }}
strategy:
Expand Down
3 changes: 2 additions & 1 deletion README.md
Expand Up @@ -49,12 +49,13 @@ The `dotnet-version` input supports following syntax:
- **A.B.C** (e.g 6.0.400, 7.0.100-preview.7.22377.5) - installs exact version of .NET SDK
- **A.B** or **A.B.x** (e.g. 3.1, 3.1.x) - installs the latest patch version of .NET SDK on the channel `3.1`, including prerelease versions (preview, rc)
- **A** or **A.x** (e.g. 3, 3.x) - installs the latest minor version of the specified major tag, including prerelease versions (preview, rc)
- **A.B.Cxx** (e.g. 6.0.4xx) - available since `.NET 5.0` release. Installs the latest version of the specific SDK release, including prerelease versions (preview, rc).


## Using the `dotnet-quality` input
This input sets up the action to install the latest build of the specified quality in the channel. The possible values of `dotnet-quality` are: **daily**, **signed**, **validated**, **preview**, **ga**.

> **Note**: `dotnet-quality` input can be used only with .NET SDK version in 'A.B', 'A.B.x', 'A' and 'A.x' formats where the major version is higher than 5. In other cases, `dotnet-quality` input will be ignored.
> **Note**: `dotnet-quality` input can be used only with .NET SDK version in 'A.B', 'A.B.x', 'A', 'A.x' and 'A.B.Cxx' formats where the major version is higher than 5. In other cases, `dotnet-quality` input will be ignored.
```yml
steps:
Expand Down
72 changes: 58 additions & 14 deletions __tests__/installer.test.ts
Expand Up @@ -48,8 +48,13 @@ describe('installer tests', () => {
it('should return version of .NET SDK after installation complete', async () => {
const inputVersion = '3.1.100';
const inputQuality = '' as QualityOptions;
const stdout = `Fictitious dotnet version ${inputVersion} is installed`;
getExecOutputSpy.mockImplementation(() => {
return Promise.resolve({exitCode: 0, stdout: '', stderr: ''});
return Promise.resolve({
exitCode: 0,
stdout: `${stdout}`,
stderr: ''
});
});
maxSatisfyingSpy.mockImplementation(() => inputVersion);

Expand All @@ -65,9 +70,14 @@ describe('installer tests', () => {
it(`should supply 'version' argument to the installation script if supplied version is in A.B.C syntax`, async () => {
const inputVersion = '6.0.300';
const inputQuality = '' as QualityOptions;
const stdout = `Fictitious dotnet version ${inputVersion} is installed`;

getExecOutputSpy.mockImplementation(() => {
return Promise.resolve({exitCode: 0, stdout: '', stderr: ''});
return Promise.resolve({
exitCode: 0,
stdout: `${stdout}`,
stderr: ''
});
});
maxSatisfyingSpy.mockImplementation(() => inputVersion);

Expand All @@ -91,9 +101,13 @@ describe('installer tests', () => {
it(`should warn if the 'quality' input is set and the supplied version is in A.B.C syntax`, async () => {
const inputVersion = '6.0.300';
const inputQuality = 'ga' as QualityOptions;

const stdout = `Fictitious dotnet version ${inputVersion} is installed`;
getExecOutputSpy.mockImplementation(() => {
return Promise.resolve({exitCode: 0, stdout: '', stderr: ''});
return Promise.resolve({
exitCode: 0,
stdout: `${stdout}`,
stderr: ''
});
});
maxSatisfyingSpy.mockImplementation(() => inputVersion);

Expand All @@ -105,16 +119,21 @@ describe('installer tests', () => {
await dotnetInstaller.installDotnet();

expect(warningSpy).toHaveBeenCalledWith(
`'dotnet-quality' input can be used only with .NET SDK version in A.B, A.B.x, A and A.x formats where the major tag is higher than 5. You specified: ${inputVersion}. 'dotnet-quality' input is ignored.`
`The 'dotnet-quality' input can be used only with .NET SDK version in A.B, A.B.x, A, A.x and A.B.Cxx formats where the major tag is higher than 5. You specified: ${inputVersion}. 'dotnet-quality' input is ignored.`
);
});

it(`should warn if the 'quality' input is set and version isn't in A.B.C syntax but major tag is lower then 6`, async () => {
const inputVersion = '3.1';
const inputQuality = 'ga' as QualityOptions;
const stdout = `Fictitious dotnet version 3.1.100 is installed`;

getExecOutputSpy.mockImplementation(() => {
return Promise.resolve({exitCode: 0, stdout: '', stderr: ''});
return Promise.resolve({
exitCode: 0,
stdout: `${stdout}`,
stderr: ''
});
});
maxSatisfyingSpy.mockImplementation(() => inputVersion);

Expand All @@ -126,7 +145,7 @@ describe('installer tests', () => {
await dotnetInstaller.installDotnet();

expect(warningSpy).toHaveBeenCalledWith(
`'dotnet-quality' input can be used only with .NET SDK version in A.B, A.B.x, A and A.x formats where the major tag is higher than 5. You specified: ${inputVersion}. 'dotnet-quality' input is ignored.`
`The 'dotnet-quality' input can be used only with .NET SDK version in A.B, A.B.x, A, A.x and A.B.Cxx formats where the major tag is higher than 5. You specified: ${inputVersion}. 'dotnet-quality' input is ignored.`
);
});

Expand All @@ -135,10 +154,11 @@ describe('installer tests', () => {
async inputVersion => {
const inputQuality = 'ga' as QualityOptions;
const exitCode = 0;
const stdout = `Fictitious dotnet version 6.0.0 is installed`;
getExecOutputSpy.mockImplementation(() => {
return Promise.resolve({
exitCode: exitCode,
stdout: '',
stdout: `${stdout}`,
stderr: ''
});
});
Expand Down Expand Up @@ -167,10 +187,11 @@ describe('installer tests', () => {
async inputVersion => {
const inputQuality = '' as QualityOptions;
const exitCode = 0;
const stdout = `Fictitious dotnet version 6.0.0 is installed`;
getExecOutputSpy.mockImplementation(() => {
return Promise.resolve({
exitCode: exitCode,
stdout: '',
stdout: `${stdout}`,
stderr: ''
});
});
Expand Down Expand Up @@ -199,9 +220,14 @@ describe('installer tests', () => {
process.env['https_proxy'] = 'https://proxy.com';
const inputVersion = '6.0.100';
const inputQuality = '' as QualityOptions;
const stdout = `Fictitious dotnet version ${inputVersion} is installed`;

getExecOutputSpy.mockImplementation(() => {
return Promise.resolve({exitCode: 0, stdout: '', stderr: ''});
return Promise.resolve({
exitCode: 0,
stdout: `${stdout}`,
stderr: ''
});
});
maxSatisfyingSpy.mockImplementation(() => inputVersion);

Expand All @@ -225,9 +251,14 @@ describe('installer tests', () => {
process.env['no_proxy'] = 'first.url,second.url';
const inputVersion = '6.0.100';
const inputQuality = '' as QualityOptions;
const stdout = `Fictitious dotnet version 6.0.0 is installed`;

getExecOutputSpy.mockImplementation(() => {
return Promise.resolve({exitCode: 0, stdout: '', stderr: ''});
return Promise.resolve({
exitCode: 0,
stdout: `${stdout}`,
stderr: ''
});
});
maxSatisfyingSpy.mockImplementation(() => inputVersion);

Expand Down Expand Up @@ -275,7 +306,8 @@ describe('installer tests', () => {
'3.1.*',
'3.1.X',
'3.1.2',
'3.1.0-preview1'
'3.1.0-preview1',
'6.0.2xx'
]).test(
'if valid version is supplied (%s), it should return version object with some value',
async version => {
Expand Down Expand Up @@ -327,7 +359,7 @@ describe('installer tests', () => {
}
);

each(['3', '3.1', '3.1.x', '3.1.*', '3.1.X']).test(
each(['3', '3.1', '3.1.x', '3.1.*', '3.1.X', '6.0.2xx']).test(
"if version that can be resolved to 'channel' option is supplied (%s), it should set type to 'channel' in version object",
async version => {
const dotnetVersionResolver = new installer.DotnetVersionResolver(
Expand All @@ -342,7 +374,7 @@ describe('installer tests', () => {
}
);

each(['6.0', '6.0.x', '6.0.*', '6.0.X']).test(
each(['6.0', '6.0.x', '6.0.*', '6.0.X', '6.0.2xx']).test(
"if version that can be resolved to 'channel' option is supplied and its major tag is >= 6 (%s), it should set type to 'channel' and qualityFlag to 'true' in version object",
async version => {
const dotnetVersionResolver = new installer.DotnetVersionResolver(
Expand Down Expand Up @@ -394,6 +426,18 @@ describe('installer tests', () => {
}
}
);

it(`should throw if dotnet-version is supplied in A.B.Cxx syntax with major tag lower that 5`, async () => {
const version = '3.0.1xx';
const dotnetVersionResolver = new installer.DotnetVersionResolver(
version
);
await expect(
async () => await dotnetVersionResolver.createDotNetVersion()
).rejects.toThrow(
`'dotnet-version' was supplied in invalid format: ${version}! The A.B.Cxx syntax is available since the .NET 5.0 release.`
);
});
});
});
});
35 changes: 31 additions & 4 deletions __tests__/setup-dotnet.test.ts
Expand Up @@ -12,6 +12,7 @@ describe('setup-dotnet tests', () => {
const getInputSpy = jest.spyOn(core, 'getInput');
const getMultilineInputSpy = jest.spyOn(core, 'getMultilineInput');
const setFailedSpy = jest.spyOn(core, 'setFailed');
const warningSpy = jest.spyOn(core, 'warning');
const debugSpy = jest.spyOn(core, 'debug');
const infoSpy = jest.spyOn(core, 'info');
const setOutputSpy = jest.spyOn(core, 'setOutput');
Expand Down Expand Up @@ -58,7 +59,7 @@ describe('setup-dotnet tests', () => {

const expectedDebugMessage =
'No version found, trying to find version from global.json';
const expectedInfoMessage = `global.json wasn't found in the root directory. No .NET version will be installed.`;
const expectedInfoMessage = `The global.json wasn't found in the root directory. No .NET version will be installed.`;

await setup.run();

Expand All @@ -72,7 +73,7 @@ describe('setup-dotnet tests', () => {
inputs['dotnet-version'] = ['6.0'];
inputs['dotnet-quality'] = 'fictitiousQuality';

const expectedErrorMessage = `${inputs['dotnet-quality']} is not a supported value for 'dotnet-quality' option. Supported values are: daily, signed, validated, preview, ga.`;
const expectedErrorMessage = `Value '${inputs['dotnet-quality']}' is not supported for the 'dotnet-quality' option. Supported values are: daily, signed, validated, preview, ga.`;

await setup.run();
expect(setFailedSpy).toHaveBeenCalledWith(expectedErrorMessage);
Expand Down Expand Up @@ -133,14 +134,40 @@ describe('setup-dotnet tests', () => {
);
});

it('should call setOutput() after installation complete', async () => {
it('should call setOutput() after installation complete successfully', async () => {
inputs['dotnet-version'] = ['6.0.300'];

installDotnetSpy.mockImplementation(() => Promise.resolve(''));
installDotnetSpy.mockImplementation(() =>
Promise.resolve(`${inputs['dotnet-version']}`)
);
addToPathSpy.mockImplementation(() => {});

await setup.run();
expect(setOutputSpy).toHaveBeenCalledTimes(1);
});

it(`shouldn't call setOutput() if parsing dotnet-installer logs failed`, async () => {
inputs['dotnet-version'] = ['6.0.300'];
const warningMessage = `Failed to output the installed version of .NET. The 'dotnet-version' output will not be set.`;

installDotnetSpy.mockImplementation(() => Promise.resolve(null));
addToPathSpy.mockImplementation(() => {});

await setup.run();
expect(warningSpy).toHaveBeenCalledWith(warningMessage);
expect(setOutputSpy).not.toHaveBeenCalled();
});

it(`shouldn't call setOutput() if actions didn't install .NET`, async () => {
inputs['dotnet-version'] = [];
const warningMessage = `The 'dotnet-version' output will not be set.`;

addToPathSpy.mockImplementation(() => {});

await setup.run();

expect(infoSpy).toHaveBeenCalledWith(warningMessage);
expect(setOutputSpy).not.toHaveBeenCalled();
});
});
});
2 changes: 1 addition & 1 deletion action.yml
Expand Up @@ -6,7 +6,7 @@ branding:
color: green
inputs:
dotnet-version:
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'
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.'
global-json-file:
Expand Down

0 comments on commit aa983c5

Please sign in to comment.