Merge branch 'main' into refactor-nuget-cfg-parse

This commit is contained in:
Evgenii Korolevskii 2022-10-13 16:34:35 +02:00
commit 239baf3c5b
11 changed files with 250 additions and 255 deletions

View File

@ -1,6 +1,6 @@
--- ---
name: "@actions/core" name: "@actions/core"
version: 1.9.1 version: 1.10.0
type: npm type: npm
summary: Actions core lib summary: Actions core lib
homepage: https://github.com/actions/toolkit/tree/main/packages/core homepage: https://github.com/actions/toolkit/tree/main/packages/core

View File

@ -7,5 +7,6 @@
"trailingComma": "none", "trailingComma": "none",
"bracketSpacing": false, "bracketSpacing": false,
"arrowParens": "avoid", "arrowParens": "avoid",
"parser": "typescript" "parser": "typescript",
"endOfLine": "auto"
} }

View File

@ -195,16 +195,24 @@ Some environment variables may be necessary for your particular case or to impro
| **Env.variable** | **Description** | **Default value** | | **Env.variable** | **Description** | **Default value** |
| ----------- | ----------- | ----------- | | ----------- | ----------- | ----------- |
| DOTNET_INSTALL_DIR |Specifies a directory where .NET SDKs should be installed by the action.|*default value for each OS* |
| DOTNET_NOLOGO |Removes logo and telemetry message from first run of dotnet cli|*false*| | DOTNET_NOLOGO |Removes logo and telemetry message from first run of dotnet cli|*false*|
| DOTNET_CLI_TELEMETRY_OPTOUT |Opt-out of telemetry being sent to Microsoft|*false*| | DOTNET_CLI_TELEMETRY_OPTOUT |Opt-out of telemetry being sent to Microsoft|*false*|
| DOTNET_MULTILEVEL_LOOKUP |Configures whether the global install location is used as a fall-back|*true*| | DOTNET_MULTILEVEL_LOOKUP |Configures whether the global install location is used as a fall-back|*true*|
The default value of the `DOTNET_INSTALL_DIR` environment variable depends on the operation system which is used on a runner:
| **Operation system** | **Default value** |
| ----------- | ----------- |
| **Windows** | `C:\Program Files\dotnet` |
| **Ubuntu** | `/usr/share/dotnet` |
| **macOS** | `/Users/runner/.dotnet` |
**Example usage**: **Example usage**:
```yml ```yml
build: build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
env: env:
DOTNET_NOLOGO: true DOTNET_INSTALL_DIR: "path/to/directory"
steps: steps:
- uses: actions/checkout@main - uses: actions/checkout@main
- uses: actions/setup-dotnet@v3 - uses: actions/setup-dotnet@v3

View File

@ -5,11 +5,7 @@ import path from 'path';
const fakeSourcesDirForTesting = path.join( const fakeSourcesDirForTesting = path.join(
__dirname, __dirname,
'runner', 'runner',
path.join( path.join(Math.random().toString(36).substring(7)),
Math.random()
.toString(36)
.substring(7)
),
's' 's'
); );

297
dist/index.js vendored
View File

