diff --git a/README.md b/README.md index d9f440b..cbd7f07 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ You know how handy that 'Visual Studio Developer Command Prompt' is on your loca ```yml - name: Add msbuild to PATH - uses: microsoft/setup-msbuild@v1.0.2 + uses: microsoft/setup-msbuild@v1.0.3 ``` ## Specifying specific versions of Visual Studio @@ -15,7 +15,7 @@ You may have a situation where your Actions runner has multiple versions of Visu ```yml - name: Add msbuild to PATH - uses: microsoft/setup-msbuild@v1.0.2 + uses: microsoft/setup-msbuild@v1.0.3 with: vs-version: '[16.4,16.5)' ``` @@ -27,7 +27,7 @@ This makes use of the vswhere tool which is a tool delivered by Microsoft to hel ```yml - name: Add msbuild to PATH - uses: microsoft/setup-msbuild@v1.0.2 + uses: microsoft/setup-msbuild@v1.0.3 with: vswhere-path: 'C:\path\to\your\tools\' ``` diff --git a/action.yml b/action.yml index c47c883..e7e3c2c 100644 --- a/action.yml +++ b/action.yml @@ -11,6 +11,9 @@ inputs: vs-version: description: 'Version of Visual Studio to search; defaults to latest if not specified' required: false + vs-prerelease: + description: 'Enable searching for pre-release versions of Visual Studio/MSBuild' + required: false outputs: msbuildPath: description: 'The resulting location of msbuild for your inputs' diff --git a/dist/index.js b/dist/index.js index f9150ed..beb5699 100644 --- a/dist/index.js +++ b/dist/index.js @@ -934,6 +934,32 @@ class ExecState extends events.EventEmitter { /***/ }), +/***/ 82: +/***/ (function(__unusedmodule, exports) { + +"use strict"; + +// We use any as a valid input type +/* eslint-disable @typescript-eslint/no-explicit-any */ +Object.defineProperty(exports, "__esModule", { value: true }); +/** + * Sanitizes an input into a string so it can be passed into issueCommand safely + * @param input input to sanitize into a string + */ +function toCommandValue(input) { + if (input === null || input === undefined) { + return ''; + } + else if (typeof input === 'string' || input instanceof String) { + return input; + } + return JSON.stringify(input); +} +exports.toCommandValue = toCommandValue; +//# sourceMappingURL=utils.js.map + +/***/ }), + /***/ 87: /***/ (function(module) { @@ -941,6 +967,42 @@ module.exports = require("os"); /***/ }), +/***/ 102: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +// For internal use, subject to change. +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result["default"] = mod; + return result; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +// We use any as a valid input type +/* eslint-disable @typescript-eslint/no-explicit-any */ +const fs = __importStar(__webpack_require__(747)); +const os = __importStar(__webpack_require__(87)); +const utils_1 = __webpack_require__(82); +function issueCommand(command, message) { + const filePath = process.env[`GITHUB_${command}`]; + if (!filePath) { + throw new Error(`Unable to find environment variable for file command ${command}`); + } + if (!fs.existsSync(filePath)) { + throw new Error(`Missing file at path: ${filePath}`); + } + fs.appendFileSync(filePath, `${utils_1.toCommandValue(message)}${os.EOL}`, { + encoding: 'utf8' + }); +} +exports.issueCommand = issueCommand; +//# sourceMappingURL=file-command.js.map + +/***/ }), + /***/ 129: /***/ (function(module) { @@ -978,8 +1040,12 @@ const io = __importStar(__webpack_require__(1)); const IS_WINDOWS = process.platform === 'win32'; const VS_VERSION = core.getInput('vs-version') || 'latest'; const VSWHERE_PATH = core.getInput('vswhere-path'); +const ALLOW_PRERELEASE = core.getInput('vs-prerelease') || 'false'; // if a specific version of VS is requested let VSWHERE_EXEC = '-products * -requires Microsoft.Component.MSBuild -property installationPath -latest '; +if (ALLOW_PRERELEASE === 'true') { + VSWHERE_EXEC += ' -prerelease '; +} if (VS_VERSION !== 'latest') { VSWHERE_EXEC += `-version "${VS_VERSION}" `; } @@ -1071,17 +1137,25 @@ module.exports = require("assert"); "use strict"; +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result["default"] = mod; + return result; +}; Object.defineProperty(exports, "__esModule", { value: true }); -const os = __webpack_require__(87); +const os = __importStar(__webpack_require__(87)); +const utils_1 = __webpack_require__(82); /** * Commands * * Command Format: - * ##[name key=value;key=value]message + * ::name key=value,key=value::message * * Examples: - * ##[warning]This is the user warning message - * ##[set-secret name=mypassword]definitelyNotAPassword! + * ::warning::This is the message + * ::set-env name=MY_VAR::some value */ function issueCommand(command, properties, message) { const cmd = new Command(command, properties, message); @@ -1106,34 +1180,39 @@ class Command { let cmdStr = CMD_STRING + this.command; if (this.properties && Object.keys(this.properties).length > 0) { cmdStr += ' '; + let first = true; for (const key in this.properties) { if (this.properties.hasOwnProperty(key)) { const val = this.properties[key]; if (val) { - // safely append the val - avoid blowing up when attempting to - // call .replace() if message is not a string for some reason - cmdStr += `${key}=${escape(`${val || ''}`)},`; + if (first) { + first = false; + } + else { + cmdStr += ','; + } + cmdStr += `${key}=${escapeProperty(val)}`; } } } } - cmdStr += CMD_STRING; - // safely append the message - avoid blowing up when attempting to - // call .replace() if message is not a string for some reason - const message = `${this.message || ''}`; - cmdStr += escapeData(message); + cmdStr += `${CMD_STRING}${escapeData(this.message)}`; return cmdStr; } } function escapeData(s) { - return s.replace(/\r/g, '%0D').replace(/\n/g, '%0A'); + return utils_1.toCommandValue(s) + .replace(/%/g, '%25') + .replace(/\r/g, '%0D') + .replace(/\n/g, '%0A'); } -function escape(s) { - return s +function escapeProperty(s) { + return utils_1.toCommandValue(s) + .replace(/%/g, '%25') .replace(/\r/g, '%0D') .replace(/\n/g, '%0A') - .replace(/]/g, '%5D') - .replace(/;/g, '%3B'); + .replace(/:/g, '%3A') + .replace(/,/g, '%2C'); } //# sourceMappingURL=command.js.map @@ -1153,10 +1232,19 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result["default"] = mod; + return result; +}; Object.defineProperty(exports, "__esModule", { value: true }); const command_1 = __webpack_require__(431); -const os = __webpack_require__(87); -const path = __webpack_require__(622); +const file_command_1 = __webpack_require__(102); +const utils_1 = __webpack_require__(82); +const os = __importStar(__webpack_require__(87)); +const path = __importStar(__webpack_require__(622)); /** * The code to exit an action */ @@ -1177,11 +1265,21 @@ var ExitCode; /** * Sets env variable for this action and future actions in the job * @param name the name of the variable to set - * @param val the value of the variable + * @param val the value of the variable. Non-string values will be converted to a string via JSON.stringify */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any function exportVariable(name, val) { - process.env[name] = val; - command_1.issueCommand('set-env', { name }, val); + const convertedVal = utils_1.toCommandValue(val); + process.env[name] = convertedVal; + const filePath = process.env['GITHUB_ENV'] || ''; + if (filePath) { + const delimiter = '_GitHubActionsFileCommandDelimeter_'; + const commandValue = `${name}<<${delimiter}${os.EOL}${convertedVal}${os.EOL}${delimiter}`; + file_command_1.issueCommand('ENV', commandValue); + } + else { + command_1.issueCommand('set-env', { name }, convertedVal); + } } exports.exportVariable = exportVariable; /** @@ -1197,7 +1295,13 @@ exports.setSecret = setSecret; * @param inputPath */ function addPath(inputPath) { - command_1.issueCommand('add-path', {}, inputPath); + const filePath = process.env['GITHUB_PATH'] || ''; + if (filePath) { + file_command_1.issueCommand('PATH', inputPath); + } + else { + command_1.issueCommand('add-path', {}, inputPath); + } process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`; } exports.addPath = addPath; @@ -1220,12 +1324,22 @@ exports.getInput = getInput; * Sets the value of an output. * * @param name name of the output to set - * @param value value to store + * @param value value to store. Non-string values will be converted to a string via JSON.stringify */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any function setOutput(name, value) { command_1.issueCommand('set-output', { name }, value); } exports.setOutput = setOutput; +/** + * Enables or disables the echoing of commands into stdout for the rest of the step. + * Echoing is disabled by default if ACTIONS_STEP_DEBUG is not set. + * + */ +function setCommandEcho(enabled) { + command_1.issue('echo', enabled ? 'on' : 'off'); +} +exports.setCommandEcho = setCommandEcho; //----------------------------------------------------------------------- // Results //----------------------------------------------------------------------- @@ -1242,6 +1356,13 @@ exports.setFailed = setFailed; //----------------------------------------------------------------------- // Logging Commands //----------------------------------------------------------------------- +/** + * Gets whether Actions Step Debug is on or not + */ +function isDebug() { + return process.env['RUNNER_DEBUG'] === '1'; +} +exports.isDebug = isDebug; /** * Writes debug message to user log * @param message debug message @@ -1252,18 +1373,18 @@ function debug(message) { exports.debug = debug; /** * Adds an error issue - * @param message error issue message + * @param message error issue message. Errors will be converted to string via toString() */ function error(message) { - command_1.issue('error', message); + command_1.issue('error', message instanceof Error ? message.toString() : message); } exports.error = error; /** * Adds an warning issue - * @param message warning issue message + * @param message warning issue message. Errors will be converted to string via toString() */ function warning(message) { - command_1.issue('warning', message); + command_1.issue('warning', message instanceof Error ? message.toString() : message); } exports.warning = warning; /** @@ -1321,8 +1442,9 @@ exports.group = group; * Saves state for current action, the state can only be retrieved by this action's post job execution. * * @param name name of the state to store - * @param value value to store + * @param value value to store. Non-string values will be converted to a string via JSON.stringify */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any function saveState(name, value) { command_1.issueCommand('save-state', { name }, value); } diff --git a/package.json b/package.json index df463af..86a4f0b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "setup-msbuild", - "version": "1.0.1", + "version": "1.0.3", "private": true, "description": "Helps set up specific MSBuild tool into PATH for later usage.", "main": "lib/main.js", diff --git a/src/main.ts b/src/main.ts index 05035ca..6512bda 100644 --- a/src/main.ts +++ b/src/main.ts @@ -8,9 +8,14 @@ import {ExecOptions} from '@actions/exec/lib/interfaces' const IS_WINDOWS = process.platform === 'win32' const VS_VERSION = core.getInput('vs-version') || 'latest' const VSWHERE_PATH = core.getInput('vswhere-path') +const ALLOW_PRERELEASE = core.getInput('vs-prerelease') || 'false' // if a specific version of VS is requested let VSWHERE_EXEC = '-products * -requires Microsoft.Component.MSBuild -property installationPath -latest ' +if (ALLOW_PRERELEASE === 'true') { + VSWHERE_EXEC += ' -prerelease ' + } + if (VS_VERSION !== 'latest') { VSWHERE_EXEC += `-version "${VS_VERSION}" ` }