Add ability to write resolved version of SDK into the output variable (#324)
This commit is contained in:
parent
0705ef0281
commit
c7e7147fd3
|
@ -238,6 +238,60 @@ jobs:
|
|||
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 }}
|
||||
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
|
||||
container:
|
||||
|
|
48
README.md
48
README.md
|
@ -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
|
||||
|
|
|
@ -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');
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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';
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
});
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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');
|
||||
|
@ -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');
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
@ -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',
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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')}`);
|
||||
}
|
||||
|
@ -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';
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
@ -25688,6 +25714,14 @@ module.exports = require("fs");
|
|||
|
||||
/***/ }),
|
||||
|
||||
/***/ 3292:
|
||||
/***/ ((module) => {
|
||||
|
||||
"use strict";
|
||||
module.exports = require("fs/promises");
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 3685:
|
||||
/***/ ((module) => {
|
||||
|
||||
|
|
|
@ -4,9 +4,10 @@ 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 semver from 'semver';
|
||||
import {IS_LINUX, IS_WINDOWS} from './utils';
|
||||
import {IS_LINUX, IS_WINDOWS, IS_MAC} from './utils';
|
||||
import {QualityOptions} from './setup-dotnet';
|
||||
|
||||
export interface DotnetVersion {
|
||||
|
@ -116,6 +117,10 @@ export class DotnetCoreInstaller {
|
|||
'dotnet'
|
||||
);
|
||||
private static readonly installationDirectoryLinux = '/usr/share/dotnet';
|
||||
private static readonly installationDirectoryMac = path.join(
|
||||
process.env['HOME'] + '',
|
||||
'.dotnet'
|
||||
);
|
||||
|
||||
static addToPath() {
|
||||
if (process.env['DOTNET_INSTALL_DIR']) {
|
||||
|
@ -136,10 +141,10 @@ export class DotnetCoreInstaller {
|
|||
);
|
||||
} else {
|
||||
// This is the default set in install-dotnet.sh
|
||||
core.addPath(path.join(process.env['HOME'] + '', '.dotnet'));
|
||||
core.addPath(DotnetCoreInstaller.installationDirectoryMac);
|
||||
core.exportVariable(
|
||||
'DOTNET_ROOT',
|
||||
path.join(process.env['HOME'] + '', '.dotnet')
|
||||
DotnetCoreInstaller.installationDirectoryMac
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -164,7 +169,7 @@ export class DotnetCoreInstaller {
|
|||
}
|
||||
}
|
||||
|
||||
public async installDotnet() {
|
||||
public async installDotnet(): Promise<string> {
|
||||
const windowsDefaultOptions = [
|
||||
'-NoLogo',
|
||||
'-Sta',
|
||||
|
@ -204,12 +209,13 @@ export class DotnetCoreInstaller {
|
|||
}
|
||||
|
||||
scriptArguments.push(
|
||||
`-InstallDir '${DotnetCoreInstaller.installationDirectoryWindows}'`
|
||||
'-InstallDir',
|
||||
`'${DotnetCoreInstaller.installationDirectoryWindows}'`
|
||||
);
|
||||
// process.env must be explicitly passed in for DOTNET_INSTALL_DIR to be used
|
||||
scriptPath =
|
||||
(await io.which('pwsh', false)) || (await io.which('powershell', true));
|
||||
scriptArguments = [...windowsDefaultOptions, scriptArguments.join(' ')];
|
||||
scriptArguments = windowsDefaultOptions.concat(scriptArguments);
|
||||
} else {
|
||||
chmodSync(escapedScript, '777');
|
||||
scriptPath = await io.which(escapedScript, true);
|
||||
|
@ -229,6 +235,13 @@ export class DotnetCoreInstaller {
|
|||
DotnetCoreInstaller.installationDirectoryLinux
|
||||
);
|
||||
}
|
||||
|
||||
if (IS_MAC) {
|
||||
scriptArguments.push(
|
||||
'--install-dir',
|
||||
DotnetCoreInstaller.installationDirectoryMac
|
||||
);
|
||||
}
|
||||
}
|
||||
const {exitCode, stdout} = await exec.getExecOutput(
|
||||
`"${scriptPath}"`,
|
||||
|
@ -238,5 +251,25 @@ export class DotnetCoreInstaller {
|
|||
if (exitCode) {
|
||||
throw new Error(`Failed to install dotnet ${exitCode}. ${stdout}`);
|
||||
}
|
||||
|
||||
return this.outputDotnetVersion(
|
||||
dotnetVersion.value,
|
||||
scriptArguments[scriptArguments.length - 1]
|
||||
);
|
||||
}
|
||||
|
||||
private async outputDotnetVersion(
|
||||
version,
|
||||
installationPath
|
||||
): Promise<string> {
|
||||
let versionsOnRunner: string[] = await readdir(
|
||||
path.join(installationPath.replace(/'/g, ''), 'sdk')
|
||||
);
|
||||
|
||||
let installedVersion = semver.maxSatisfying(versionsOnRunner, version, {
|
||||
includePrerelease: true
|
||||
})!;
|
||||
|
||||
return installedVersion;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ import * as core from '@actions/core';
|
|||
import {DotnetCoreInstaller} from './installer';
|
||||
import * as fs from 'fs';
|
||||
import path from 'path';
|
||||
import semver from 'semver';
|
||||
import * as auth from './authutil';
|
||||
|
||||
const qualityOptions = [
|
||||
|
@ -26,6 +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 globalJsonFileInput = core.getInput('global-json-file');
|
||||
if (globalJsonFileInput) {
|
||||
|
@ -60,7 +62,8 @@ export async function run() {
|
|||
const uniqueVersions = new Set<string>(versions);
|
||||
for (const version of uniqueVersions) {
|
||||
dotnetInstaller = new DotnetCoreInstaller(version, quality);
|
||||
await dotnetInstaller.installDotnet();
|
||||
const installedVersion = await dotnetInstaller.installDotnet();
|
||||
installedDotnetVersions.push(installedVersion);
|
||||
}
|
||||
DotnetCoreInstaller.addToPath();
|
||||
}
|
||||
|
@ -71,6 +74,20 @@ 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);
|
||||
|
||||
const matchersPath = path.join(__dirname, '..', '.github');
|
||||
core.info(`##[add-matcher]${path.join(matchersPath, 'csc.json')}`);
|
||||
} catch (error) {
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
export const IS_WINDOWS = process.platform === 'win32';
|
||||
export const IS_LINUX = process.platform === 'linux';
|
||||
export const IS_MAC = process.platform === 'darwin';
|
||||
|
|
Loading…
Reference in New Issue