Compare commits

..

1 Commits

Author SHA1 Message Date
fc16ae6170 prod dependencies 2020-02-20 17:02:07 -08:00
30 changed files with 170 additions and 510 deletions

View File

@ -1,10 +1,5 @@
name: "build-test-dev" name: "build-test-dev"
on: on:
pull_request:
branches:
- dev
paths-ignore:
- '*.md'
push: push:
branches: branches:
- dev - dev
@ -17,27 +12,14 @@ jobs:
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: Setup MSBuild (vswhere-path) - name: Setup MSBuild
id: setup_msbuild_explicit id: setup_msbuild
uses: ./ uses: ./
with: with:
vswhere-path: C:\ProgramData\chocolatey\bin vs-version: "[16.4,16.5]"
- name: Setup MSBuild (PATH)
id: setup_msbuild_path
uses: ./
- name: Setup MSBuild (fallback)
id: setup_msbuild_fallback
uses: ./
env:
PATH: ''
- name: echo msbuild path - name: echo msbuild path
run: | run: echo "${{ steps.setup_msbuild.outputs.msbuildPath }}"
echo "vswhere-path: ${{ steps.setup_msbuild_explicit.outputs.msbuildPath }}"
echo "PATH: ${{ steps.setup_msbuild_path.outputs.msbuildPath }}"
echo "Fallback: ${{ steps.setup_msbuild_fallback.outputs.msbuildPath }}"
- name: echo MSBuild - name: echo MSBuild
run: msbuild -version run: msbuild -version

2
.gitignore vendored
View File

@ -1,5 +1,5 @@
# Dependency directory # Dependency directory
#node_modules # node_modules
# Rest pulled from https://github.com/github/gitignore/blob/master/Node.gitignore # Rest pulled from https://github.com/github/gitignore/blob/master/Node.gitignore
# Logs # Logs

View File

@ -3,40 +3,35 @@ You know how handy that 'Visual Studio Developer Command Prompt' is on your loca
## Usage ## Usage
```yml ```
- name: Add msbuild to PATH - name: Add msbuild to PATH
uses: microsoft/setup-msbuild@v1.0.1 uses: microsoft/setup-msbuild@v1.0.0
``` ```
## Specifying specific versions of Visual Studio ## Specifying specific versions of Visual Studio
You may have a situation where your Actions runner has multiple versions of Visual Studio and you need to find a specific version of the tool. Simply add the `vs-version` input to specify the range of versions to find. If looking for a specific version, specify the minimum and maximum versions as shown in the example below, which will look for just 16.4. You may have a situation where your Actions runner has multiple versions of Visual Studio and you need to find a specific version of the tool. Simply add the `vs-version` input to specify the range of versions to find. If looking for a specific version, enter that version number twice as a range.
```yml
- name: Add msbuild to PATH
uses: microsoft/setup-msbuild@v1.0.1
with:
vs-version: '[16.4,16.5)'
``` ```
- name: Add msbuild to PATH
The syntax is the same used for Visual Studio extensions, where square brackets like "[" mean inclusive, and parenthesis like "(" mean exclusive. A comma is always required, but eliding the minimum version looks for all older versions and eliding the maximum version looks for all newer versions. See the [vswhere wiki](https://github.com/microsoft/vswhere/wiki) for more details. uses: microsoft/setup-msbuild@v1.0.0
with:
vs-version: [16.4,16.5]
```
## How does this work? ## How does this work?
This makes use of the vswhere tool which is a tool is delivered by Microsoft to help in identifying Visual Studio installs and various components. This tool is installed on the hosted Windows runners for GitHub Actions. If you are using a self-hosted runner, you either need to make sure vswhere.exe is in your agent's PATH or specify a full path to the location using: This makes use of the vswhere tool which is a tool is delivered by Microsoft to help in identifying Visual Studio installs and various components. This tool is installed on the hosted Windows runners for GitHub Actions. If you are using a self-hosted runner, you either need to make sure vswhere.exe is in your agent's PATH or specify a full path to the location using:
```yml ```
- name: Add msbuild to PATH - name: Add msbuild to PATH
uses: microsoft/setup-msbuild@v1.0.1 uses: microsoft/setup-msbuild@v1.0.0
with: with:
vswhere-path: 'C:\path\to\your\tools\' vswhere-path: 'C:\path\to\your\tools\'
``` ```
## Notes on arguments
While the Action enables you to specify a `vswhere` path as well as a `vs-version`, these are more advanced options and when using GitHub-hosted runners you should not need these and is recommended you don't specify them. Using these require you to fully understand the runner environment, updates to the tools on the runner, and can cause failures if you are out of sync. For GitHub-hosted runners, omitting these arguments is the preferred usage.
## Building this repo ## Building this repo
As with most GitHub Actions, this requires NodeJS development tools. After installing NodeJS, you can build this by executing: As with most GitHub Actions, this requires NodeJS development tools. After installing NodeJS, you can build this by executing:
```bash ```
npm install npm install
npm run build npm run build
npm run pack npm run pack

44
dist/index.js vendored
View File

