Skip to content

Commit 629365b

Browse files
committed
Merge branch 'main' into refactor-nuget-cfg-parse
2 parents 942a0be + c7e7147 commit 629365b

File tree

9 files changed

+254
-15
lines changed

9 files changed

+254
-15
lines changed

.github/workflows/workflow.yml

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,60 @@ jobs:
237237
$version = & dotnet --version
238238
Write-Host "Installed version: $version"
239239
if (-not ($version.Contains("preview") -or $version.Contains("rc"))) { throw "Unexpected version" }
240+
241+
test-dotnet-version-output-during-single-version-installation:
242+
runs-on: ${{ matrix.operating-system }}
243+
strategy:
244+
fail-fast: false
245+
matrix:
246+
operating-system: [ubuntu-latest, windows-latest, macOS-latest]
247+
steps:
248+
- name: Checkout
249+
uses: actions/checkout@v3
250+
- name: Clear toolcache
251+
shell: pwsh
252+
run: __tests__/clear-toolcache.ps1 ${{ runner.os }}
253+
254+
- name: Setup dotnet 6.0.401
255+
uses: ./
256+
id: step1
257+
with:
258+
dotnet-version: "6.0.401"
259+
260+
- name: Verify value of the dotnet-version output
261+
shell: pwsh
262+
run: |
263+
$version = & dotnet --version
264+
Write-Host "Installed version: $version"
265+
if (-not ($version -eq '${{steps.step1.outputs.dotnet-version}}')) { throw "Unexpected output value" }
266+
267+
test-dotnet-version-output-during-multiple-version-installation:
268+
runs-on: ${{ matrix.operating-system }}
269+
strategy:
270+
fail-fast: false
271+
matrix:
272+
operating-system: [ubuntu-latest, windows-latest, macOS-latest]
273+
steps:
274+
- name: Checkout
275+
uses: actions/checkout@v3
276+
- name: Clear toolcache
277+
shell: pwsh
278+
run: __tests__/clear-toolcache.ps1 ${{ runner.os }}
279+
280+
- name: Setup dotnet 6.0.401, 5.0.408, 7.0.100-rc.1.22431.12
281+
uses: ./
282+
id: step2
283+
with:
284+
dotnet-version: |
285+
7.0.100-rc.1.22431.12
286+
6.0.401
287+
5.0.408
288+
289+
- name: Verify value of the dotnet-version output
290+
shell: pwsh
291+
run: |
292+
$version = "7.0.100-rc.1.22431.12"
293+
if (-not ($version -eq '${{steps.step2.outputs.dotnet-version}}')) { throw "Unexpected output value" }
240294
241295
test-proxy:
242296
runs-on: ubuntu-latest

