From 4f6b2f576a2b2ce2f10314af6c29ddbc83956fdb Mon Sep 17 00:00:00 2001 From: IvanZosimov Date: Mon, 10 Apr 2023 16:23:29 +0200 Subject: [PATCH 01/30] Change the logic to support A.B.Cxx --- src/installer.ts | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/src/installer.ts b/src/installer.ts index ef9e993..5b4633c 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -12,7 +12,7 @@ import {IS_LINUX, IS_WINDOWS} from './utils'; import {QualityOptions} from './setup-dotnet'; export interface DotnetVersion { - type: string; + type: string | null; value: string; qualityFlag: boolean; } @@ -27,22 +27,25 @@ export class DotnetVersionResolver { } private async resolveVersionInput(): Promise { - if (!semver.validRange(this.inputVersion)) { + const isLatestPatchSyntax = /^\d+\.\d+\.\d{1}x{2}$/.test(this.inputVersion); + if (!semver.validRange(this.inputVersion) && !isLatestPatchSyntax) { throw new Error( - `'dotnet-version' was supplied in invalid format: ${this.inputVersion}! Supported syntax: A.B.C, A.B, A.B.x, A, A.x` + `'dotnet-version' was supplied in invalid format: ${this.inputVersion}! Supported syntax: A.B.C, A.B, A.B.x, A, A.x, A.B.Cxx` ); } if (semver.valid(this.inputVersion)) { this.resolvedArgument.type = 'version'; this.resolvedArgument.value = this.inputVersion; + } else if (!this.inputVersion) { + this.resolvedArgument.type = null; } else { + this.resolvedArgument.type = 'channel'; const [major, minor] = this.inputVersion.split('.'); - - if (this.isNumericTag(major)) { - this.resolvedArgument.type = 'channel'; - if (this.isNumericTag(minor)) { - this.resolvedArgument.value = `${major}.${minor}`; - } else { + if (isLatestPatchSyntax) { + this.resolvedArgument.value = this.inputVersion; + } else if (this.isNumericTag(major) && this.isNumericTag(minor)) { + this.resolvedArgument.value = `${major}.${minor}`; + } else { const httpClient = new hc.HttpClient('actions/setup-dotnet', [], { allowRetries: true, maxRetries: 3 @@ -51,7 +54,6 @@ export class DotnetVersionResolver { httpClient, [major, minor] ); - } } this.resolvedArgument.qualityFlag = +major >= 6 ? true : false; } @@ -61,11 +63,7 @@ export class DotnetVersionResolver { return /^\d+$/.test(versionTag); } - public async createDotNetVersion(): Promise<{ - type: string; - value: string; - qualityFlag: boolean; - }> { + public async createDotNetVersion(): Promise { await this.resolveVersionInput(); if (!this.resolvedArgument.type) { return this.resolvedArgument; From 660c25a3213763a17c64160616134dea8dd372f4 Mon Sep 17 00:00:00 2001 From: IvanZosimov Date: Mon, 10 Apr 2023 16:24:56 +0200 Subject: [PATCH 02/30] Rebuild action --- dist/index.js | 36 ++++++++++++++++++++++-------------- src/installer.ts | 16 ++++++++-------- 2 files changed, 30 insertions(+), 22 deletions(-) diff --git a/dist/index.js b/dist/index.js index 8e20d7f..92fa846 100644 --- a/dist/index.js +++ b/dist/index.js @@ -250,27 +250,35 @@ class DotnetVersionResolver { } resolveVersionInput() { return __awaiter(this, void 0, void 0, function* () { - if (!semver_1.default.validRange(this.inputVersion)) { - throw new Error(`'dotnet-version' was supplied in invalid format: ${this.inputVersion}! Supported syntax: A.B.C, A.B, A.B.x, A, A.x`); + const isLatestPatchSyntax = /^\d+\.\d+\.\d{1}x{2}$/.test(this.inputVersion); + if (!semver_1.default.validRange(this.inputVersion) && !isLatestPatchSyntax) { + throw new Error(`'dotnet-version' was supplied in invalid format: ${this.inputVersion}! Supported syntax: A.B.C, A.B, A.B.x, A, A.x, A.B.Cxx`); } if (semver_1.default.valid(this.inputVersion)) { this.resolvedArgument.type = 'version'; this.resolvedArgument.value = this.inputVersion; } + else if (!this.inputVersion) { + this.resolvedArgument.type = null; + } else { + this.resolvedArgument.type = 'channel'; const [major, minor] = this.inputVersion.split('.'); - if (this.isNumericTag(major)) { - this.resolvedArgument.type = 'channel'; - if (this.isNumericTag(minor)) { - this.resolvedArgument.value = `${major}.${minor}`; - } - else { - const httpClient = new hc.HttpClient('actions/setup-dotnet', [], { - allowRetries: true, - maxRetries: 3 - }); - this.resolvedArgument.value = yield this.getLatestVersion(httpClient, [major, minor]); - } + if (isLatestPatchSyntax) { + this.resolvedArgument.value = this.inputVersion; + } + else if (this.isNumericTag(major) && this.isNumericTag(minor)) { + this.resolvedArgument.value = `${major}.${minor}`; + } + else { + const httpClient = new hc.HttpClient('actions/setup-dotnet', [], { + allowRetries: true, + maxRetries: 3 + }); + this.resolvedArgument.value = yield this.getLatestVersion(httpClient, [ + major, + minor + ]); } this.resolvedArgument.qualityFlag = +major >= 6 ? true : false; } diff --git a/src/installer.ts b/src/installer.ts index 5b4633c..3764766 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -46,14 +46,14 @@ export class DotnetVersionResolver { } else if (this.isNumericTag(major) && this.isNumericTag(minor)) { this.resolvedArgument.value = `${major}.${minor}`; } else { - const httpClient = new hc.HttpClient('actions/setup-dotnet', [], { - allowRetries: true, - maxRetries: 3 - }); - this.resolvedArgument.value = await this.getLatestVersion( - httpClient, - [major, minor] - ); + const httpClient = new hc.HttpClient('actions/setup-dotnet', [], { + allowRetries: true, + maxRetries: 3 + }); + this.resolvedArgument.value = await this.getLatestVersion(httpClient, [ + major, + minor + ]); } this.resolvedArgument.qualityFlag = +major >= 6 ? true : false; } From f199d27aa16f8e90965db2b0d490f64f00b05178 Mon Sep 17 00:00:00 2001 From: IvanZosimov Date: Mon, 10 Apr 2023 16:58:35 +0200 Subject: [PATCH 03/30] Update solution --- dist/index.js | 3 --- src/installer.ts | 4 +--- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/dist/index.js b/dist/index.js index 92fa846..423a712 100644 --- a/dist/index.js +++ b/dist/index.js @@ -258,9 +258,6 @@ class DotnetVersionResolver { this.resolvedArgument.type = 'version'; this.resolvedArgument.value = this.inputVersion; } - else if (!this.inputVersion) { - this.resolvedArgument.type = null; - } else { this.resolvedArgument.type = 'channel'; const [major, minor] = this.inputVersion.split('.'); diff --git a/src/installer.ts b/src/installer.ts index 3764766..62b85d4 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -12,7 +12,7 @@ import {IS_LINUX, IS_WINDOWS} from './utils'; import {QualityOptions} from './setup-dotnet'; export interface DotnetVersion { - type: string | null; + type: string; value: string; qualityFlag: boolean; } @@ -36,8 +36,6 @@ export class DotnetVersionResolver { if (semver.valid(this.inputVersion)) { this.resolvedArgument.type = 'version'; this.resolvedArgument.value = this.inputVersion; - } else if (!this.inputVersion) { - this.resolvedArgument.type = null; } else { this.resolvedArgument.type = 'channel'; const [major, minor] = this.inputVersion.split('.'); From 0318091611d2eafad5e6d5f2d63c36cb06599242 Mon Sep 17 00:00:00 2001 From: IvanZosimov Date: Tue, 11 Apr 2023 13:20:34 +0200 Subject: [PATCH 04/30] Update resolveVersionInput() --- dist/index.js | 19 ++++++++----------- src/installer.ts | 24 ++++++++---------------- 2 files changed, 16 insertions(+), 27 deletions(-) diff --git a/dist/index.js b/dist/index.js index 423a712..6a33cee 100644 --- a/dist/index.js +++ b/dist/index.js @@ -268,14 +268,7 @@ class DotnetVersionResolver { this.resolvedArgument.value = `${major}.${minor}`; } else { - const httpClient = new hc.HttpClient('actions/setup-dotnet', [], { - allowRetries: true, - maxRetries: 3 - }); - this.resolvedArgument.value = yield this.getLatestVersion(httpClient, [ - major, - minor - ]); + this.resolvedArgument.value = yield this.getLatestByMajorTag(major); } this.resolvedArgument.qualityFlag = +major >= 6 ? true : false; } @@ -301,17 +294,21 @@ class DotnetVersionResolver { return this.resolvedArgument; }); } - getLatestVersion(httpClient, versionParts) { + getLatestByMajorTag(majorTag) { return __awaiter(this, void 0, void 0, function* () { + const httpClient = new hc.HttpClient('actions/setup-dotnet', [], { + allowRetries: true, + maxRetries: 3 + }); const response = yield httpClient.getJson(DotnetVersionResolver.DotNetCoreIndexUrl); const result = response.result || {}; const releasesInfo = result['releases-index']; const releaseInfo = releasesInfo.find(info => { const sdkParts = info['channel-version'].split('.'); - return sdkParts[0] === versionParts[0]; + return sdkParts[0] === majorTag; }); if (!releaseInfo) { - throw new Error(`Could not find info for version ${versionParts.join('.')} at ${DotnetVersionResolver.DotNetCoreIndexUrl}`); + throw new Error(`Could not find info for version with major tag: v${majorTag} at ${DotnetVersionResolver.DotNetCoreIndexUrl}`); } return releaseInfo['channel-version']; }); diff --git a/src/installer.ts b/src/installer.ts index 62b85d4..ec89a79 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -44,14 +44,7 @@ export class DotnetVersionResolver { } else if (this.isNumericTag(major) && this.isNumericTag(minor)) { this.resolvedArgument.value = `${major}.${minor}`; } else { - const httpClient = new hc.HttpClient('actions/setup-dotnet', [], { - allowRetries: true, - maxRetries: 3 - }); - this.resolvedArgument.value = await this.getLatestVersion(httpClient, [ - major, - minor - ]); + this.resolvedArgument.value = await this.getLatestByMajorTag(major); } this.resolvedArgument.qualityFlag = +major >= 6 ? true : false; } @@ -76,10 +69,11 @@ export class DotnetVersionResolver { return this.resolvedArgument; } - private async getLatestVersion( - httpClient: hc.HttpClient, - versionParts: string[] - ): Promise { + private async getLatestByMajorTag(majorTag: string): Promise { + const httpClient = new hc.HttpClient('actions/setup-dotnet', [], { + allowRetries: true, + maxRetries: 3 + }); const response = await httpClient.getJson( DotnetVersionResolver.DotNetCoreIndexUrl ); @@ -88,14 +82,12 @@ export class DotnetVersionResolver { const releaseInfo = releasesInfo.find(info => { const sdkParts: string[] = info['channel-version'].split('.'); - return sdkParts[0] === versionParts[0]; + return sdkParts[0] === majorTag; }); if (!releaseInfo) { throw new Error( - `Could not find info for version ${versionParts.join('.')} at ${ - DotnetVersionResolver.DotNetCoreIndexUrl - }` + `Could not find info for version with major tag: v${majorTag} at ${DotnetVersionResolver.DotNetCoreIndexUrl}` ); } From 12f70884d768a07fbd0e6c3566651161a817b92e Mon Sep 17 00:00:00 2001 From: IvanZosimov Date: Tue, 11 Apr 2023 13:23:50 +0200 Subject: [PATCH 05/30] Fix typo --- dist/index.js | 2 +- src/installer.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dist/index.js b/dist/index.js index 6a33cee..0515933 100644 --- a/dist/index.js +++ b/dist/index.js @@ -308,7 +308,7 @@ class DotnetVersionResolver { return sdkParts[0] === majorTag; }); if (!releaseInfo) { - throw new Error(`Could not find info for version with major tag: v${majorTag} at ${DotnetVersionResolver.DotNetCoreIndexUrl}`); + throw new Error(`Could not find info for version with major tag: ${majorTag} at ${DotnetVersionResolver.DotNetCoreIndexUrl}`); } return releaseInfo['channel-version']; }); diff --git a/src/installer.ts b/src/installer.ts index ec89a79..2fad685 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -87,7 +87,7 @@ export class DotnetVersionResolver { if (!releaseInfo) { throw new Error( - `Could not find info for version with major tag: v${majorTag} at ${DotnetVersionResolver.DotNetCoreIndexUrl}` + `Could not find info for version with major tag: ${majorTag} at ${DotnetVersionResolver.DotNetCoreIndexUrl}` ); } From aa34a3ceaa698ef02004c91a4fc3bca128678557 Mon Sep 17 00:00:00 2001 From: IvanZosimov Date: Tue, 11 Apr 2023 13:44:35 +0200 Subject: [PATCH 06/30] Fix typo --- dist/index.js | 2 +- src/installer.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dist/index.js b/dist/index.js index 0515933..bc00897 100644 --- a/dist/index.js +++ b/dist/index.js @@ -308,7 +308,7 @@ class DotnetVersionResolver { return sdkParts[0] === majorTag; }); if (!releaseInfo) { - throw new Error(`Could not find info for version with major tag: ${majorTag} at ${DotnetVersionResolver.DotNetCoreIndexUrl}`); + throw new Error(`Could not find info for version with major tag: "${majorTag}" at ${DotnetVersionResolver.DotNetCoreIndexUrl}`); } return releaseInfo['channel-version']; }); diff --git a/src/installer.ts b/src/installer.ts index 2fad685..22fa100 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -87,7 +87,7 @@ export class DotnetVersionResolver { if (!releaseInfo) { throw new Error( - `Could not find info for version with major tag: ${majorTag} at ${DotnetVersionResolver.DotNetCoreIndexUrl}` + `Could not find info for version with major tag: "${majorTag}" at ${DotnetVersionResolver.DotNetCoreIndexUrl}` ); } From 5f570676c249d99788f868b377a4e76fc46b28c6 Mon Sep 17 00:00:00 2001 From: IvanZosimov Date: Tue, 11 Apr 2023 15:53:11 +0200 Subject: [PATCH 07/30] Add unit and e2e tests --- .github/workflows/e2e-tests.yml | 24 ++++++++++++++++++++++++ __tests__/installer.test.ts | 5 +++-- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml index 1be4173..36fd1ef 100644 --- a/.github/workflows/e2e-tests.yml +++ b/.github/workflows/e2e-tests.yml @@ -165,6 +165,30 @@ jobs: shell: pwsh run: __tests__/verify-dotnet.ps1 3.1 2.2 + test-setup-with-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 '3.1.1xx' + uses: ./ + with: + dotnet-version: '3.1.1xx' + - name: Setup dotnet '6.0.3xx' + uses: ./ + with: + dotnet-version: '6.0.3xx' + - name: Verify dotnet + shell: pwsh + run: __tests__/verify-dotnet.ps1 3.1.1 6.0.3 + test-setup-global-json-specified-and-version: runs-on: ${{ matrix.operating-system }} strategy: diff --git a/__tests__/installer.test.ts b/__tests__/installer.test.ts index 1a7e024..6c20afe 100644 --- a/__tests__/installer.test.ts +++ b/__tests__/installer.test.ts @@ -201,6 +201,7 @@ describe('DotnetVersionResolver tests', () => { '.2.3', '.2.x', '*.', + '*', '1.2.', '1.2.-abc', 'a.b', @@ -221,7 +222,7 @@ describe('DotnetVersionResolver tests', () => { } ); - each(['3.1', '3.1.x', '3.1.*', '3.1.X']).test( + each(['3.1', '3.1.x', '3.1.*', '3.1.X', '3.1.1xx']).test( "if version: '%s' that can be resolved to 'channel' option is supplied, it should set type to 'channel' in version object", async version => { const dotnetVersionResolver = new installer.DotnetVersionResolver( @@ -233,7 +234,7 @@ describe('DotnetVersionResolver 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.1xx']).test( "if version: '%s' that can be resolved to 'channel' option is supplied and its major tag is >= 6, it should set type to 'channel' and qualityFlag to 'true' in version object", async version => { const dotnetVersionResolver = new installer.DotnetVersionResolver( From 34c30d0e8188386834a5bb496c316cdeba7658c0 Mon Sep 17 00:00:00 2001 From: IvanZosimov Date: Wed, 12 Apr 2023 15:44:03 +0200 Subject: [PATCH 08/30] Refactor logic --- .github/workflows/e2e-tests.yml | 10 +++---- __tests__/installer.test.ts | 3 +- dist/index.js | 50 ++++++++++++++++++++++----------- src/installer.ts | 49 +++++++++++++++++++++++--------- 4 files changed, 75 insertions(+), 37 deletions(-) diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml index 36fd1ef..f3588e8 100644 --- a/.github/workflows/e2e-tests.yml +++ b/.github/workflows/e2e-tests.yml @@ -177,17 +177,17 @@ jobs: - name: Clear toolcache shell: pwsh run: __tests__/clear-toolcache.ps1 ${{ runner.os }} - - name: Setup dotnet '3.1.1xx' + - name: Setup dotnet '5.0.1xx' uses: ./ with: - dotnet-version: '3.1.1xx' - - name: Setup dotnet '6.0.3xx' + dotnet-version: '5.0.1xx' + - name: Setup dotnet '7.0.1xx' uses: ./ with: - dotnet-version: '6.0.3xx' + dotnet-version: '7.0.1xx' - name: Verify dotnet shell: pwsh - run: __tests__/verify-dotnet.ps1 3.1.1 6.0.3 + run: __tests__/verify-dotnet.ps1 5.0.1 7.0.1 test-setup-global-json-specified-and-version: runs-on: ${{ matrix.operating-system }} diff --git a/__tests__/installer.test.ts b/__tests__/installer.test.ts index 6c20afe..363310c 100644 --- a/__tests__/installer.test.ts +++ b/__tests__/installer.test.ts @@ -201,7 +201,6 @@ describe('DotnetVersionResolver tests', () => { '.2.3', '.2.x', '*.', - '*', '1.2.', '1.2.-abc', 'a.b', @@ -222,7 +221,7 @@ describe('DotnetVersionResolver tests', () => { } ); - each(['3.1', '3.1.x', '3.1.*', '3.1.X', '3.1.1xx']).test( + each(['3.1', '3.1.x', '3.1.*', '3.1.X', '5.0.1xx']).test( "if version: '%s' that can be resolved to 'channel' option is supplied, it should set type to 'channel' in version object", async version => { const dotnetVersionResolver = new installer.DotnetVersionResolver( diff --git a/dist/index.js b/dist/index.js index bc00897..ed522cc 100644 --- a/dist/index.js +++ b/dist/index.js @@ -250,33 +250,51 @@ class DotnetVersionResolver { } resolveVersionInput() { return __awaiter(this, void 0, void 0, function* () { - const isLatestPatchSyntax = /^\d+\.\d+\.\d{1}x{2}$/.test(this.inputVersion); - if (!semver_1.default.validRange(this.inputVersion) && !isLatestPatchSyntax) { + if (!semver_1.default.validRange(this.inputVersion) && !this.isLatestPatchSyntax()) { throw new Error(`'dotnet-version' was supplied in invalid format: ${this.inputVersion}! Supported syntax: A.B.C, A.B, A.B.x, A, A.x, A.B.Cxx`); } if (semver_1.default.valid(this.inputVersion)) { - this.resolvedArgument.type = 'version'; - this.resolvedArgument.value = this.inputVersion; + this.createVersionArgument(); } else { - this.resolvedArgument.type = 'channel'; - const [major, minor] = this.inputVersion.split('.'); - if (isLatestPatchSyntax) { - this.resolvedArgument.value = this.inputVersion; - } - else if (this.isNumericTag(major) && this.isNumericTag(minor)) { - this.resolvedArgument.value = `${major}.${minor}`; - } - else { - this.resolvedArgument.value = yield this.getLatestByMajorTag(major); - } - this.resolvedArgument.qualityFlag = +major >= 6 ? true : false; + yield this.createChannelArgument(); } }); } isNumericTag(versionTag) { return /^\d+$/.test(versionTag); } + isLatestPatchSyntax() { + var _b, _c; + const majorTag = (_c = (_b = this.inputVersion.match(/^(?\d+)\.\d+\.\d{1}x{2}$/)) === null || _b === void 0 ? void 0 : _b.groups) === null || _c === void 0 ? void 0 : _c.majorTag; + if (majorTag && parseInt(majorTag) < 5) { + throw new Error(`'dotnet-version' was supplied in invalid format: ${this.inputVersion}! The A.B.Cxx syntax is available since the .NET 5.0 release.`); + } + return majorTag ? true : false; + } + createVersionArgument() { + this.resolvedArgument.type = 'version'; + this.resolvedArgument.value = this.inputVersion; + } + createChannelArgument() { + return __awaiter(this, void 0, void 0, function* () { + this.resolvedArgument.type = 'channel'; + const [major, minor] = this.inputVersion.split('.'); + if (this.isLatestPatchSyntax()) { + this.resolvedArgument.value = this.inputVersion; + } + else if (this.isNumericTag(major) && this.isNumericTag(minor)) { + this.resolvedArgument.value = `${major}.${minor}`; + } + else if (this.isNumericTag(major)) { + this.resolvedArgument.value = yield this.getLatestByMajorTag(major); + } + else { + this.resolvedArgument.value = 'LTS'; + } + this.resolvedArgument.qualityFlag = +major >= 6 ? true : false; + }); + } createDotNetVersion() { return __awaiter(this, void 0, void 0, function* () { yield this.resolveVersionInput(); diff --git a/src/installer.ts b/src/installer.ts index 22fa100..9b85f7b 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -27,26 +27,15 @@ export class DotnetVersionResolver { } private async resolveVersionInput(): Promise { - const isLatestPatchSyntax = /^\d+\.\d+\.\d{1}x{2}$/.test(this.inputVersion); - if (!semver.validRange(this.inputVersion) && !isLatestPatchSyntax) { + if (!semver.validRange(this.inputVersion) && !this.isLatestPatchSyntax()) { throw new Error( `'dotnet-version' was supplied in invalid format: ${this.inputVersion}! Supported syntax: A.B.C, A.B, A.B.x, A, A.x, A.B.Cxx` ); } if (semver.valid(this.inputVersion)) { - this.resolvedArgument.type = 'version'; - this.resolvedArgument.value = this.inputVersion; + this.createVersionArgument(); } else { - this.resolvedArgument.type = 'channel'; - const [major, minor] = this.inputVersion.split('.'); - if (isLatestPatchSyntax) { - this.resolvedArgument.value = this.inputVersion; - } else if (this.isNumericTag(major) && this.isNumericTag(minor)) { - this.resolvedArgument.value = `${major}.${minor}`; - } else { - this.resolvedArgument.value = await this.getLatestByMajorTag(major); - } - this.resolvedArgument.qualityFlag = +major >= 6 ? true : false; + await this.createChannelArgument(); } } @@ -54,6 +43,38 @@ export class DotnetVersionResolver { return /^\d+$/.test(versionTag); } + private isLatestPatchSyntax() { + const majorTag = this.inputVersion.match( + /^(?\d+)\.\d+\.\d{1}x{2}$/ + )?.groups?.majorTag; + if (majorTag && parseInt(majorTag) < 5) { + throw new Error( + `'dotnet-version' was supplied in invalid format: ${this.inputVersion}! The A.B.Cxx syntax is available since the .NET 5.0 release.` + ); + } + return majorTag ? true : false; + } + + private createVersionArgument() { + this.resolvedArgument.type = 'version'; + this.resolvedArgument.value = this.inputVersion; + } + + private async createChannelArgument() { + this.resolvedArgument.type = 'channel'; + const [major, minor] = this.inputVersion.split('.'); + if (this.isLatestPatchSyntax()) { + this.resolvedArgument.value = this.inputVersion; + } else if (this.isNumericTag(major) && this.isNumericTag(minor)) { + this.resolvedArgument.value = `${major}.${minor}`; + } else if (this.isNumericTag(major)) { + this.resolvedArgument.value = await this.getLatestByMajorTag(major); + } else { + this.resolvedArgument.value = 'LTS'; + } + this.resolvedArgument.qualityFlag = +major >= 6 ? true : false; + } + public async createDotNetVersion(): Promise { await this.resolveVersionInput(); if (!this.resolvedArgument.type) { From 7358a445904166c3f83f0d04320d96f189925490 Mon Sep 17 00:00:00 2001 From: IvanZosimov Date: Wed, 12 Apr 2023 16:44:51 +0200 Subject: [PATCH 09/30] Update unit tests --- .github/workflows/e2e-tests.yml | 6 +++--- dist/index.js | 3 ++- src/installer.ts | 3 ++- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml index f3588e8..551ad8c 100644 --- a/.github/workflows/e2e-tests.yml +++ b/.github/workflows/e2e-tests.yml @@ -177,17 +177,17 @@ jobs: - name: Clear toolcache shell: pwsh run: __tests__/clear-toolcache.ps1 ${{ runner.os }} - - name: Setup dotnet '5.0.1xx' + - name: Setup dotnet '5.0.2xx' uses: ./ with: - dotnet-version: '5.0.1xx' + dotnet-version: '5.0.2xx' - name: Setup dotnet '7.0.1xx' uses: ./ with: dotnet-version: '7.0.1xx' - name: Verify dotnet shell: pwsh - run: __tests__/verify-dotnet.ps1 5.0.1 7.0.1 + run: __tests__/verify-dotnet.ps1 5.0.2 7.0.1 test-setup-global-json-specified-and-version: runs-on: ${{ matrix.operating-system }} diff --git a/dist/index.js b/dist/index.js index ed522cc..a9e8a7e 100644 --- a/dist/index.js +++ b/dist/index.js @@ -290,9 +290,10 @@ class DotnetVersionResolver { this.resolvedArgument.value = yield this.getLatestByMajorTag(major); } else { + // Resolve LTS version of .NET if "dotnet-version" is specified as *, x or X this.resolvedArgument.value = 'LTS'; } - this.resolvedArgument.qualityFlag = +major >= 6 ? true : false; + this.resolvedArgument.qualityFlag = parseInt(major) >= 6 ? true : false; }); } createDotNetVersion() { diff --git a/src/installer.ts b/src/installer.ts index 9b85f7b..211c6c7 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -70,9 +70,10 @@ export class DotnetVersionResolver { } else if (this.isNumericTag(major)) { this.resolvedArgument.value = await this.getLatestByMajorTag(major); } else { + // Resolve LTS version of .NET if "dotnet-version" is specified as *, x or X this.resolvedArgument.value = 'LTS'; } - this.resolvedArgument.qualityFlag = +major >= 6 ? true : false; + this.resolvedArgument.qualityFlag = parseInt(major) >= 6 ? true : false; } public async createDotNetVersion(): Promise { From 559e47b01b20368e2cfc1fc8975b5ffe267f5c89 Mon Sep 17 00:00:00 2001 From: IvanZosimov Date: Thu, 13 Apr 2023 10:33:52 +0200 Subject: [PATCH 10/30] Fix review points --- .github/workflows/e2e-tests.yml | 24 ------------------------ dist/index.js | 16 +++++++++++++--- src/installer.ts | 18 +++++++++++++++--- 3 files changed, 28 insertions(+), 30 deletions(-) diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml index 551ad8c..1be4173 100644 --- a/.github/workflows/e2e-tests.yml +++ b/.github/workflows/e2e-tests.yml @@ -165,30 +165,6 @@ jobs: shell: pwsh run: __tests__/verify-dotnet.ps1 3.1 2.2 - test-setup-with-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 '5.0.2xx' - uses: ./ - with: - dotnet-version: '5.0.2xx' - - name: Setup dotnet '7.0.1xx' - uses: ./ - with: - dotnet-version: '7.0.1xx' - - name: Verify dotnet - shell: pwsh - run: __tests__/verify-dotnet.ps1 5.0.2 7.0.1 - test-setup-global-json-specified-and-version: runs-on: ${{ matrix.operating-system }} strategy: diff --git a/dist/index.js b/dist/index.js index a9e8a7e..40338d4 100644 --- a/dist/index.js +++ b/dist/index.js @@ -243,6 +243,11 @@ const path_1 = __importDefault(__nccwpck_require__(1017)); const os_1 = __importDefault(__nccwpck_require__(2037)); const semver_1 = __importDefault(__nccwpck_require__(5911)); const utils_1 = __nccwpck_require__(918); +var DotnetInstallerLimits; +(function (DotnetInstallerLimits) { + DotnetInstallerLimits[DotnetInstallerLimits["QualityInputMinimalMajorTag"] = 6] = "QualityInputMinimalMajorTag"; + DotnetInstallerLimits[DotnetInstallerLimits["LatestPatchSyntaxMinimalMajorTag"] = 5] = "LatestPatchSyntaxMinimalMajorTag"; +})(DotnetInstallerLimits || (DotnetInstallerLimits = {})); class DotnetVersionResolver { constructor(version) { this.inputVersion = version.trim(); @@ -267,7 +272,9 @@ class DotnetVersionResolver { isLatestPatchSyntax() { var _b, _c; const majorTag = (_c = (_b = this.inputVersion.match(/^(?\d+)\.\d+\.\d{1}x{2}$/)) === null || _b === void 0 ? void 0 : _b.groups) === null || _c === void 0 ? void 0 : _c.majorTag; - if (majorTag && parseInt(majorTag) < 5) { + if (majorTag && + parseInt(majorTag) < + DotnetInstallerLimits.LatestPatchSyntaxMinimalMajorTag) { throw new Error(`'dotnet-version' was supplied in invalid format: ${this.inputVersion}! The A.B.Cxx syntax is available since the .NET 5.0 release.`); } return majorTag ? true : false; @@ -290,10 +297,13 @@ class DotnetVersionResolver { this.resolvedArgument.value = yield this.getLatestByMajorTag(major); } else { - // Resolve LTS version of .NET if "dotnet-version" is specified as *, x or X + // If "dotnet-version" is specified as *, x or X resolve latest version of .NET explicitly from LTS channel. The version argument will be set to "latest" by default. this.resolvedArgument.value = 'LTS'; } - this.resolvedArgument.qualityFlag = parseInt(major) >= 6 ? true : false; + this.resolvedArgument.qualityFlag = + parseInt(major) >= DotnetInstallerLimits.QualityInputMinimalMajorTag + ? true + : false; }); } createDotNetVersion() { diff --git a/src/installer.ts b/src/installer.ts index 211c6c7..a105fef 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -17,6 +17,11 @@ export interface DotnetVersion { qualityFlag: boolean; } +enum DotnetInstallerLimits { + QualityInputMinimalMajorTag = 6, + LatestPatchSyntaxMinimalMajorTag = 5 +} + export class DotnetVersionResolver { private inputVersion: string; private resolvedArgument: DotnetVersion; @@ -47,7 +52,11 @@ export class DotnetVersionResolver { const majorTag = this.inputVersion.match( /^(?\d+)\.\d+\.\d{1}x{2}$/ )?.groups?.majorTag; - if (majorTag && parseInt(majorTag) < 5) { + if ( + majorTag && + parseInt(majorTag) < + DotnetInstallerLimits.LatestPatchSyntaxMinimalMajorTag + ) { throw new Error( `'dotnet-version' was supplied in invalid format: ${this.inputVersion}! The A.B.Cxx syntax is available since the .NET 5.0 release.` ); @@ -70,10 +79,13 @@ export class DotnetVersionResolver { } else if (this.isNumericTag(major)) { this.resolvedArgument.value = await this.getLatestByMajorTag(major); } else { - // Resolve LTS version of .NET if "dotnet-version" is specified as *, x or X + // If "dotnet-version" is specified as *, x or X resolve latest version of .NET explicitly from LTS channel. The version argument will be set to "latest" by default. this.resolvedArgument.value = 'LTS'; } - this.resolvedArgument.qualityFlag = parseInt(major) >= 6 ? true : false; + this.resolvedArgument.qualityFlag = + parseInt(major) >= DotnetInstallerLimits.QualityInputMinimalMajorTag + ? true + : false; } public async createDotNetVersion(): Promise { From b72f430d3615f3631ecde8d268101c3804566f79 Mon Sep 17 00:00:00 2001 From: IvanZosimov Date: Thu, 13 Apr 2023 17:28:59 +0200 Subject: [PATCH 11/30] Update e2e tests --- .github/workflows/e2e-tests.yml | 37 +++---- __tests__/e2e-test-csproj/Test.cs | 14 +++ __tests__/e2e-test-csproj/test.csproj | 15 +++ __tests__/sample-csproj/Program.cs | 15 --- __tests__/sample-csproj/sample.csproj | 18 ---- __tests__/verify-dotnet.ps1 | 137 +++++++++++++++----------- 6 files changed, 123 insertions(+), 113 deletions(-) create mode 100644 __tests__/e2e-test-csproj/Test.cs create mode 100644 __tests__/e2e-test-csproj/test.csproj delete mode 100644 __tests__/sample-csproj/Program.cs delete mode 100644 __tests__/sample-csproj/sample.csproj diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml index 1be4173..fd6e85b 100644 --- a/.github/workflows/e2e-tests.yml +++ b/.github/workflows/e2e-tests.yml @@ -33,7 +33,7 @@ jobs: 3.0.x - name: Verify dotnet shell: pwsh - run: __tests__/verify-dotnet.ps1 2.2.402 3.1.404 '3.0' + run: __tests__/verify-dotnet.ps1 -Patterns 2.2.402, 3.1.404, 3.0 test-setup-full-version: runs-on: ${{ matrix.operating-system }} @@ -60,13 +60,9 @@ jobs: source-url: https://api.nuget.org/v3/index.json env: NUGET_AUTH_TOKEN: NOTATOKEN - - name: Verify nuget config file - shell: pwsh - run: | - if (-Not (Test-Path "../nuget.config")) { throw "nuget file not generated correctly" } - name: Verify dotnet shell: pwsh - run: __tests__/verify-dotnet.ps1 3.1.201 2.2.402 + run: __tests__/verify-dotnet.ps1 -Patterns 3.1.201, 2.2.402 -CheckNugetConfig test-setup-without-patch-version: runs-on: ${{ matrix.operating-system }} @@ -91,7 +87,7 @@ jobs: dotnet-version: '2.2' - name: Verify dotnet shell: pwsh - run: __tests__/verify-dotnet.ps1 3.1 2.2 + run: __tests__/verify-dotnet.ps1 -Patterns 3.1, 2.2 test-setup-prerelease-version: runs-on: ${{ matrix.operating-system }} @@ -105,17 +101,13 @@ jobs: - name: Clear toolcache shell: pwsh run: __tests__/clear-toolcache.ps1 ${{ runner.os }} - - name: Setup dotnet '2.2' - uses: ./ - with: - dotnet-version: '2.2' - name: Setup dotnet '3.1.100-preview1-014459' uses: ./ with: dotnet-version: '3.1.100-preview1-014459' - name: Verify dotnet shell: pwsh - run: __tests__/verify-dotnet.ps1 3.1.100-preview1-014459 + run: __tests__/verify-dotnet.ps1 -Patterns 3.1.100-preview1-014459 test-setup-latest-patch-version: runs-on: ${{ matrix.operating-system }} @@ -139,7 +131,7 @@ jobs: dotnet-version: 2.2.X - name: Verify dotnet shell: pwsh - run: __tests__/verify-dotnet.ps1 '2.2' '3.1' + run: __tests__/verify-dotnet.ps1 -Patterns 2.2, 3.1 test-setup-with-wildcard: runs-on: ${{ matrix.operating-system }} @@ -163,7 +155,7 @@ jobs: dotnet-version: 2.2.* - name: Verify dotnet shell: pwsh - run: __tests__/verify-dotnet.ps1 3.1 2.2 + run: __tests__/verify-dotnet.ps1 -Patterns 3.1, 2.2 test-setup-global-json-specified-and-version: runs-on: ${{ matrix.operating-system }} @@ -181,7 +173,7 @@ jobs: shell: bash run: | mkdir subdirectory - echo '{"sdk":{"version": "2.2","rollForward": "latestFeature"}}' > ./subdirectory/global.json + echo '{"sdk":{"version": "2.2.207","rollForward": "latestFeature"}}' > ./subdirectory/global.json - name: Setup dotnet uses: ./ with: @@ -189,7 +181,7 @@ jobs: global-json-file: ./subdirectory/global.json - name: Verify dotnet shell: pwsh - run: __tests__/verify-dotnet.ps1 2.2 3.1 + run: __tests__/verify-dotnet.ps1 -Patterns 2.2.207, 3.1 test-setup-with-dotnet-quality: runs-on: ${{ matrix.operating-system }} @@ -209,12 +201,9 @@ jobs: with: dotnet-version: '7.0' dotnet-quality: 'preview' - - name: Verify preview version + - name: Verify dotnet shell: pwsh - run: | - $version = & dotnet --version - Write-Host "Installed version: $version" - if (-not ($version.Contains("preview") -or $version.Contains("rc"))) { throw "Unexpected version" } + run: __tests__/verify-dotnet.ps1 -Patterns 7.0 -ContainedPattern "preview" test-dotnet-version-output-during-single-version-installation: runs-on: ${{ matrix.operating-system }} @@ -300,7 +289,8 @@ jobs: env: NUGET_AUTH_TOKEN: NOTATOKEN - name: Verify dotnet - run: __tests__/verify-dotnet.sh 3.1.201 + shell: pwsh + run: __tests__/verify-dotnet.ps1 -Patterns 3.1.201 -CheckNugetConfig test-bypass-proxy: runs-on: ubuntu-latest @@ -320,4 +310,5 @@ jobs: env: NUGET_AUTH_TOKEN: NOTATOKEN - name: Verify dotnet - run: __tests__/verify-dotnet.sh 3.1.201 + shell: pwsh + run: __tests__/verify-dotnet.ps1 -Patterns 3.1.201 -CheckNugetConfig diff --git a/__tests__/e2e-test-csproj/Test.cs b/__tests__/e2e-test-csproj/Test.cs new file mode 100644 index 0000000..533bdb8 --- /dev/null +++ b/__tests__/e2e-test-csproj/Test.cs @@ -0,0 +1,14 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace test_csproj +{ + [TestClass] + public class Test + { + [TestMethod] + public void TestMethod() + { + Assert.AreEqual((1 + 1), 2); + } + } +} diff --git a/__tests__/e2e-test-csproj/test.csproj b/__tests__/e2e-test-csproj/test.csproj new file mode 100644 index 0000000..370186a --- /dev/null +++ b/__tests__/e2e-test-csproj/test.csproj @@ -0,0 +1,15 @@ + + + + $(TEST_TARGET_FRAMEWORK) + + false + + + + + + + + + diff --git a/__tests__/sample-csproj/Program.cs b/__tests__/sample-csproj/Program.cs deleted file mode 100644 index f14c939..0000000 --- a/__tests__/sample-csproj/Program.cs +++ /dev/null @@ -1,15 +0,0 @@ -using Microsoft.VisualStudio.TestTools.UnitTesting; -using System; - -namespace sample_csproj -{ - [TestClass] - public class Program - { - [TestMethod] - public void TestMethod1() - { - Console.WriteLine("Hello, World!"); - } - } -} diff --git a/__tests__/sample-csproj/sample.csproj b/__tests__/sample-csproj/sample.csproj deleted file mode 100644 index be6d7ea..0000000 --- a/__tests__/sample-csproj/sample.csproj +++ /dev/null @@ -1,18 +0,0 @@ - - - - netcoreapp3.1;netcoreapp3.0;netcoreapp2.2 - sample_csproj - - false - - - - - - - - - - - diff --git a/__tests__/verify-dotnet.ps1 b/__tests__/verify-dotnet.ps1 index 7068c87..53befbb 100755 --- a/__tests__/verify-dotnet.ps1 +++ b/__tests__/verify-dotnet.ps1 @@ -1,73 +1,96 @@ -if (!$args[0]) -{ - throw "Must supply dotnet version argument" -} +param( + [ValidateNotNullOrEmpty()] + [string[]]$Patterns, + [ValidateNotNullOrEmpty()] + [string]$ContainedPattern, + [switch]$CheckNugetConfig +) -$dotnet = Get-Command dotnet | Select-Object -First 1 | ForEach-Object { $_.Path } -Write-Host "Found '$dotnet'" - -if($args.count -eq 1) -{ - $version = & $dotnet --version | Out-String | ForEach-Object { $_.Trim() } - Write-Host "Version $version" - if (-not ($version.StartsWith($args[0].ToString()))) +if ($CheckNugetConfig.IsPresent) { + if (!(Test-Path "../nuget.config")) { - Write-Host "PATH='$env:PATH'" - throw "Unexpected version" + throw "The nuget.config file is not generated correctly." } } -if ($args[1]) +if (!$Patterns.Count) { - # SDKs are listed on multiple lines with the path afterwards in square brackets - $versions = & $dotnet --list-sdks | ForEach-Object { $_.SubString(0, $_.IndexOf('[')).Trim() } - Write-Host "Installed versions: $versions" - $InstalledVersionCount = 0 - foreach($arg in $args){ - foreach ($version in $versions) + throw "At least 1 dotnet-version pattern should be supplied to script." +} + +Write-Host "Those patterns were supplied to the script: $($Patterns -join ', ')." +$dotnet = Get-Command dotnet | Select-Object -First 1 | ForEach-Object { $_.Path } +Write-Host "Found: '$dotnet'" + +# SDKs are listed on multiple lines with the path afterwards in square brackets +$versions = & $dotnet --list-sdks | ForEach-Object { $_.SubString(0, $_.IndexOf('[')).Trim() } +Write-Host "Installed versions: $($versions -join ', ')." +$InstalledVersionCount = 0 +foreach($pattern in $Patterns) +{ + foreach ($version in $versions) + { + if ($ContainedPattern) { - if ($version.StartsWith($arg.ToString())) + if ($version.StartsWith($pattern.ToString()) -and $version.Contains($ContainedPattern)) { $InstalledVersionCount++ + } + } + elseif ($version.StartsWith($pattern.ToString())) + { + $InstalledVersionCount++ } - } - } - if ( $InstalledVersionCount -ne $args.Count) - { - Write-Host "PATH='$env:PATH'" - throw "Unexpected version" } } +if ( $InstalledVersionCount -ne $Patterns.Count) +{ + throw "An unexpected version of Dotnet is found on the machine, please check the script's dotnet-version patterns." +} -Write-Host "Building sample csproj" -& $dotnet build __tests__/sample-csproj/ --no-cache -if ($LASTEXITCODE -ne 0) +Write-Host "Changing directory to the ./__tests__/e2e-test-csproj" +Set-Location ./__tests__/e2e-test-csproj + +$targetFrameworkVersionMapping = @{ + "1.0" = "netcoreapp1.0"; + "1.1" = "netcoreapp1.1"; + "2.0" = "netcoreapp2.0"; + "2.1" = "netcoreapp2.1"; + "2.2" = "netcoreapp2.2"; + "3.0" = "netcoreapp3.0"; + "3.1" = "netcoreapp3.1"; + "5.0" = "net5.0"; + "6.0" = "net6.0"; + "7.0" = "net7.0"; + } + +foreach ($version in $versions) { - throw "Unexpected exit code $LASTEXITCODE" + Write-Host "Creating temporary global.json file for $version .NET version." + & $dotnet new globaljson --sdk-version $version --force + Write-Host "The global.json file for the version $version is created. Currently used .NET version is: $(& $dotnet --version)" + $version -match "^(?\d+\.\d+)" + Write-Host "Setting the TEST_TARGET_FRAMEWORK environment variable to $($targetFrameworkVersionMapping[$Matches.key])" + [Environment]::SetEnvironmentVariable('TEST_TARGET_FRAMEWORK', $($targetFrameworkVersionMapping[$Matches.key])) + + Write-Host "Building test C# project with $version .NET version." + & $dotnet build --no-cache + if ($LASTEXITCODE -ne 0) + { + throw "Building process is not successful, exit code: $LASTEXITCODE" + } + + Write-Host "Testing compiled C# project with $version .NET version." + & $dotnet test --no-build + if ($LASTEXITCODE -ne 0) + { + throw "Testing process is not successful, exit code: $LASTEXITCODE" + } + + Write-Host "Tests are completed successfully!" + + Write-Host "Removing temprary global.json file." + Remove-Item ./global.json } -Write-Host "Testing compiled app" -$sample_output = "$(dotnet test __tests__/sample-csproj/ --no-build)" -Write-Host "Sample output: $sample_output" -# For Side-by-Side installs we want to run the tests twice, for a single install the tests will run once -if ($args[1]) -{ - if ($sample_output -notlike "*Test Run Successful.*Test Run Successful.*") - { - throw "Unexpected output" - } -} -if ($args[2]) -{ - if ($sample_output -notlike "*Test Run Successful.*Test Run Successful.*Test Run Successful.*") - { - throw "Unexpected output" - } -} -else -{ - if ($sample_output -notlike "*Test Run Successful.*") - { - throw "Unexpected output" - } -} +Set-Location ../.. \ No newline at end of file From 180a15970f461b60527b6ce1498e27bb3fcca3c6 Mon Sep 17 00:00:00 2001 From: IvanZosimov Date: Wed, 19 Apr 2023 13:40:44 +0200 Subject: [PATCH 12/30] Update e2e test infrastructure --- .github/workflows/e2e-tests.yml | 48 ++++++++------ .github/workflows/test-dotnet.yml | 8 +-- .gitignore | 4 +- __tests__/e2e-test-csproj/Test.cs | 8 ++- __tests__/e2e-test-csproj/test.csproj | 2 +- __tests__/verify-dotnet.ps1 | 90 ++++++++++++++++----------- __tests__/verify-dotnet.sh | 44 ------------- 7 files changed, 92 insertions(+), 112 deletions(-) delete mode 100755 __tests__/verify-dotnet.sh diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml index fd6e85b..9963bbc 100644 --- a/.github/workflows/e2e-tests.yml +++ b/.github/workflows/e2e-tests.yml @@ -33,7 +33,7 @@ jobs: 3.0.x - name: Verify dotnet shell: pwsh - run: __tests__/verify-dotnet.ps1 -Patterns 2.2.402, 3.1.404, 3.0 + run: __tests__/verify-dotnet.ps1 -Patterns "^2.2.402$", "^3.1.404$", "^3.0" test-setup-full-version: runs-on: ${{ matrix.operating-system }} @@ -62,7 +62,7 @@ jobs: NUGET_AUTH_TOKEN: NOTATOKEN - name: Verify dotnet shell: pwsh - run: __tests__/verify-dotnet.ps1 -Patterns 3.1.201, 2.2.402 -CheckNugetConfig + run: __tests__/verify-dotnet.ps1 -Patterns "^3.1.201$", "^2.2.402$" -CheckNugetConfig test-setup-without-patch-version: runs-on: ${{ matrix.operating-system }} @@ -87,7 +87,7 @@ jobs: dotnet-version: '2.2' - name: Verify dotnet shell: pwsh - run: __tests__/verify-dotnet.ps1 -Patterns 3.1, 2.2 + run: __tests__/verify-dotnet.ps1 -Patterns "^3.1", "^2.2" test-setup-prerelease-version: runs-on: ${{ matrix.operating-system }} @@ -107,7 +107,7 @@ jobs: dotnet-version: '3.1.100-preview1-014459' - name: Verify dotnet shell: pwsh - run: __tests__/verify-dotnet.ps1 -Patterns 3.1.100-preview1-014459 + run: __tests__/verify-dotnet.ps1 -Patterns "3.1.100-preview1-014459" test-setup-latest-patch-version: runs-on: ${{ matrix.operating-system }} @@ -131,7 +131,7 @@ jobs: dotnet-version: 2.2.X - name: Verify dotnet shell: pwsh - run: __tests__/verify-dotnet.ps1 -Patterns 2.2, 3.1 + run: __tests__/verify-dotnet.ps1 -Patterns "^2.2", "^3.1" test-setup-with-wildcard: runs-on: ${{ matrix.operating-system }} @@ -155,7 +155,7 @@ jobs: dotnet-version: 2.2.* - name: Verify dotnet shell: pwsh - run: __tests__/verify-dotnet.ps1 -Patterns 3.1, 2.2 + run: __tests__/verify-dotnet.ps1 -Patterns "^3.1", "^2.2" test-setup-global-json-specified-and-version: runs-on: ${{ matrix.operating-system }} @@ -181,7 +181,7 @@ jobs: global-json-file: ./subdirectory/global.json - name: Verify dotnet shell: pwsh - run: __tests__/verify-dotnet.ps1 -Patterns 2.2.207, 3.1 + run: __tests__/verify-dotnet.ps1 -Patterns "^2.2", "^3.1" test-setup-with-dotnet-quality: runs-on: ${{ matrix.operating-system }} @@ -203,7 +203,7 @@ jobs: dotnet-quality: 'preview' - name: Verify dotnet shell: pwsh - run: __tests__/verify-dotnet.ps1 -Patterns 7.0 -ContainedPattern "preview" + run: __tests__/verify-dotnet.ps1 -Patterns "^7\.0\.\d+-" test-dotnet-version-output-during-single-version-installation: runs-on: ${{ matrix.operating-system }} @@ -262,7 +262,7 @@ jobs: test-proxy: runs-on: ubuntu-latest container: - image: mcr.microsoft.com/dotnet/core/runtime-deps:3.0-bionic + image: ubuntu:latest options: --dns 127.0.0.1 services: squid-proxy: @@ -275,22 +275,29 @@ jobs: steps: - name: Checkout uses: actions/checkout@v3 - - name: Clear tool cache - run: rm -rf "/usr/share/dotnet" - - name: Install curl + - name: Install Powershell run: | - apt update - apt -y install curl - - name: Setup dotnet 3.1.201 + apt-get update + apt-get install -y wget apt-transport-https software-properties-common + wget -q "https://packages.microsoft.com/config/ubuntu/$(lsb_release -rs)/packages-microsoft-prod.deb" + dpkg -i packages-microsoft-prod.deb + rm packages-microsoft-prod.deb + apt-get update + apt-get install -y powershell + - name: Clear toolcache + shell: pwsh + run: __tests__/clear-toolcache.ps1 ${{ runner.os }} + - name: Setup dotnet 6.0 uses: ./ with: - dotnet-version: 3.1.201 + dotnet-version: 6.0 source-url: https://api.nuget.org/v3/index.json env: NUGET_AUTH_TOKEN: NOTATOKEN - name: Verify dotnet shell: pwsh - run: __tests__/verify-dotnet.ps1 -Patterns 3.1.201 -CheckNugetConfig + run: | + __tests__/verify-dotnet.ps1 -Patterns "^6.0" -CheckNugetConfig test-bypass-proxy: runs-on: ubuntu-latest @@ -300,8 +307,9 @@ jobs: steps: - name: Checkout uses: actions/checkout@v3 - - name: Clear tool cache - run: rm -rf "/usr/share/dotnet" + - name: Clear toolcache + shell: pwsh + run: __tests__/clear-toolcache.ps1 ${{ runner.os }} - name: Setup dotnet 3.1.201 uses: ./ with: @@ -311,4 +319,4 @@ jobs: NUGET_AUTH_TOKEN: NOTATOKEN - name: Verify dotnet shell: pwsh - run: __tests__/verify-dotnet.ps1 -Patterns 3.1.201 -CheckNugetConfig + run: __tests__/verify-dotnet.ps1 -Patterns "^3.1.201$" -CheckNugetConfig diff --git a/.github/workflows/test-dotnet.yml b/.github/workflows/test-dotnet.yml index 0b37d28..760167b 100644 --- a/.github/workflows/test-dotnet.yml +++ b/.github/workflows/test-dotnet.yml @@ -18,7 +18,7 @@ jobs: fail-fast: false matrix: operating-system: [ubuntu-latest, windows-latest, macOS-latest] - dotnet-version: ['2.1', '2.2', '3.0', '3.1', '5.0'] + dotnet-version: ['2.1', '2.2', '3.0', '3.1', '5.0', '6.0', '7.0'] steps: - name: Checkout uses: actions/checkout@v3 @@ -29,9 +29,7 @@ jobs: uses: ./ with: dotnet-version: ${{ matrix.dotnet-version }} - - name: Check installed version + - name: Verify installed version shell: pwsh run: | - $version = & dotnet --version - Write-Host "Installed version: $version" - if (-not $version.StartsWith("${{ matrix.dotnet-version }}")) { throw "Unexpected version" } + __tests__/verify-dotnet.ps1 -Patterns "^${{ matrix.dotnet-version }}" diff --git a/.gitignore b/.gitignore index b339e2c..1cb082a 100644 --- a/.gitignore +++ b/.gitignore @@ -3,8 +3,8 @@ global.json lib/ node_modules/ __tests__/runner/* -__tests__/sample-csproj/bin/ -__tests__/sample-csproj/obj/ +__tests__/e2e-test-csproj/bin/ +__tests__/e2e-test-csproj/obj/ # Rest of the file pulled from https://github.com/github/gitignore/blob/master/Node.gitignore # Logs diff --git a/__tests__/e2e-test-csproj/Test.cs b/__tests__/e2e-test-csproj/Test.cs index 533bdb8..ba9573a 100644 --- a/__tests__/e2e-test-csproj/Test.cs +++ b/__tests__/e2e-test-csproj/Test.cs @@ -1,4 +1,5 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; namespace test_csproj { @@ -7,8 +8,11 @@ namespace test_csproj { [TestMethod] public void TestMethod() - { - Assert.AreEqual((1 + 1), 2); + { + Console.WriteLine("TestMethod"); + int calculatedResult = 1000 / 25; + int expectedResult = 40; + Assert.AreEqual(calculatedResult, expectedResult); } } } diff --git a/__tests__/e2e-test-csproj/test.csproj b/__tests__/e2e-test-csproj/test.csproj index 370186a..769269f 100644 --- a/__tests__/e2e-test-csproj/test.csproj +++ b/__tests__/e2e-test-csproj/test.csproj @@ -2,11 +2,11 @@ $(TEST_TARGET_FRAMEWORK) - false + diff --git a/__tests__/verify-dotnet.ps1 b/__tests__/verify-dotnet.ps1 index 53befbb..496fec2 100755 --- a/__tests__/verify-dotnet.ps1 +++ b/__tests__/verify-dotnet.ps1 @@ -1,57 +1,68 @@ +<# + .DESCRIPTION + Verifies that installed on the machine .NET SDK versions match the input patterns. + Optionally checks that the nuget.config file is generated correctly. + + .PARAMETER Patterns + Specifies the regular expression patterns that should be matched with the installed + on the machine .NET SDK versions. The number of patterns should be equal to the number + of installed .NET versions. + + .PARAMETER CheckNugetConfig + Switches the check for the existence of the nuget.config file. + + .EXAMPLE + PS> .\verify-dotnet.ps1 -Paterns "^3.1.200$", "^6.0" -CheckNugetConfig +#> + param( [ValidateNotNullOrEmpty()] + [Parameter(Mandatory=$true)] [string[]]$Patterns, - [ValidateNotNullOrEmpty()] - [string]$ContainedPattern, [switch]$CheckNugetConfig ) -if ($CheckNugetConfig.IsPresent) { - if (!(Test-Path "../nuget.config")) - { - throw "The nuget.config file is not generated correctly." - } +$PatternsList = [System.Collections.ArrayList]($Patterns) + +if ($CheckNugetConfig.IsPresent -and !(Test-Path "../nuget.config")) { + throw "The nuget.config file is not generated correctly." } -if (!$Patterns.Count) -{ - throw "At least 1 dotnet-version pattern should be supplied to script." -} +$PatternsCount = $PatternsList.Count -Write-Host "Those patterns were supplied to the script: $($Patterns -join ', ')." +Write-Host "Those patterns were supplied to the script: $($PatternsList -join ', ')." $dotnet = Get-Command dotnet | Select-Object -First 1 | ForEach-Object { $_.Path } Write-Host "Found: '$dotnet'" # SDKs are listed on multiple lines with the path afterwards in square brackets -$versions = & $dotnet --list-sdks | ForEach-Object { $_.SubString(0, $_.IndexOf('[')).Trim() } -Write-Host "Installed versions: $($versions -join ', ')." -$InstalledVersionCount = 0 -foreach($pattern in $Patterns) +$Versions = & $dotnet --list-sdks | ForEach-Object { $_.SubString(0, $_.IndexOf('[')).Trim() } +Write-Host "Found installed versions: $($Versions -join ', ')." +$InstalledVersionCount = $Versions.Count + +foreach($version in $Versions) { - foreach ($version in $versions) + foreach($pattern in $PatternsList) { - if ($ContainedPattern) - { - if ($version.StartsWith($pattern.ToString()) -and $version.Contains($ContainedPattern)) - { - $InstalledVersionCount++ - } - } - elseif ($version.StartsWith($pattern.ToString())) - { - $InstalledVersionCount++ - } + if ($version -match $pattern) + { + $PatternsList.Remove($pattern) + $InstalledVersionCount-- + break + } } } -if ( $InstalledVersionCount -ne $Patterns.Count) + +if ( $InstalledVersionCount -ne 0) { - throw "An unexpected version of Dotnet is found on the machine, please check the script's dotnet-version patterns." + throw "An unexpected version of Dotnet is found on the machine, please check the correctness of the -Patterns input." } Write-Host "Changing directory to the ./__tests__/e2e-test-csproj" -Set-Location ./__tests__/e2e-test-csproj +$workingDir = Get-Location +$testProjectDir = "./__tests__/e2e-test-csproj" +Set-Location $testProjectDir -$targetFrameworkVersionMapping = @{ +$targetFrameworkVersionMap = @{ "1.0" = "netcoreapp1.0"; "1.1" = "netcoreapp1.1"; "2.0" = "netcoreapp2.0"; @@ -64,14 +75,17 @@ $targetFrameworkVersionMapping = @{ "7.0" = "net7.0"; } -foreach ($version in $versions) +foreach ($version in $Versions) { + # Creating temporary global.json file inside e2e-test-csproj dir and setting exact version of .NET inside allows to override default behavior of .NET and run build and tests on that exact version. Write-Host "Creating temporary global.json file for $version .NET version." & $dotnet new globaljson --sdk-version $version --force - Write-Host "The global.json file for the version $version is created. Currently used .NET version is: $(& $dotnet --version)" + Write-Host "The global.json file for the version $version is created. Currently used .NET version is: $(& $dotnet --version)." + + # Environment variable TEST_TARGET_FRAMEWORK is used inside the test.csproj file to target required framework version $version -match "^(?\d+\.\d+)" - Write-Host "Setting the TEST_TARGET_FRAMEWORK environment variable to $($targetFrameworkVersionMapping[$Matches.key])" - [Environment]::SetEnvironmentVariable('TEST_TARGET_FRAMEWORK', $($targetFrameworkVersionMapping[$Matches.key])) + Write-Host "Setting the TEST_TARGET_FRAMEWORK environment variable to $($targetFrameworkVersionMap[$Matches.key])" + [Environment]::SetEnvironmentVariable('TEST_TARGET_FRAMEWORK', $($targetFrameworkVersionMap[$Matches.key])) Write-Host "Building test C# project with $version .NET version." & $dotnet build --no-cache @@ -89,8 +103,8 @@ foreach ($version in $versions) Write-Host "Tests are completed successfully!" - Write-Host "Removing temprary global.json file." + Write-Host "Removing temporary global.json file." Remove-Item ./global.json } -Set-Location ../.. \ No newline at end of file +Set-Location $workingDir \ No newline at end of file diff --git a/__tests__/verify-dotnet.sh b/__tests__/verify-dotnet.sh deleted file mode 100755 index 098d076..0000000 --- a/__tests__/verify-dotnet.sh +++ /dev/null @@ -1,44 +0,0 @@ -if [ -z "$1" ]; then - echo "Must supply dotnet version argument" - exit 1 -fi - -if [ ! -f "../nuget.config" ]; then - echo "nuget file not generated correctly" - exit 1 -fi - -dotnet_version="$(dotnet --version)" -echo "Found dotnet version '$dotnet_version'" -if [ -z "$(echo $dotnet_version | grep $1)" ]; then - echo "Unexpected version" - exit 1 -fi - -if [ -n "$2" ]; then - dotnet_version="$(dotnet --list-sdks)" - echo "Found dotnet version '$dotnet_version'" - if [ -z "$(echo $dotnet_version | grep $2)" ]; then - echo "Unexpected version" - exit 1 - fi -fi - -echo "Building sample csproj" -dotnet build __tests__/sample-csproj/ --no-cache || exit 1 - -echo "Testing compiled app" -sample_output=$(dotnet test __tests__/sample-csproj/ --no-build) -echo "Sample output: $sample_output" -# For Side-by-Side installs we want to run the tests twice, for a single install the tests will run once -if [ -n "$2" ]; then - if [ -z "$(echo $sample_output | grep "Test Run Successful.*Test Run Successful.")" ]; then - echo "Unexpected output" - exit 1 - fi -else - if [ -z "$(echo $sample_output | grep "Test Run Successful.")" ]; then - echo "Unexpected output" - exit 1 - fi -fi \ No newline at end of file From a79ce57e6b19c164cea1267185d12ae20544407c Mon Sep 17 00:00:00 2001 From: IvanZosimov Date: Wed, 19 Apr 2023 13:43:18 +0200 Subject: [PATCH 13/30] Update contribution documentation --- docs/contributors.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/contributors.md b/docs/contributors.md index 0141e97..3d2a55d 100644 --- a/docs/contributors.md +++ b/docs/contributors.md @@ -67,7 +67,7 @@ Pull requests are the easiest way to contribute changes to git repos at GitHub. **Learn more about how to implement tests:** Adding or changing tests is an integral part of making a change to the code. -Unit tests are in the `__tests__` folder, and end-to-end tests are in the `workflows` folder, particularly in the [workflow.yml](https://github.com/actions/setup-dotnet/blob/main/.github/workflows/workflow.yml). +Unit tests are in the `__tests__` folder, and end-to-end tests are in the `workflows` folder, particularly in the [e2e-tests.yml](https://github.com/actions/setup-dotnet/blob/main/.github/workflows/e2e-tests.yml). - The contributor can add various types of tests (like unit tests or end-to-end tests), which, in his opinion, will be necessary and sufficient for testing new or changed functionality - Tests should cover a successful execution, as well as some edge cases and possible errors From e8ac21d503508fd057b818619cd0e31c3db74e30 Mon Sep 17 00:00:00 2001 From: IvanZosimov Date: Wed, 19 Apr 2023 15:41:28 +0200 Subject: [PATCH 14/30] Fix typos --- __tests__/verify-dotnet.ps1 | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/__tests__/verify-dotnet.ps1 b/__tests__/verify-dotnet.ps1 index 496fec2..b937a14 100755 --- a/__tests__/verify-dotnet.ps1 +++ b/__tests__/verify-dotnet.ps1 @@ -28,9 +28,7 @@ if ($CheckNugetConfig.IsPresent -and !(Test-Path "../nuget.config")) { throw "The nuget.config file is not generated correctly." } -$PatternsCount = $PatternsList.Count - -Write-Host "Those patterns were supplied to the script: $($PatternsList -join ', ')." +Write-Host "These patterns were supplied to the script: $($PatternsList -join ', ')." $dotnet = Get-Command dotnet | Select-Object -First 1 | ForEach-Object { $_.Path } Write-Host "Found: '$dotnet'" @@ -57,9 +55,9 @@ if ( $InstalledVersionCount -ne 0) throw "An unexpected version of Dotnet is found on the machine, please check the correctness of the -Patterns input." } -Write-Host "Changing directory to the ./__tests__/e2e-test-csproj" $workingDir = Get-Location $testProjectDir = "./__tests__/e2e-test-csproj" +Write-Host "Changing directory to the $testProjectDir" Set-Location $testProjectDir $targetFrameworkVersionMap = @{ From 50b46b3b1d8734a2d964e6961fe5ba5ee1b91280 Mon Sep 17 00:00:00 2001 From: IvanZosimov Date: Wed, 19 Apr 2023 16:24:27 +0200 Subject: [PATCH 15/30] Update verify-dotnet.ps1 --- .github/workflows/test-dotnet.yml | 2 +- __tests__/verify-dotnet.ps1 | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test-dotnet.yml b/.github/workflows/test-dotnet.yml index 760167b..03b9a29 100644 --- a/.github/workflows/test-dotnet.yml +++ b/.github/workflows/test-dotnet.yml @@ -18,7 +18,7 @@ jobs: fail-fast: false matrix: operating-system: [ubuntu-latest, windows-latest, macOS-latest] - dotnet-version: ['2.1', '2.2', '3.0', '3.1', '5.0', '6.0', '7.0'] + dotnet-version: ['2.1', '2.2', '3.0', '3.1', '5.0', '6.0', '7.0', '8.0'] steps: - name: Checkout uses: actions/checkout@v3 diff --git a/__tests__/verify-dotnet.ps1 b/__tests__/verify-dotnet.ps1 index b937a14..fa4876d 100755 --- a/__tests__/verify-dotnet.ps1 +++ b/__tests__/verify-dotnet.ps1 @@ -71,6 +71,7 @@ $targetFrameworkVersionMap = @{ "5.0" = "net5.0"; "6.0" = "net6.0"; "7.0" = "net7.0"; + "8.0" = "net8.0"; } foreach ($version in $Versions) @@ -78,10 +79,18 @@ foreach ($version in $Versions) # Creating temporary global.json file inside e2e-test-csproj dir and setting exact version of .NET inside allows to override default behavior of .NET and run build and tests on that exact version. Write-Host "Creating temporary global.json file for $version .NET version." & $dotnet new globaljson --sdk-version $version --force + if (!(Test-Path "./global.json")) + { + throw "An error occured while creating the global.json file. Exit code: $LASTEXITCODE" + } Write-Host "The global.json file for the version $version is created. Currently used .NET version is: $(& $dotnet --version)." # Environment variable TEST_TARGET_FRAMEWORK is used inside the test.csproj file to target required framework version - $version -match "^(?\d+\.\d+)" + $version -match "^(?\d+\.\d+)" | Out-Null + if (!($targetFrameworkVersionMap.ContainsKey($Matches.key))) + { + throw "The map with the framework targets doesn't contain a target name for the version $version." + } Write-Host "Setting the TEST_TARGET_FRAMEWORK environment variable to $($targetFrameworkVersionMap[$Matches.key])" [Environment]::SetEnvironmentVariable('TEST_TARGET_FRAMEWORK', $($targetFrameworkVersionMap[$Matches.key])) From 255362be61a1c67b8f9b3441049f77c0aa1e8898 Mon Sep 17 00:00:00 2001 From: IvanZosimov Date: Wed, 19 Apr 2023 16:32:38 +0200 Subject: [PATCH 16/30] Silent dotnet new globaljson command --- __tests__/verify-dotnet.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/__tests__/verify-dotnet.ps1 b/__tests__/verify-dotnet.ps1 index fa4876d..187c715 100755 --- a/__tests__/verify-dotnet.ps1 +++ b/__tests__/verify-dotnet.ps1 @@ -78,7 +78,7 @@ foreach ($version in $Versions) { # Creating temporary global.json file inside e2e-test-csproj dir and setting exact version of .NET inside allows to override default behavior of .NET and run build and tests on that exact version. Write-Host "Creating temporary global.json file for $version .NET version." - & $dotnet new globaljson --sdk-version $version --force + & $dotnet new globaljson --sdk-version $version --force | Out-Null if (!(Test-Path "./global.json")) { throw "An error occured while creating the global.json file. Exit code: $LASTEXITCODE" From 7d08dc7593e68a8fd87b871930df2cace89d7c66 Mon Sep 17 00:00:00 2001 From: IvanZosimov Date: Wed, 19 Apr 2023 16:48:00 +0200 Subject: [PATCH 17/30] Add e2e test --- .github/workflows/e2e-tests.yml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml index 9963bbc..31ecca7 100644 --- a/.github/workflows/e2e-tests.yml +++ b/.github/workflows/e2e-tests.yml @@ -205,6 +205,27 @@ jobs: shell: pwsh run: __tests__/verify-dotnet.ps1 -Patterns "^7\.0\.\d+-" + 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-dotnet-version-output-during-single-version-installation: runs-on: ${{ matrix.operating-system }} strategy: From 6adeb768cee8b4e95f5d006c4d702894fe7eb050 Mon Sep 17 00:00:00 2001 From: IvanZosimov Date: Fri, 5 May 2023 10:43:09 +0200 Subject: [PATCH 18/30] Update docs --- README.md | 3 +- __tests__/installer.test.ts | 368 +++++++++++++++++------------------- action.yml | 2 +- dist/index.js | 21 +- src/installer.ts | 23 +-- 5 files changed, 197 insertions(+), 220 deletions(-) diff --git a/README.md b/README.md index b275fc3..c2f6d55 100644 --- a/README.md +++ b/README.md @@ -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: diff --git a/__tests__/installer.test.ts b/__tests__/installer.test.ts index 363310c..4830e7a 100644 --- a/__tests__/installer.test.ts +++ b/__tests__/installer.test.ts @@ -53,232 +53,202 @@ describe('DotnetCoreInstaller tests', () => { } }, 30000); - it('Aquires multiple versions of dotnet', async () => { - const versions = ['2.2.207', '3.1.120']; + // it('Aquires multiple versions of dotnet', async () => { + // const versions = ['2.2.207', '3.1.120']; - for (const version of versions) { - await getDotnet(version); - } - expect(fs.existsSync(path.join(toolDir, 'sdk', '2.2.207'))).toBe(true); - expect(fs.existsSync(path.join(toolDir, 'sdk', '3.1.120'))).toBe(true); + // for (const version of versions) { + // await getDotnet(version); + // } + // expect(fs.existsSync(path.join(toolDir, 'sdk', '2.2.207'))).toBe(true); + // expect(fs.existsSync(path.join(toolDir, 'sdk', '3.1.120'))).toBe(true); - if (IS_WINDOWS) { - expect(fs.existsSync(path.join(toolDir, 'dotnet.exe'))).toBe(true); - } else { - expect(fs.existsSync(path.join(toolDir, 'dotnet'))).toBe(true); - } + // if (IS_WINDOWS) { + // expect(fs.existsSync(path.join(toolDir, 'dotnet.exe'))).toBe(true); + // } else { + // expect(fs.existsSync(path.join(toolDir, 'dotnet'))).toBe(true); + // } - expect(process.env.DOTNET_ROOT).toBeDefined(); - expect(process.env.PATH).toBeDefined(); - expect(process.env.DOTNET_ROOT).toBe(toolDir); - expect(process.env.PATH?.startsWith(toolDir)).toBe(true); - }, 600000); + // expect(process.env.DOTNET_ROOT).toBeDefined(); + // expect(process.env.PATH).toBeDefined(); + // expect(process.env.DOTNET_ROOT).toBe(toolDir); + // expect(process.env.PATH?.startsWith(toolDir)).toBe(true); + // }, 600000); - it('Acquires version of dotnet if no matching version is installed', async () => { - await getDotnet('3.1.201'); - expect(fs.existsSync(path.join(toolDir, 'sdk', '3.1.201'))).toBe(true); - if (IS_WINDOWS) { - expect(fs.existsSync(path.join(toolDir, 'dotnet.exe'))).toBe(true); - } else { - expect(fs.existsSync(path.join(toolDir, 'dotnet'))).toBe(true); - } + // it('Acquires version of dotnet if no matching version is installed', async () => { + // await getDotnet('3.1.201'); + // expect(fs.existsSync(path.join(toolDir, 'sdk', '3.1.201'))).toBe(true); + // if (IS_WINDOWS) { + // expect(fs.existsSync(path.join(toolDir, 'dotnet.exe'))).toBe(true); + // } else { + // expect(fs.existsSync(path.join(toolDir, 'dotnet'))).toBe(true); + // } - expect(process.env.DOTNET_ROOT).toBeDefined(); - expect(process.env.PATH).toBeDefined(); - expect(process.env.DOTNET_ROOT).toBe(toolDir); - expect(process.env.PATH?.startsWith(toolDir)).toBe(true); - }, 600000); //This needs some time to download on "slower" internet connections + // expect(process.env.DOTNET_ROOT).toBeDefined(); + // expect(process.env.PATH).toBeDefined(); + // expect(process.env.DOTNET_ROOT).toBe(toolDir); + // expect(process.env.PATH?.startsWith(toolDir)).toBe(true); + // }, 600000); //This needs some time to download on "slower" internet connections - it('Acquires generic version of dotnet if no matching version is installed', async () => { - await getDotnet('3.1'); - const directory = fs - .readdirSync(path.join(toolDir, 'sdk')) - .filter(fn => fn.startsWith('3.1.')); - expect(directory.length > 0).toBe(true); - if (IS_WINDOWS) { - expect(fs.existsSync(path.join(toolDir, 'dotnet.exe'))).toBe(true); - } else { - expect(fs.existsSync(path.join(toolDir, 'dotnet'))).toBe(true); - } + // it('Acquires generic version of dotnet if no matching version is installed', async () => { + // await getDotnet('3.1'); + // const directory = fs + // .readdirSync(path.join(toolDir, 'sdk')) + // .filter(fn => fn.startsWith('3.1.')); + // expect(directory.length > 0).toBe(true); + // if (IS_WINDOWS) { + // expect(fs.existsSync(path.join(toolDir, 'dotnet.exe'))).toBe(true); + // } else { + // expect(fs.existsSync(path.join(toolDir, 'dotnet'))).toBe(true); + // } - expect(process.env.DOTNET_ROOT).toBeDefined(); - expect(process.env.PATH).toBeDefined(); - expect(process.env.DOTNET_ROOT).toBe(toolDir); - expect(process.env.PATH?.startsWith(toolDir)).toBe(true); - }, 600000); //This needs some time to download on "slower" internet connections + // expect(process.env.DOTNET_ROOT).toBeDefined(); + // expect(process.env.PATH).toBeDefined(); + // expect(process.env.DOTNET_ROOT).toBe(toolDir); + // expect(process.env.PATH?.startsWith(toolDir)).toBe(true); + // }, 600000); //This needs some time to download on "slower" internet connections it('Returns string with installed SDK version', async () => { - const version = '3.1.120'; + const version = '6.0.1xx'; const installedVersion = await getDotnet(version); expect(installedVersion).toBe('3.1.120'); }, 600000); - - it('Throws if no location contains correct dotnet version', async () => { - await expect(async () => { - await getDotnet('1000.0.0'); - }).rejects.toThrow(); - }, 30000); - - it('Uses an up to date bash download script', async () => { - const httpCallbackClient = new hc.HttpClient('setup-dotnet-test', [], { - allowRetries: true, - maxRetries: 3 - }); - const response: hc.HttpClientResponse = await httpCallbackClient.get( - 'https://dot.net/v1/dotnet-install.sh' - ); - expect(response.message.statusCode).toBe(200); - const upToDateContents: string = await response.readBody(); - const currentContents: string = fs - .readFileSync( - path.join(__dirname, '..', 'externals', 'install-dotnet.sh') - ) - .toString(); - expect(normalizeFileContents(currentContents)).toBe( - normalizeFileContents(upToDateContents) - ); - }, 30000); - - it('Uses an up to date powershell download script', async () => { - const httpCallbackClient = new hc.HttpClient('setup-dotnet-test', [], { - allowRetries: true, - maxRetries: 3 - }); - const response: hc.HttpClientResponse = await httpCallbackClient.get( - 'https://dot.net/v1/dotnet-install.ps1' - ); - expect(response.message.statusCode).toBe(200); - const upToDateContents: string = await response.readBody(); - const currentContents: string = fs - .readFileSync( - path.join(__dirname, '..', 'externals', 'install-dotnet.ps1') - ) - .toString(); - expect(normalizeFileContents(currentContents)).toBe( - normalizeFileContents(upToDateContents) - ); - }, 30000); }); -describe('DotnetVersionResolver tests', () => { - each([ - '3.1', - '3.x', - '3.1.x', - '3.1.*', - '3.1.X', - '3.1.2', - '3.1.0-preview1' - ]).test( - "if valid version: '%s' is supplied, it should return version object with some value", - async version => { - const dotnetVersionResolver = new installer.DotnetVersionResolver( - version - ); - const versionObject = await dotnetVersionResolver.createDotNetVersion(); +// describe('DotnetVersionResolver tests', () => { +// each([ +// '3.1', +// '3.x', +// '3.1.x', +// '3.1.*', +// '3.1.X', +// '3.1.2', +// '3.1.0-preview1' +// ]).test( +// "if valid version: '%s' is supplied, it should return version object with some value", +// async version => { +// const dotnetVersionResolver = new installer.DotnetVersionResolver( +// version +// ); +// const versionObject = await dotnetVersionResolver.createDotNetVersion(); - expect(!!versionObject.value).toBe(true); - } - ); +// expect(!!versionObject.value).toBe(true); +// } +// ); - each([ - '.', - '..', - ' . ', - '. ', - ' .', - ' . . ', - ' .. ', - ' . ', - '-1.-1', - '-1', - '-1.-1.-1', - '..3', - '1..3', - '1..', - '.2.3', - '.2.x', - '*.', - '1.2.', - '1.2.-abc', - 'a.b', - 'a.b.c', - 'a.b.c-preview', - ' 0 . 1 . 2 ', - 'invalid' - ]).test( - "if invalid version: '%s' is supplied, it should throw", - async version => { - const dotnetVersionResolver = new installer.DotnetVersionResolver( - version - ); +// each([ +// '.', +// '..', +// ' . ', +// '. ', +// ' .', +// ' . . ', +// ' .. ', +// ' . ', +// '-1.-1', +// '-1', +// '-1.-1.-1', +// '..3', +// '1..3', +// '1..', +// '.2.3', +// '.2.x', +// '*.', +// '1.2.', +// '1.2.-abc', +// 'a.b', +// 'a.b.c', +// 'a.b.c-preview', +// ' 0 . 1 . 2 ', +// 'invalid' +// ]).test( +// "if invalid version: '%s' is supplied, it should throw", +// async version => { +// const dotnetVersionResolver = new installer.DotnetVersionResolver( +// version +// ); - await expect( - async () => await dotnetVersionResolver.createDotNetVersion() - ).rejects.toThrow(); - } - ); +// await expect( +// async () => await dotnetVersionResolver.createDotNetVersion() +// ).rejects.toThrow(); +// } +// ); - each(['3.1', '3.1.x', '3.1.*', '3.1.X', '5.0.1xx']).test( - "if version: '%s' that can be resolved to 'channel' option is supplied, it should set type to 'channel' in version object", - async version => { - const dotnetVersionResolver = new installer.DotnetVersionResolver( - version - ); - const versionObject = await dotnetVersionResolver.createDotNetVersion(); +// each(['3.1', '3.1.x', '3.1.*', '3.1.X', '5.0.1xx']).test( +// "if version: '%s' that can be resolved to 'channel' option is supplied, it should set type to 'channel' in version object", +// async version => { +// const dotnetVersionResolver = new installer.DotnetVersionResolver( +// version +// ); +// const versionObject = await dotnetVersionResolver.createDotNetVersion(); - expect(versionObject.type.toLowerCase().includes('channel')).toBe(true); - } - ); +// expect(versionObject.type.toLowerCase().includes('channel')).toBe(true); +// } +// ); - each(['6.0', '6.0.x', '6.0.*', '6.0.X', '6.0.1xx']).test( - "if version: '%s' that can be resolved to 'channel' option is supplied and its major tag is >= 6, it should set type to 'channel' and qualityFlag to 'true' in version object", - async version => { - const dotnetVersionResolver = new installer.DotnetVersionResolver( - version - ); - const versionObject = await dotnetVersionResolver.createDotNetVersion(); +// each(['6.0', '6.0.x', '6.0.*', '6.0.X', '6.0.1xx']).test( +// "if version: '%s' that can be resolved to 'channel' option is supplied and its major tag is >= 6, it should set type to 'channel' and qualityFlag to 'true' in version object", +// async version => { +// const dotnetVersionResolver = new installer.DotnetVersionResolver( +// version +// ); +// const versionObject = await dotnetVersionResolver.createDotNetVersion(); - expect(versionObject.type.toLowerCase().includes('channel')).toBe(true); - expect(versionObject.qualityFlag).toBe(true); - } - ); +// expect(versionObject.type.toLowerCase().includes('channel')).toBe(true); +// expect(versionObject.qualityFlag).toBe(true); +// } +// ); - each(['3.1.2', '3.1.0-preview1']).test( - "if version: '%s' that can be resolved to 'version' option is supplied, it should set quality flag to 'false' and type to 'version' in version object", - async version => { - const dotnetVersionResolver = new installer.DotnetVersionResolver( - version - ); - const versionObject = await dotnetVersionResolver.createDotNetVersion(); +// each(['3.1.2', '3.1.0-preview1']).test( +// "if version: '%s' that can be resolved to 'version' option is supplied, it should set quality flag to 'false' and type to 'version' in version object", +// async version => { +// const dotnetVersionResolver = new installer.DotnetVersionResolver( +// version +// ); +// const versionObject = await dotnetVersionResolver.createDotNetVersion(); - expect(versionObject.type.toLowerCase().includes('version')).toBe(true); - expect(versionObject.qualityFlag).toBe(false); - } - ); +// expect(versionObject.type.toLowerCase().includes('version')).toBe(true); +// expect(versionObject.qualityFlag).toBe(false); +// } +// ); - each(['3.1.2', '3.1']).test( - 'it should create proper line arguments for powershell/bash installation scripts', - async version => { - const dotnetVersionResolver = new installer.DotnetVersionResolver( - version - ); - const versionObject = await dotnetVersionResolver.createDotNetVersion(); - const windowsRegEx = new RegExp(/^-[VC]/); - const nonWindowsRegEx = new RegExp(/^--[vc]/); +// each(['3.1.2', '3.1']).test( +// 'it should create proper line arguments for powershell/bash installation scripts', +// async version => { +// const dotnetVersionResolver = new installer.DotnetVersionResolver( +// version +// ); +// const versionObject = await dotnetVersionResolver.createDotNetVersion(); +// const windowsRegEx = new RegExp(/^-[VC]/); +// const nonWindowsRegEx = new RegExp(/^--[vc]/); - if (IS_WINDOWS) { - expect(windowsRegEx.test(versionObject.type)).toBe(true); - expect(nonWindowsRegEx.test(versionObject.type)).toBe(false); - } else { - expect(nonWindowsRegEx.test(versionObject.type)).toBe(true); - expect(windowsRegEx.test(versionObject.type)).toBe(false); - } - } - ); -}); +// if (IS_WINDOWS) { +// expect(windowsRegEx.test(versionObject.type)).toBe(true); +// expect(nonWindowsRegEx.test(versionObject.type)).toBe(false); +// } else { +// expect(nonWindowsRegEx.test(versionObject.type)).toBe(true); +// expect(windowsRegEx.test(versionObject.type)).toBe(false); +// } +// } +// ); + +// it('Should throw if supplied dotnet version is in A.B.Cxx syntax and the major tag is lower than 5', async () => { +// const version = '3.1.1xx'; +// const dotnetVersionResolver = new installer.DotnetVersionResolver(version); +// await expect(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.` +// ); +// }, 600000); + +// it('Should resolve version supplied as * to channel type and set value to LTS', async () => { +// const version = '*'; +// const dotnetVersionResolver = new installer.DotnetVersionResolver(version); +// const versionObject = await dotnetVersionResolver.createDotNetVersion(); +// expect(versionObject.type.toLowerCase().includes('channel')).toBe(true); +// expect(versionObject.value).toBe('LTS'); +// }, 600000); +// }); function normalizeFileContents(contents: string): string { return contents diff --git a/action.yml b/action.yml index dafec86..eec3975 100644 --- a/action.yml +++ b/action.yml @@ -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, 3.1.4xx' dotnet-quality: description: 'Optional quality of the build. The possible values are: daily, signed, validated, preview, ga.' global-json-file: diff --git a/dist/index.js b/dist/index.js index 40338d4..7346d82 100644 --- a/dist/index.js +++ b/dist/index.js @@ -297,7 +297,7 @@ class DotnetVersionResolver { this.resolvedArgument.value = yield this.getLatestByMajorTag(major); } else { - // If "dotnet-version" is specified as *, x or X resolve latest version of .NET explicitly from LTS channel. The version argument will be set to "latest" by default. + // If "dotnet-version" is specified as *, x or X resolve latest version of .NET explicitly from LTS channel. The version argument will default to "latest" by install-dotnet script. this.resolvedArgument.value = 'LTS'; } this.resolvedArgument.qualityFlag = @@ -377,6 +377,7 @@ class DotnetCoreInstaller { } installDotnet() { return __awaiter(this, void 0, void 0, function* () { + const listOfInstalledVersions = yield this.getListOfInstalledVersions(); const windowsDefaultOptions = [ '-NoLogo', '-Sta', @@ -433,17 +434,21 @@ class DotnetCoreInstaller { if (exitCode) { throw new Error(`Failed to install dotnet, exit code: ${exitCode}. ${stderr}`); } - return this.outputDotnetVersion(dotnetVersion.value); + return this.outputDotnetVersion(listOfInstalledVersions); }); } - outputDotnetVersion(version) { + getListOfInstalledVersions() { return __awaiter(this, void 0, void 0, function* () { const installationPath = process.env['DOTNET_INSTALL_DIR']; - const versionsOnRunner = yield (0, promises_1.readdir)(path_1.default.join(installationPath.replace(/'/g, ''), 'sdk')); - const installedVersion = semver_1.default.maxSatisfying(versionsOnRunner, version, { - includePrerelease: true - }); - return installedVersion; + const versionsOnRunner = (yield (0, promises_1.readdir)(path_1.default.join(installationPath.replace(/'/g, ''), 'sdk'))).filter((el) => semver_1.default.valid(el)); + return versionsOnRunner; + }); + } + outputDotnetVersion(listOfInstalledVersions) { + return __awaiter(this, void 0, void 0, function* () { + const updatedListOfInstalledVersions = yield this.getListOfInstalledVersions(); + const installedVersion = updatedListOfInstalledVersions.filter((el) => !listOfInstalledVersions.includes(el)); + return installedVersion[0]; }); } } diff --git a/src/installer.ts b/src/installer.ts index a105fef..7663de9 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -79,7 +79,7 @@ export class DotnetVersionResolver { } else if (this.isNumericTag(major)) { this.resolvedArgument.value = await this.getLatestByMajorTag(major); } else { - // If "dotnet-version" is specified as *, x or X resolve latest version of .NET explicitly from LTS channel. The version argument will be set to "latest" by default. + // If "dotnet-version" is specified as *, x or X resolve latest version of .NET explicitly from LTS channel. The version argument will default to "latest" by install-dotnet script. this.resolvedArgument.value = 'LTS'; } this.resolvedArgument.qualityFlag = @@ -199,6 +199,7 @@ export class DotnetCoreInstaller { } public async installDotnet(): Promise { + const listOfInstalledVersions = await this.getListOfInstalledVersions(); const windowsDefaultOptions = [ '-NoLogo', '-Sta', @@ -268,20 +269,20 @@ export class DotnetCoreInstaller { `Failed to install dotnet, exit code: ${exitCode}. ${stderr}` ); } - - return this.outputDotnetVersion(dotnetVersion.value); + return await this.outputDotnetVersion(listOfInstalledVersions); } - private async outputDotnetVersion(version): Promise { + private async getListOfInstalledVersions(): Promise { const installationPath = process.env['DOTNET_INSTALL_DIR']!; - const versionsOnRunner: string[] = await readdir( + const versionsOnRunner: string[] = (await readdir( path.join(installationPath.replace(/'/g, ''), 'sdk') - ); + )).filter((el) => semver.valid(el)); + return versionsOnRunner; + } - const installedVersion = semver.maxSatisfying(versionsOnRunner, version, { - includePrerelease: true - })!; - - return installedVersion; + private async outputDotnetVersion(listOfInstalledVersions: string[]): Promise { + const updatedListOfInstalledVersions = await this.getListOfInstalledVersions(); + const installedVersion = updatedListOfInstalledVersions.filter((el) => !listOfInstalledVersions.includes(el)) + return installedVersion[0]; } } From c5a57b219c805c87cd7a98b4ae0e64c541f1352e Mon Sep 17 00:00:00 2001 From: IvanZosimov Date: Fri, 5 May 2023 10:44:54 +0200 Subject: [PATCH 19/30] Update unit-tests --- __tests__/installer.test.ts | 332 ++++++++++++++++++------------------ src/installer.ts | 17 +- 2 files changed, 177 insertions(+), 172 deletions(-) diff --git a/__tests__/installer.test.ts b/__tests__/installer.test.ts index 4830e7a..f84e303 100644 --- a/__tests__/installer.test.ts +++ b/__tests__/installer.test.ts @@ -53,59 +53,59 @@ describe('DotnetCoreInstaller tests', () => { } }, 30000); - // it('Aquires multiple versions of dotnet', async () => { - // const versions = ['2.2.207', '3.1.120']; + it('Aquires multiple versions of dotnet', async () => { + const versions = ['2.2.207', '3.1.120']; - // for (const version of versions) { - // await getDotnet(version); - // } - // expect(fs.existsSync(path.join(toolDir, 'sdk', '2.2.207'))).toBe(true); - // expect(fs.existsSync(path.join(toolDir, 'sdk', '3.1.120'))).toBe(true); + for (const version of versions) { + await getDotnet(version); + } + expect(fs.existsSync(path.join(toolDir, 'sdk', '2.2.207'))).toBe(true); + expect(fs.existsSync(path.join(toolDir, 'sdk', '3.1.120'))).toBe(true); - // if (IS_WINDOWS) { - // expect(fs.existsSync(path.join(toolDir, 'dotnet.exe'))).toBe(true); - // } else { - // expect(fs.existsSync(path.join(toolDir, 'dotnet'))).toBe(true); - // } + if (IS_WINDOWS) { + expect(fs.existsSync(path.join(toolDir, 'dotnet.exe'))).toBe(true); + } else { + expect(fs.existsSync(path.join(toolDir, 'dotnet'))).toBe(true); + } - // expect(process.env.DOTNET_ROOT).toBeDefined(); - // expect(process.env.PATH).toBeDefined(); - // expect(process.env.DOTNET_ROOT).toBe(toolDir); - // expect(process.env.PATH?.startsWith(toolDir)).toBe(true); - // }, 600000); + expect(process.env.DOTNET_ROOT).toBeDefined(); + expect(process.env.PATH).toBeDefined(); + expect(process.env.DOTNET_ROOT).toBe(toolDir); + expect(process.env.PATH?.startsWith(toolDir)).toBe(true); + }, 600000); - // it('Acquires version of dotnet if no matching version is installed', async () => { - // await getDotnet('3.1.201'); - // expect(fs.existsSync(path.join(toolDir, 'sdk', '3.1.201'))).toBe(true); - // if (IS_WINDOWS) { - // expect(fs.existsSync(path.join(toolDir, 'dotnet.exe'))).toBe(true); - // } else { - // expect(fs.existsSync(path.join(toolDir, 'dotnet'))).toBe(true); - // } + it('Acquires version of dotnet if no matching version is installed', async () => { + await getDotnet('3.1.201'); + expect(fs.existsSync(path.join(toolDir, 'sdk', '3.1.201'))).toBe(true); + if (IS_WINDOWS) { + expect(fs.existsSync(path.join(toolDir, 'dotnet.exe'))).toBe(true); + } else { + expect(fs.existsSync(path.join(toolDir, 'dotnet'))).toBe(true); + } - // expect(process.env.DOTNET_ROOT).toBeDefined(); - // expect(process.env.PATH).toBeDefined(); - // expect(process.env.DOTNET_ROOT).toBe(toolDir); - // expect(process.env.PATH?.startsWith(toolDir)).toBe(true); - // }, 600000); //This needs some time to download on "slower" internet connections + expect(process.env.DOTNET_ROOT).toBeDefined(); + expect(process.env.PATH).toBeDefined(); + expect(process.env.DOTNET_ROOT).toBe(toolDir); + expect(process.env.PATH?.startsWith(toolDir)).toBe(true); + }, 600000); //This needs some time to download on "slower" internet connections - // it('Acquires generic version of dotnet if no matching version is installed', async () => { - // await getDotnet('3.1'); - // const directory = fs - // .readdirSync(path.join(toolDir, 'sdk')) - // .filter(fn => fn.startsWith('3.1.')); - // expect(directory.length > 0).toBe(true); - // if (IS_WINDOWS) { - // expect(fs.existsSync(path.join(toolDir, 'dotnet.exe'))).toBe(true); - // } else { - // expect(fs.existsSync(path.join(toolDir, 'dotnet'))).toBe(true); - // } + it('Acquires generic version of dotnet if no matching version is installed', async () => { + await getDotnet('3.1'); + const directory = fs + .readdirSync(path.join(toolDir, 'sdk')) + .filter(fn => fn.startsWith('3.1.')); + expect(directory.length > 0).toBe(true); + if (IS_WINDOWS) { + expect(fs.existsSync(path.join(toolDir, 'dotnet.exe'))).toBe(true); + } else { + expect(fs.existsSync(path.join(toolDir, 'dotnet'))).toBe(true); + } - // expect(process.env.DOTNET_ROOT).toBeDefined(); - // expect(process.env.PATH).toBeDefined(); - // expect(process.env.DOTNET_ROOT).toBe(toolDir); - // expect(process.env.PATH?.startsWith(toolDir)).toBe(true); - // }, 600000); //This needs some time to download on "slower" internet connections + expect(process.env.DOTNET_ROOT).toBeDefined(); + expect(process.env.PATH).toBeDefined(); + expect(process.env.DOTNET_ROOT).toBe(toolDir); + expect(process.env.PATH?.startsWith(toolDir)).toBe(true); + }, 600000); //This needs some time to download on "slower" internet connections it('Returns string with installed SDK version', async () => { const version = '6.0.1xx'; @@ -116,139 +116,139 @@ describe('DotnetCoreInstaller tests', () => { }, 600000); }); -// describe('DotnetVersionResolver tests', () => { -// each([ -// '3.1', -// '3.x', -// '3.1.x', -// '3.1.*', -// '3.1.X', -// '3.1.2', -// '3.1.0-preview1' -// ]).test( -// "if valid version: '%s' is supplied, it should return version object with some value", -// async version => { -// const dotnetVersionResolver = new installer.DotnetVersionResolver( -// version -// ); -// const versionObject = await dotnetVersionResolver.createDotNetVersion(); +describe('DotnetVersionResolver tests', () => { + each([ + '3.1', + '3.x', + '3.1.x', + '3.1.*', + '3.1.X', + '3.1.2', + '3.1.0-preview1' + ]).test( + "if valid version: '%s' is supplied, it should return version object with some value", + async version => { + const dotnetVersionResolver = new installer.DotnetVersionResolver( + version + ); + const versionObject = await dotnetVersionResolver.createDotNetVersion(); -// expect(!!versionObject.value).toBe(true); -// } -// ); + expect(!!versionObject.value).toBe(true); + } + ); -// each([ -// '.', -// '..', -// ' . ', -// '. ', -// ' .', -// ' . . ', -// ' .. ', -// ' . ', -// '-1.-1', -// '-1', -// '-1.-1.-1', -// '..3', -// '1..3', -// '1..', -// '.2.3', -// '.2.x', -// '*.', -// '1.2.', -// '1.2.-abc', -// 'a.b', -// 'a.b.c', -// 'a.b.c-preview', -// ' 0 . 1 . 2 ', -// 'invalid' -// ]).test( -// "if invalid version: '%s' is supplied, it should throw", -// async version => { -// const dotnetVersionResolver = new installer.DotnetVersionResolver( -// version -// ); + each([ + '.', + '..', + ' . ', + '. ', + ' .', + ' . . ', + ' .. ', + ' . ', + '-1.-1', + '-1', + '-1.-1.-1', + '..3', + '1..3', + '1..', + '.2.3', + '.2.x', + '*.', + '1.2.', + '1.2.-abc', + 'a.b', + 'a.b.c', + 'a.b.c-preview', + ' 0 . 1 . 2 ', + 'invalid' + ]).test( + "if invalid version: '%s' is supplied, it should throw", + async version => { + const dotnetVersionResolver = new installer.DotnetVersionResolver( + version + ); -// await expect( -// async () => await dotnetVersionResolver.createDotNetVersion() -// ).rejects.toThrow(); -// } -// ); + await expect( + async () => await dotnetVersionResolver.createDotNetVersion() + ).rejects.toThrow(); + } + ); -// each(['3.1', '3.1.x', '3.1.*', '3.1.X', '5.0.1xx']).test( -// "if version: '%s' that can be resolved to 'channel' option is supplied, it should set type to 'channel' in version object", -// async version => { -// const dotnetVersionResolver = new installer.DotnetVersionResolver( -// version -// ); -// const versionObject = await dotnetVersionResolver.createDotNetVersion(); + each(['3.1', '3.1.x', '3.1.*', '3.1.X', '5.0.1xx']).test( + "if version: '%s' that can be resolved to 'channel' option is supplied, it should set type to 'channel' in version object", + async version => { + const dotnetVersionResolver = new installer.DotnetVersionResolver( + version + ); + const versionObject = await dotnetVersionResolver.createDotNetVersion(); -// expect(versionObject.type.toLowerCase().includes('channel')).toBe(true); -// } -// ); + expect(versionObject.type.toLowerCase().includes('channel')).toBe(true); + } + ); -// each(['6.0', '6.0.x', '6.0.*', '6.0.X', '6.0.1xx']).test( -// "if version: '%s' that can be resolved to 'channel' option is supplied and its major tag is >= 6, it should set type to 'channel' and qualityFlag to 'true' in version object", -// async version => { -// const dotnetVersionResolver = new installer.DotnetVersionResolver( -// version -// ); -// const versionObject = await dotnetVersionResolver.createDotNetVersion(); + each(['6.0', '6.0.x', '6.0.*', '6.0.X', '6.0.1xx']).test( + "if version: '%s' that can be resolved to 'channel' option is supplied and its major tag is >= 6, it should set type to 'channel' and qualityFlag to 'true' in version object", + async version => { + const dotnetVersionResolver = new installer.DotnetVersionResolver( + version + ); + const versionObject = await dotnetVersionResolver.createDotNetVersion(); -// expect(versionObject.type.toLowerCase().includes('channel')).toBe(true); -// expect(versionObject.qualityFlag).toBe(true); -// } -// ); + expect(versionObject.type.toLowerCase().includes('channel')).toBe(true); + expect(versionObject.qualityFlag).toBe(true); + } + ); -// each(['3.1.2', '3.1.0-preview1']).test( -// "if version: '%s' that can be resolved to 'version' option is supplied, it should set quality flag to 'false' and type to 'version' in version object", -// async version => { -// const dotnetVersionResolver = new installer.DotnetVersionResolver( -// version -// ); -// const versionObject = await dotnetVersionResolver.createDotNetVersion(); + each(['3.1.2', '3.1.0-preview1']).test( + "if version: '%s' that can be resolved to 'version' option is supplied, it should set quality flag to 'false' and type to 'version' in version object", + async version => { + const dotnetVersionResolver = new installer.DotnetVersionResolver( + version + ); + const versionObject = await dotnetVersionResolver.createDotNetVersion(); -// expect(versionObject.type.toLowerCase().includes('version')).toBe(true); -// expect(versionObject.qualityFlag).toBe(false); -// } -// ); + expect(versionObject.type.toLowerCase().includes('version')).toBe(true); + expect(versionObject.qualityFlag).toBe(false); + } + ); -// each(['3.1.2', '3.1']).test( -// 'it should create proper line arguments for powershell/bash installation scripts', -// async version => { -// const dotnetVersionResolver = new installer.DotnetVersionResolver( -// version -// ); -// const versionObject = await dotnetVersionResolver.createDotNetVersion(); -// const windowsRegEx = new RegExp(/^-[VC]/); -// const nonWindowsRegEx = new RegExp(/^--[vc]/); + each(['3.1.2', '3.1']).test( + 'it should create proper line arguments for powershell/bash installation scripts', + async version => { + const dotnetVersionResolver = new installer.DotnetVersionResolver( + version + ); + const versionObject = await dotnetVersionResolver.createDotNetVersion(); + const windowsRegEx = new RegExp(/^-[VC]/); + const nonWindowsRegEx = new RegExp(/^--[vc]/); -// if (IS_WINDOWS) { -// expect(windowsRegEx.test(versionObject.type)).toBe(true); -// expect(nonWindowsRegEx.test(versionObject.type)).toBe(false); -// } else { -// expect(nonWindowsRegEx.test(versionObject.type)).toBe(true); -// expect(windowsRegEx.test(versionObject.type)).toBe(false); -// } -// } -// ); + if (IS_WINDOWS) { + expect(windowsRegEx.test(versionObject.type)).toBe(true); + expect(nonWindowsRegEx.test(versionObject.type)).toBe(false); + } else { + expect(nonWindowsRegEx.test(versionObject.type)).toBe(true); + expect(windowsRegEx.test(versionObject.type)).toBe(false); + } + } + ); -// it('Should throw if supplied dotnet version is in A.B.Cxx syntax and the major tag is lower than 5', async () => { -// const version = '3.1.1xx'; -// const dotnetVersionResolver = new installer.DotnetVersionResolver(version); -// await expect(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.` -// ); -// }, 600000); + it('Should throw if supplied dotnet version is in A.B.Cxx syntax and the major tag is lower than 5', async () => { + const version = '3.1.1xx'; + const dotnetVersionResolver = new installer.DotnetVersionResolver(version); + await expect(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.` + ); + }, 600000); -// it('Should resolve version supplied as * to channel type and set value to LTS', async () => { -// const version = '*'; -// const dotnetVersionResolver = new installer.DotnetVersionResolver(version); -// const versionObject = await dotnetVersionResolver.createDotNetVersion(); -// expect(versionObject.type.toLowerCase().includes('channel')).toBe(true); -// expect(versionObject.value).toBe('LTS'); -// }, 600000); -// }); + it('Should resolve version supplied as * to channel type and set value to LTS', async () => { + const version = '*'; + const dotnetVersionResolver = new installer.DotnetVersionResolver(version); + const versionObject = await dotnetVersionResolver.createDotNetVersion(); + expect(versionObject.type.toLowerCase().includes('channel')).toBe(true); + expect(versionObject.value).toBe('LTS'); + }, 600000); +}); function normalizeFileContents(contents: string): string { return contents diff --git a/src/installer.ts b/src/installer.ts index 7663de9..b8e628f 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -274,15 +274,20 @@ export class DotnetCoreInstaller { private async getListOfInstalledVersions(): Promise { const installationPath = process.env['DOTNET_INSTALL_DIR']!; - const versionsOnRunner: string[] = (await readdir( - path.join(installationPath.replace(/'/g, ''), 'sdk') - )).filter((el) => semver.valid(el)); + const versionsOnRunner: string[] = ( + await readdir(path.join(installationPath.replace(/'/g, ''), 'sdk')) + ).filter(el => semver.valid(el)); return versionsOnRunner; } - private async outputDotnetVersion(listOfInstalledVersions: string[]): Promise { - const updatedListOfInstalledVersions = await this.getListOfInstalledVersions(); - const installedVersion = updatedListOfInstalledVersions.filter((el) => !listOfInstalledVersions.includes(el)) + private async outputDotnetVersion( + listOfInstalledVersions: string[] + ): Promise { + const updatedListOfInstalledVersions = + await this.getListOfInstalledVersions(); + const installedVersion = updatedListOfInstalledVersions.filter( + el => !listOfInstalledVersions.includes(el) + ); return installedVersion[0]; } } From 0bc43909e03ff13fcbfd1901bd7fe6084e064162 Mon Sep 17 00:00:00 2001 From: IvanZosimov Date: Mon, 15 May 2023 11:45:07 +0200 Subject: [PATCH 20/30] Update mechanic of outputting installed dotnet version --- src/installer.ts | 32 ++++++++++++-------------------- 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/src/installer.ts b/src/installer.ts index b8e628f..a12529f 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -4,7 +4,6 @@ import * as exec from '@actions/exec'; import * as io from '@actions/io'; import * as hc from '@actions/http-client'; import {chmodSync} from 'fs'; -import {readdir} from 'fs/promises'; import path from 'path'; import os from 'os'; import semver from 'semver'; @@ -199,7 +198,6 @@ export class DotnetCoreInstaller { } public async installDotnet(): Promise { - const listOfInstalledVersions = await this.getListOfInstalledVersions(); const windowsDefaultOptions = [ '-NoLogo', '-Sta', @@ -259,7 +257,7 @@ export class DotnetCoreInstaller { ignoreReturnCode: true, env: process.env as {string: string} }; - const {exitCode, stderr} = await exec.getExecOutput( + const {exitCode, stdout, stderr} = await exec.getExecOutput( `"${scriptPath}"`, scriptArguments, getExecOutputOptions @@ -269,25 +267,19 @@ export class DotnetCoreInstaller { `Failed to install dotnet, exit code: ${exitCode}. ${stderr}` ); } - return await this.outputDotnetVersion(listOfInstalledVersions); + + return this.parseInstalledVersion(stdout); } - private async getListOfInstalledVersions(): Promise { - const installationPath = process.env['DOTNET_INSTALL_DIR']!; - const versionsOnRunner: string[] = ( - await readdir(path.join(installationPath.replace(/'/g, ''), 'sdk')) - ).filter(el => semver.valid(el)); - return versionsOnRunner; - } + private parseInstalledVersion(stdout: string): string { + const regex = /(?\d+\.\d+\.\d+[a-z0-9._-]*)/gm; + const matchedResult = regex.exec(stdout); - private async outputDotnetVersion( - listOfInstalledVersions: string[] - ): Promise { - const updatedListOfInstalledVersions = - await this.getListOfInstalledVersions(); - const installedVersion = updatedListOfInstalledVersions.filter( - el => !listOfInstalledVersions.includes(el) - ); - return installedVersion[0]; + if (!matchedResult) { + throw new Error( + `Failed to parse installed by the script version of .NET` + ); + } + return matchedResult.groups!.version; } } From fbdbede901202ddf504297fd4db70888bbb69e10 Mon Sep 17 00:00:00 2001 From: IvanZosimov Date: Mon, 15 May 2023 11:49:01 +0200 Subject: [PATCH 21/30] Rebuild solution --- dist/index.js | 34 +++++++++------------------------- 1 file changed, 9 insertions(+), 25 deletions(-) diff --git a/dist/index.js b/dist/index.js index 7346d82..51fc3a2 100644 --- a/dist/index.js +++ b/dist/index.js @@ -238,7 +238,6 @@ const exec = __importStar(__nccwpck_require__(1514)); const io = __importStar(__nccwpck_require__(7436)); const hc = __importStar(__nccwpck_require__(6255)); const fs_1 = __nccwpck_require__(7147); -const promises_1 = __nccwpck_require__(3292); const path_1 = __importDefault(__nccwpck_require__(1017)); const os_1 = __importDefault(__nccwpck_require__(2037)); const semver_1 = __importDefault(__nccwpck_require__(5911)); @@ -377,7 +376,6 @@ class DotnetCoreInstaller { } installDotnet() { return __awaiter(this, void 0, void 0, function* () { - const listOfInstalledVersions = yield this.getListOfInstalledVersions(); const windowsDefaultOptions = [ '-NoLogo', '-Sta', @@ -430,26 +428,20 @@ class DotnetCoreInstaller { ignoreReturnCode: true, env: process.env }; - const { exitCode, stderr } = yield exec.getExecOutput(`"${scriptPath}"`, scriptArguments, getExecOutputOptions); + const { exitCode, stdout, stderr } = yield exec.getExecOutput(`"${scriptPath}"`, scriptArguments, getExecOutputOptions); if (exitCode) { throw new Error(`Failed to install dotnet, exit code: ${exitCode}. ${stderr}`); } - return this.outputDotnetVersion(listOfInstalledVersions); + return this.parseInstalledVersion(stdout); }); } - getListOfInstalledVersions() { - return __awaiter(this, void 0, void 0, function* () { - const installationPath = process.env['DOTNET_INSTALL_DIR']; - const versionsOnRunner = (yield (0, promises_1.readdir)(path_1.default.join(installationPath.replace(/'/g, ''), 'sdk'))).filter((el) => semver_1.default.valid(el)); - return versionsOnRunner; - }); - } - outputDotnetVersion(listOfInstalledVersions) { - return __awaiter(this, void 0, void 0, function* () { - const updatedListOfInstalledVersions = yield this.getListOfInstalledVersions(); - const installedVersion = updatedListOfInstalledVersions.filter((el) => !listOfInstalledVersions.includes(el)); - return installedVersion[0]; - }); + parseInstalledVersion(stdout) { + const regex = /(?\d+\.\d+\.\d+[a-z0-9._-]*)/gm; + const matchedResult = regex.exec(stdout); + if (!matchedResult) { + throw new Error(`Failed to parse installed by the script version of .NET`); + } + return matchedResult.groups.version; } } exports.DotnetCoreInstaller = DotnetCoreInstaller; @@ -21120,14 +21112,6 @@ module.exports = require("fs"); /***/ }), -/***/ 3292: -/***/ ((module) => { - -"use strict"; -module.exports = require("fs/promises"); - -/***/ }), - /***/ 3685: /***/ ((module) => { From e8501859aa05b6b71ff73e66a11c30973f9e01ff Mon Sep 17 00:00:00 2001 From: IvanZosimov Date: Mon, 15 May 2023 14:24:28 +0200 Subject: [PATCH 22/30] Update unit tests --- __tests__/installer.test.ts | 51 +++++++++++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 10 deletions(-) diff --git a/__tests__/installer.test.ts b/__tests__/installer.test.ts index 4694e5d..0d264b5 100644 --- a/__tests__/installer.test.ts +++ b/__tests__/installer.test.ts @@ -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); @@ -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); @@ -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); @@ -112,9 +126,14 @@ describe('installer tests', () => { 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); @@ -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: '' }); }); @@ -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: '' }); }); @@ -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); @@ -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); @@ -396,4 +427,4 @@ describe('installer tests', () => { ); }); }); -}); \ No newline at end of file +}); From fefaa59d2eb646c641920b07bfc9897559f8d6d6 Mon Sep 17 00:00:00 2001 From: IvanZosimov Date: Tue, 16 May 2023 14:58:18 +0200 Subject: [PATCH 23/30] update logic of outputting dotnet-version --- dist/index.js | 40 ++++++++++++++++++++++++------- src/installer.ts | 9 ++++--- src/setup-dotnet.ts | 58 +++++++++++++++++++++++++++++++++++---------- 3 files changed, 82 insertions(+), 25 deletions(-) diff --git a/dist/index.js b/dist/index.js index 51fc3a2..dc3e1f6 100644 --- a/dist/index.js +++ b/dist/index.js @@ -439,7 +439,8 @@ class DotnetCoreInstaller { const regex = /(?\d+\.\d+\.\d+[a-z0-9._-]*)/gm; const matchedResult = regex.exec(stdout); if (!matchedResult) { - throw new Error(`Failed to parse installed by the script version of .NET`); + core.warning(`Failed to parse installed by the script version of .NET`); + return null; } return matchedResult.groups.version; } @@ -577,13 +578,18 @@ function run() { if (sourceUrl) { auth.configAuthentication(sourceUrl, configFile); } - const comparisonRange = globalJsonFileInput - ? versions[versions.length - 1] - : '*'; - const versionToOutput = semver_1.default.maxSatisfying(installedDotnetVersions, comparisonRange, { - includePrerelease: true - }); - core.setOutput('dotnet-version', versionToOutput); + // const comparisonRange: string = globalJsonFileInput + // ? versions[versions.length - 1]! + // : '*'; + // const versionToOutput = semver.maxSatisfying( + // installedDotnetVersions, + // comparisonRange, + // { + // includePrerelease: true + // } + // ); + // core.setOutput('dotnet-version', versionToOutput); + outputInstalledVersion(installedDotnetVersions, globalJsonFileInput); const matchersPath = path_1.default.join(__dirname, '..', '.github'); core.info(`##[add-matcher]${path_1.default.join(matchersPath, 'csc.json')}`); } @@ -608,6 +614,24 @@ function getVersionFromGlobalJson(globalJsonPath) { } return version; } +function outputInstalledVersion(installedVersions, globalJsonFileInput) { + if (!installedVersions.length) { + core.info(`No .NET version was installed. The 'dotnet-version' output will not be set.`); + } + if (installedVersions.includes(null)) { + core.warning(`Failed to output the installed version of .NET. The 'dotnet-version' output will not be set.`); + return; + } + if (globalJsonFileInput) { + const versionToOutput = installedVersions.at(-1); + core.setOutput('dotnet-version', versionToOutput); + return; + } + const versionToOutput = semver_1.default.maxSatisfying(installedVersions, '*', { + includePrerelease: true + }); + core.setOutput('dotnet-version', versionToOutput); +} run(); diff --git a/src/installer.ts b/src/installer.ts index a12529f..d31ec00 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -197,7 +197,7 @@ export class DotnetCoreInstaller { } } - public async installDotnet(): Promise { + public async installDotnet(): Promise { const windowsDefaultOptions = [ '-NoLogo', '-Sta', @@ -271,14 +271,13 @@ export class DotnetCoreInstaller { return this.parseInstalledVersion(stdout); } - private parseInstalledVersion(stdout: string): string { + private parseInstalledVersion(stdout: string): string | null { const regex = /(?\d+\.\d+\.\d+[a-z0-9._-]*)/gm; const matchedResult = regex.exec(stdout); if (!matchedResult) { - throw new Error( - `Failed to parse installed by the script version of .NET` - ); + core.warning(`Failed to parse installed by the script version of .NET`); + return null; } return matchedResult.groups!.version; } diff --git a/src/setup-dotnet.ts b/src/setup-dotnet.ts index 31c80a2..1a4755a 100644 --- a/src/setup-dotnet.ts +++ b/src/setup-dotnet.ts @@ -27,7 +27,7 @@ export async function run() { // Proxy, auth, (etc) are still set up, even if no version is identified // const versions = core.getMultilineInput('dotnet-version'); - const installedDotnetVersions: string[] = []; + const installedDotnetVersions: (string | null)[] = []; const globalJsonFileInput = core.getInput('global-json-file'); if (globalJsonFileInput) { @@ -78,19 +78,20 @@ export async function run() { auth.configAuthentication(sourceUrl, configFile); } - const comparisonRange: string = globalJsonFileInput - ? versions[versions.length - 1]! - : '*'; + // const comparisonRange: string = globalJsonFileInput + // ? versions[versions.length - 1]! + // : '*'; - const versionToOutput = semver.maxSatisfying( - installedDotnetVersions, - comparisonRange, - { - includePrerelease: true - } - ); + // const versionToOutput = semver.maxSatisfying( + // installedDotnetVersions, + // comparisonRange, + // { + // includePrerelease: true + // } + // ); - core.setOutput('dotnet-version', versionToOutput); + // core.setOutput('dotnet-version', versionToOutput); + outputInstalledVersion(installedDotnetVersions, globalJsonFileInput); const matchersPath = path.join(__dirname, '..', '.github'); core.info(`##[add-matcher]${path.join(matchersPath, 'csc.json')}`); @@ -116,4 +117,37 @@ function getVersionFromGlobalJson(globalJsonPath: string): string { return version; } +function outputInstalledVersion( + installedVersions: (string | null)[], + globalJsonFileInput: string +): void { + if (!installedVersions.length) { + core.info( + `No .NET version was installed. The 'dotnet-version' output will not be set.` + ); + } + if (installedVersions.includes(null)) { + core.warning( + `Failed to output the installed version of .NET. The 'dotnet-version' output will not be set.` + ); + return; + } + + if (globalJsonFileInput) { + const versionToOutput = installedVersions.at(-1); + core.setOutput('dotnet-version', versionToOutput); + return; + } + + const versionToOutput = semver.maxSatisfying( + installedVersions as string[], + '*', + { + includePrerelease: true + } + ); + + core.setOutput('dotnet-version', versionToOutput); +} + run(); From 21cf89aa73470741965b60731b60d061054d3e05 Mon Sep 17 00:00:00 2001 From: IvanZosimov Date: Tue, 16 May 2023 15:13:18 +0200 Subject: [PATCH 24/30] Remove commented lines of code --- dist/index.js | 11 ----------- src/setup-dotnet.ts | 13 ------------- 2 files changed, 24 deletions(-) diff --git a/dist/index.js b/dist/index.js index dc3e1f6..2b8903f 100644 --- a/dist/index.js +++ b/dist/index.js @@ -578,17 +578,6 @@ function run() { if (sourceUrl) { auth.configAuthentication(sourceUrl, configFile); } - // const comparisonRange: string = globalJsonFileInput - // ? versions[versions.length - 1]! - // : '*'; - // const versionToOutput = semver.maxSatisfying( - // installedDotnetVersions, - // comparisonRange, - // { - // includePrerelease: true - // } - // ); - // core.setOutput('dotnet-version', versionToOutput); outputInstalledVersion(installedDotnetVersions, globalJsonFileInput); const matchersPath = path_1.default.join(__dirname, '..', '.github'); core.info(`##[add-matcher]${path_1.default.join(matchersPath, 'csc.json')}`); diff --git a/src/setup-dotnet.ts b/src/setup-dotnet.ts index 1a4755a..188257b 100644 --- a/src/setup-dotnet.ts +++ b/src/setup-dotnet.ts @@ -78,19 +78,6 @@ export async function run() { auth.configAuthentication(sourceUrl, configFile); } - // const comparisonRange: string = globalJsonFileInput - // ? versions[versions.length - 1]! - // : '*'; - - // const versionToOutput = semver.maxSatisfying( - // installedDotnetVersions, - // comparisonRange, - // { - // includePrerelease: true - // } - // ); - - // core.setOutput('dotnet-version', versionToOutput); outputInstalledVersion(installedDotnetVersions, globalJsonFileInput); const matchersPath = path.join(__dirname, '..', '.github'); From 2f028bc0440d3fe98ed5bb0dac9e76ee3d85bb1e Mon Sep 17 00:00:00 2001 From: IvanZosimov Date: Thu, 18 May 2023 11:11:51 +0200 Subject: [PATCH 25/30] update unit and e2e tests --- .github/workflows/e2e-tests.yml | 67 ++++++++++++++++++++++----------- __tests__/installer.test.ts | 36 ++++++++++++++++-- __tests__/setup-dotnet.test.ts | 31 ++++++++++++++- dist/index.js | 3 +- src/installer.ts | 2 +- src/setup-dotnet.ts | 2 + 6 files changed, 113 insertions(+), 28 deletions(-) diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml index 6d00d5d..3933a34 100644 --- a/.github/workflows/e2e-tests.yml +++ b/.github/workflows/e2e-tests.yml @@ -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: @@ -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: @@ -205,27 +251,6 @@ jobs: shell: pwsh run: __tests__/verify-dotnet.ps1 -Patterns "^7\.0\.\d+-" - 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-dotnet-version-output-during-single-version-installation: runs-on: ${{ matrix.operating-system }} strategy: diff --git a/__tests__/installer.test.ts b/__tests__/installer.test.ts index 0d264b5..08aa8e7 100644 --- a/__tests__/installer.test.ts +++ b/__tests__/installer.test.ts @@ -306,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 => { @@ -358,7 +359,16 @@ 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', + '6.0.2XX', + '6.0.2**' + ]).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( @@ -373,7 +383,15 @@ 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', + '6.0.2XX', + '6.0.2**' + ]).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( @@ -425,6 +443,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.` + ); + }); }); }); }); diff --git a/__tests__/setup-dotnet.test.ts b/__tests__/setup-dotnet.test.ts index 831408c..45043a1 100644 --- a/__tests__/setup-dotnet.test.ts +++ b/__tests__/setup-dotnet.test.ts @@ -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'); @@ -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 = `No .NET version was installed. The 'dotnet-version' output will not be set.`; + + addToPathSpy.mockImplementation(() => {}); + + await setup.run(); + + expect(infoSpy).toHaveBeenCalledWith(warningMessage); + expect(setOutputSpy).not.toHaveBeenCalled(); + }); }); }); diff --git a/dist/index.js b/dist/index.js index 2b8903f..aca3dd0 100644 --- a/dist/index.js +++ b/dist/index.js @@ -270,7 +270,7 @@ class DotnetVersionResolver { } isLatestPatchSyntax() { var _b, _c; - const majorTag = (_c = (_b = this.inputVersion.match(/^(?\d+)\.\d+\.\d{1}x{2}$/)) === null || _b === void 0 ? void 0 : _b.groups) === null || _c === void 0 ? void 0 : _c.majorTag; + const majorTag = (_c = (_b = this.inputVersion.match(/^(?\d+)\.\d+\.\d{1}(x|X|\*){2}$/)) === null || _b === void 0 ? void 0 : _b.groups) === null || _c === void 0 ? void 0 : _c.majorTag; if (majorTag && parseInt(majorTag) < DotnetInstallerLimits.LatestPatchSyntaxMinimalMajorTag) { @@ -606,6 +606,7 @@ function getVersionFromGlobalJson(globalJsonPath) { function outputInstalledVersion(installedVersions, globalJsonFileInput) { if (!installedVersions.length) { core.info(`No .NET version was installed. The 'dotnet-version' output will not be set.`); + return; } if (installedVersions.includes(null)) { core.warning(`Failed to output the installed version of .NET. The 'dotnet-version' output will not be set.`); diff --git a/src/installer.ts b/src/installer.ts index d31ec00..e4c3ffe 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -49,7 +49,7 @@ export class DotnetVersionResolver { private isLatestPatchSyntax() { const majorTag = this.inputVersion.match( - /^(?\d+)\.\d+\.\d{1}x{2}$/ + /^(?\d+)\.\d+\.\d{1}(x|X|\*){2}$/ )?.groups?.majorTag; if ( majorTag && diff --git a/src/setup-dotnet.ts b/src/setup-dotnet.ts index 188257b..e7e7726 100644 --- a/src/setup-dotnet.ts +++ b/src/setup-dotnet.ts @@ -112,7 +112,9 @@ function outputInstalledVersion( core.info( `No .NET version was installed. The 'dotnet-version' output will not be set.` ); + return; } + if (installedVersions.includes(null)) { core.warning( `Failed to output the installed version of .NET. The 'dotnet-version' output will not be set.` From 898aa0ce4d1e9419e27e53897ec70fd148115484 Mon Sep 17 00:00:00 2001 From: IvanZosimov Date: Thu, 18 May 2023 11:16:22 +0200 Subject: [PATCH 26/30] Fix typo --- action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/action.yml b/action.yml index eec3975..acac654 100644 --- a/action.yml +++ b/action.yml @@ -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, 3.1.4xx' + 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: From 83a1653fa32f4cf123fe3aec2962ff47ffd65859 Mon Sep 17 00:00:00 2001 From: IvanZosimov Date: Thu, 18 May 2023 11:46:40 +0200 Subject: [PATCH 27/30] Update regular expresiion for isLatestPatchSyntax() --- __tests__/installer.test.ts | 21 ++------------------- dist/index.js | 2 +- src/installer.ts | 2 +- 3 files changed, 4 insertions(+), 21 deletions(-) diff --git a/__tests__/installer.test.ts b/__tests__/installer.test.ts index 08aa8e7..808d34a 100644 --- a/__tests__/installer.test.ts +++ b/__tests__/installer.test.ts @@ -359,16 +359,7 @@ describe('installer tests', () => { } ); - each([ - '3', - '3.1', - '3.1.x', - '3.1.*', - '3.1.X', - '6.0.2xx', - '6.0.2XX', - '6.0.2**' - ]).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( @@ -383,15 +374,7 @@ describe('installer tests', () => { } ); - each([ - '6.0', - '6.0.x', - '6.0.*', - '6.0.X', - '6.0.2xx', - '6.0.2XX', - '6.0.2**' - ]).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( diff --git a/dist/index.js b/dist/index.js index aca3dd0..093671e 100644 --- a/dist/index.js +++ b/dist/index.js @@ -270,7 +270,7 @@ class DotnetVersionResolver { } isLatestPatchSyntax() { var _b, _c; - const majorTag = (_c = (_b = this.inputVersion.match(/^(?\d+)\.\d+\.\d{1}(x|X|\*){2}$/)) === null || _b === void 0 ? void 0 : _b.groups) === null || _c === void 0 ? void 0 : _c.majorTag; + const majorTag = (_c = (_b = this.inputVersion.match(/^(?\d+)\.\d+\.\d{1}x{2}$/)) === null || _b === void 0 ? void 0 : _b.groups) === null || _c === void 0 ? void 0 : _c.majorTag; if (majorTag && parseInt(majorTag) < DotnetInstallerLimits.LatestPatchSyntaxMinimalMajorTag) { diff --git a/src/installer.ts b/src/installer.ts index e4c3ffe..d31ec00 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -49,7 +49,7 @@ export class DotnetVersionResolver { private isLatestPatchSyntax() { const majorTag = this.inputVersion.match( - /^(?\d+)\.\d+\.\d{1}(x|X|\*){2}$/ + /^(?\d+)\.\d+\.\d{1}x{2}$/ )?.groups?.majorTag; if ( majorTag && From 3cf3e230c1d440ed4250ff9a4f8ef1f2b7bc19d6 Mon Sep 17 00:00:00 2001 From: IvanZosimov Date: Thu, 18 May 2023 12:01:55 +0200 Subject: [PATCH 28/30] Fix informational message --- dist/index.js | 2 +- src/installer.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dist/index.js b/dist/index.js index 093671e..649f940 100644 --- a/dist/index.js +++ b/dist/index.js @@ -371,7 +371,7 @@ class DotnetCoreInstaller { scriptArguments.push(option, this.quality); } else { - core.warning(`'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: ${this.version}. 'dotnet-quality' input is ignored.`); + core.warning(`'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: ${this.version}. 'dotnet-quality' input is ignored.`); } } installDotnet() { diff --git a/src/installer.ts b/src/installer.ts index d31ec00..18aef22 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -192,7 +192,7 @@ export class DotnetCoreInstaller { scriptArguments.push(option, this.quality); } else { core.warning( - `'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: ${this.version}. 'dotnet-quality' input is ignored.` + `'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: ${this.version}. 'dotnet-quality' input is ignored.` ); } } From 38b49fb7178824be5cb7b9acd01eb2627e719a0b Mon Sep 17 00:00:00 2001 From: IvanZosimov Date: Thu, 18 May 2023 12:39:22 +0200 Subject: [PATCH 29/30] Fix informational and debug messages --- __tests__/installer.test.ts | 4 ++-- __tests__/setup-dotnet.test.ts | 6 +++--- dist/index.js | 12 ++++++------ src/installer.ts | 6 +++--- src/setup-dotnet.ts | 8 +++----- 5 files changed, 17 insertions(+), 19 deletions(-) diff --git a/__tests__/installer.test.ts b/__tests__/installer.test.ts index 808d34a..c9f815e 100644 --- a/__tests__/installer.test.ts +++ b/__tests__/installer.test.ts @@ -119,7 +119,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.` ); }); @@ -145,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.` ); }); diff --git a/__tests__/setup-dotnet.test.ts b/__tests__/setup-dotnet.test.ts index 45043a1..9e4b8ca 100644 --- a/__tests__/setup-dotnet.test.ts +++ b/__tests__/setup-dotnet.test.ts @@ -59,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 = `A global.json wasn't found in the root directory. No .NET version will be installed.`; await setup.run(); @@ -73,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); @@ -160,7 +160,7 @@ describe('setup-dotnet tests', () => { it(`shouldn't call setOutput() if actions didn't install .NET`, async () => { inputs['dotnet-version'] = []; - const warningMessage = `No .NET version was installed. The 'dotnet-version' output will not be set.`; + const warningMessage = `The 'dotnet-version' output will not be set.`; addToPathSpy.mockImplementation(() => {}); diff --git a/dist/index.js b/dist/index.js index 649f940..90e197b 100644 --- a/dist/index.js +++ b/dist/index.js @@ -255,7 +255,7 @@ class DotnetVersionResolver { resolveVersionInput() { return __awaiter(this, void 0, void 0, function* () { if (!semver_1.default.validRange(this.inputVersion) && !this.isLatestPatchSyntax()) { - throw new Error(`'dotnet-version' was supplied in invalid format: ${this.inputVersion}! Supported syntax: A.B.C, A.B, A.B.x, A, A.x, A.B.Cxx`); + throw new Error(`The 'dotnet-version' was supplied in invalid format: ${this.inputVersion}! Supported syntax: A.B.C, A.B, A.B.x, A, A.x, A.B.Cxx`); } if (semver_1.default.valid(this.inputVersion)) { this.createVersionArgument(); @@ -274,7 +274,7 @@ class DotnetVersionResolver { if (majorTag && parseInt(majorTag) < DotnetInstallerLimits.LatestPatchSyntaxMinimalMajorTag) { - throw new Error(`'dotnet-version' was supplied in invalid format: ${this.inputVersion}! The A.B.Cxx syntax is available since the .NET 5.0 release.`); + throw new Error(`The 'dotnet-version' was supplied in invalid format: ${this.inputVersion}! The A.B.Cxx syntax is available since the .NET 5.0 release.`); } return majorTag ? true : false; } @@ -371,7 +371,7 @@ class DotnetCoreInstaller { scriptArguments.push(option, this.quality); } else { - core.warning(`'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: ${this.version}. 'dotnet-quality' input is ignored.`); + core.warning(`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: ${this.version}. 'dotnet-quality' input is ignored.`); } } installDotnet() { @@ -556,13 +556,13 @@ function run() { versions.push(getVersionFromGlobalJson(globalJsonPath)); } else { - core.info(`global.json wasn't found in the root directory. No .NET version will be installed.`); + core.info(`A global.json wasn't found in the root directory. No .NET version will be installed.`); } } if (versions.length) { const quality = core.getInput('dotnet-quality'); if (quality && !qualityOptions.includes(quality)) { - throw new Error(`${quality} is not a supported value for 'dotnet-quality' option. Supported values are: daily, signed, validated, preview, ga.`); + throw new Error(`Value '${quality}' is not supported for the 'dotnet-quality' option. Supported values are: daily, signed, validated, preview, ga.`); } let dotnetInstaller; const uniqueVersions = new Set(versions); @@ -605,7 +605,7 @@ function getVersionFromGlobalJson(globalJsonPath) { } function outputInstalledVersion(installedVersions, globalJsonFileInput) { if (!installedVersions.length) { - core.info(`No .NET version was installed. The 'dotnet-version' output will not be set.`); + core.info(`The 'dotnet-version' output will not be set.`); return; } if (installedVersions.includes(null)) { diff --git a/src/installer.ts b/src/installer.ts index 18aef22..f86dfa0 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -33,7 +33,7 @@ export class DotnetVersionResolver { private async resolveVersionInput(): Promise { if (!semver.validRange(this.inputVersion) && !this.isLatestPatchSyntax()) { throw new Error( - `'dotnet-version' was supplied in invalid format: ${this.inputVersion}! Supported syntax: A.B.C, A.B, A.B.x, A, A.x, A.B.Cxx` + `The 'dotnet-version' was supplied in invalid format: ${this.inputVersion}! Supported syntax: A.B.C, A.B, A.B.x, A, A.x, A.B.Cxx` ); } if (semver.valid(this.inputVersion)) { @@ -57,7 +57,7 @@ export class DotnetVersionResolver { DotnetInstallerLimits.LatestPatchSyntaxMinimalMajorTag ) { throw new Error( - `'dotnet-version' was supplied in invalid format: ${this.inputVersion}! The A.B.Cxx syntax is available since the .NET 5.0 release.` + `The 'dotnet-version' was supplied in invalid format: ${this.inputVersion}! The A.B.Cxx syntax is available since the .NET 5.0 release.` ); } return majorTag ? true : false; @@ -192,7 +192,7 @@ export class DotnetCoreInstaller { scriptArguments.push(option, this.quality); } else { core.warning( - `'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: ${this.version}. '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: ${this.version}. 'dotnet-quality' input is ignored.` ); } } diff --git a/src/setup-dotnet.ts b/src/setup-dotnet.ts index e7e7726..cf26f14 100644 --- a/src/setup-dotnet.ts +++ b/src/setup-dotnet.ts @@ -48,7 +48,7 @@ export async function run() { versions.push(getVersionFromGlobalJson(globalJsonPath)); } else { core.info( - `global.json wasn't found in the root directory. No .NET version will be installed.` + `A global.json wasn't found in the root directory. No .NET version will be installed.` ); } } @@ -58,7 +58,7 @@ export async function run() { if (quality && !qualityOptions.includes(quality)) { throw new Error( - `${quality} is not a supported value for 'dotnet-quality' option. Supported values are: daily, signed, validated, preview, ga.` + `Value '${quality}' is not supported for the 'dotnet-quality' option. Supported values are: daily, signed, validated, preview, ga.` ); } @@ -109,9 +109,7 @@ function outputInstalledVersion( globalJsonFileInput: string ): void { if (!installedVersions.length) { - core.info( - `No .NET version was installed. The 'dotnet-version' output will not be set.` - ); + core.info(`The 'dotnet-version' output will not be set.`); return; } From b05a3f26b3adff9936a0ef8b806a7d9a57b72a6d Mon Sep 17 00:00:00 2001 From: IvanZosimov Date: Mon, 22 May 2023 12:27:33 +0200 Subject: [PATCH 30/30] Fix review points, rebuild solution --- __tests__/setup-dotnet.test.ts | 2 +- dist/index.js | 18 ++++++------------ src/installer.ts | 14 ++++---------- src/setup-dotnet.ts | 4 ++-- 4 files changed, 13 insertions(+), 25 deletions(-) diff --git a/__tests__/setup-dotnet.test.ts b/__tests__/setup-dotnet.test.ts index 9e4b8ca..2a32d63 100644 --- a/__tests__/setup-dotnet.test.ts +++ b/__tests__/setup-dotnet.test.ts @@ -59,7 +59,7 @@ describe('setup-dotnet tests', () => { const expectedDebugMessage = 'No version found, trying to find version from global.json'; - const expectedInfoMessage = `A 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(); diff --git a/dist/index.js b/dist/index.js index 90e197b..088b68f 100644 --- a/dist/index.js +++ b/dist/index.js @@ -242,11 +242,8 @@ const path_1 = __importDefault(__nccwpck_require__(1017)); const os_1 = __importDefault(__nccwpck_require__(2037)); const semver_1 = __importDefault(__nccwpck_require__(5911)); const utils_1 = __nccwpck_require__(918); -var DotnetInstallerLimits; -(function (DotnetInstallerLimits) { - DotnetInstallerLimits[DotnetInstallerLimits["QualityInputMinimalMajorTag"] = 6] = "QualityInputMinimalMajorTag"; - DotnetInstallerLimits[DotnetInstallerLimits["LatestPatchSyntaxMinimalMajorTag"] = 5] = "LatestPatchSyntaxMinimalMajorTag"; -})(DotnetInstallerLimits || (DotnetInstallerLimits = {})); +const QUALITY_INPUT_MINIMAL_MAJOR_TAG = 6; +const LATEST_PATCH_SYNTAX_MINIMAL_MAJOR_TAG = 5; class DotnetVersionResolver { constructor(version) { this.inputVersion = version.trim(); @@ -272,8 +269,7 @@ class DotnetVersionResolver { var _b, _c; const majorTag = (_c = (_b = this.inputVersion.match(/^(?\d+)\.\d+\.\d{1}x{2}$/)) === null || _b === void 0 ? void 0 : _b.groups) === null || _c === void 0 ? void 0 : _c.majorTag; if (majorTag && - parseInt(majorTag) < - DotnetInstallerLimits.LatestPatchSyntaxMinimalMajorTag) { + parseInt(majorTag) < LATEST_PATCH_SYNTAX_MINIMAL_MAJOR_TAG) { throw new Error(`The 'dotnet-version' was supplied in invalid format: ${this.inputVersion}! The A.B.Cxx syntax is available since the .NET 5.0 release.`); } return majorTag ? true : false; @@ -300,9 +296,7 @@ class DotnetVersionResolver { this.resolvedArgument.value = 'LTS'; } this.resolvedArgument.qualityFlag = - parseInt(major) >= DotnetInstallerLimits.QualityInputMinimalMajorTag - ? true - : false; + parseInt(major) >= QUALITY_INPUT_MINIMAL_MAJOR_TAG ? true : false; }); } createDotNetVersion() { @@ -556,7 +550,7 @@ function run() { versions.push(getVersionFromGlobalJson(globalJsonPath)); } else { - core.info(`A global.json wasn't found in the root directory. No .NET version will be installed.`); + core.info(`The global.json wasn't found in the root directory. No .NET version will be installed.`); } } if (versions.length) { @@ -613,7 +607,7 @@ function outputInstalledVersion(installedVersions, globalJsonFileInput) { return; } if (globalJsonFileInput) { - const versionToOutput = installedVersions.at(-1); + const versionToOutput = installedVersions.at(-1); // .NET SDK version parsed from the global.json file is installed last core.setOutput('dotnet-version', versionToOutput); return; } diff --git a/src/installer.ts b/src/installer.ts index f86dfa0..a993be8 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -16,11 +16,8 @@ export interface DotnetVersion { qualityFlag: boolean; } -enum DotnetInstallerLimits { - QualityInputMinimalMajorTag = 6, - LatestPatchSyntaxMinimalMajorTag = 5 -} - +const QUALITY_INPUT_MINIMAL_MAJOR_TAG = 6; +const LATEST_PATCH_SYNTAX_MINIMAL_MAJOR_TAG = 5; export class DotnetVersionResolver { private inputVersion: string; private resolvedArgument: DotnetVersion; @@ -53,8 +50,7 @@ export class DotnetVersionResolver { )?.groups?.majorTag; if ( majorTag && - parseInt(majorTag) < - DotnetInstallerLimits.LatestPatchSyntaxMinimalMajorTag + parseInt(majorTag) < LATEST_PATCH_SYNTAX_MINIMAL_MAJOR_TAG ) { throw new Error( `The 'dotnet-version' was supplied in invalid format: ${this.inputVersion}! The A.B.Cxx syntax is available since the .NET 5.0 release.` @@ -82,9 +78,7 @@ export class DotnetVersionResolver { this.resolvedArgument.value = 'LTS'; } this.resolvedArgument.qualityFlag = - parseInt(major) >= DotnetInstallerLimits.QualityInputMinimalMajorTag - ? true - : false; + parseInt(major) >= QUALITY_INPUT_MINIMAL_MAJOR_TAG ? true : false; } public async createDotNetVersion(): Promise { diff --git a/src/setup-dotnet.ts b/src/setup-dotnet.ts index cf26f14..58de8ef 100644 --- a/src/setup-dotnet.ts +++ b/src/setup-dotnet.ts @@ -48,7 +48,7 @@ export async function run() { versions.push(getVersionFromGlobalJson(globalJsonPath)); } else { core.info( - `A global.json wasn't found in the root directory. No .NET version will be installed.` + `The global.json wasn't found in the root directory. No .NET version will be installed.` ); } } @@ -121,7 +121,7 @@ function outputInstalledVersion( } if (globalJsonFileInput) { - const versionToOutput = installedVersions.at(-1); + const versionToOutput = installedVersions.at(-1); // .NET SDK version parsed from the global.json file is installed last core.setOutput('dotnet-version', versionToOutput); return; }