@ -8,7 +8,11 @@
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k; if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) { }) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k; if (k2 === undefined) k2 = k;
o[k2] = m[k]; o[k2] = m[k];
@ -21,7 +25,7 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
var __importStar = (this && this.__importStar) || function (mod) { var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod; if (mod && mod.__esModule) return mod;
var result = {}; var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod); __setModuleDefault(result, mod);
return result; return result;
}; };
@ -31,7 +35,8 @@ const fs = __importStar(__nccwpck_require__(7147));
const path = __importStar(__nccwpck_require__(1017)); const path = __importStar(__nccwpck_require__(1017));
const core = __importStar(__nccwpck_require__(2186)); const core = __importStar(__nccwpck_require__(2186));
const github = __importStar(__nccwpck_require__(5438)); const github = __importStar(__nccwpck_require__(5438));
const fast_xml_parser_1 = __nccwpck_require__(2603); const xmlbuilder = __importStar(__nccwpck_require__(2958));
const xmlParser = __importStar(__nccwpck_require__(7448));
function configAuthentication(feedUrl, existingFileLocation = '', processRoot = process.cwd()) { function configAuthentication(feedUrl, existingFileLocation = '', processRoot = process.cwd()) {
const existingNuGetConfig = path.resolve(processRoot, existingFileLocation === '' const existingNuGetConfig = path.resolve(processRoot, existingFileLocation === ''
? getExistingNugetConfig(processRoot) ? getExistingNugetConfig(processRoot)
@ -54,8 +59,8 @@ function getExistingNugetConfig(processRoot) {
return defaultConfigName; return defaultConfigName;
} }
function writeFeedToFile(feedUrl, existingFileLocation, tempFileLocation) { function writeFeedToFile(feedUrl, existingFileLocation, tempFileLocation) {
var _a, _b;
core.info(`dotnet-auth: Finding any source references in ${existingFileLocation}, writing a new temporary configuration file with credentials to ${tempFileLocation}`); core.info(`dotnet-auth: Finding any source references in ${existingFileLocation}, writing a new temporary configuration file with credentials to ${tempFileLocation}`);
let xml;
let sourceKeys = []; let sourceKeys = [];
let owner = core.getInput('owner'); let owner = core.getInput('owner');
let sourceUrl = feedUrl; let sourceUrl = feedUrl;
@ -68,18 +73,27 @@ function writeFeedToFile(feedUrl, existingFileLocation, tempFileLocation) {
if (fs.existsSync(existingFileLocation)) { if (fs.existsSync(existingFileLocation)) {
// get key from existing NuGet.config so NuGet/dotnet can match credentials // get key from existing NuGet.config so NuGet/dotnet can match credentials
const curContents = fs.readFileSync(existingFileLocation, 'utf8'); const curContents = fs.readFileSync(existingFileLocation, 'utf8');
const parserOptions = { const json = xmlParser.parse(curContents, { ignoreAttributes: false });
ignoreAttributes: false
};
const parser = new fast_xml_parser_1.XMLParser(parserOptions);
const json = parser.parse(curContents);
if (typeof json.configuration === 'undefined') { if (typeof json.configuration === 'undefined') {
throw new Error(`The provided NuGet.config seems invalid.`); throw new Error(`The provided NuGet.config seems invalid.`);
} }
if ((_b = (_a = json.configuration) === null || _a === void 0 ? void 0 : _a.packageSources) === null || _b === void 0 ? void 0 : _b.add) { if (typeof json.configuration.packageSources != 'undefined') {
const packageSources = json.configuration.packageSources.add; if (typeof json.configuration.packageSources.add != 'undefined') {
if (Array.isArray(packageSources)) { // file has at least one <add>
packageSources.forEach(source => { if (typeof json.configuration.packageSources.add[0] === 'undefined') {
// file has only one <add>
if (json.configuration.packageSources.add['@_value']
.toLowerCase()
.includes(feedUrl.toLowerCase())) {
const key = json.configuration.packageSources.add['@_key'];
sourceKeys.push(key);
core.debug(`Found a URL with key ${key}`);
}
}
else {
// file has 2+ <add>
for (let i = 0; i < json.configuration.packageSources.add.length; i++) {
const source = json.configuration.packageSources.add[i];
const value = source['@_value']; const value = source['@_value'];
core.debug(`source '${value}'`); core.debug(`source '${value}'`);
if (value.toLowerCase().includes(feedUrl.toLowerCase())) { if (value.toLowerCase().includes(feedUrl.toLowerCase())) {
@ -87,98 +101,48 @@ function writeFeedToFile(feedUrl, existingFileLocation, tempFileLocation) {
sourceKeys.push(key); sourceKeys.push(key);
core.debug(`Found a URL with key ${key}`); core.debug(`Found a URL with key ${key}`);
} }
});
}
else {
if (packageSources['@_value']
.toLowerCase()
.includes(feedUrl.toLowerCase())) {
const key = packageSources['@_key'];
sourceKeys.push(key);
core.debug(`Found a URL with key ${key}`);
} }
} }
} }
} }
const xmlSource = [
{
'?xml': [
{
'#text': ''
} }
], xml = xmlbuilder
':@': { .create('configuration')
'@_version': '1.0' .ele('config')
} .ele('add', { key: 'defaultPushSource', value: sourceUrl })
}, .up()
{ .up();
configuration: [
{
config: [
{
add: [],
':@': {
'@_key': 'defaultPushSource',
'@_value': sourceUrl
}
}
]
}
]
}
];
if (!sourceKeys.length) { if (!sourceKeys.length) {
let keystring = 'Source'; let keystring = 'Source';
xmlSource[1].configuration.push({ xml = xml
packageSources: [ .ele('packageSources')
{ .ele('add', { key: keystring, value: sourceUrl })
add: [], .up()
':@': { .up();
'@_key': keystring,
'@_value': sourceUrl
}
}
]
});
sourceKeys.push(keystring); sourceKeys.push(keystring);
} }
const packageSourceCredentials = []; xml = xml.ele('packageSourceCredentials');
sourceKeys.forEach(key => { sourceKeys.forEach(key => {
if (!isValidKey(key)) { if (!isValidKey(key)) {
throw new Error("Source name can contain letters, numbers, and '-', '_', '.' symbols only. Please, fix source name in NuGet.config and try again."); throw new Error("Source name can contain letters, numbers, and '-', '_', '.' symbols only. Please, fix source name in NuGet.config and try again.");
} }
packageSourceCredentials.push({ xml = xml
[key]: [ .ele(key)
{ .ele('add', { key: 'Username', value: owner })
add: [], .up()
':@': { .ele('add', {
'@_key': 'Username', key: 'ClearTextPassword',
'@_value': owner value: process.env.NUGET_AUTH_TOKEN
} })
}, .up()
{ .up();
add: [],
':@': {
'@_key': 'ClearTextPassword',
'@_value': process.env.NUGET_AUTH_TOKEN
}
}
]
}); });
}); // If NuGet fixes itself such that on Linux it can look for environment variables in the config file (it doesn't seem to work today),
xmlSource[1].configuration.push({ // use this for the value above
packageSourceCredentials // process.platform == 'win32'
}); // ? '%NUGET_AUTH_TOKEN%'
const xmlBuilderOptions = { // : '$NUGET_AUTH_TOKEN'
format: true, const output = xml.end({ pretty: true });
ignoreAttributes: false,
preserveOrder: true,
allowBooleanAttributes: true,
suppressBooleanAttributes: true,
suppressEmptyNode: true
};
const builder = new fast_xml_parser_1.XMLBuilder(xmlBuilderOptions);
const output = builder.build(xmlSource).trim();
fs.writeFileSync(tempFileLocation, output); fs.writeFileSync(tempFileLocation, output);
} }
@ -192,7 +156,11 @@ function writeFeedToFile(feedUrl, existingFileLocation, tempFileLocation) {
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k; if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) { }) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k; if (k2 === undefined) k2 = k;
o[k2] = m[k]; o[k2] = m[k];
@ -205,7 +173,7 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
var __importStar = (this && this.__importStar) || function (mod) { var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod; if (mod && mod.__esModule) return mod;
var result = {}; var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod); __setModuleDefault(result, mod);
return result; return result;
}; };
@ -221,6 +189,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
var __importDefault = (this && this.__importDefault) || function (mod) { var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod }; return (mod && mod.__esModule) ? mod : { "default": mod };
}; };
var _a;
Object.defineProperty(exports, "__esModule", ({ value: true })); Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.DotnetCoreInstaller = exports.DotnetVersionResolver = void 0; exports.DotnetCoreInstaller = exports.DotnetVersionResolver = void 0;
// Load tempDirectory before it gets wiped by tool-cache // Load tempDirectory before it gets wiped by tool-cache
@ -231,6 +200,7 @@ const hc = __importStar(__nccwpck_require__(6255));
const fs_1 = __nccwpck_require__(7147); const fs_1 = __nccwpck_require__(7147);
const promises_1 = __nccwpck_require__(3292); const promises_1 = __nccwpck_require__(3292);
const path_1 = __importDefault(__nccwpck_require__(1017)); const path_1 = __importDefault(__nccwpck_require__(1017));
const os_1 = __importDefault(__nccwpck_require__(2037));
const semver_1 = __importDefault(__nccwpck_require__(5911)); const semver_1 = __importDefault(__nccwpck_require__(5911));
const utils_1 = __nccwpck_require__(918); const utils_1 = __nccwpck_require__(918);
class DotnetVersionResolver { class DotnetVersionResolver {
@ -309,27 +279,22 @@ class DotnetCoreInstaller {
this.version = version; this.version = version;
this.quality = quality; this.quality = quality;
} }
static convertInstallPathToAbsolute(installDir) {
let transformedPath;
if (path_1.default.isAbsolute(installDir)) {
transformedPath = installDir;
}
else {
transformedPath = installDir.startsWith('~')
? path_1.default.join(os_1.default.homedir(), installDir.slice(1))
: (transformedPath = path_1.default.join(process.cwd(), installDir));
}
return path_1.default.normalize(transformedPath);
}
static addToPath() { static addToPath() {
if (process.env['DOTNET_INSTALL_DIR']) {
core.addPath(process.env['DOTNET_INSTALL_DIR']); core.addPath(process.env['DOTNET_INSTALL_DIR']);
core.exportVariable('DOTNET_ROOT', process.env['DOTNET_INSTALL_DIR']); core.exportVariable('DOTNET_ROOT', process.env['DOTNET_INSTALL_DIR']);
} }
else {
if (utils_1.IS_WINDOWS) {
core.addPath(DotnetCoreInstaller.installationDirectoryWindows);
core.exportVariable('DOTNET_ROOT', DotnetCoreInstaller.installationDirectoryWindows);
}
else if (utils_1.IS_LINUX) {
core.addPath(DotnetCoreInstaller.installationDirectoryLinux);
core.exportVariable('DOTNET_ROOT', DotnetCoreInstaller.installationDirectoryLinux);
}
else {
// This is the default set in install-dotnet.sh
core.addPath(DotnetCoreInstaller.installationDirectoryMac);
core.exportVariable('DOTNET_ROOT', DotnetCoreInstaller.installationDirectoryMac);
}
}
}
setQuality(dotnetVersion, scriptArguments) { setQuality(dotnetVersion, scriptArguments) {
const option = utils_1.IS_WINDOWS ? '-Quality' : '--quality'; const option = utils_1.IS_WINDOWS ? '-Quality' : '--quality';
if (dotnetVersion.qualityFlag) { if (dotnetVersion.qualityFlag) {
@ -373,14 +338,12 @@ class DotnetCoreInstaller {
if (process.env['no_proxy'] != null) { if (process.env['no_proxy'] != null) {
scriptArguments.push(`-ProxyBypassList ${process.env['no_proxy']}`); scriptArguments.push(`-ProxyBypassList ${process.env['no_proxy']}`);
} }
scriptArguments.push('-InstallDir', `'${DotnetCoreInstaller.installationDirectoryWindows}'`);
// process.env must be explicitly passed in for DOTNET_INSTALL_DIR to be used
scriptPath = scriptPath =
(yield io.which('pwsh', false)) || (yield io.which('powershell', true)); (yield io.which('pwsh', false)) || (yield io.which('powershell', true));
scriptArguments = windowsDefaultOptions.concat(scriptArguments); scriptArguments = windowsDefaultOptions.concat(scriptArguments);
} }
else { else {
fs_1.chmodSync(escapedScript, '777'); (0, fs_1.chmodSync)(escapedScript, '777');
scriptPath = yield io.which(escapedScript, true); scriptPath = yield io.which(escapedScript, true);
scriptArguments = []; scriptArguments = [];
if (dotnetVersion.type) { if (dotnetVersion.type) {
@ -389,23 +352,23 @@ class DotnetCoreInstaller {
if (this.quality) { if (this.quality) {
this.setQuality(dotnetVersion, scriptArguments); this.setQuality(dotnetVersion, scriptArguments);
} }
if (utils_1.IS_LINUX) {
scriptArguments.push('--install-dir', DotnetCoreInstaller.installationDirectoryLinux);
} }
if (utils_1.IS_MAC) { // process.env must be explicitly passed in for DOTNET_INSTALL_DIR to be used
scriptArguments.push('--install-dir', DotnetCoreInstaller.installationDirectoryMac); const getExecOutputOptions = {
} ignoreReturnCode: true,
} env: process.env
const { exitCode, stdout } = yield exec.getExecOutput(`"${scriptPath}"`, scriptArguments, { ignoreReturnCode: true }); };
const { exitCode, stdout } = yield exec.getExecOutput(`"${scriptPath}"`, scriptArguments, getExecOutputOptions);
if (exitCode) { if (exitCode) {
throw new Error(`Failed to install dotnet ${exitCode}. ${stdout}`); throw new Error(`Failed to install dotnet ${exitCode}. ${stdout}`);
} }
return this.outputDotnetVersion(dotnetVersion.value, scriptArguments[scriptArguments.length - 1]); return this.outputDotnetVersion(dotnetVersion.value);
}); });
} }
outputDotnetVersion(version, installationPath) { outputDotnetVersion(version) {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
let versionsOnRunner = yield promises_1.readdir(path_1.default.join(installationPath.replace(/'/g, ''), 'sdk')); const installationPath = process.env['DOTNET_INSTALL_DIR'];
let versionsOnRunner = yield (0, promises_1.readdir)(path_1.default.join(installationPath.replace(/'/g, ''), 'sdk'));
let installedVersion = semver_1.default.maxSatisfying(versionsOnRunner, version, { let installedVersion = semver_1.default.maxSatisfying(versionsOnRunner, version, {
includePrerelease: true includePrerelease: true
}); });
@ -414,9 +377,27 @@ class DotnetCoreInstaller {
} }
} }
exports.DotnetCoreInstaller = DotnetCoreInstaller; exports.DotnetCoreInstaller = DotnetCoreInstaller;
DotnetCoreInstaller.installationDirectoryWindows = path_1.default.join(process.env['PROGRAMFILES'] + '', 'dotnet'); _a = DotnetCoreInstaller;
DotnetCoreInstaller.installationDirectoryLinux = '/usr/share/dotnet'; (() => {
DotnetCoreInstaller.installationDirectoryMac = path_1.default.join(process.env['HOME'] + '', '.dotnet'); const installationDirectoryWindows = path_1.default.join(process.env['PROGRAMFILES'] + '', 'dotnet');
const installationDirectoryLinux = '/usr/share/dotnet';
const installationDirectoryMac = path_1.default.join(process.env['HOME'] + '', '.dotnet');
const dotnetInstallDir = process.env['DOTNET_INSTALL_DIR'];
if (dotnetInstallDir) {
process.env['DOTNET_INSTALL_DIR'] =
_a.convertInstallPathToAbsolute(dotnetInstallDir);
}
else {
if (utils_1.IS_WINDOWS) {
process.env['DOTNET_INSTALL_DIR'] = installationDirectoryWindows;
}
else {
process.env['DOTNET_INSTALL_DIR'] = utils_1.IS_LINUX
? installationDirectoryLinux
: installationDirectoryMac;
}
}
})();
/***/ }), /***/ }),
@ -428,7 +409,11 @@ DotnetCoreInstaller.installationDirectoryMac = path_1.default.join(process.env['
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k; if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) { }) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k; if (k2 === undefined) k2 = k;
o[k2] = m[k]; o[k2] = m[k];
@ -441,7 +426,7 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
var __importStar = (this && this.__importStar) || function (mod) { var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod; if (mod && mod.__esModule) return mod;
var result = {}; var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod); __setModuleDefault(result, mod);
return result; return result;
}; };
@ -563,10 +548,9 @@ run();
"use strict"; "use strict";
Object.defineProperty(exports, "__esModule", ({ value: true })); Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.IS_MAC = exports.IS_LINUX = exports.IS_WINDOWS = void 0; exports.IS_LINUX = exports.IS_WINDOWS = void 0;
exports.IS_WINDOWS = process.platform === 'win32'; exports.IS_WINDOWS = process.platform === 'win32';
exports.IS_LINUX = process.platform === 'linux'; exports.IS_LINUX = process.platform === 'linux';
exports.IS_MAC = process.platform === 'darwin';
/***/ }), /***/ }),
@ -710,7 +694,6 @@ const file_command_1 = __nccwpck_require__(717);
const utils_1 = __nccwpck_require__(5278); const utils_1 = __nccwpck_require__(5278);
const os = __importStar(__nccwpck_require__(2037)); const os = __importStar(__nccwpck_require__(2037));
const path = __importStar(__nccwpck_require__(1017)); const path = __importStar(__nccwpck_require__(1017));
const uuid_1 = __nccwpck_require__(5840);
const oidc_utils_1 = __nccwpck_require__(8041); const oidc_utils_1 = __nccwpck_require__(8041);
/** /**
* The code to exit an action * The code to exit an action
@ -740,20 +723,9 @@ function exportVariable(name, val) {
process.env[name] = convertedVal; process.env[name] = convertedVal;
const filePath = process.env['GITHUB_ENV'] || ''; const filePath = process.env['GITHUB_ENV'] || '';
if (filePath) { if (filePath) {
const delimiter = `ghadelimiter_${uuid_1.v4()}`; return file_command_1.issueFileCommand('ENV', file_command_1.prepareKeyValueMessage(name, val));
// These should realistically never happen, but just in case someone finds a way to exploit uuid generation let's not allow keys or values that contain the delimiter.
if (name.includes(delimiter)) {
throw new Error(`Unexpected input: name should not contain the delimiter "${delimiter}"`);
} }
if (convertedVal.includes(delimiter)) {
throw new Error(`Unexpected input: value should not contain the delimiter "${delimiter}"`);
}
const commandValue = `${name}<<${delimiter}${os.EOL}${convertedVal}${os.EOL}${delimiter}`;
file_command_1.issueCommand('ENV', commandValue);
}
else {
command_1.issueCommand('set-env', { name }, convertedVal); command_1.issueCommand('set-env', { name }, convertedVal);
}
} }
exports.exportVariable = exportVariable; exports.exportVariable = exportVariable;
/** /**
@ -771,7 +743,7 @@ exports.setSecret = setSecret;
function addPath(inputPath) { function addPath(inputPath) {
const filePath = process.env['GITHUB_PATH'] || ''; const filePath = process.env['GITHUB_PATH'] || '';
if (filePath) { if (filePath) {
file_command_1.issueCommand('PATH', inputPath); file_command_1.issueFileCommand('PATH', inputPath);
} }
else { else {
command_1.issueCommand('add-path', {}, inputPath); command_1.issueCommand('add-path', {}, inputPath);
@ -811,7 +783,10 @@ function getMultilineInput(name, options) {
const inputs = getInput(name, options) const inputs = getInput(name, options)
.split('\n') .split('\n')
.filter(x => x !== ''); .filter(x => x !== '');
if (options && options.trimWhitespace === false) {
return inputs; return inputs;
}
return inputs.map(input => input.trim());
} }
exports.getMultilineInput = getMultilineInput; exports.getMultilineInput = getMultilineInput;
/** /**
@ -844,8 +819,12 @@ exports.getBooleanInput = getBooleanInput;
*/ */
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
function setOutput(name, value) { function setOutput(name, value) {
const filePath = process.env['GITHUB_OUTPUT'] || '';
if (filePath) {
return file_command_1.issueFileCommand('OUTPUT', file_command_1.prepareKeyValueMessage(name, value));
}
process.stdout.write(os.EOL); process.stdout.write(os.EOL);
command_1.issueCommand('set-output', { name }, value); command_1.issueCommand('set-output', { name }, utils_1.toCommandValue(value));
} }
exports.setOutput = setOutput; exports.setOutput = setOutput;
/** /**
@ -974,7 +953,11 @@ exports.group = group;
*/ */
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
function saveState(name, value) { function saveState(name, value) {
command_1.issueCommand('save-state', { name }, value); const filePath = process.env['GITHUB_STATE'] || '';
if (filePath) {
return file_command_1.issueFileCommand('STATE', file_command_1.prepareKeyValueMessage(name, value));
}
command_1.issueCommand('save-state', { name }, utils_1.toCommandValue(value));
} }
exports.saveState = saveState; exports.saveState = saveState;
/** /**
@ -1040,13 +1023,14 @@ var __importStar = (this && this.__importStar) || function (mod) {
return result; return result;
}; };
Object.defineProperty(exports, "__esModule", ({ value: true })); Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.issueCommand = void 0; exports.prepareKeyValueMessage = exports.issueFileCommand = void 0;
// We use any as a valid input type // We use any as a valid input type
/* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/no-explicit-any */
const fs = __importStar(__nccwpck_require__(7147)); const fs = __importStar(__nccwpck_require__(7147));
const os = __importStar(__nccwpck_require__(2037)); const os = __importStar(__nccwpck_require__(2037));
const uuid_1 = __nccwpck_require__(5840);
const utils_1 = __nccwpck_require__(5278); const utils_1 = __nccwpck_require__(5278);
function issueCommand(command, message) { function issueFileCommand(command, message) {
const filePath = process.env[`GITHUB_${command}`]; const filePath = process.env[`GITHUB_${command}`];
if (!filePath) { if (!filePath) {
throw new Error(`Unable to find environment variable for file command ${command}`); throw new Error(`Unable to find environment variable for file command ${command}`);
@ -1058,7 +1042,22 @@ function issueCommand(command, message) {
encoding: 'utf8' encoding: 'utf8'
}); });
} }
exports.issueCommand = issueCommand; exports.issueFileCommand = issueFileCommand;
function prepareKeyValueMessage(key, value) {
const delimiter = `ghadelimiter_${uuid_1.v4()}`;
const convertedValue = utils_1.toCommandValue(value);
// These should realistically never happen, but just in case someone finds a
// way to exploit uuid generation let's not allow keys or values that contain
// the delimiter.
if (key.includes(delimiter)) {
throw new Error(`Unexpected input: name should not contain the delimiter "${delimiter}"`);
}
if (convertedValue.includes(delimiter)) {
throw new Error(`Unexpected input: value should not contain the delimiter "${delimiter}"`);
}
return `${key}<<${delimiter}${os.EOL}${convertedValue}${os.EOL}${delimiter}`;
}
exports.prepareKeyValueMessage = prepareKeyValueMessage;
//# sourceMappingURL=file-command.js.map //# sourceMappingURL=file-command.js.map
/***/ }), /***/ }),