README.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,54 @@ steps:
141141
```
142142
> **Note**: It's the only way to push a package to nuget.org feed for macOS/Linux machines due to API key config store limitations.
143143

144+
# Outputs and environment variables
145+
146+
## Outputs
147+
148+
### `dotnet-version`
149+
150+
Using the **dotnet-version** output it's possible to get the installed by the action .NET SDK version.
151+
152+
**Single version installation**
153+
154+
In case of a single version installation, the `dotnet-version` output contains the version that is installed by the action.
155+
156+
```yaml
157+
- uses: actions/setup-dotnet@v3
158+
id: cp310
159+
with:
160+
dotnet-version: 3.1.422
161+
- run: echo '${{ steps.cp310.outputs.dotnet-version }}' # outputs 3.1.422
162+
```
163+
164+
**Multiple version installation**
165+
166+
In case of a multiple version installation, the `dotnet-version` output contains the latest version that is installed by the action.
167+
168+
```yaml
169+
- uses: actions/setup-dotnet@v3
170+
id: cp310
171+
with:
172+
dotnet-version: |
173+
3.1.422
174+
5.0.408
175+
- run: echo '${{ steps.cp310.outputs.dotnet-version }}' # outputs 5.0.408
176+
```
177+
**Installation from global.json**
178+
179+
When the `dotnet-version` input is used along with the `global-json-file` input, the `dotnet-version` output contains the version resolved from the `global.json`.
180+
181+
```yaml
182+
- uses: actions/setup-dotnet@v3
183+
id: cp310
184+
with:
185+
dotnet-version: |
186+
3.1.422
187+
5.0.408
188+
global-json-file: "./global.json" # contains version 2.2.207
189+
- run: echo '${{ steps.cp310.outputs.dotnet-version }}' # outputs 2.2.207
190+
```
191+
144192
## Environment variables
145193

146194
Some environment variables may be necessary for your particular case or to improve logging. Some examples are listed below, but the full list with complete details can be found here: https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-environment-variables

__tests__/installer.test.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,15 @@ describe('DotnetCoreInstaller tests', () => {
107107
expect(process.env.PATH?.startsWith(toolDir)).toBe(true);
108108
}, 600000); //This needs some time to download on "slower" internet connections
109109

110+
it('Returns string with installed SDK version', async () => {
111+
const version = '3.1.120';
112+
let installedVersion: string;
113+
114+
installedVersion = await getDotnet(version);
115+
116+
expect(installedVersion).toBe('3.1.120');
117+
}, 600000);
118+
110119
it('Throws if no location contains correct dotnet version', async () => {
111120
await expect(async () => {
112121
await getDotnet('1000.0.0');
@@ -267,11 +276,15 @@ function normalizeFileContents(contents: string): string {
267276
.replace(new RegExp('\r', 'g'), '\n');
268277
}
269278

270-
async function getDotnet(version: string, quality: string = ''): Promise<void> {
279+
async function getDotnet(
280+
version: string,
281+
quality: string = ''
282+
): Promise<string> {
271283
const dotnetInstaller = new installer.DotnetCoreInstaller(
272284
version,
273285
quality as QualityOptions
274286
);
275-
await dotnetInstaller.installDotnet();
287+
const installedVersion = await dotnetInstaller.installDotnet();
276288
installer.DotnetCoreInstaller.addToPath();
289+
return installedVersion;
277290
}

__tests__/setup-dotnet.test.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import * as io from '@actions/io';
2+
import * as core from '@actions/core';
23
import fs from 'fs';
34
import os from 'os';
45
import path from 'path';
@@ -20,6 +21,12 @@ if (IS_WINDOWS) {
2021
const tempDir = path.join(__dirname, 'runner', 'temp2');
2122

2223
describe('setup-dotnet tests', () => {
24+
let getInputSpy = jest.spyOn(core, 'getInput');
25+
let getMultilineInputSpy = jest.spyOn(core, 'getMultilineInput');
26+
let setOutputSpy = jest.spyOn(core, 'setOutput');
27+
28+
let inputs = {} as any;
29+
2330
beforeAll(async () => {
2431
process.env.RUNNER_TOOL_CACHE = toolDir;
2532
process.env.DOTNET_INSTALL_DIR = toolDir;
@@ -59,4 +66,33 @@ describe('setup-dotnet tests', () => {
5966
expect(fs.existsSync(path.join(toolDir, 'dotnet'))).toBe(true);
6067
}
6168
}, 400000);
69+
70+
it("Sets output with the latest installed by action version if global.json file isn't specified", async () => {
71+
inputs['dotnet-version'] = ['3.1.201', '6.0.401'];
72+
73+
getMultilineInputSpy.mockImplementation(input => inputs[input]);
74+
75+
await setup.run();
76+
77+
expect(setOutputSpy).toBeCalledWith('dotnet-version', '6.0.401');
78+
}, 400000);
79+
80+
it("Sets output with the version specified in global.json, if it's present", async () => {
81+
const globalJsonPath = path.join(process.cwd(), 'global.json');
82+
const jsonContents = `{${os.EOL}"sdk": {${os.EOL}"version": "3.0.103"${os.EOL}}${os.EOL}}`;
83+
if (!fs.existsSync(globalJsonPath)) {
84+
fs.writeFileSync(globalJsonPath, jsonContents);
85+
}
86+
87+
inputs['dotnet-version'] = ['3.1.201', '6.0.401'];
88+
inputs['global-json-file'] = './global.json';
89+
90+
getMultilineInputSpy.mockImplementation(input => inputs[input]);
91+
92+
getInputSpy.mockImplementation(input => inputs[input]);
93+
94+
await setup.run();
95+
96+
expect(setOutputSpy).toBeCalledWith('dotnet-version', '3.0.103');
97+
}, 400000);
6298
});

action.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ inputs:
1717
description: 'Optional OWNER for using packages from GitHub Package Registry organizations/users other than the current repository''s owner. Only used if a GPR URL is also provided in source-url'
1818
config-file:
1919
description: 'Optional NuGet.config location, if your NuGet.config isn''t located in the root of the repo.'
20+
outputs:
21+
dotnet-version:
22+
description: 'Contains the installed by action .NET SDK version for reuse.'
2023
runs:
2124
using: 'node16'
2225
main: 'dist/index.js'

dist/index.js

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,7 @@ const exec = __importStar(__nccwpck_require__(1514));
229229
const io = __importStar(__nccwpck_require__(7436));
230230
const hc = __importStar(__nccwpck_require__(6255));
231231
const fs_1 = __nccwpck_require__(7147);
232+
const promises_1 = __nccwpck_require__(3292);
232233
const path_1 = __importDefault(__nccwpck_require__(1017));
233234
const semver_1 = __importDefault(__nccwpck_require__(5911));
234235
const utils_1 = __nccwpck_require__(918);
@@ -324,8 +325,8 @@ class DotnetCoreInstaller {
324325
}
325326
else {
326327
// This is the default set in install-dotnet.sh
327-
core.addPath(path_1.default.join(process.env['HOME'] + '', '.dotnet'));
328-
core.exportVariable('DOTNET_ROOT', path_1.default.join(process.env['HOME'] + '', '.dotnet'));
328+
core.addPath(DotnetCoreInstaller.installationDirectoryMac);
329+
core.exportVariable('DOTNET_ROOT', DotnetCoreInstaller.installationDirectoryMac);
329330
}
330331
}
331332
}
@@ -372,11 +373,11 @@ class DotnetCoreInstaller {
372373
if (process.env['no_proxy'] != null) {
373374
scriptArguments.push(`-ProxyBypassList ${process.env['no_proxy']}`);
374375
}
375-
scriptArguments.push(`-InstallDir '${DotnetCoreInstaller.installationDirectoryWindows}'`);
376+
scriptArguments.push('-InstallDir', `'${DotnetCoreInstaller.installationDirectoryWindows}'`);
376377
// process.env must be explicitly passed in for DOTNET_INSTALL_DIR to be used
377378
scriptPath =
378379
(yield io.which('pwsh', false)) || (yield io.which('powershell', true));
379-
scriptArguments = [...windowsDefaultOptions, scriptArguments.join(' ')];
380+
scriptArguments = windowsDefaultOptions.concat(scriptArguments);
380381
}
381382
else {
382383
fs_1.chmodSync(escapedScript, '777');
@@ -391,17 +392,31 @@ class DotnetCoreInstaller {
391392
if (utils_1.IS_LINUX) {
392393
scriptArguments.push('--install-dir', DotnetCoreInstaller.installationDirectoryLinux);
393394
}
395+
if (utils_1.IS_MAC) {
396+
scriptArguments.push('--install-dir', DotnetCoreInstaller.installationDirectoryMac);
397+
}
394398
}
395399
const { exitCode, stdout } = yield exec.getExecOutput(`"${scriptPath}"`, scriptArguments, { ignoreReturnCode: true });
396400
if (exitCode) {
397401
throw new Error(`Failed to install dotnet ${exitCode}. ${stdout}`);
398402
}
403+
return this.outputDotnetVersion(dotnetVersion.value, scriptArguments[scriptArguments.length - 1]);
404+
});
405+
}
406+
outputDotnetVersion(version, installationPath) {
407+
return __awaiter(this, void 0, void 0, function* () {
408+
let versionsOnRunner = yield promises_1.readdir(path_1.default.join(installationPath.replace(/'/g, ''), 'sdk'));
409+
let installedVersion = semver_1.default.maxSatisfying(versionsOnRunner, version, {
410+
includePrerelease: true
411+
});
412+
return installedVersion;
399413
});
400414
}
401415
}
402416
exports.DotnetCoreInstaller = DotnetCoreInstaller;
403417
DotnetCoreInstaller.installationDirectoryWindows = path_1.default.join(process.env['PROGRAMFILES'] + '', 'dotnet');
404418
DotnetCoreInstaller.installationDirectoryLinux = '/usr/share/dotnet';
419+
DotnetCoreInstaller.installationDirectoryMac = path_1.default.join(process.env['HOME'] + '', '.dotnet');
405420

406421

407422
/***/ }),
@@ -448,6 +463,7 @@ const core = __importStar(__nccwpck_require__(2186));
448463
const installer_1 = __nccwpck_require__(1480);
449464
const fs = __importStar(__nccwpck_require__(7147));
450465
const path_1 = __importDefault(__nccwpck_require__(1017));
466+
const semver_1 = __importDefault(__nccwpck_require__(5911));
451467
const auth = __importStar(__nccwpck_require__(8527));
452468
const qualityOptions = [
453469
'daily',
@@ -469,6 +485,7 @@ function run() {
469485
// Proxy, auth, (etc) are still set up, even if no version is identified
470486
//
471487
const versions = core.getMultilineInput('dotnet-version');
488+
const installedDotnetVersions = [];
472489
const globalJsonFileInput = core.getInput('global-json-file');
473490
if (globalJsonFileInput) {
474491
const globalJsonPath = path_1.default.join(process.cwd(), globalJsonFileInput);
@@ -494,7 +511,8 @@ function run() {
494511
const uniqueVersions = new Set(versions);
495512
for (const version of uniqueVersions) {
496513
dotnetInstaller = new installer_1.DotnetCoreInstaller(version, quality);
497-
yield dotnetInstaller.installDotnet();
514+
const installedVersion = yield dotnetInstaller.installDotnet();
515+
installedDotnetVersions.push(installedVersion);
498516
}
499517
installer_1.DotnetCoreInstaller.addToPath();
500518
}
@@ -503,6 +521,13 @@ function run() {
503521
if (sourceUrl) {
504522
auth.configAuthentication(sourceUrl, configFile);
505523
}
524+
const comparisonRange = globalJsonFileInput
525+
? versions[versions.length - 1]
526+
: '*';
527+
const versionToOutput = semver_1.default.maxSatisfying(installedDotnetVersions, comparisonRange, {
528+
includePrerelease: true
529+
});
530+
core.setOutput('dotnet-version', versionToOutput);
506531
const matchersPath = path_1.default.join(__dirname, '..', '.github');
507532
core.info(`##[add-matcher]${path_1.default.join(matchersPath, 'csc.json')}`);
508533
}
@@ -538,9 +563,10 @@ run();
538563
"use strict";
539564

540565
Object.defineProperty(exports, "__esModule", ({ value: true }));
541-
exports.IS_LINUX = exports.IS_WINDOWS = void 0;
566+
exports.IS_MAC = exports.IS_LINUX = exports.IS_WINDOWS = void 0;
542567
exports.IS_WINDOWS = process.platform === 'win32';
543568
exports.IS_LINUX = process.platform === 'linux';
569+
exports.IS_MAC = process.platform === 'darwin';
544570

545571

546572
/***/ }),
@@ -21016,6 +21042,14 @@ module.exports = require("fs");
2101621042

2101721043
/***/ }),
2101821044

21045+
/***/ 3292:
21046+
/***/ ((module) => {
21047+
21048+
"use strict";
21049+
module.exports = require("fs/promises");
21050+
21051+
/***/ }),
21052+
2101921053
/***/ 3685:
2102021054
/***/ ((module) => {
2102121055

0 commit comments

Comments
 (0)