@ -972,17 +972,22 @@ var __importStar = (this && this.__importStar) || function (mod) {
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
const core = __importStar(__webpack_require__(470)); const core = __importStar(__webpack_require__(470));
const exec = __importStar(__webpack_require__(986)); const exec = __importStar(__webpack_require__(986));
const fs = __importStar(__webpack_require__(747));
const path = __importStar(__webpack_require__(622)); const path = __importStar(__webpack_require__(622));
const io = __importStar(__webpack_require__(1)); const io = __importStar(__webpack_require__(1));
const IS_WINDOWS = process.platform === 'win32'; const IS_WINDOWS = process.platform === 'win32';
const VS_VERSION = core.getInput('vs-version') || 'latest'; const VS_VERSION = core.getInput('vs-version') || 'latest';
const VSWHERE_PATH = core.getInput('vswhere-path'); const VSWHERE_PATH = core.getInput('vswhere-path') ||
path.join(process.env['ProgramFiles(x86)'], 'Microsoft Visual Studio\\Installer');
// if a specific version of VS is requested // if a specific version of VS is requested
let VSWHERE_EXEC = '-products * -requires Microsoft.Component.MSBuild -property installationPath -latest '; let VSWHERE_EXEC = '';
if (VS_VERSION !== 'latest') { if (VS_VERSION === 'latest') {
VSWHERE_EXEC += `-version "${VS_VERSION}" `; VSWHERE_EXEC += '-latest ';
} }
else {
VSWHERE_EXEC += `-version ${VS_VERSION} `;
}
VSWHERE_EXEC +=
'-requires Microsoft.Component.MSBuild -find MSBuild\\**\\Bin\\MSBuild.exe';
core.debug(`Execution arguments: ${VSWHERE_EXEC}`); core.debug(`Execution arguments: ${VSWHERE_EXEC}`);
function run() { function run() {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
@ -996,7 +1001,6 @@ function run() {
let vswhereToolExe = ''; let vswhereToolExe = '';
if (VSWHERE_PATH) { if (VSWHERE_PATH) {
// specified a path for vswhere, use it // specified a path for vswhere, use it
core.debug(`Using given vswhere-path: ${VSWHERE_PATH}`);
vswhereToolExe = path.join(VSWHERE_PATH, 'vswhere.exe'); vswhereToolExe = path.join(VSWHERE_PATH, 'vswhere.exe');
} }
else { else {
@ -1004,41 +1008,29 @@ function run() {
try { try {
const vsWhereInPath = yield io.which('vswhere', true); const vsWhereInPath = yield io.which('vswhere', true);
core.debug(`Found tool in PATH: ${vsWhereInPath}`); core.debug(`Found tool in PATH: ${vsWhereInPath}`);
vswhereToolExe = vsWhereInPath; vswhereToolExe = path.join(vsWhereInPath, 'vswhere.exe');
} }
catch (_a) { catch (_a) {
// fall back to VS-installed path // wasn't found because which threw
vswhereToolExe = path.join(process.env['ProgramFiles(x86)'], 'Microsoft Visual Studio\\Installer\\vswhere.exe');
core.debug(`Trying Visual Studio-installed path: ${vswhereToolExe}`);
} }
} finally {
if (!fs.existsSync(vswhereToolExe)) {
core.setFailed('setup-msbuild requires the path to where vswhere.exe exists'); core.setFailed('setup-msbuild requires the path to where vswhere.exe exists');
return; }
} }
core.debug(`Full tool exe: ${vswhereToolExe}`); core.debug(`Full tool exe: ${vswhereToolExe}`);
let foundToolPath = ''; let foundToolPath = '';
const options = {}; const options = {};
options.listeners = { options.listeners = {
stdout: (data) => { stdout: (data) => {
const installationPath = data.toString().trim(); // eslint-disable-next-line prefer-const
core.debug(`Found installation path: ${installationPath}`); let output = data.toString();
let toolPath = path.join(installationPath, 'MSBuild\\Current\\Bin\\MSBuild.exe'); foundToolPath += output;
core.debug(`Checking for path: ${toolPath}`);
if (!fs.existsSync(toolPath)) {
toolPath = path.join(installationPath, 'MSBuild\\15.0\\Bin\\MSBuild.exe');
core.debug(`Checking for path: ${toolPath}`);
if (!fs.existsSync(toolPath)) {
return;
}
}
foundToolPath = toolPath;
} }
}; };
// execute the find putting the result of the command in the options foundToolPath // execute the find putting the result of the command in the options foundToolPath
yield exec.exec(`"${vswhereToolExe}" ${VSWHERE_EXEC}`, [], options); yield exec.exec(`"${vswhereToolExe}" ${VSWHERE_EXEC}`, [], options);
if (!foundToolPath) { if (!foundToolPath) {
core.setFailed('Unable to find MSBuild.'); core.setFailed('Unable to find msbuild.');
return; return;
} }
// extract the folder location for the tool // extract the folder location for the tool

2
node_modules/.bin/semver generated vendored
View File

@ -2,7 +2,7 @@
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in case `uname` in
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;; *CYGWIN*) basedir=`cygpath -w "$basedir"`;;
esac esac
if [ -x "$basedir/node" ]; then if [ -x "$basedir/node" ]; then

20
node_modules/.bin/semver.cmd generated vendored
View File

@ -1,17 +1,7 @@
@ECHO off @IF EXIST "%~dp0\node.exe" (
SETLOCAL "%~dp0\node.exe" "%~dp0\..\semver\bin\semver.js" %*
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE ( ) ELSE (
SET "_prog=node" @SETLOCAL
SET PATHEXT=%PATHEXT:;.JS;=;% @SET PATHEXT=%PATHEXT:;.JS;=;%
node "%~dp0\..\semver\bin\semver.js" %*
) )
"%_prog%" "%dp0%\..\semver\bin\semver.js" %*
ENDLOCAL
EXIT /b %errorlevel%
:find_dp0
SET dp0=%~dp0
EXIT /b

18
node_modules/.bin/semver.ps1 generated vendored
View File

@ -1,18 +0,0 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
& "$basedir/node$exe" "$basedir/../semver/bin/semver.js" $args
$ret=$LASTEXITCODE
} else {
& "node$exe" "$basedir/../semver/bin/semver.js" $args
$ret=$LASTEXITCODE
}
exit $ret

2
node_modules/.bin/uuid generated vendored
View File

@ -2,7 +2,7 @@
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in case `uname` in
*CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;; *CYGWIN*) basedir=`cygpath -w "$basedir"`;;
esac esac
if [ -x "$basedir/node" ]; then if [ -x "$basedir/node" ]; then

20
node_modules/.bin/uuid.cmd generated vendored
View File

@ -1,17 +1,7 @@
@ECHO off @IF EXIST "%~dp0\node.exe" (
SETLOCAL "%~dp0\node.exe" "%~dp0\..\uuid\bin\uuid" %*
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE ( ) ELSE (
SET "_prog=node" @SETLOCAL
SET PATHEXT=%PATHEXT:;.JS;=;% @SET PATHEXT=%PATHEXT:;.JS;=;%
node "%~dp0\..\uuid\bin\uuid" %*
) )
"%_prog%" "%dp0%\..\uuid\bin\uuid" %*
ENDLOCAL
EXIT /b %errorlevel%
:find_dp0
SET dp0=%~dp0
EXIT /b

18
node_modules/.bin/uuid.ps1 generated vendored
View File

@ -1,18 +0,0 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
& "$basedir/node$exe" "$basedir/../uuid/bin/uuid" $args
$ret=$LASTEXITCODE
} else {
& "node$exe" "$basedir/../uuid/bin/uuid" $args
$ret=$LASTEXITCODE
}
exit $ret

View File

@ -2,7 +2,7 @@
"_args": [ "_args": [
[ [
"@actions/core@1.2.0", "@actions/core@1.2.0",
"C:\\Users\\timheuer\\Documents\\GitHub\\setup-msbuild" "C:\\users\\timheuer\\documents\\github\\setup-msbuild"
] ]
], ],
"_from": "@actions/core@1.2.0", "_from": "@actions/core@1.2.0",
@ -28,7 +28,7 @@
], ],
"_resolved": "https://registry.npmjs.org/@actions/core/-/core-1.2.0.tgz", "_resolved": "https://registry.npmjs.org/@actions/core/-/core-1.2.0.tgz",
"_spec": "1.2.0", "_spec": "1.2.0",
"_where": "C:\\Users\\timheuer\\Documents\\GitHub\\setup-msbuild", "_where": "C:\\users\\timheuer\\documents\\github\\setup-msbuild",
"bugs": { "bugs": {
"url": "https://github.com/actions/toolkit/issues" "url": "https://github.com/actions/toolkit/issues"
}, },

View File

@ -2,7 +2,7 @@
"_args": [ "_args": [
[ [
"@actions/exec@1.0.3", "@actions/exec@1.0.3",
"C:\\Users\\timheuer\\Documents\\GitHub\\setup-msbuild" "C:\\users\\timheuer\\documents\\github\\setup-msbuild"
] ]
], ],
"_from": "@actions/exec@1.0.3", "_from": "@actions/exec@1.0.3",
@ -28,7 +28,7 @@
], ],
"_resolved": "https://registry.npmjs.org/@actions/exec/-/exec-1.0.3.tgz", "_resolved": "https://registry.npmjs.org/@actions/exec/-/exec-1.0.3.tgz",
"_spec": "1.0.3", "_spec": "1.0.3",
"_where": "C:\\Users\\timheuer\\Documents\\GitHub\\setup-msbuild", "_where": "C:\\users\\timheuer\\documents\\github\\setup-msbuild",
"bugs": { "bugs": {
"url": "https://github.com/actions/toolkit/issues" "url": "https://github.com/actions/toolkit/issues"
}, },