51
package-lock.json generated
View File

@ -1,15 +1,15 @@
{ {
"name": "setup-dotnet", "name": "setup-dotnet",
"version": "3.0.0", "version": "3.0.2",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "setup-dotnet", "name": "setup-dotnet",
"version": "3.0.0", "version": "3.0.2",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@actions/core": "^1.9.1", "@actions/core": "^1.10.0",
"@actions/exec": "^1.0.4", "@actions/exec": "^1.0.4",
"@actions/github": "^1.1.0", "@actions/github": "^1.1.0",
"@actions/http-client": "^2.0.1", "@actions/http-client": "^2.0.1",
@ -25,16 +25,16 @@
"husky": "^8.0.1", "husky": "^8.0.1",
"jest": "^27.2.5", "jest": "^27.2.5",
"jest-circus": "^27.2.5", "jest-circus": "^27.2.5",
"prettier": "^1.19.1", "prettier": "^2.7.1",
"ts-jest": "^27.0.5", "ts-jest": "^27.0.5",
"typescript": "^3.9.7", "typescript": "^4.8.4",
"wget-improved": "^3.2.1" "wget-improved": "^3.2.1"
} }
}, },
"node_modules/@actions/core": { "node_modules/@actions/core": {
"version": "1.9.1", "version": "1.10.0",
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.9.1.tgz", "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.10.0.tgz",
"integrity": "sha512-5ad+U2YGrmmiw6du20AQW5XuWo7UKN2052FjSV7MX+Wfjf8sCqcsZe62NfgHys4QI4/Y+vQvLKYL8jWtA1ZBTA==", "integrity": "sha512-2aZDDa3zrrZbP5ZYg159sNoLRb61nQ7awl5pSvIq5Qpj81vwDzdMRKzkWJGJuwVvWpvZKx7vspJALyvaaIQyug==",
"dependencies": { "dependencies": {
"@actions/http-client": "^2.0.1", "@actions/http-client": "^2.0.1",
"uuid": "^8.3.2" "uuid": "^8.3.2"
@ -3884,15 +3884,18 @@
} }
}, },
"node_modules/prettier": { "node_modules/prettier": {
"version": "1.19.1", "version": "2.7.1",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz",
"integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==",
"dev": true, "dev": true,
"bin": { "bin": {
"prettier": "bin-prettier.js" "prettier": "bin-prettier.js"
}, },
"engines": { "engines": {
"node": ">=4" "node": ">=10.13.0"
},
"funding": {
"url": "https://github.com/prettier/prettier?sponsor=1"
} }
}, },
"node_modules/pretty-format": { "node_modules/pretty-format": {
@ -4436,9 +4439,9 @@
} }
}, },
"node_modules/typescript": { "node_modules/typescript": {
"version": "3.9.7", "version": "4.8.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.7.tgz", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz",
"integrity": "sha512-BLbiRkiBzAwsjut4x/dsibSTB6yWpwT5qWmC2OfuCg3GgVQCSgMs4vEctYPhsaGtd0AeuuHMkjZ2h2WG8MSzRw==", "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==",
"dev": true, "dev": true,
"bin": { "bin": {
"tsc": "bin/tsc", "tsc": "bin/tsc",
@ -4723,9 +4726,9 @@
}, },
"dependencies": { "dependencies": {
"@actions/core": { "@actions/core": {
"version": "1.9.1", "version": "1.10.0",
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.9.1.tgz", "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.10.0.tgz",
"integrity": "sha512-5ad+U2YGrmmiw6du20AQW5XuWo7UKN2052FjSV7MX+Wfjf8sCqcsZe62NfgHys4QI4/Y+vQvLKYL8jWtA1ZBTA==", "integrity": "sha512-2aZDDa3zrrZbP5ZYg159sNoLRb61nQ7awl5pSvIq5Qpj81vwDzdMRKzkWJGJuwVvWpvZKx7vspJALyvaaIQyug==",
"requires": { "requires": {
"@actions/http-client": "^2.0.1", "@actions/http-client": "^2.0.1",
"uuid": "^8.3.2" "uuid": "^8.3.2"
@ -7724,9 +7727,9 @@
"dev": true "dev": true
}, },
"prettier": { "prettier": {
"version": "1.19.1", "version": "2.7.1",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz",
"integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==",
"dev": true "dev": true
}, },
"pretty-format": { "pretty-format": {
@ -8129,9 +8132,9 @@
} }
}, },
"typescript": { "typescript": {
"version": "3.9.7", "version": "4.8.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.7.tgz", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz",
"integrity": "sha512-BLbiRkiBzAwsjut4x/dsibSTB6yWpwT5qWmC2OfuCg3GgVQCSgMs4vEctYPhsaGtd0AeuuHMkjZ2h2WG8MSzRw==", "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==",
"dev": true "dev": true
}, },
"universal-user-agent": { "universal-user-agent": {

View File

@ -1,6 +1,6 @@
{ {
"name": "setup-dotnet", "name": "setup-dotnet",
"version": "3.0.0", "version": "3.0.2",
"private": true, "private": true,
"description": "setup dotnet action", "description": "setup dotnet action",
"main": "lib/setup-dotnet.js", "main": "lib/setup-dotnet.js",
@ -24,7 +24,7 @@
"author": "GitHub", "author": "GitHub",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@actions/core": "^1.9.1", "@actions/core": "^1.10.0",
"@actions/exec": "^1.0.4", "@actions/exec": "^1.0.4",
"@actions/github": "^1.1.0", "@actions/github": "^1.1.0",
"@actions/http-client": "^2.0.1", "@actions/http-client": "^2.0.1",
@ -40,9 +40,9 @@
"husky": "^8.0.1", "husky": "^8.0.1",
"jest": "^27.2.5", "jest": "^27.2.5",
"jest-circus": "^27.2.5", "jest-circus": "^27.2.5",
"prettier": "^1.19.1", "prettier": "^2.7.1",
"ts-jest": "^27.0.5", "ts-jest": "^27.0.5",
"typescript": "^3.9.7", "typescript": "^4.8.4",
"wget-improved": "^3.2.1" "wget-improved": "^3.2.1"
}, },
"jest": { "jest": {

View File

@ -6,8 +6,9 @@ import * as hc from '@actions/http-client';
import {chmodSync} from 'fs'; import {chmodSync} from 'fs';
import {readdir} from 'fs/promises'; import {readdir} from 'fs/promises';
import path from 'path'; import path from 'path';
import os from 'os';
import semver from 'semver'; import semver from 'semver';
import {IS_LINUX, IS_WINDOWS, IS_MAC} from './utils'; import {IS_LINUX, IS_WINDOWS} from './utils';
import {QualityOptions} from './setup-dotnet'; import {QualityOptions} from './setup-dotnet';
export interface DotnetVersion { export interface DotnetVersion {
@ -112,40 +113,29 @@ export class DotnetVersionResolver {
export class DotnetCoreInstaller { export class DotnetCoreInstaller {
private version: string; private version: string;
private quality: QualityOptions; private quality: QualityOptions;
private static readonly installationDirectoryWindows = path.join(
static {
const installationDirectoryWindows = path.join(
process.env['PROGRAMFILES'] + '', process.env['PROGRAMFILES'] + '',
'dotnet' 'dotnet'
); );
private static readonly installationDirectoryLinux = '/usr/share/dotnet'; const installationDirectoryLinux = '/usr/share/dotnet';
private static readonly installationDirectoryMac = path.join( const installationDirectoryMac = path.join(
process.env['HOME'] + '', process.env['HOME'] + '',
'.dotnet' '.dotnet'
); );
const dotnetInstallDir: string | undefined =
static addToPath() { process.env['DOTNET_INSTALL_DIR'];
if (process.env['DOTNET_INSTALL_DIR']) { if (dotnetInstallDir) {
core.addPath(process.env['DOTNET_INSTALL_DIR']); process.env['DOTNET_INSTALL_DIR'] =
core.exportVariable('DOTNET_ROOT', process.env['DOTNET_INSTALL_DIR']); this.convertInstallPathToAbsolute(dotnetInstallDir);
} else { } else {
if (IS_WINDOWS) { if (IS_WINDOWS) {
core.addPath(DotnetCoreInstaller.installationDirectoryWindows); process.env['DOTNET_INSTALL_DIR'] = installationDirectoryWindows;
core.exportVariable(
'DOTNET_ROOT',
DotnetCoreInstaller.installationDirectoryWindows
);
} else if (IS_LINUX) {
core.addPath(DotnetCoreInstaller.installationDirectoryLinux);
core.exportVariable(
'DOTNET_ROOT',
DotnetCoreInstaller.installationDirectoryLinux
);
} else { } else {
// This is the default set in install-dotnet.sh process.env['DOTNET_INSTALL_DIR'] = IS_LINUX
core.addPath(DotnetCoreInstaller.installationDirectoryMac); ? installationDirectoryLinux
core.exportVariable( : installationDirectoryMac;
'DOTNET_ROOT',
DotnetCoreInstaller.installationDirectoryMac
);
} }
} }
} }
@ -155,6 +145,23 @@ export class DotnetCoreInstaller {
this.quality = quality; this.quality = quality;
} }
private static convertInstallPathToAbsolute(installDir: string): string {
let transformedPath;
if (path.isAbsolute(installDir)) {
transformedPath = installDir;
} else {
transformedPath = installDir.startsWith('~')
? path.join(os.homedir(), installDir.slice(1))
: (transformedPath = path.join(process.cwd(), installDir));
}
return path.normalize(transformedPath);
}
static addToPath() {
core.addPath(process.env['DOTNET_INSTALL_DIR']!);
core.exportVariable('DOTNET_ROOT', process.env['DOTNET_INSTALL_DIR']);
}
private setQuality( private setQuality(
dotnetVersion: DotnetVersion, dotnetVersion: DotnetVersion,
scriptArguments: string[] scriptArguments: string[]
@ -208,11 +215,6 @@ export class DotnetCoreInstaller {
scriptArguments.push(`-ProxyBypassList ${process.env['no_proxy']}`); scriptArguments.push(`-ProxyBypassList ${process.env['no_proxy']}`);
} }
scriptArguments.push(
'-InstallDir',
`'${DotnetCoreInstaller.installationDirectoryWindows}'`
);
// process.env must be explicitly passed in for DOTNET_INSTALL_DIR to be used
scriptPath = scriptPath =
(await io.which('pwsh', false)) || (await io.which('powershell', true)); (await io.which('pwsh', false)) || (await io.which('powershell', true));
scriptArguments = windowsDefaultOptions.concat(scriptArguments); scriptArguments = windowsDefaultOptions.concat(scriptArguments);
@ -228,40 +230,26 @@ export class DotnetCoreInstaller {
if (this.quality) { if (this.quality) {
this.setQuality(dotnetVersion, scriptArguments); this.setQuality(dotnetVersion, scriptArguments);
} }
if (IS_LINUX) {
scriptArguments.push(
'--install-dir',
DotnetCoreInstaller.installationDirectoryLinux
);
}
if (IS_MAC) {
scriptArguments.push(
'--install-dir',
DotnetCoreInstaller.installationDirectoryMac
);
}
} }
// process.env must be explicitly passed in for DOTNET_INSTALL_DIR to be used
const getExecOutputOptions = {
ignoreReturnCode: true,
env: process.env as {string: string}
};
const {exitCode, stdout} = await exec.getExecOutput( const {exitCode, stdout} = await exec.getExecOutput(
`"${scriptPath}"`, `"${scriptPath}"`,
scriptArguments, scriptArguments,
{ignoreReturnCode: true} getExecOutputOptions
); );
if (exitCode) { if (exitCode) {
throw new Error(`Failed to install dotnet ${exitCode}. ${stdout}`); throw new Error(`Failed to install dotnet ${exitCode}. ${stdout}`);
} }
return this.outputDotnetVersion( return this.outputDotnetVersion(dotnetVersion.value);
dotnetVersion.value,
scriptArguments[scriptArguments.length - 1]
);
} }
private async outputDotnetVersion( private async outputDotnetVersion(version): Promise<string> {
version, const installationPath = process.env['DOTNET_INSTALL_DIR']!;
installationPath
): Promise<string> {
let versionsOnRunner: string[] = await readdir( let versionsOnRunner: string[] = await readdir(
path.join(installationPath.replace(/'/g, ''), 'sdk') path.join(installationPath.replace(/'/g, ''), 'sdk')
); );

View File

@ -1,3 +1,2 @@
export const IS_WINDOWS = process.platform === 'win32'; export const IS_WINDOWS = process.platform === 'win32';
export const IS_LINUX = process.platform === 'linux'; export const IS_LINUX = process.platform === 'linux';
export const IS_MAC = process.platform === 'darwin';

View File

@ -35,6 +35,7 @@
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
/* Additional Checks */ /* Additional Checks */
"useUnknownInCatchVariables": false, /* Type catch clause variables as 'unknown' instead of 'any'. */
// "noUnusedLocals": true, /* Report errors on unused locals. */ // "noUnusedLocals": true, /* Report errors on unused locals. */
// "noUnusedParameters": true, /* Report errors on unused parameters. */ // "noUnusedParameters": true, /* Report errors on unused parameters. */
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */