Skip to content

Commit

Permalink
Add ability to write resolved version of SDK into the output variable (
Browse files Browse the repository at this point in the history
  • Loading branch information
IvanZosimov committed Sep 29, 2022
1 parent 0705ef0 commit c7e7147
Show file tree
Hide file tree
Showing 9 changed files with 254 additions and 15 deletions.
54 changes: 54 additions & 0 deletions .github/workflows/workflow.yml
Expand Up @@ -237,6 +237,60 @@ jobs:
$version = & dotnet --version
Write-Host "Installed version: $version"
if (-not ($version.Contains("preview") -or $version.Contains("rc"))) { throw "Unexpected version" }
test-dotnet-version-output-during-single-version-installation:
runs-on: ${{ matrix.operating-system }}

This comment has been minimized.

Copy link
@Rastu12

Rastu12 Oct 14, 2022

package.json

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.401
uses: ./
id: step1
with:
dotnet-version: "6.0.401"

- name: Verify value of the dotnet-version output
shell: pwsh
run: |
$version = & dotnet --version
Write-Host "Installed version: $version"
if (-not ($version -eq '${{steps.step1.outputs.dotnet-version}}')) { throw "Unexpected output value" }
test-dotnet-version-output-during-multiple-version-installation:
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.401, 5.0.408, 7.0.100-rc.1.22431.12
uses: ./
id: step2
with:
dotnet-version: |
7.0.100-rc.1.22431.12
6.0.401
5.0.408
- name: Verify value of the dotnet-version output
shell: pwsh
run: |
$version = "7.0.100-rc.1.22431.12"
if (-not ($version -eq '${{steps.step2.outputs.dotnet-version}}')) { throw "Unexpected output value" }
test-proxy:
runs-on: ubuntu-latest
Expand Down
48 changes: 48 additions & 0 deletions README.md
Expand Up @@ -141,6 +141,54 @@ steps:
```
> **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.
# Outputs and environment variables

## Outputs

### `dotnet-version`

Using the **dotnet-version** output it's possible to get the installed by the action .NET SDK version.

**Single version installation**

In case of a single version installation, the `dotnet-version` output contains the version that is installed by the action.

```yaml
- uses: actions/setup-dotnet@v3
id: cp310
with:
dotnet-version: 3.1.422
- run: echo '${{ steps.cp310.outputs.dotnet-version }}' # outputs 3.1.422
```

**Multiple version installation**

In case of a multiple version installation, the `dotnet-version` output contains the latest version that is installed by the action.

```yaml
- uses: actions/setup-dotnet@v3
id: cp310
with:
dotnet-version: |
3.1.422
5.0.408
- run: echo '${{ steps.cp310.outputs.dotnet-version }}' # outputs 5.0.408
```
**Installation from global.json**

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`.

```yaml
- uses: actions/setup-dotnet@v3
id: cp310
with:
dotnet-version: |
3.1.422
5.0.408
global-json-file: "./global.json" # contains version 2.2.207
- run: echo '${{ steps.cp310.outputs.dotnet-version }}' # outputs 2.2.207
```

## Environment variables

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
Expand Down
17 changes: 15 additions & 2 deletions __tests__/installer.test.ts
Expand Up @@ -107,6 +107,15 @@ describe('DotnetCoreInstaller tests', () => {
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';
let installedVersion: string;

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');
Expand Down Expand Up @@ -267,11 +276,15 @@ function normalizeFileContents(contents: string): string {
.replace(new RegExp('\r', 'g'), '\n');
}

async function getDotnet(version: string, quality: string = ''): Promise<void> {
async function getDotnet(
version: string,
quality: string = ''
): Promise<string> {
const dotnetInstaller = new installer.DotnetCoreInstaller(
version,
quality as QualityOptions
);
await dotnetInstaller.installDotnet();
const installedVersion = await dotnetInstaller.installDotnet();
installer.DotnetCoreInstaller.addToPath();
return installedVersion;
}
36 changes: 36 additions & 0 deletions __tests__/setup-dotnet.test.ts
@@ -1,4 +1,5 @@
import * as io from '@actions/io';
import * as core from '@actions/core';
import fs from 'fs';
import os from 'os';
import path from 'path';
Expand All @@ -20,6 +21,12 @@ if (IS_WINDOWS) {
const tempDir = path.join(__dirname, 'runner', 'temp2');

describe('setup-dotnet tests', () => {
let getInputSpy = jest.spyOn(core, 'getInput');
let getMultilineInputSpy = jest.spyOn(core, 'getMultilineInput');
let setOutputSpy = jest.spyOn(core, 'setOutput');

let inputs = {} as any;

beforeAll(async () => {
process.env.RUNNER_TOOL_CACHE = toolDir;
process.env.DOTNET_INSTALL_DIR = toolDir;
Expand Down Expand Up @@ -59,4 +66,33 @@ describe('setup-dotnet tests', () => {
expect(fs.existsSync(path.join(toolDir, 'dotnet'))).toBe(true);
}
}, 400000);

it("Sets output with the latest installed by action version if global.json file isn't specified", async () => {
inputs['dotnet-version'] = ['3.1.201', '6.0.401'];

getMultilineInputSpy.mockImplementation(input => inputs[input]);

await setup.run();

expect(setOutputSpy).toBeCalledWith('dotnet-version', '6.0.401');
}, 400000);

it("Sets output with the version specified in global.json, if it's present", async () => {
const globalJsonPath = path.join(process.cwd(), 'global.json');
const jsonContents = `{${os.EOL}"sdk": {${os.EOL}"version": "3.0.103"${os.EOL}}${os.EOL}}`;
if (!fs.existsSync(globalJsonPath)) {
fs.writeFileSync(globalJsonPath, jsonContents);
}

inputs['dotnet-version'] = ['3.1.201', '6.0.401'];
inputs['global-json-file'] = './global.json';

getMultilineInputSpy.mockImplementation(input => inputs[input]);

getInputSpy.mockImplementation(input => inputs[input]);

await setup.run();

expect(setOutputSpy).toBeCalledWith('dotnet-version', '3.0.103');
}, 400000);
});
3 changes: 3 additions & 0 deletions action.yml
Expand Up @@ -17,6 +17,9 @@ inputs:
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'
config-file:
description: 'Optional NuGet.config location, if your NuGet.config isn''t located in the root of the repo.'
outputs:
dotnet-version:
description: 'Contains the installed by action .NET SDK version for reuse.'
runs:
using: 'node16'
main: 'dist/index.js'
46 changes: 40 additions & 6 deletions dist/index.js
Expand Up @@ -189,6 +189,7 @@ 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 semver_1 = __importDefault(__nccwpck_require__(5911));
const utils_1 = __nccwpck_require__(918);
Expand Down Expand Up @@ -284,8 +285,8 @@ class DotnetCoreInstaller {
}
else {
// This is the default set in install-dotnet.sh
core.addPath(path_1.default.join(process.env['HOME'] + '', '.dotnet'));
core.exportVariable('DOTNET_ROOT', path_1.default.join(process.env['HOME'] + '', '.dotnet'));
core.addPath(DotnetCoreInstaller.installationDirectoryMac);
core.exportVariable('DOTNET_ROOT', DotnetCoreInstaller.installationDirectoryMac);
}
}
}
Expand Down Expand Up @@ -332,11 +333,11 @@ class DotnetCoreInstaller {
if (process.env['no_proxy'] != null) {
scriptArguments.push(`-ProxyBypassList ${process.env['no_proxy']}`);
}
scriptArguments.push(`-InstallDir '${DotnetCoreInstaller.installationDirectoryWindows}'`);
scriptArguments.push('-InstallDir', `'${DotnetCoreInstaller.installationDirectoryWindows}'`);
// process.env must be explicitly passed in for DOTNET_INSTALL_DIR to be used
scriptPath =
(yield io.which('pwsh', false)) || (yield io.which('powershell', true));
scriptArguments = [...windowsDefaultOptions, scriptArguments.join(' ')];
scriptArguments = windowsDefaultOptions.concat(scriptArguments);
}
else {
fs_1.chmodSync(escapedScript, '777');
Expand All @@ -351,17 +352,31 @@ class DotnetCoreInstaller {
if (utils_1.IS_LINUX) {
scriptArguments.push('--install-dir', DotnetCoreInstaller.installationDirectoryLinux);
}
if (utils_1.IS_MAC) {
scriptArguments.push('--install-dir', DotnetCoreInstaller.installationDirectoryMac);
}
}
const { exitCode, stdout } = yield exec.getExecOutput(`"${scriptPath}"`, scriptArguments, { ignoreReturnCode: true });
if (exitCode) {
throw new Error(`Failed to install dotnet ${exitCode}. ${stdout}`);
}
return this.outputDotnetVersion(dotnetVersion.value, scriptArguments[scriptArguments.length - 1]);
});
}
outputDotnetVersion(version, installationPath) {
return __awaiter(this, void 0, void 0, function* () {
let versionsOnRunner = yield promises_1.readdir(path_1.default.join(installationPath.replace(/'/g, ''), 'sdk'));
let installedVersion = semver_1.default.maxSatisfying(versionsOnRunner, version, {
includePrerelease: true
});
return installedVersion;
});
}
}
exports.DotnetCoreInstaller = DotnetCoreInstaller;
DotnetCoreInstaller.installationDirectoryWindows = path_1.default.join(process.env['PROGRAMFILES'] + '', 'dotnet');
DotnetCoreInstaller.installationDirectoryLinux = '/usr/share/dotnet';
DotnetCoreInstaller.installationDirectoryMac = path_1.default.join(process.env['HOME'] + '', '.dotnet');


/***/ }),
Expand Down Expand Up @@ -408,6 +423,7 @@ const core = __importStar(__nccwpck_require__(2186));
const installer_1 = __nccwpck_require__(1480);
const fs = __importStar(__nccwpck_require__(7147));
const path_1 = __importDefault(__nccwpck_require__(1017));
const semver_1 = __importDefault(__nccwpck_require__(5911));
const auth = __importStar(__nccwpck_require__(8527));
const qualityOptions = [
'daily',
Expand All @@ -429,6 +445,7 @@ function run() {
// Proxy, auth, (etc) are still set up, even if no version is identified
//
const versions = core.getMultilineInput('dotnet-version');
const installedDotnetVersions = [];
const globalJsonFileInput = core.getInput('global-json-file');
if (globalJsonFileInput) {
const globalJsonPath = path_1.default.join(process.cwd(), globalJsonFileInput);
Expand All @@ -454,7 +471,8 @@ function run() {
const uniqueVersions = new Set(versions);
for (const version of uniqueVersions) {
dotnetInstaller = new installer_1.DotnetCoreInstaller(version, quality);
yield dotnetInstaller.installDotnet();
const installedVersion = yield dotnetInstaller.installDotnet();
installedDotnetVersions.push(installedVersion);
}
installer_1.DotnetCoreInstaller.addToPath();
}
Expand All @@ -463,6 +481,13 @@ 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 matchersPath = path_1.default.join(__dirname, '..', '.github');
core.info(`##[add-matcher]${path_1.default.join(matchersPath, 'csc.json')}`);
}
Expand Down Expand Up @@ -498,9 +523,10 @@ run();
"use strict";

Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.IS_LINUX = exports.IS_WINDOWS = void 0;
exports.IS_MAC = exports.IS_LINUX = exports.IS_WINDOWS = void 0;
exports.IS_WINDOWS = process.platform === 'win32';
exports.IS_LINUX = process.platform === 'linux';
exports.IS_MAC = process.platform === 'darwin';


/***/ }),
Expand Down Expand Up @@ -25688,6 +25714,14 @@ module.exports = require("fs");

/***/ }),

/***/ 3292:
/***/ ((module) => {

"use strict";
module.exports = require("fs/promises");

/***/ }),

/***/ 3685:
/***/ ((module) => {

Expand Down

0 comments on commit c7e7147

Please sign in to comment.