View File

@ -18,8 +18,6 @@ A lightweight HTTP client optimized for use with actions, TypeScript with generi
- Basic, Bearer and PAT Support out of the box. Extensible handlers for others. - Basic, Bearer and PAT Support out of the box. Extensible handlers for others.
- Redirects supported - Redirects supported
Features and releases [here](./RELEASES.md)
## Install ## Install
``` ```
@ -51,11 +49,7 @@ export NODE_DEBUG=http
## Node support ## Node support
The http-client is built using the latest LTS version of Node 12. It may work on previous node LTS versions but it's tested and officially supported on Node12+. The http-client is built using the latest LTS version of Node 12. We also support the latest LTS for Node 6, 8 and Node 10.
## Support and Versioning
We follow semver and will hold compatibility between major versions and increment the minor version with new features and capabilities (while holding compat).
## Contributing ## Contributing

View File

@ -1,16 +0,0 @@
## Releases
## 1.0.7
Update NPM dependencies and add 429 to the list of HttpCodes
## 1.0.6
Automatically sends Content-Type and Accept application/json headers for \<verb>Json() helper methods if not set in the client or parameters.
## 1.0.5
Adds \<verb>Json() helper methods for json over http scenarios.
## 1.0.4
Started to add \<verb>Json() helper methods. Do not use this release for that. Use >= 1.0.5 since there was an issue with types.
## 1.0.1 to 1.0.3
Adds proxy support.

View File

@ -6,9 +6,7 @@ class BasicCredentialHandler {
this.password = password; this.password = password;
} }
prepareRequest(options) { prepareRequest(options) {
options.headers['Authorization'] = options.headers['Authorization'] = 'Basic ' + Buffer.from(this.username + ':' + this.password).toString('base64');
'Basic ' +
Buffer.from(this.username + ':' + this.password).toString('base64');
} }
// This handler cannot handle 401 // This handler cannot handle 401
canHandleAuthentication(response) { canHandleAuthentication(response) {
@ -44,8 +42,7 @@ class PersonalAccessTokenCredentialHandler {
// currently implements pre-authorization // currently implements pre-authorization
// TODO: support preAuth = false where it hooks on 401 // TODO: support preAuth = false where it hooks on 401
prepareRequest(options) { prepareRequest(options) {
options.headers['Authorization'] = options.headers['Authorization'] = 'Basic ' + Buffer.from('PAT:' + this.token).toString('base64');
'Basic ' + Buffer.from('PAT:' + this.token).toString('base64');
} }
// This handler cannot handle 401 // This handler cannot handle 401
canHandleAuthentication(response) { canHandleAuthentication(response) {

View File

@ -1,5 +1,5 @@
/// <reference types="node" /> /// <reference types="node" />
import http = require('http'); import http = require("http");
import ifm = require('./interfaces'); import ifm = require('./interfaces');
export declare enum HttpCodes { export declare enum HttpCodes {
OK = 200, OK = 200,
@ -23,25 +23,12 @@ export declare enum HttpCodes {
RequestTimeout = 408, RequestTimeout = 408,
Conflict = 409, Conflict = 409,
Gone = 410, Gone = 410,
TooManyRequests = 429,
InternalServerError = 500, InternalServerError = 500,
NotImplemented = 501, NotImplemented = 501,
BadGateway = 502, BadGateway = 502,
ServiceUnavailable = 503, ServiceUnavailable = 503,
GatewayTimeout = 504 GatewayTimeout = 504
} }
export declare enum Headers {
Accept = "accept",
ContentType = "content-type"
}
export declare enum MediaTypes {
ApplicationJson = "application/json"
}
/**
* Returns the proxy URL, depending upon the supplied url and proxy environment variables.
* @param serverUrl The server URL where the request will be sent. For example, https://api.github.com
*/
export declare function getProxyUrl(serverUrl: string): string;
export declare class HttpClientResponse implements ifm.IHttpClientResponse { export declare class HttpClientResponse implements ifm.IHttpClientResponse {
constructor(message: http.IncomingMessage); constructor(message: http.IncomingMessage);
message: http.IncomingMessage; message: http.IncomingMessage;
@ -72,14 +59,6 @@ export declare class HttpClient {
put(requestUrl: string, data: string, additionalHeaders?: ifm.IHeaders): Promise<ifm.IHttpClientResponse>; put(requestUrl: string, data: string, additionalHeaders?: ifm.IHeaders): Promise<ifm.IHttpClientResponse>;
head(requestUrl: string, additionalHeaders?: ifm.IHeaders): Promise<ifm.IHttpClientResponse>; head(requestUrl: string, additionalHeaders?: ifm.IHeaders): Promise<ifm.IHttpClientResponse>;
sendStream(verb: string, requestUrl: string, stream: NodeJS.ReadableStream, additionalHeaders?: ifm.IHeaders): Promise<ifm.IHttpClientResponse>; sendStream(verb: string, requestUrl: string, stream: NodeJS.ReadableStream, additionalHeaders?: ifm.IHeaders): Promise<ifm.IHttpClientResponse>;
/**
* Gets a typed object from an endpoint
* Be aware that not found returns a null. Other errors (4xx, 5xx) reject the promise
*/
getJson<T>(requestUrl: string, additionalHeaders?: ifm.IHeaders): Promise<ifm.ITypedResponse<T>>;
postJson<T>(requestUrl: string, obj: any, additionalHeaders?: ifm.IHeaders): Promise<ifm.ITypedResponse<T>>;
putJson<T>(requestUrl: string, obj: any, additionalHeaders?: ifm.IHeaders): Promise<ifm.ITypedResponse<T>>;
patchJson<T>(requestUrl: string, obj: any, additionalHeaders?: ifm.IHeaders): Promise<ifm.ITypedResponse<T>>;
/** /**
* Makes a raw http request. * Makes a raw http request.
* All other methods such as get, post, patch, and request ultimately call this. * All other methods such as get, post, patch, and request ultimately call this.
@ -111,9 +90,6 @@ export declare class HttpClient {
getAgent(serverUrl: string): http.Agent; getAgent(serverUrl: string): http.Agent;
private _prepareRequest; private _prepareRequest;
private _mergeHeaders; private _mergeHeaders;
private _getExistingOrDefaultHeader;
private _getAgent; private _getAgent;
private _performExponentialBackoff; private _performExponentialBackoff;
private static dateTimeDeserializer;
private _processResponse;
} }

View File

@ -28,43 +28,14 @@ var HttpCodes;
HttpCodes[HttpCodes["RequestTimeout"] = 408] = "RequestTimeout"; HttpCodes[HttpCodes["RequestTimeout"] = 408] = "RequestTimeout";
HttpCodes[HttpCodes["Conflict"] = 409] = "Conflict"; HttpCodes[HttpCodes["Conflict"] = 409] = "Conflict";
HttpCodes[HttpCodes["Gone"] = 410] = "Gone"; HttpCodes[HttpCodes["Gone"] = 410] = "Gone";
HttpCodes[HttpCodes["TooManyRequests"] = 429] = "TooManyRequests";
HttpCodes[HttpCodes["InternalServerError"] = 500] = "InternalServerError"; HttpCodes[HttpCodes["InternalServerError"] = 500] = "InternalServerError";
HttpCodes[HttpCodes["NotImplemented"] = 501] = "NotImplemented"; HttpCodes[HttpCodes["NotImplemented"] = 501] = "NotImplemented";
HttpCodes[HttpCodes["BadGateway"] = 502] = "BadGateway"; HttpCodes[HttpCodes["BadGateway"] = 502] = "BadGateway";
HttpCodes[HttpCodes["ServiceUnavailable"] = 503] = "ServiceUnavailable"; HttpCodes[HttpCodes["ServiceUnavailable"] = 503] = "ServiceUnavailable";
HttpCodes[HttpCodes["GatewayTimeout"] = 504] = "GatewayTimeout"; HttpCodes[HttpCodes["GatewayTimeout"] = 504] = "GatewayTimeout";
})(HttpCodes = exports.HttpCodes || (exports.HttpCodes = {})); })(HttpCodes = exports.HttpCodes || (exports.HttpCodes = {}));
var Headers; const HttpRedirectCodes = [HttpCodes.MovedPermanently, HttpCodes.ResourceMoved, HttpCodes.SeeOther, HttpCodes.TemporaryRedirect, HttpCodes.PermanentRedirect];
(function (Headers) { const HttpResponseRetryCodes = [HttpCodes.BadGateway, HttpCodes.ServiceUnavailable, HttpCodes.GatewayTimeout];
Headers["Accept"] = "accept";
Headers["ContentType"] = "content-type";
})(Headers = exports.Headers || (exports.Headers = {}));
var MediaTypes;
(function (MediaTypes) {
MediaTypes["ApplicationJson"] = "application/json";
})(MediaTypes = exports.MediaTypes || (exports.MediaTypes = {}));
/**
* Returns the proxy URL, depending upon the supplied url and proxy environment variables.
* @param serverUrl The server URL where the request will be sent. For example, https://api.github.com
*/
function getProxyUrl(serverUrl) {
let proxyUrl = pm.getProxyUrl(url.parse(serverUrl));
return proxyUrl ? proxyUrl.href : '';
}
exports.getProxyUrl = getProxyUrl;
const HttpRedirectCodes = [
HttpCodes.MovedPermanently,
HttpCodes.ResourceMoved,
HttpCodes.SeeOther,
HttpCodes.TemporaryRedirect,
HttpCodes.PermanentRedirect
];
const HttpResponseRetryCodes = [
HttpCodes.BadGateway,
HttpCodes.ServiceUnavailable,
HttpCodes.GatewayTimeout
];
const RetryableHttpVerbs = ['OPTIONS', 'GET', 'DELETE', 'HEAD']; const RetryableHttpVerbs = ['OPTIONS', 'GET', 'DELETE', 'HEAD'];
const ExponentialBackoffCeiling = 10; const ExponentialBackoffCeiling = 10;
const ExponentialBackoffTimeSlice = 5; const ExponentialBackoffTimeSlice = 5;
@ -152,36 +123,6 @@ class HttpClient {
sendStream(verb, requestUrl, stream, additionalHeaders) { sendStream(verb, requestUrl, stream, additionalHeaders) {
return this.request(verb, requestUrl, stream, additionalHeaders); return this.request(verb, requestUrl, stream, additionalHeaders);
} }
/**
* Gets a typed object from an endpoint
* Be aware that not found returns a null. Other errors (4xx, 5xx) reject the promise
*/
async getJson(requestUrl, additionalHeaders = {}) {
additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson);
let res = await this.get(requestUrl, additionalHeaders);
return this._processResponse(res, this.requestOptions);
}
async postJson(requestUrl, obj, additionalHeaders = {}) {
let data = JSON.stringify(obj, null, 2);
additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson);
additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson);
let res = await this.post(requestUrl, data, additionalHeaders);
return this._processResponse(res, this.requestOptions);
}
async putJson(requestUrl, obj, additionalHeaders = {}) {
let data = JSON.stringify(obj, null, 2);
additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson);
additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson);
let res = await this.put(requestUrl, data, additionalHeaders);
return this._processResponse(res, this.requestOptions);
}
async patchJson(requestUrl, obj, additionalHeaders = {}) {
let data = JSON.stringify(obj, null, 2);
additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson);
additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson);
let res = await this.patch(requestUrl, data, additionalHeaders);
return this._processResponse(res, this.requestOptions);
}
/** /**
* Makes a raw http request. * Makes a raw http request.
* All other methods such as get, post, patch, and request ultimately call this. * All other methods such as get, post, patch, and request ultimately call this.
@ -189,22 +130,18 @@ class HttpClient {
*/ */
async request(verb, requestUrl, data, headers) { async request(verb, requestUrl, data, headers) {
if (this._disposed) { if (this._disposed) {
throw new Error('Client has already been disposed.'); throw new Error("Client has already been disposed.");
} }
let parsedUrl = url.parse(requestUrl); let parsedUrl = url.parse(requestUrl);
let info = this._prepareRequest(verb, parsedUrl, headers); let info = this._prepareRequest(verb, parsedUrl, headers);
// Only perform retries on reads since writes may not be idempotent. // Only perform retries on reads since writes may not be idempotent.
let maxTries = this._allowRetries && RetryableHttpVerbs.indexOf(verb) != -1 let maxTries = (this._allowRetries && RetryableHttpVerbs.indexOf(verb) != -1) ? this._maxRetries + 1 : 1;
? this._maxRetries + 1
: 1;
let numTries = 0; let numTries = 0;
let response; let response;
while (numTries < maxTries) { while (numTries < maxTries) {
response = await this.requestRaw(info, data); response = await this.requestRaw(info, data);
// Check if it's an authentication challenge // Check if it's an authentication challenge
if (response && if (response && response.message && response.message.statusCode === HttpCodes.Unauthorized) {
response.message &&
response.message.statusCode === HttpCodes.Unauthorized) {
let authenticationHandler; let authenticationHandler;
for (let i = 0; i < this.handlers.length; i++) { for (let i = 0; i < this.handlers.length; i++) {
if (this.handlers[i].canHandleAuthentication(response)) { if (this.handlers[i].canHandleAuthentication(response)) {
@ -222,32 +159,21 @@ class HttpClient {
} }
} }
let redirectsRemaining = this._maxRedirects; let redirectsRemaining = this._maxRedirects;
while (HttpRedirectCodes.indexOf(response.message.statusCode) != -1 && while (HttpRedirectCodes.indexOf(response.message.statusCode) != -1
this._allowRedirects && && this._allowRedirects
redirectsRemaining > 0) { && redirectsRemaining > 0) {
const redirectUrl = response.message.headers['location']; const redirectUrl = response.message.headers["location"];
if (!redirectUrl) { if (!redirectUrl) {
// if there's no location to redirect to, we won't // if there's no location to redirect to, we won't
break; break;
} }
let parsedRedirectUrl = url.parse(redirectUrl); let parsedRedirectUrl = url.parse(redirectUrl);
if (parsedUrl.protocol == 'https:' && if (parsedUrl.protocol == 'https:' && parsedUrl.protocol != parsedRedirectUrl.protocol && !this._allowRedirectDowngrade) {
parsedUrl.protocol != parsedRedirectUrl.protocol && throw new Error("Redirect from HTTPS to HTTP protocol. This downgrade is not allowed for security reasons. If you want to allow this behavior, set the allowRedirectDowngrade option to true.");
!this._allowRedirectDowngrade) {
throw new Error('Redirect from HTTPS to HTTP protocol. This downgrade is not allowed for security reasons. If you want to allow this behavior, set the allowRedirectDowngrade option to true.');
} }
// we need to finish reading the response before reassigning response // we need to finish reading the response before reassigning response
// which will leak the open socket. // which will leak the open socket.
await response.readBody(); await response.readBody();
// strip authorization header if redirected to a different hostname
if (parsedRedirectUrl.hostname !== parsedUrl.hostname) {
for (let header in headers) {
// header names are case insensitive
if (header.toLowerCase() === 'authorization') {
delete headers[header];
}
}
}
// let's make the request with the new redirectUrl // let's make the request with the new redirectUrl
info = this._prepareRequest(verb, parsedRedirectUrl, headers); info = this._prepareRequest(verb, parsedRedirectUrl, headers);
response = await this.requestRaw(info, data); response = await this.requestRaw(info, data);
@ -298,8 +224,8 @@ class HttpClient {
*/ */
requestRawWithCallback(info, data, onResult) { requestRawWithCallback(info, data, onResult) {
let socket; let socket;
if (typeof data === 'string') { if (typeof (data) === 'string') {
info.options.headers['Content-Length'] = Buffer.byteLength(data, 'utf8'); info.options.headers["Content-Length"] = Buffer.byteLength(data, 'utf8');
} }
let callbackCalled = false; let callbackCalled = false;
let handleResult = (err, res) => { let handleResult = (err, res) => {
@ -312,7 +238,7 @@ class HttpClient {
let res = new HttpClientResponse(msg); let res = new HttpClientResponse(msg);
handleResult(null, res); handleResult(null, res);
}); });
req.on('socket', sock => { req.on('socket', (sock) => {
socket = sock; socket = sock;
}); });
// If we ever get disconnected, we want the socket to timeout eventually // If we ever get disconnected, we want the socket to timeout eventually
@ -327,10 +253,10 @@ class HttpClient {
// res should have headers // res should have headers
handleResult(err, null); handleResult(err, null);
}); });
if (data && typeof data === 'string') { if (data && typeof (data) === 'string') {
req.write(data, 'utf8'); req.write(data, 'utf8');
} }
if (data && typeof data !== 'string') { if (data && typeof (data) !== 'string') {
data.on('close', function () { data.on('close', function () {
req.end(); req.end();
}); });
@ -357,40 +283,29 @@ class HttpClient {
const defaultPort = usingSsl ? 443 : 80; const defaultPort = usingSsl ? 443 : 80;
info.options = {}; info.options = {};
info.options.host = info.parsedUrl.hostname; info.options.host = info.parsedUrl.hostname;
info.options.port = info.parsedUrl.port info.options.port = info.parsedUrl.port ? parseInt(info.parsedUrl.port) : defaultPort;
? parseInt(info.parsedUrl.port) info.options.path = (info.parsedUrl.pathname || '') + (info.parsedUrl.search || '');
: defaultPort;
info.options.path =
(info.parsedUrl.pathname || '') + (info.parsedUrl.search || '');
info.options.method = method; info.options.method = method;
info.options.headers = this._mergeHeaders(headers); info.options.headers = this._mergeHeaders(headers);
if (this.userAgent != null) { if (this.userAgent != null) {
info.options.headers['user-agent'] = this.userAgent; info.options.headers["user-agent"] = this.userAgent;
} }
info.options.agent = this._getAgent(info.parsedUrl); info.options.agent = this._getAgent(info.parsedUrl);
// gives handlers an opportunity to participate // gives handlers an opportunity to participate
if (this.handlers) { if (this.handlers) {
this.handlers.forEach(handler => { this.handlers.forEach((handler) => {
handler.prepareRequest(info.options); handler.prepareRequest(info.options);
}); });
} }
return info; return info;
} }
_mergeHeaders(headers) { _mergeHeaders(headers) {
const lowercaseKeys = obj => Object.keys(obj).reduce((c, k) => ((c[k.toLowerCase()] = obj[k]), c), {}); const lowercaseKeys = obj => Object.keys(obj).reduce((c, k) => (c[k.toLowerCase()] = obj[k], c), {});
if (this.requestOptions && this.requestOptions.headers) { if (this.requestOptions && this.requestOptions.headers) {
return Object.assign({}, lowercaseKeys(this.requestOptions.headers), lowercaseKeys(headers)); return Object.assign({}, lowercaseKeys(this.requestOptions.headers), lowercaseKeys(headers));
} }
return lowercaseKeys(headers || {}); return lowercaseKeys(headers || {});
} }
_getExistingOrDefaultHeader(additionalHeaders, header, _default) {
const lowercaseKeys = obj => Object.keys(obj).reduce((c, k) => ((c[k.toLowerCase()] = obj[k]), c), {});
let clientHeader;
if (this.requestOptions && this.requestOptions.headers) {
clientHeader = lowercaseKeys(this.requestOptions.headers)[header];
}
return additionalHeaders[header] || clientHeader || _default;
}
_getAgent(parsedUrl) { _getAgent(parsedUrl) {
let agent; let agent;
let proxyUrl = pm.getProxyUrl(parsedUrl); let proxyUrl = pm.getProxyUrl(parsedUrl);
@ -422,7 +337,7 @@ class HttpClient {
proxyAuth: proxyUrl.auth, proxyAuth: proxyUrl.auth,
host: proxyUrl.hostname, host: proxyUrl.hostname,
port: proxyUrl.port port: proxyUrl.port
} },
}; };
let tunnelAgent; let tunnelAgent;
const overHttps = proxyUrl.protocol === 'https:'; const overHttps = proxyUrl.protocol === 'https:';
@ -449,9 +364,7 @@ class HttpClient {
// we don't want to set NODE_TLS_REJECT_UNAUTHORIZED=0 since that will affect request for entire process // we don't want to set NODE_TLS_REJECT_UNAUTHORIZED=0 since that will affect request for entire process
// http.RequestOptions doesn't expose a way to modify RequestOptions.agent.options // http.RequestOptions doesn't expose a way to modify RequestOptions.agent.options
// we have to cast it to any and change it directly // we have to cast it to any and change it directly
agent.options = Object.assign(agent.options || {}, { agent.options = Object.assign(agent.options || {}, { rejectUnauthorized: false });
rejectUnauthorized: false
});
} }
return agent; return agent;
} }
@ -460,72 +373,5 @@ class HttpClient {
const ms = ExponentialBackoffTimeSlice * Math.pow(2, retryNumber); const ms = ExponentialBackoffTimeSlice * Math.pow(2, retryNumber);
return new Promise(resolve => setTimeout(() => resolve(), ms)); return new Promise(resolve => setTimeout(() => resolve(), ms));
} }
static dateTimeDeserializer(key, value) {
if (typeof value === 'string') {
let a = new Date(value);
if (!isNaN(a.valueOf())) {
return a;
}
}
return value;
}
async _processResponse(res, options) {
return new Promise(async (resolve, reject) => {
const statusCode = res.message.statusCode;
const response = {
statusCode: statusCode,
result: null,
headers: {}
};
// not found leads to null obj returned
if (statusCode == HttpCodes.NotFound) {
resolve(response);
}
let obj;
let contents;
// get the result from the body
try {
contents = await res.readBody();
if (contents && contents.length > 0) {
if (options && options.deserializeDates) {
obj = JSON.parse(contents, HttpClient.dateTimeDeserializer);
}
else {
obj = JSON.parse(contents);
}
response.result = obj;
}
response.headers = res.message.headers;
}
catch (err) {
// Invalid resource (contents not json); leaving result obj null
}
// note that 3xx redirects are handled by the http layer.
if (statusCode > 299) {
let msg;
// if exception/error in body, attempt to get better error
if (obj && obj.message) {
msg = obj.message;
}
else if (contents && contents.length > 0) {
// it may be the case that the exception is in the body message as string
msg = contents;
}
else {
msg = 'Failed request: (' + statusCode + ')';
}
let err = new Error(msg);
// attach statusCode and body obj (if available) to the error object
err['statusCode'] = statusCode;
if (response.result) {
err['result'] = response.result;
}
reject(err);
}
else {
resolve(response);
}
});
}
} }
exports.HttpClient = HttpClient; exports.HttpClient = HttpClient;

View File

@ -1,6 +1,6 @@
/// <reference types="node" /> /// <reference types="node" />
import http = require('http'); import http = require("http");
import url = require('url'); import url = require("url");
export interface IHeaders { export interface IHeaders {
[key: string]: any; [key: string]: any;
} }
@ -39,12 +39,6 @@ export interface IRequestOptions {
maxRedirects?: number; maxRedirects?: number;
maxSockets?: number; maxSockets?: number;
keepAlive?: boolean; keepAlive?: boolean;
deserializeDates?: boolean;
allowRetries?: boolean; allowRetries?: boolean;
maxRetries?: number; maxRetries?: number;
} }
export interface ITypedResponse<T> {
statusCode: number;
result: T | null;
headers: Object;
}

View File

@ -1,2 +1,3 @@
"use strict"; "use strict";
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
;

View File

@ -1,33 +1,33 @@
{ {
"_args": [ "_args": [
[ [
"@actions/http-client@1.0.8", "@actions/http-client@1.0.2",
"." "C:\\users\\timheuer\\documents\\github\\setup-msbuild"
] ]
], ],
"_from": "@actions/http-client@1.0.8", "_from": "@actions/http-client@1.0.2",
"_id": "@actions/http-client@1.0.8", "_id": "@actions/http-client@1.0.2",
"_inBundle": false, "_inBundle": false,
"_integrity": "sha512-G4JjJ6f9Hb3Zvejj+ewLLKLf99ZC+9v+yCxoYf9vSyH+WkzPLB2LuUtRMGNkooMqdugGBFStIKXOuvH1W+EctA==", "_integrity": "sha512-ngdGx7aXM7i9BFT+7e3RWWAEt3bX4tKrdI5w5hf0wYpHz66u5Nw6AFSFXG5wzQyUQbkgeNRnJZyK2zciGqXgrQ==",
"_location": "/@actions/http-client", "_location": "/@actions/http-client",
"_phantomChildren": {}, "_phantomChildren": {},
"_requested": { "_requested": {
"type": "version", "type": "version",
"registry": true, "registry": true,
"raw": "@actions/http-client@1.0.8", "raw": "@actions/http-client@1.0.2",
"name": "@actions/http-client", "name": "@actions/http-client",
"escapedName": "@actions%2fhttp-client", "escapedName": "@actions%2fhttp-client",
"scope": "@actions", "scope": "@actions",
"rawSpec": "1.0.8", "rawSpec": "1.0.2",
"saveSpec": null, "saveSpec": null,
"fetchSpec": "1.0.8" "fetchSpec": "1.0.2"
}, },
"_requiredBy": [ "_requiredBy": [
"/@actions/tool-cache" "/@actions/tool-cache"
], ],
"_resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-1.0.8.tgz", "_resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-1.0.2.tgz",
"_spec": "1.0.8", "_spec": "1.0.2",
"_where": ".", "_where": "C:\\users\\timheuer\\documents\\github\\setup-msbuild",
"author": { "author": {
"name": "GitHub, Inc." "name": "GitHub, Inc."
}, },
@ -39,13 +39,12 @@
}, },
"description": "Actions Http Client", "description": "Actions Http Client",
"devDependencies": { "devDependencies": {
"@types/jest": "^25.1.4", "@types/jest": "^24.0.25",
"@types/node": "^12.12.31", "@types/node": "^12.12.24",
"jest": "^25.1.0", "jest": "^24.9.0",
"prettier": "^2.0.4",
"proxy": "^1.0.1", "proxy": "^1.0.1",
"ts-jest": "^25.2.1", "ts-jest": "^24.3.0",
"typescript": "^3.8.3" "typescript": "^3.7.4"
}, },
"homepage": "https://github.com/actions/http-client#readme", "homepage": "https://github.com/actions/http-client#readme",
"keywords": [ "keywords": [
@ -60,11 +59,8 @@
"url": "git+https://github.com/actions/http-client.git" "url": "git+https://github.com/actions/http-client.git"
}, },
"scripts": { "scripts": {
"audit-check": "npm audit --audit-level=moderate",
"build": "rm -Rf ./_out && tsc && cp package*.json ./_out && cp *.md ./_out && cp LICENSE ./_out && cp actions.png ./_out", "build": "rm -Rf ./_out && tsc && cp package*.json ./_out && cp *.md ./_out && cp LICENSE ./_out && cp actions.png ./_out",
"format": "prettier --write *.ts && prettier --write **/*.ts",
"format-check": "prettier --check *.ts && prettier --check **/*.ts",
"test": "jest" "test": "jest"
}, },
"version": "1.0.8" "version": "1.0.2"
} }

View File

@ -1,4 +1,3 @@
/// <reference types="node" /> /// <reference types="node" />
import * as url from 'url'; import * as url from 'url';
export declare function getProxyUrl(reqUrl: url.Url): url.Url | undefined; export declare function getProxyUrl(reqUrl: url.Url): url.Url;
export declare function checkBypass(reqUrl: url.Url): boolean;

View File

@ -3,16 +3,33 @@ Object.defineProperty(exports, "__esModule", { value: true });
const url = require("url"); const url = require("url");
function getProxyUrl(reqUrl) { function getProxyUrl(reqUrl) {
let usingSsl = reqUrl.protocol === 'https:'; let usingSsl = reqUrl.protocol === 'https:';
let noProxy = process.env["no_proxy"] ||
process.env["NO_PROXY"];
let bypass;
if (noProxy && typeof noProxy === 'string') {
let bypassList = noProxy.split(',');
for (let i = 0; i < bypassList.length; i++) {
let item = bypassList[i];
if (item &&
typeof item === "string" &&
reqUrl.host.toLocaleLowerCase() == item.trim().toLocaleLowerCase()) {
bypass = true;
break;
}
}
}
let proxyUrl; let proxyUrl;
if (checkBypass(reqUrl)) { if (bypass) {
return proxyUrl; return proxyUrl;
} }
let proxyVar; let proxyVar;
if (usingSsl) { if (usingSsl) {
proxyVar = process.env['https_proxy'] || process.env['HTTPS_PROXY']; proxyVar = process.env["https_proxy"] ||
process.env["HTTPS_PROXY"];
} }
else { else {
proxyVar = process.env['http_proxy'] || process.env['HTTP_PROXY']; proxyVar = process.env["http_proxy"] ||
process.env["HTTP_PROXY"];
} }
if (proxyVar) { if (proxyVar) {
proxyUrl = url.parse(proxyVar); proxyUrl = url.parse(proxyVar);
@ -20,39 +37,3 @@ function getProxyUrl(reqUrl) {
return proxyUrl; return proxyUrl;
} }
exports.getProxyUrl = getProxyUrl; exports.getProxyUrl = getProxyUrl;
function checkBypass(reqUrl) {
if (!reqUrl.hostname) {
return false;
}
let noProxy = process.env['no_proxy'] || process.env['NO_PROXY'] || '';
if (!noProxy) {
return false;
}
// Determine the request port
let reqPort;
if (reqUrl.port) {
reqPort = Number(reqUrl.port);
}
else if (reqUrl.protocol === 'http:') {
reqPort = 80;
}
else if (reqUrl.protocol === 'https:') {
reqPort = 443;
}
// Format the request hostname and hostname with port
let upperReqHosts = [reqUrl.hostname.toUpperCase()];
if (typeof reqPort === 'number') {
upperReqHosts.push(`${upperReqHosts[0]}:${reqPort}`);
}
// Compare request host against noproxy
for (let upperNoProxyItem of noProxy
.split(',')
.map(x => x.trim().toUpperCase())
.filter(x => x)) {
if (upperReqHosts.some(x => x === upperNoProxyItem)) {
return true;
}
}
return false;
}
exports.checkBypass = checkBypass;

View File

@ -2,7 +2,7 @@
"_args": [ "_args": [
[ [
"@actions/io@1.0.2", "@actions/io@1.0.2",
"C:\\Users\\timheuer\\Documents\\GitHub\\setup-msbuild" "C:\\users\\timheuer\\documents\\github\\setup-msbuild"
] ]
], ],
"_from": "@actions/io@1.0.2", "_from": "@actions/io@1.0.2",
@ -28,7 +28,7 @@
], ],
"_resolved": "https://registry.npmjs.org/@actions/io/-/io-1.0.2.tgz", "_resolved": "https://registry.npmjs.org/@actions/io/-/io-1.0.2.tgz",
"_spec": "1.0.2", "_spec": "1.0.2",
"_where": "C:\\Users\\timheuer\\Documents\\GitHub\\setup-msbuild", "_where": "C:\\users\\timheuer\\documents\\github\\setup-msbuild",
"bugs": { "bugs": {
"url": "https://github.com/actions/toolkit/issues" "url": "https://github.com/actions/toolkit/issues"
}, },

View File

@ -2,7 +2,7 @@
"_args": [ "_args": [
[ [
"@actions/tool-cache@1.3.0", "@actions/tool-cache@1.3.0",
"C:\\Users\\timheuer\\Documents\\GitHub\\setup-msbuild" "C:\\users\\timheuer\\documents\\github\\setup-msbuild"
] ]
], ],
"_from": "@actions/tool-cache@1.3.0", "_from": "@actions/tool-cache@1.3.0",
@ -27,7 +27,7 @@
], ],
"_resolved": "https://registry.npmjs.org/@actions/tool-cache/-/tool-cache-1.3.0.tgz", "_resolved": "https://registry.npmjs.org/@actions/tool-cache/-/tool-cache-1.3.0.tgz",
"_spec": "1.3.0", "_spec": "1.3.0",
"_where": "C:\\Users\\timheuer\\Documents\\GitHub\\setup-msbuild", "_where": "C:\\users\\timheuer\\documents\\github\\setup-msbuild",
"bugs": { "bugs": {
"url": "https://github.com/actions/toolkit/issues" "url": "https://github.com/actions/toolkit/issues"
}, },

6
node_modules/semver/package.json generated vendored
View File

@ -2,7 +2,7 @@
"_args": [ "_args": [
[ [
"semver@6.3.0", "semver@6.3.0",
"C:\\Users\\timheuer\\Documents\\GitHub\\setup-msbuild" "C:\\users\\timheuer\\documents\\github\\setup-msbuild"
] ]
], ],
"_from": "semver@6.3.0", "_from": "semver@6.3.0",
@ -29,9 +29,9 @@
], ],
"_resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "_resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"_spec": "6.3.0", "_spec": "6.3.0",
"_where": "C:\\Users\\timheuer\\Documents\\GitHub\\setup-msbuild", "_where": "C:\\users\\timheuer\\documents\\github\\setup-msbuild",
"bin": { "bin": {
"semver": "bin/semver.js" "semver": "./bin/semver.js"
}, },
"bugs": { "bugs": {
"url": "https://github.com/npm/node-semver/issues" "url": "https://github.com/npm/node-semver/issues"

4
node_modules/tunnel/package.json generated vendored
View File

@ -2,7 +2,7 @@
"_args": [ "_args": [
[ [
"tunnel@0.0.6", "tunnel@0.0.6",
"C:\\Users\\timheuer\\Documents\\GitHub\\setup-msbuild" "C:\\users\\timheuer\\documents\\github\\setup-msbuild"
] ]
], ],
"_from": "tunnel@0.0.6", "_from": "tunnel@0.0.6",
@ -26,7 +26,7 @@
], ],
"_resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", "_resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz",
"_spec": "0.0.6", "_spec": "0.0.6",
"_where": "C:\\Users\\timheuer\\Documents\\GitHub\\setup-msbuild", "_where": "C:\\users\\timheuer\\documents\\github\\setup-msbuild",
"author": { "author": {
"name": "Koichi Kobayashi", "name": "Koichi Kobayashi",
"email": "koichik@improvement.jp" "email": "koichik@improvement.jp"

6
node_modules/uuid/package.json generated vendored
View File

@ -2,7 +2,7 @@
"_args": [ "_args": [
[ [
"uuid@3.3.3", "uuid@3.3.3",
"C:\\Users\\timheuer\\Documents\\GitHub\\setup-msbuild" "C:\\users\\timheuer\\documents\\github\\setup-msbuild"
] ]
], ],
"_from": "uuid@3.3.3", "_from": "uuid@3.3.3",
@ -27,9 +27,9 @@
], ],
"_resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz", "_resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz",
"_spec": "3.3.3", "_spec": "3.3.3",
"_where": "C:\\Users\\timheuer\\Documents\\GitHub\\setup-msbuild", "_where": "C:\\users\\timheuer\\documents\\github\\setup-msbuild",
"bin": { "bin": {
"uuid": "bin/uuid" "uuid": "./bin/uuid"
}, },
"browser": { "browser": {
"./lib/rng.js": "./lib/rng-browser.js", "./lib/rng.js": "./lib/rng-browser.js",

26
package-lock.json generated
View File

@ -1,6 +1,6 @@
{ {
"name": "setup-msbuild", "name": "setup-msbuild",
"version": "1.0.1", "version": "1.0.0",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {
@ -18,9 +18,9 @@
} }
}, },
"@actions/http-client": { "@actions/http-client": {
"version": "1.0.8", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-1.0.8.tgz", "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-1.0.2.tgz",
"integrity": "sha512-G4JjJ6f9Hb3Zvejj+ewLLKLf99ZC+9v+yCxoYf9vSyH+WkzPLB2LuUtRMGNkooMqdugGBFStIKXOuvH1W+EctA==", "integrity": "sha512-ngdGx7aXM7i9BFT+7e3RWWAEt3bX4tKrdI5w5hf0wYpHz66u5Nw6AFSFXG5wzQyUQbkgeNRnJZyK2zciGqXgrQ==",
"requires": { "requires": {
"tunnel": "0.0.6" "tunnel": "0.0.6"
} }
@ -662,9 +662,9 @@
"dev": true "dev": true
}, },
"acorn": { "acorn": {
"version": "6.4.1", "version": "6.4.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz", "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.0.tgz",
"integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==", "integrity": "sha512-gac8OEcQ2Li1dxIEWGZzsp2BitJxwkwcOm0zHAJLcPJaVvm58FRnk6RkuLRpU1EujipU2ZFODv2P9DLMfnV8mw==",
"dev": true "dev": true
}, },
"acorn-globals": { "acorn-globals": {
@ -4226,9 +4226,9 @@
}, },
"dependencies": { "dependencies": {
"acorn": { "acorn": {
"version": "5.7.4", "version": "5.7.3",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz", "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz",
"integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==", "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==",
"dev": true "dev": true
} }
} }
@ -4365,9 +4365,9 @@
} }
}, },
"lodash": { "lodash": {
"version": "4.17.19", "version": "4.17.15",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
"integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
"dev": true "dev": true
}, },
"lodash.memoize": { "lodash.memoize": {

View File

@ -1,6 +1,6 @@
{ {
"name": "setup-msbuild", "name": "setup-msbuild",
"version": "1.0.1", "version": "1.0.0",
"private": true, "private": true,
"description": "Helps set up specific MSBuild tool into PATH for later usage.", "description": "Helps set up specific MSBuild tool into PATH for later usage.",
"main": "lib/main.js", "main": "lib/main.js",
@ -11,7 +11,7 @@
"lint": "eslint src/**/*.ts", "lint": "eslint src/**/*.ts",
"pack": "ncc build", "pack": "ncc build",
"test": "jest", "test": "jest",
"all": "npm run build && npm run format && npm run lint && npm run pack" "all": "npm run build && npm run format && npm run lint && npm run pack && npm test"
}, },
"repository": { "repository": {
"type": "git", "type": "git",

View File

@ -1,19 +1,27 @@
import * as core from '@actions/core' import * as core from '@actions/core'
import * as exec from '@actions/exec' import * as exec from '@actions/exec'
import * as fs from 'fs'
import * as path from 'path' import * as path from 'path'
import * as io from '@actions/io' import * as io from '@actions/io'
import {ExecOptions} from '@actions/exec/lib/interfaces' import {ExecOptions} from '@actions/exec/lib/interfaces'
const IS_WINDOWS = process.platform === 'win32' const IS_WINDOWS = process.platform === 'win32'
const VS_VERSION = core.getInput('vs-version') || 'latest' const VS_VERSION = core.getInput('vs-version') || 'latest'
const VSWHERE_PATH = core.getInput('vswhere-path') const VSWHERE_PATH =
core.getInput('vswhere-path') ||
path.join(
process.env['ProgramFiles(x86)'] as string,
'Microsoft Visual Studio\\Installer'
)
// if a specific version of VS is requested // if a specific version of VS is requested
let VSWHERE_EXEC = '-products * -requires Microsoft.Component.MSBuild -property installationPath -latest ' let VSWHERE_EXEC = ''
if (VS_VERSION !== 'latest') { if (VS_VERSION === 'latest') {
VSWHERE_EXEC += `-version "${VS_VERSION}" ` VSWHERE_EXEC += '-latest '
} else {
VSWHERE_EXEC += `-version ${VS_VERSION} `
} }
VSWHERE_EXEC +=
'-requires Microsoft.Component.MSBuild -find MSBuild\\**\\Bin\\MSBuild.exe'
core.debug(`Execution arguments: ${VSWHERE_EXEC}`) core.debug(`Execution arguments: ${VSWHERE_EXEC}`)
@ -30,30 +38,20 @@ async function run(): Promise<void> {
if (VSWHERE_PATH) { if (VSWHERE_PATH) {
// specified a path for vswhere, use it // specified a path for vswhere, use it
core.debug(`Using given vswhere-path: ${VSWHERE_PATH}`)
vswhereToolExe = path.join(VSWHERE_PATH, 'vswhere.exe') vswhereToolExe = path.join(VSWHERE_PATH, 'vswhere.exe')
} else { } else {
// check in PATH to see if it is there // check in PATH to see if it is there
try { try {
const vsWhereInPath: string = await io.which('vswhere', true) const vsWhereInPath: string = await io.which('vswhere', true)
core.debug(`Found tool in PATH: ${vsWhereInPath}`) core.debug(`Found tool in PATH: ${vsWhereInPath}`)
vswhereToolExe = vsWhereInPath vswhereToolExe = path.join(vsWhereInPath, 'vswhere.exe')
} catch { } catch {
// fall back to VS-installed path // wasn't found because which threw
vswhereToolExe = path.join( } finally {
process.env['ProgramFiles(x86)'] as string,
'Microsoft Visual Studio\\Installer\\vswhere.exe'
)
core.debug(`Trying Visual Studio-installed path: ${vswhereToolExe}`)
}
}
if (!fs.existsSync(vswhereToolExe)) {
core.setFailed( core.setFailed(
'setup-msbuild requires the path to where vswhere.exe exists' 'setup-msbuild requires the path to where vswhere.exe exists'
) )
}
return
} }
core.debug(`Full tool exe: ${vswhereToolExe}`) core.debug(`Full tool exe: ${vswhereToolExe}`)
@ -62,28 +60,9 @@ async function run(): Promise<void> {
const options: ExecOptions = {} const options: ExecOptions = {}
options.listeners = { options.listeners = {
stdout: (data: Buffer) => { stdout: (data: Buffer) => {
const installationPath = data.toString().trim() // eslint-disable-next-line prefer-const
core.debug(`Found installation path: ${installationPath}`) let output = data.toString()
foundToolPath += output
let toolPath = path.join(
installationPath,
'MSBuild\\Current\\Bin\\MSBuild.exe'
)
core.debug(`Checking for path: ${toolPath}`)
if (!fs.existsSync(toolPath)) {
toolPath = path.join(
installationPath,
'MSBuild\\15.0\\Bin\\MSBuild.exe'
)
core.debug(`Checking for path: ${toolPath}`)
if (!fs.existsSync(toolPath)) {
return
}
}
foundToolPath = toolPath
} }
} }
@ -91,7 +70,7 @@ async function run(): Promise<void> {
await exec.exec(`"${vswhereToolExe}" ${VSWHERE_EXEC}`, [], options) await exec.exec(`"${vswhereToolExe}" ${VSWHERE_EXEC}`, [], options)
if (!foundToolPath) { if (!foundToolPath) {
core.setFailed('Unable to find MSBuild.') core.setFailed('Unable to find msbuild.')
return return
} }