wip
This commit is contained in:
		
							parent
							
								
									339aa41a8d
								
							
						
					
					
						commit
						ecf0ce62f9
					
				
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -2,6 +2,9 @@ node_modules/ | ||||
| lib/ | ||||
| __tests__/runner/* | ||||
| 
 | ||||
| validate/temp | ||||
| validate/node | ||||
| 
 | ||||
| # Rest of the file pulled from https://github.com/github/gitignore/blob/master/Node.gitignore | ||||
| # Logs | ||||
| logs | ||||
|  | ||||
							
								
								
									
										10
									
								
								action.yml
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								action.yml
									
									
									
									
									
								
							| @ -1,17 +1,21 @@ | ||||
| name: 'Setup Node.js environment' | ||||
| description: 'Setup a Node.js environment and add it to the PATH, additionally providing proxy support' | ||||
| description: 'Setup a Node.js environment by adding problem matchers and optionally downloading and adding it to the PATH' | ||||
| author: 'GitHub' | ||||
| inputs: | ||||
|   always-auth: | ||||
|     description: 'Set always-auth in npmrc' | ||||
|     default: 'false' | ||||
|   node-version: | ||||
|     description: 'Version Spec of the version to use.  Examples: 10.x, 10.15.1, >=10.15.0' | ||||
|     default: '10.x' | ||||
|     description: 'Version Spec of the version to use.  Examples: 12.x, 10.15.1, >=10.15.0' | ||||
|   registry-url: | ||||
|     description: 'Optional registry to set up for auth. Will set the registry in a project level .npmrc and .yarnrc file, and set up auth to read in from env.NODE_AUTH_TOKEN' | ||||
|   scope: | ||||
|     description: 'Optional scope for authenticating against scoped registries' | ||||
|   token: | ||||
|     description: Used to pull node distributions from node-versions.  Since there's a default, this is typically not supplied by the user. | ||||
|     default: ${{ github.token }} | ||||
| # TODO: add input to control forcing to pull from cloud or dist.  | ||||
| #       escape valve for someone having issues or needing the absolute latest which isn't cached yet | ||||
| # Deprecated option, do not use. Will not be supported after October 1, 2019 | ||||
|   version: | ||||
|     description: 'Deprecated. Use node-version instead. Will not be supported after October 1, 2019' | ||||
|  | ||||
							
								
								
									
										1066
									
								
								dist/index.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1066
									
								
								dist/index.js
									
									
									
									
										vendored
									
									
								
							| @ -1237,49 +1237,181 @@ function authenticationPlugin(octokit, options) { | ||||
| /***/ }), | ||||
| 
 | ||||
| /***/ 20: | ||||
| /***/ (function(module, __unusedexports, __webpack_require__) { | ||||
| /***/ (function(__unusedmodule, exports, __webpack_require__) { | ||||
| 
 | ||||
| "use strict"; | ||||
| 
 | ||||
| 
 | ||||
| const cp = __webpack_require__(129); | ||||
| const parse = __webpack_require__(568); | ||||
| const enoent = __webpack_require__(881); | ||||
| 
 | ||||
| function spawn(command, args, options) { | ||||
|     // Parse the arguments
 | ||||
|     const parsed = parse(command, args, options); | ||||
| 
 | ||||
|     // Spawn the child process
 | ||||
|     const spawned = cp.spawn(parsed.command, parsed.args, parsed.options); | ||||
| 
 | ||||
|     // Hook into child process "exit" event to emit an error if the command
 | ||||
|     // does not exists, see: https://github.com/IndigoUnited/node-cross-spawn/issues/16
 | ||||
|     enoent.hookChildProcess(spawned, parsed); | ||||
| 
 | ||||
|     return spawned; | ||||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||||
| const url = __webpack_require__(835); | ||||
| function getProxyUrl(reqUrl) { | ||||
|     let usingSsl = reqUrl.protocol === 'https:'; | ||||
|     let proxyUrl; | ||||
|     if (checkBypass(reqUrl)) { | ||||
|         return proxyUrl; | ||||
|     } | ||||
|     let proxyVar; | ||||
|     if (usingSsl) { | ||||
|         proxyVar = process.env['https_proxy'] || process.env['HTTPS_PROXY']; | ||||
|     } | ||||
|     else { | ||||
|         proxyVar = process.env['http_proxy'] || process.env['HTTP_PROXY']; | ||||
|     } | ||||
|     if (proxyVar) { | ||||
|         proxyUrl = url.parse(proxyVar); | ||||
|     } | ||||
|     return proxyUrl; | ||||
| } | ||||
| 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; | ||||
| 
 | ||||
| function spawnSync(command, args, options) { | ||||
|     // Parse the arguments
 | ||||
|     const parsed = parse(command, args, options); | ||||
| 
 | ||||
|     // Spawn the child process
 | ||||
|     const result = cp.spawnSync(parsed.command, parsed.args, parsed.options); | ||||
| /***/ }), | ||||
| 
 | ||||
|     // Analyze if the command does not exist, see: https://github.com/IndigoUnited/node-cross-spawn/issues/16
 | ||||
|     result.error = result.error || enoent.verifyENOENTSync(result.status, parsed); | ||||
| /***/ 31: | ||||
| /***/ (function(module, exports, __webpack_require__) { | ||||
| 
 | ||||
| "use strict"; | ||||
| 
 | ||||
| var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||||
|     function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||||
|     return new (P || (P = Promise))(function (resolve, reject) { | ||||
|         function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||||
|         function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||||
|         function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||||
|         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 semver = __importStar(__webpack_require__(280)); | ||||
| const core_1 = __webpack_require__(470); | ||||
| // needs to be require for core node modules to be mocked
 | ||||
| /* eslint @typescript-eslint/no-require-imports: 0 */ | ||||
| const os = __webpack_require__(87); | ||||
| const cp = __webpack_require__(129); | ||||
| const fs = __webpack_require__(747); | ||||
| function _findMatch(versionSpec, stable, candidates, archFilter) { | ||||
|     return __awaiter(this, void 0, void 0, function* () { | ||||
|         const platFilter = os.platform(); | ||||
|         let result; | ||||
|         let match; | ||||
|         let file; | ||||
|         for (const candidate of candidates) { | ||||
|             const version = candidate.version; | ||||
|             core_1.debug(`check ${version} satisfies ${versionSpec}`); | ||||
|             if (semver.satisfies(version, versionSpec) && | ||||
|                 (!stable || candidate.stable === stable)) { | ||||
|                 file = candidate.files.find(item => { | ||||
|                     core_1.debug(`${item.arch}===${archFilter} && ${item.platform}===${platFilter}`); | ||||
|                     let chk = item.arch === archFilter && item.platform === platFilter; | ||||
|                     if (chk && item.platform_version) { | ||||
|                         const osVersion = module.exports._getOsVersion(); | ||||
|                         if (osVersion === item.platform_version) { | ||||
|                             chk = true; | ||||
|                         } | ||||
|                         else { | ||||
|                             chk = semver.satisfies(osVersion, item.platform_version); | ||||
|                         } | ||||
|                     } | ||||
|                     return chk; | ||||
|                 }); | ||||
|                 if (file) { | ||||
|                     core_1.debug(`matched ${candidate.version}`); | ||||
|                     match = candidate; | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         if (match && file) { | ||||
|             // clone since we're mutating the file list to be only the file that matches
 | ||||
|             result = Object.assign({}, match); | ||||
|             result.files = [file]; | ||||
|         } | ||||
|         return result; | ||||
|     }); | ||||
| } | ||||
| 
 | ||||
| module.exports = spawn; | ||||
| module.exports.spawn = spawn; | ||||
| module.exports.sync = spawnSync; | ||||
| 
 | ||||
| module.exports._parse = parse; | ||||
| module.exports._enoent = enoent; | ||||
| 
 | ||||
| exports._findMatch = _findMatch; | ||||
| function _getOsVersion() { | ||||
|     // TODO: add windows and other linux, arm variants
 | ||||
|     // right now filtering on version is only an ubuntu and macos scenario for tools we build for hosted (python)
 | ||||
|     const plat = os.platform(); | ||||
|     let version = ''; | ||||
|     if (plat === 'darwin') { | ||||
|         version = cp.execSync('sw_vers -productVersion').toString(); | ||||
|     } | ||||
|     else if (plat === 'linux') { | ||||
|         // lsb_release process not in some containers, readfile
 | ||||
|         // Run cat /etc/lsb-release
 | ||||
|         // DISTRIB_ID=Ubuntu
 | ||||
|         // DISTRIB_RELEASE=18.04
 | ||||
|         // DISTRIB_CODENAME=bionic
 | ||||
|         // DISTRIB_DESCRIPTION="Ubuntu 18.04.4 LTS"
 | ||||
|         const lsbContents = module.exports._readLinuxVersionFile(); | ||||
|         if (lsbContents) { | ||||
|             const lines = lsbContents.split('\n'); | ||||
|             for (const line of lines) { | ||||
|                 const parts = line.split('='); | ||||
|                 if (parts.length === 2 && parts[0].trim() === 'DISTRIB_RELEASE') { | ||||
|                     version = parts[1].trim(); | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     return version; | ||||
| } | ||||
| exports._getOsVersion = _getOsVersion; | ||||
| function _readLinuxVersionFile() { | ||||
|     const lsbFile = '/etc/lsb-release'; | ||||
|     let contents = ''; | ||||
|     if (fs.existsSync(lsbFile)) { | ||||
|         contents = fs.readFileSync(lsbFile).toString(); | ||||
|     } | ||||
|     return contents; | ||||
| } | ||||
| exports._readLinuxVersionFile = _readLinuxVersionFile; | ||||
| //# sourceMappingURL=manifest.js.map
 | ||||
| 
 | ||||
| /***/ }), | ||||
| 
 | ||||
| @ -2890,6 +3022,53 @@ module.exports = windowsRelease; | ||||
| 
 | ||||
| module.exports = require("os"); | ||||
| 
 | ||||
| /***/ }), | ||||
| 
 | ||||
| /***/ 108: | ||||
| /***/ (function(module, __unusedexports, __webpack_require__) { | ||||
| 
 | ||||
| "use strict"; | ||||
| 
 | ||||
| 
 | ||||
| const cp = __webpack_require__(129); | ||||
| const parse = __webpack_require__(568); | ||||
| const enoent = __webpack_require__(881); | ||||
| 
 | ||||
| function spawn(command, args, options) { | ||||
|     // Parse the arguments
 | ||||
|     const parsed = parse(command, args, options); | ||||
| 
 | ||||
|     // Spawn the child process
 | ||||
|     const spawned = cp.spawn(parsed.command, parsed.args, parsed.options); | ||||
| 
 | ||||
|     // Hook into child process "exit" event to emit an error if the command
 | ||||
|     // does not exists, see: https://github.com/IndigoUnited/node-cross-spawn/issues/16
 | ||||
|     enoent.hookChildProcess(spawned, parsed); | ||||
| 
 | ||||
|     return spawned; | ||||
| } | ||||
| 
 | ||||
| function spawnSync(command, args, options) { | ||||
|     // Parse the arguments
 | ||||
|     const parsed = parse(command, args, options); | ||||
| 
 | ||||
|     // Spawn the child process
 | ||||
|     const result = cp.spawnSync(parsed.command, parsed.args, parsed.options); | ||||
| 
 | ||||
|     // Analyze if the command does not exist, see: https://github.com/IndigoUnited/node-cross-spawn/issues/16
 | ||||
|     result.error = result.error || enoent.verifyENOENTSync(result.status, parsed); | ||||
| 
 | ||||
|     return result; | ||||
| } | ||||
| 
 | ||||
| module.exports = spawn; | ||||
| module.exports.spawn = spawn; | ||||
| module.exports.sync = spawnSync; | ||||
| 
 | ||||
| module.exports._parse = parse; | ||||
| module.exports._enoent = enoent; | ||||
| 
 | ||||
| 
 | ||||
| /***/ }), | ||||
| 
 | ||||
| /***/ 118: | ||||
| @ -4487,7 +4666,7 @@ module.exports = require("https"); | ||||
| /***/ 215: | ||||
| /***/ (function(module) { | ||||
| 
 | ||||
| module.exports = {"name":"@octokit/rest","version":"16.38.1","publishConfig":{"access":"public"},"description":"GitHub REST API client for Node.js","keywords":["octokit","github","rest","api-client"],"author":"Gregor Martynus (https://github.com/gr2m)","contributors":[{"name":"Mike de Boer","email":"info@mikedeboer.nl"},{"name":"Fabian Jakobs","email":"fabian@c9.io"},{"name":"Joe Gallo","email":"joe@brassafrax.com"},{"name":"Gregor Martynus","url":"https://github.com/gr2m"}],"repository":"https://github.com/octokit/rest.js","dependencies":{"@octokit/auth-token":"^2.4.0","@octokit/request":"^5.2.0","@octokit/request-error":"^1.0.2","atob-lite":"^2.0.0","before-after-hook":"^2.0.0","btoa-lite":"^1.0.0","deprecation":"^2.0.0","lodash.get":"^4.4.2","lodash.set":"^4.3.2","lodash.uniq":"^4.5.0","octokit-pagination-methods":"^1.1.0","once":"^1.4.0","universal-user-agent":"^4.0.0"},"devDependencies":{"@gimenete/type-writer":"^0.1.3","@octokit/auth":"^1.1.1","@octokit/fixtures-server":"^5.0.6","@octokit/graphql":"^4.2.0","@types/node":"^13.1.0","bundlesize":"^0.18.0","chai":"^4.1.2","compression-webpack-plugin":"^3.1.0","cypress":"^3.0.0","glob":"^7.1.2","http-proxy-agent":"^3.0.0","lodash.camelcase":"^4.3.0","lodash.merge":"^4.6.1","lodash.upperfirst":"^4.3.1","mkdirp":"^0.5.1","mocha":"^6.0.0","mustache":"^4.0.0","nock":"^11.3.3","npm-run-all":"^4.1.2","nyc":"^15.0.0","prettier":"^1.14.2","proxy":"^1.0.0","semantic-release":"^16.0.0","sinon":"^8.0.0","sinon-chai":"^3.0.0","sort-keys":"^4.0.0","string-to-arraybuffer":"^1.0.0","string-to-jsdoc-comment":"^1.0.0","typescript":"^3.3.1","webpack":"^4.0.0","webpack-bundle-analyzer":"^3.0.0","webpack-cli":"^3.0.0"},"types":"index.d.ts","scripts":{"coverage":"nyc report --reporter=html && open coverage/index.html","lint":"prettier --check '{lib,plugins,scripts,test}/**/*.{js,json,ts}' 'docs/*.{js,json}' 'docs/src/**/*' index.js README.md package.json","lint:fix":"prettier --write '{lib,plugins,scripts,test}/**/*.{js,json,ts}' 'docs/*.{js,json}' 'docs/src/**/*' index.js README.md package.json","pretest":"npm run -s lint","test":"nyc mocha test/mocha-node-setup.js \"test/*/**/*-test.js\"","test:browser":"cypress run --browser chrome","build":"npm-run-all build:*","build:ts":"npm run -s update-endpoints:typescript","prebuild:browser":"mkdirp dist/","build:browser":"npm-run-all build:browser:*","build:browser:development":"webpack --mode development --entry . --output-library=Octokit --output=./dist/octokit-rest.js --profile --json > dist/bundle-stats.json","build:browser:production":"webpack --mode production --entry . --plugin=compression-webpack-plugin --output-library=Octokit --output-path=./dist --output-filename=octokit-rest.min.js --devtool source-map","generate-bundle-report":"webpack-bundle-analyzer dist/bundle-stats.json --mode=static --no-open --report dist/bundle-report.html","update-endpoints":"npm-run-all update-endpoints:*","update-endpoints:fetch-json":"node scripts/update-endpoints/fetch-json","update-endpoints:code":"node scripts/update-endpoints/code","update-endpoints:typescript":"node scripts/update-endpoints/typescript","prevalidate:ts":"npm run -s build:ts","validate:ts":"tsc --target es6 --noImplicitAny index.d.ts","postvalidate:ts":"tsc --noEmit --target es6 test/typescript-validate.ts","start-fixtures-server":"octokit-fixtures-server"},"license":"MIT","files":["index.js","index.d.ts","lib","plugins"],"nyc":{"ignore":["test"]},"release":{"publish":["@semantic-release/npm",{"path":"@semantic-release/github","assets":["dist/*","!dist/*.map.gz"]}]},"bundlesize":[{"path":"./dist/octokit-rest.min.js.gz","maxSize":"33 kB"}],"_resolved":"https://registry.npmjs.org/@octokit/rest/-/rest-16.38.1.tgz","_integrity":"sha512-zyNFx+/Bd1EXt7LQjfrc6H4wryBQ/oDuZeZhGMBSFr1eMPFDmpEweFQR3R25zjKwBQpDY7L5GQO6A3XSaOfV1w==","_from":"@octokit/rest@16.38.1"}; | ||||
| module.exports = {"_args":[["@octokit/rest@16.38.1","/Users/bryan/Projects/setup-node"]],"_from":"@octokit/rest@16.38.1","_id":"@octokit/rest@16.38.1","_inBundle":false,"_integrity":"sha512-zyNFx+/Bd1EXt7LQjfrc6H4wryBQ/oDuZeZhGMBSFr1eMPFDmpEweFQR3R25zjKwBQpDY7L5GQO6A3XSaOfV1w==","_location":"/@octokit/rest","_phantomChildren":{"os-name":"3.1.0"},"_requested":{"type":"version","registry":true,"raw":"@octokit/rest@16.38.1","name":"@octokit/rest","escapedName":"@octokit%2frest","scope":"@octokit","rawSpec":"16.38.1","saveSpec":null,"fetchSpec":"16.38.1"},"_requiredBy":["/@actions/github"],"_resolved":"https://registry.npmjs.org/@octokit/rest/-/rest-16.38.1.tgz","_spec":"16.38.1","_where":"/Users/bryan/Projects/setup-node","author":{"name":"Gregor Martynus","url":"https://github.com/gr2m"},"bugs":{"url":"https://github.com/octokit/rest.js/issues"},"bundlesize":[{"path":"./dist/octokit-rest.min.js.gz","maxSize":"33 kB"}],"contributors":[{"name":"Mike de Boer","email":"info@mikedeboer.nl"},{"name":"Fabian Jakobs","email":"fabian@c9.io"},{"name":"Joe Gallo","email":"joe@brassafrax.com"},{"name":"Gregor Martynus","url":"https://github.com/gr2m"}],"dependencies":{"@octokit/auth-token":"^2.4.0","@octokit/request":"^5.2.0","@octokit/request-error":"^1.0.2","atob-lite":"^2.0.0","before-after-hook":"^2.0.0","btoa-lite":"^1.0.0","deprecation":"^2.0.0","lodash.get":"^4.4.2","lodash.set":"^4.3.2","lodash.uniq":"^4.5.0","octokit-pagination-methods":"^1.1.0","once":"^1.4.0","universal-user-agent":"^4.0.0"},"description":"GitHub REST API client for Node.js","devDependencies":{"@gimenete/type-writer":"^0.1.3","@octokit/auth":"^1.1.1","@octokit/fixtures-server":"^5.0.6","@octokit/graphql":"^4.2.0","@types/node":"^13.1.0","bundlesize":"^0.18.0","chai":"^4.1.2","compression-webpack-plugin":"^3.1.0","cypress":"^3.0.0","glob":"^7.1.2","http-proxy-agent":"^3.0.0","lodash.camelcase":"^4.3.0","lodash.merge":"^4.6.1","lodash.upperfirst":"^4.3.1","mkdirp":"^0.5.1","mocha":"^6.0.0","mustache":"^4.0.0","nock":"^11.3.3","npm-run-all":"^4.1.2","nyc":"^15.0.0","prettier":"^1.14.2","proxy":"^1.0.0","semantic-release":"^16.0.0","sinon":"^8.0.0","sinon-chai":"^3.0.0","sort-keys":"^4.0.0","string-to-arraybuffer":"^1.0.0","string-to-jsdoc-comment":"^1.0.0","typescript":"^3.3.1","webpack":"^4.0.0","webpack-bundle-analyzer":"^3.0.0","webpack-cli":"^3.0.0"},"files":["index.js","index.d.ts","lib","plugins"],"homepage":"https://github.com/octokit/rest.js#readme","keywords":["octokit","github","rest","api-client"],"license":"MIT","name":"@octokit/rest","nyc":{"ignore":["test"]},"publishConfig":{"access":"public"},"release":{"publish":["@semantic-release/npm",{"path":"@semantic-release/github","assets":["dist/*","!dist/*.map.gz"]}]},"repository":{"type":"git","url":"git+https://github.com/octokit/rest.js.git"},"scripts":{"build":"npm-run-all build:*","build:browser":"npm-run-all build:browser:*","build:browser:development":"webpack --mode development --entry . --output-library=Octokit --output=./dist/octokit-rest.js --profile --json > dist/bundle-stats.json","build:browser:production":"webpack --mode production --entry . --plugin=compression-webpack-plugin --output-library=Octokit --output-path=./dist --output-filename=octokit-rest.min.js --devtool source-map","build:ts":"npm run -s update-endpoints:typescript","coverage":"nyc report --reporter=html && open coverage/index.html","generate-bundle-report":"webpack-bundle-analyzer dist/bundle-stats.json --mode=static --no-open --report dist/bundle-report.html","lint":"prettier --check '{lib,plugins,scripts,test}/**/*.{js,json,ts}' 'docs/*.{js,json}' 'docs/src/**/*' index.js README.md package.json","lint:fix":"prettier --write '{lib,plugins,scripts,test}/**/*.{js,json,ts}' 'docs/*.{js,json}' 'docs/src/**/*' index.js README.md package.json","postvalidate:ts":"tsc --noEmit --target es6 test/typescript-validate.ts","prebuild:browser":"mkdirp dist/","pretest":"npm run -s lint","prevalidate:ts":"npm run -s build:ts","start-fixtures-server":"octokit-fixtures-server","test":"nyc mocha test/mocha-node-setup.js \"test/*/**/*-test.js\"","test:browser":"cypress run --browser chrome","update-endpoints":"npm-run-all update-endpoints:*","update-endpoints:code":"node scripts/update-endpoints/code","update-endpoints:fetch-json":"node scripts/update-endpoints/fetch-json","update-endpoints:typescript":"node scripts/update-endpoints/typescript","validate:ts":"tsc --target es6 --noImplicitAny index.d.ts"},"types":"index.d.ts","version":"16.38.1"}; | ||||
| 
 | ||||
| /***/ }), | ||||
| 
 | ||||
| @ -6637,7 +6816,7 @@ function normalizePaginatedListResponse(octokit, url, response) { | ||||
| /***/ 314: | ||||
| /***/ (function(module) { | ||||
| 
 | ||||
| module.exports = {"name":"@octokit/graphql","version":"2.1.3","publishConfig":{"access":"public"},"description":"GitHub GraphQL API client for browsers and Node","main":"index.js","scripts":{"prebuild":"mkdirp dist/","build":"npm-run-all build:*","build:development":"webpack --mode development --entry . --output-library=octokitGraphql --output=./dist/octokit-graphql.js --profile --json > dist/bundle-stats.json","build:production":"webpack --mode production --entry . --plugin=compression-webpack-plugin --output-library=octokitGraphql --output-path=./dist --output-filename=octokit-graphql.min.js --devtool source-map","bundle-report":"webpack-bundle-analyzer dist/bundle-stats.json --mode=static --no-open --report dist/bundle-report.html","coverage":"nyc report --reporter=html && open coverage/index.html","coverage:upload":"nyc report --reporter=text-lcov | coveralls","pretest":"standard","test":"nyc mocha test/*-test.js","test:browser":"cypress run --browser chrome"},"repository":{"type":"git","url":"https://github.com/octokit/graphql.js.git"},"keywords":["octokit","github","api","graphql"],"author":"Gregor Martynus (https://github.com/gr2m)","license":"MIT","bugs":{"url":"https://github.com/octokit/graphql.js/issues"},"homepage":"https://github.com/octokit/graphql.js#readme","dependencies":{"@octokit/request":"^5.0.0","universal-user-agent":"^2.0.3"},"devDependencies":{"chai":"^4.2.0","compression-webpack-plugin":"^2.0.0","coveralls":"^3.0.3","cypress":"^3.1.5","fetch-mock":"^7.3.1","mkdirp":"^0.5.1","mocha":"^6.0.0","npm-run-all":"^4.1.3","nyc":"^14.0.0","semantic-release":"^15.13.3","simple-mock":"^0.8.0","standard":"^12.0.1","webpack":"^4.29.6","webpack-bundle-analyzer":"^3.1.0","webpack-cli":"^3.2.3"},"bundlesize":[{"path":"./dist/octokit-graphql.min.js.gz","maxSize":"5KB"}],"release":{"publish":["@semantic-release/npm",{"path":"@semantic-release/github","assets":["dist/*","!dist/*.map.gz"]}]},"standard":{"globals":["describe","before","beforeEach","afterEach","after","it","expect"]},"files":["lib"],"_resolved":"https://registry.npmjs.org/@octokit/graphql/-/graphql-2.1.3.tgz","_integrity":"sha512-XoXJqL2ondwdnMIW3wtqJWEwcBfKk37jO/rYkoxNPEVeLBDGsGO1TCWggrAlq3keGt/O+C/7VepXnukUxwt5vA==","_from":"@octokit/graphql@2.1.3"}; | ||||
| module.exports = {"_args":[["@octokit/graphql@2.1.3","/Users/bryan/Projects/setup-node"]],"_from":"@octokit/graphql@2.1.3","_id":"@octokit/graphql@2.1.3","_inBundle":false,"_integrity":"sha512-XoXJqL2ondwdnMIW3wtqJWEwcBfKk37jO/rYkoxNPEVeLBDGsGO1TCWggrAlq3keGt/O+C/7VepXnukUxwt5vA==","_location":"/@octokit/graphql","_phantomChildren":{},"_requested":{"type":"version","registry":true,"raw":"@octokit/graphql@2.1.3","name":"@octokit/graphql","escapedName":"@octokit%2fgraphql","scope":"@octokit","rawSpec":"2.1.3","saveSpec":null,"fetchSpec":"2.1.3"},"_requiredBy":["/@actions/github"],"_resolved":"https://registry.npmjs.org/@octokit/graphql/-/graphql-2.1.3.tgz","_spec":"2.1.3","_where":"/Users/bryan/Projects/setup-node","author":{"name":"Gregor Martynus","url":"https://github.com/gr2m"},"bugs":{"url":"https://github.com/octokit/graphql.js/issues"},"bundlesize":[{"path":"./dist/octokit-graphql.min.js.gz","maxSize":"5KB"}],"dependencies":{"@octokit/request":"^5.0.0","universal-user-agent":"^2.0.3"},"description":"GitHub GraphQL API client for browsers and Node","devDependencies":{"chai":"^4.2.0","compression-webpack-plugin":"^2.0.0","coveralls":"^3.0.3","cypress":"^3.1.5","fetch-mock":"^7.3.1","mkdirp":"^0.5.1","mocha":"^6.0.0","npm-run-all":"^4.1.3","nyc":"^14.0.0","semantic-release":"^15.13.3","simple-mock":"^0.8.0","standard":"^12.0.1","webpack":"^4.29.6","webpack-bundle-analyzer":"^3.1.0","webpack-cli":"^3.2.3"},"files":["lib"],"homepage":"https://github.com/octokit/graphql.js#readme","keywords":["octokit","github","api","graphql"],"license":"MIT","main":"index.js","name":"@octokit/graphql","publishConfig":{"access":"public"},"release":{"publish":["@semantic-release/npm",{"path":"@semantic-release/github","assets":["dist/*","!dist/*.map.gz"]}]},"repository":{"type":"git","url":"git+https://github.com/octokit/graphql.js.git"},"scripts":{"build":"npm-run-all build:*","build:development":"webpack --mode development --entry . --output-library=octokitGraphql --output=./dist/octokit-graphql.js --profile --json > dist/bundle-stats.json","build:production":"webpack --mode production --entry . --plugin=compression-webpack-plugin --output-library=octokitGraphql --output-path=./dist --output-filename=octokit-graphql.min.js --devtool source-map","bundle-report":"webpack-bundle-analyzer dist/bundle-stats.json --mode=static --no-open --report dist/bundle-report.html","coverage":"nyc report --reporter=html && open coverage/index.html","coverage:upload":"nyc report --reporter=text-lcov | coveralls","prebuild":"mkdirp dist/","pretest":"standard","test":"nyc mocha test/*-test.js","test:browser":"cypress run --browser chrome"},"standard":{"globals":["describe","before","beforeEach","afterEach","after","it","expect"]},"version":"2.1.3"}; | ||||
| 
 | ||||
| /***/ }), | ||||
| 
 | ||||
| @ -7504,6 +7683,545 @@ function Octokit(plugins, options) { | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /***/ }), | ||||
| 
 | ||||
| /***/ 403: | ||||
| /***/ (function(__unusedmodule, exports, __webpack_require__) { | ||||
| 
 | ||||
| "use strict"; | ||||
| 
 | ||||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||||
| const url = __webpack_require__(835); | ||||
| const http = __webpack_require__(605); | ||||
| const https = __webpack_require__(211); | ||||
| const pm = __webpack_require__(20); | ||||
| let tunnel; | ||||
| var HttpCodes; | ||||
| (function (HttpCodes) { | ||||
|     HttpCodes[HttpCodes["OK"] = 200] = "OK"; | ||||
|     HttpCodes[HttpCodes["MultipleChoices"] = 300] = "MultipleChoices"; | ||||
|     HttpCodes[HttpCodes["MovedPermanently"] = 301] = "MovedPermanently"; | ||||
|     HttpCodes[HttpCodes["ResourceMoved"] = 302] = "ResourceMoved"; | ||||
|     HttpCodes[HttpCodes["SeeOther"] = 303] = "SeeOther"; | ||||
|     HttpCodes[HttpCodes["NotModified"] = 304] = "NotModified"; | ||||
|     HttpCodes[HttpCodes["UseProxy"] = 305] = "UseProxy"; | ||||
|     HttpCodes[HttpCodes["SwitchProxy"] = 306] = "SwitchProxy"; | ||||
|     HttpCodes[HttpCodes["TemporaryRedirect"] = 307] = "TemporaryRedirect"; | ||||
|     HttpCodes[HttpCodes["PermanentRedirect"] = 308] = "PermanentRedirect"; | ||||
|     HttpCodes[HttpCodes["BadRequest"] = 400] = "BadRequest"; | ||||
|     HttpCodes[HttpCodes["Unauthorized"] = 401] = "Unauthorized"; | ||||
|     HttpCodes[HttpCodes["PaymentRequired"] = 402] = "PaymentRequired"; | ||||
|     HttpCodes[HttpCodes["Forbidden"] = 403] = "Forbidden"; | ||||
|     HttpCodes[HttpCodes["NotFound"] = 404] = "NotFound"; | ||||
|     HttpCodes[HttpCodes["MethodNotAllowed"] = 405] = "MethodNotAllowed"; | ||||
|     HttpCodes[HttpCodes["NotAcceptable"] = 406] = "NotAcceptable"; | ||||
|     HttpCodes[HttpCodes["ProxyAuthenticationRequired"] = 407] = "ProxyAuthenticationRequired"; | ||||
|     HttpCodes[HttpCodes["RequestTimeout"] = 408] = "RequestTimeout"; | ||||
|     HttpCodes[HttpCodes["Conflict"] = 409] = "Conflict"; | ||||
|     HttpCodes[HttpCodes["Gone"] = 410] = "Gone"; | ||||
|     HttpCodes[HttpCodes["TooManyRequests"] = 429] = "TooManyRequests"; | ||||
|     HttpCodes[HttpCodes["InternalServerError"] = 500] = "InternalServerError"; | ||||
|     HttpCodes[HttpCodes["NotImplemented"] = 501] = "NotImplemented"; | ||||
|     HttpCodes[HttpCodes["BadGateway"] = 502] = "BadGateway"; | ||||
|     HttpCodes[HttpCodes["ServiceUnavailable"] = 503] = "ServiceUnavailable"; | ||||
|     HttpCodes[HttpCodes["GatewayTimeout"] = 504] = "GatewayTimeout"; | ||||
| })(HttpCodes = exports.HttpCodes || (exports.HttpCodes = {})); | ||||
| var Headers; | ||||
| (function (Headers) { | ||||
|     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 ExponentialBackoffCeiling = 10; | ||||
| const ExponentialBackoffTimeSlice = 5; | ||||
| class HttpClientResponse { | ||||
|     constructor(message) { | ||||
|         this.message = message; | ||||
|     } | ||||
|     readBody() { | ||||
|         return new Promise(async (resolve, reject) => { | ||||
|             let output = Buffer.alloc(0); | ||||
|             this.message.on('data', (chunk) => { | ||||
|                 output = Buffer.concat([output, chunk]); | ||||
|             }); | ||||
|             this.message.on('end', () => { | ||||
|                 resolve(output.toString()); | ||||
|             }); | ||||
|         }); | ||||
|     } | ||||
| } | ||||
| exports.HttpClientResponse = HttpClientResponse; | ||||
| function isHttps(requestUrl) { | ||||
|     let parsedUrl = url.parse(requestUrl); | ||||
|     return parsedUrl.protocol === 'https:'; | ||||
| } | ||||
| exports.isHttps = isHttps; | ||||
| class HttpClient { | ||||
|     constructor(userAgent, handlers, requestOptions) { | ||||
|         this._ignoreSslError = false; | ||||
|         this._allowRedirects = true; | ||||
|         this._allowRedirectDowngrade = false; | ||||
|         this._maxRedirects = 50; | ||||
|         this._allowRetries = false; | ||||
|         this._maxRetries = 1; | ||||
|         this._keepAlive = false; | ||||
|         this._disposed = false; | ||||
|         this.userAgent = userAgent; | ||||
|         this.handlers = handlers || []; | ||||
|         this.requestOptions = requestOptions; | ||||
|         if (requestOptions) { | ||||
|             if (requestOptions.ignoreSslError != null) { | ||||
|                 this._ignoreSslError = requestOptions.ignoreSslError; | ||||
|             } | ||||
|             this._socketTimeout = requestOptions.socketTimeout; | ||||
|             if (requestOptions.allowRedirects != null) { | ||||
|                 this._allowRedirects = requestOptions.allowRedirects; | ||||
|             } | ||||
|             if (requestOptions.allowRedirectDowngrade != null) { | ||||
|                 this._allowRedirectDowngrade = requestOptions.allowRedirectDowngrade; | ||||
|             } | ||||
|             if (requestOptions.maxRedirects != null) { | ||||
|                 this._maxRedirects = Math.max(requestOptions.maxRedirects, 0); | ||||
|             } | ||||
|             if (requestOptions.keepAlive != null) { | ||||
|                 this._keepAlive = requestOptions.keepAlive; | ||||
|             } | ||||
|             if (requestOptions.allowRetries != null) { | ||||
|                 this._allowRetries = requestOptions.allowRetries; | ||||
|             } | ||||
|             if (requestOptions.maxRetries != null) { | ||||
|                 this._maxRetries = requestOptions.maxRetries; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     options(requestUrl, additionalHeaders) { | ||||
|         return this.request('OPTIONS', requestUrl, null, additionalHeaders || {}); | ||||
|     } | ||||
|     get(requestUrl, additionalHeaders) { | ||||
|         return this.request('GET', requestUrl, null, additionalHeaders || {}); | ||||
|     } | ||||
|     del(requestUrl, additionalHeaders) { | ||||
|         return this.request('DELETE', requestUrl, null, additionalHeaders || {}); | ||||
|     } | ||||
|     post(requestUrl, data, additionalHeaders) { | ||||
|         return this.request('POST', requestUrl, data, additionalHeaders || {}); | ||||
|     } | ||||
|     patch(requestUrl, data, additionalHeaders) { | ||||
|         return this.request('PATCH', requestUrl, data, additionalHeaders || {}); | ||||
|     } | ||||
|     put(requestUrl, data, additionalHeaders) { | ||||
|         return this.request('PUT', requestUrl, data, additionalHeaders || {}); | ||||
|     } | ||||
|     head(requestUrl, additionalHeaders) { | ||||
|         return this.request('HEAD', requestUrl, null, additionalHeaders || {}); | ||||
|     } | ||||
|     sendStream(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. | ||||
|      * All other methods such as get, post, patch, and request ultimately call this. | ||||
|      * Prefer get, del, post and patch | ||||
|      */ | ||||
|     async request(verb, requestUrl, data, headers) { | ||||
|         if (this._disposed) { | ||||
|             throw new Error('Client has already been disposed.'); | ||||
|         } | ||||
|         let parsedUrl = url.parse(requestUrl); | ||||
|         let info = this._prepareRequest(verb, parsedUrl, headers); | ||||
|         // Only perform retries on reads since writes may not be idempotent.
 | ||||
|         let maxTries = this._allowRetries && RetryableHttpVerbs.indexOf(verb) != -1 | ||||
|             ? this._maxRetries + 1 | ||||
|             : 1; | ||||
|         let numTries = 0; | ||||
|         let response; | ||||
|         while (numTries < maxTries) { | ||||
|             response = await this.requestRaw(info, data); | ||||
|             // Check if it's an authentication challenge
 | ||||
|             if (response && | ||||
|                 response.message && | ||||
|                 response.message.statusCode === HttpCodes.Unauthorized) { | ||||
|                 let authenticationHandler; | ||||
|                 for (let i = 0; i < this.handlers.length; i++) { | ||||
|                     if (this.handlers[i].canHandleAuthentication(response)) { | ||||
|                         authenticationHandler = this.handlers[i]; | ||||
|                         break; | ||||
|                     } | ||||
|                 } | ||||
|                 if (authenticationHandler) { | ||||
|                     return authenticationHandler.handleAuthentication(this, info, data); | ||||
|                 } | ||||
|                 else { | ||||
|                     // We have received an unauthorized response but have no handlers to handle it.
 | ||||
|                     // Let the response return to the caller.
 | ||||
|                     return response; | ||||
|                 } | ||||
|             } | ||||
|             let redirectsRemaining = this._maxRedirects; | ||||
|             while (HttpRedirectCodes.indexOf(response.message.statusCode) != -1 && | ||||
|                 this._allowRedirects && | ||||
|                 redirectsRemaining > 0) { | ||||
|                 const redirectUrl = response.message.headers['location']; | ||||
|                 if (!redirectUrl) { | ||||
|                     // if there's no location to redirect to, we won't
 | ||||
|                     break; | ||||
|                 } | ||||
|                 let parsedRedirectUrl = url.parse(redirectUrl); | ||||
|                 if (parsedUrl.protocol == 'https:' && | ||||
|                     parsedUrl.protocol != parsedRedirectUrl.protocol && | ||||
|                     !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
 | ||||
|                 // which will leak the open socket.
 | ||||
|                 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
 | ||||
|                 info = this._prepareRequest(verb, parsedRedirectUrl, headers); | ||||
|                 response = await this.requestRaw(info, data); | ||||
|                 redirectsRemaining--; | ||||
|             } | ||||
|             if (HttpResponseRetryCodes.indexOf(response.message.statusCode) == -1) { | ||||
|                 // If not a retry code, return immediately instead of retrying
 | ||||
|                 return response; | ||||
|             } | ||||
|             numTries += 1; | ||||
|             if (numTries < maxTries) { | ||||
|                 await response.readBody(); | ||||
|                 await this._performExponentialBackoff(numTries); | ||||
|             } | ||||
|         } | ||||
|         return response; | ||||
|     } | ||||
|     /** | ||||
|      * Needs to be called if keepAlive is set to true in request options. | ||||
|      */ | ||||
|     dispose() { | ||||
|         if (this._agent) { | ||||
|             this._agent.destroy(); | ||||
|         } | ||||
|         this._disposed = true; | ||||
|     } | ||||
|     /** | ||||
|      * Raw request. | ||||
|      * @param info | ||||
|      * @param data | ||||
|      */ | ||||
|     requestRaw(info, data) { | ||||
|         return new Promise((resolve, reject) => { | ||||
|             let callbackForResult = function (err, res) { | ||||
|                 if (err) { | ||||
|                     reject(err); | ||||
|                 } | ||||
|                 resolve(res); | ||||
|             }; | ||||
|             this.requestRawWithCallback(info, data, callbackForResult); | ||||
|         }); | ||||
|     } | ||||
|     /** | ||||
|      * Raw request with callback. | ||||
|      * @param info | ||||
|      * @param data | ||||
|      * @param onResult | ||||
|      */ | ||||
|     requestRawWithCallback(info, data, onResult) { | ||||
|         let socket; | ||||
|         if (typeof data === 'string') { | ||||
|             info.options.headers['Content-Length'] = Buffer.byteLength(data, 'utf8'); | ||||
|         } | ||||
|         let callbackCalled = false; | ||||
|         let handleResult = (err, res) => { | ||||
|             if (!callbackCalled) { | ||||
|                 callbackCalled = true; | ||||
|                 onResult(err, res); | ||||
|             } | ||||
|         }; | ||||
|         let req = info.httpModule.request(info.options, (msg) => { | ||||
|             let res = new HttpClientResponse(msg); | ||||
|             handleResult(null, res); | ||||
|         }); | ||||
|         req.on('socket', sock => { | ||||
|             socket = sock; | ||||
|         }); | ||||
|         // If we ever get disconnected, we want the socket to timeout eventually
 | ||||
|         req.setTimeout(this._socketTimeout || 3 * 60000, () => { | ||||
|             if (socket) { | ||||
|                 socket.end(); | ||||
|             } | ||||
|             handleResult(new Error('Request timeout: ' + info.options.path), null); | ||||
|         }); | ||||
|         req.on('error', function (err) { | ||||
|             // err has statusCode property
 | ||||
|             // res should have headers
 | ||||
|             handleResult(err, null); | ||||
|         }); | ||||
|         if (data && typeof data === 'string') { | ||||
|             req.write(data, 'utf8'); | ||||
|         } | ||||
|         if (data && typeof data !== 'string') { | ||||
|             data.on('close', function () { | ||||
|                 req.end(); | ||||
|             }); | ||||
|             data.pipe(req); | ||||
|         } | ||||
|         else { | ||||
|             req.end(); | ||||
|         } | ||||
|     } | ||||
|     /** | ||||
|      * Gets an http agent. This function is useful when you need an http agent that handles | ||||
|      * routing through a proxy server - depending upon the url and proxy environment variables. | ||||
|      * @param serverUrl  The server URL where the request will be sent. For example, https://api.github.com
 | ||||
|      */ | ||||
|     getAgent(serverUrl) { | ||||
|         let parsedUrl = url.parse(serverUrl); | ||||
|         return this._getAgent(parsedUrl); | ||||
|     } | ||||
|     _prepareRequest(method, requestUrl, headers) { | ||||
|         const info = {}; | ||||
|         info.parsedUrl = requestUrl; | ||||
|         const usingSsl = info.parsedUrl.protocol === 'https:'; | ||||
|         info.httpModule = usingSsl ? https : http; | ||||
|         const defaultPort = usingSsl ? 443 : 80; | ||||
|         info.options = {}; | ||||
|         info.options.host = info.parsedUrl.hostname; | ||||
|         info.options.port = info.parsedUrl.port | ||||
|             ? parseInt(info.parsedUrl.port) | ||||
|             : defaultPort; | ||||
|         info.options.path = | ||||
|             (info.parsedUrl.pathname || '') + (info.parsedUrl.search || ''); | ||||
|         info.options.method = method; | ||||
|         info.options.headers = this._mergeHeaders(headers); | ||||
|         if (this.userAgent != null) { | ||||
|             info.options.headers['user-agent'] = this.userAgent; | ||||
|         } | ||||
|         info.options.agent = this._getAgent(info.parsedUrl); | ||||
|         // gives handlers an opportunity to participate
 | ||||
|         if (this.handlers) { | ||||
|             this.handlers.forEach(handler => { | ||||
|                 handler.prepareRequest(info.options); | ||||
|             }); | ||||
|         } | ||||
|         return info; | ||||
|     } | ||||
|     _mergeHeaders(headers) { | ||||
|         const lowercaseKeys = obj => Object.keys(obj).reduce((c, k) => ((c[k.toLowerCase()] = obj[k]), c), {}); | ||||
|         if (this.requestOptions && this.requestOptions.headers) { | ||||
|             return Object.assign({}, lowercaseKeys(this.requestOptions.headers), 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) { | ||||
|         let agent; | ||||
|         let proxyUrl = pm.getProxyUrl(parsedUrl); | ||||
|         let useProxy = proxyUrl && proxyUrl.hostname; | ||||
|         if (this._keepAlive && useProxy) { | ||||
|             agent = this._proxyAgent; | ||||
|         } | ||||
|         if (this._keepAlive && !useProxy) { | ||||
|             agent = this._agent; | ||||
|         } | ||||
|         // if agent is already assigned use that agent.
 | ||||
|         if (!!agent) { | ||||
|             return agent; | ||||
|         } | ||||
|         const usingSsl = parsedUrl.protocol === 'https:'; | ||||
|         let maxSockets = 100; | ||||
|         if (!!this.requestOptions) { | ||||
|             maxSockets = this.requestOptions.maxSockets || http.globalAgent.maxSockets; | ||||
|         } | ||||
|         if (useProxy) { | ||||
|             // If using proxy, need tunnel
 | ||||
|             if (!tunnel) { | ||||
|                 tunnel = __webpack_require__(413); | ||||
|             } | ||||
|             const agentOptions = { | ||||
|                 maxSockets: maxSockets, | ||||
|                 keepAlive: this._keepAlive, | ||||
|                 proxy: { | ||||
|                     proxyAuth: proxyUrl.auth, | ||||
|                     host: proxyUrl.hostname, | ||||
|                     port: proxyUrl.port | ||||
|                 } | ||||
|             }; | ||||
|             let tunnelAgent; | ||||
|             const overHttps = proxyUrl.protocol === 'https:'; | ||||
|             if (usingSsl) { | ||||
|                 tunnelAgent = overHttps ? tunnel.httpsOverHttps : tunnel.httpsOverHttp; | ||||
|             } | ||||
|             else { | ||||
|                 tunnelAgent = overHttps ? tunnel.httpOverHttps : tunnel.httpOverHttp; | ||||
|             } | ||||
|             agent = tunnelAgent(agentOptions); | ||||
|             this._proxyAgent = agent; | ||||
|         } | ||||
|         // if reusing agent across request and tunneling agent isn't assigned create a new agent
 | ||||
|         if (this._keepAlive && !agent) { | ||||
|             const options = { keepAlive: this._keepAlive, maxSockets: maxSockets }; | ||||
|             agent = usingSsl ? new https.Agent(options) : new http.Agent(options); | ||||
|             this._agent = agent; | ||||
|         } | ||||
|         // if not using private agent and tunnel agent isn't setup then use global agent
 | ||||
|         if (!agent) { | ||||
|             agent = usingSsl ? https.globalAgent : http.globalAgent; | ||||
|         } | ||||
|         if (usingSsl && this._ignoreSslError) { | ||||
|             // 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
 | ||||
|             // we have to cast it to any and change it directly
 | ||||
|             agent.options = Object.assign(agent.options || {}, { | ||||
|                 rejectUnauthorized: false | ||||
|             }); | ||||
|         } | ||||
|         return agent; | ||||
|     } | ||||
|     _performExponentialBackoff(retryNumber) { | ||||
|         retryNumber = Math.min(ExponentialBackoffCeiling, retryNumber); | ||||
|         const ms = ExponentialBackoffTimeSlice * Math.pow(2, retryNumber); | ||||
|         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; | ||||
| 
 | ||||
| 
 | ||||
| /***/ }), | ||||
| 
 | ||||
| /***/ 413: | ||||
| @ -10092,9 +10810,10 @@ Object.defineProperty(exports, "__esModule", { value: true }); | ||||
| const core = __importStar(__webpack_require__(470)); | ||||
| const io = __importStar(__webpack_require__(1)); | ||||
| const fs = __importStar(__webpack_require__(747)); | ||||
| const mm = __importStar(__webpack_require__(31)); | ||||
| const os = __importStar(__webpack_require__(87)); | ||||
| const path = __importStar(__webpack_require__(622)); | ||||
| const httpm = __importStar(__webpack_require__(539)); | ||||
| const httpm = __importStar(__webpack_require__(403)); | ||||
| const semver = __importStar(__webpack_require__(280)); | ||||
| const stream = __importStar(__webpack_require__(794)); | ||||
| const util = __importStar(__webpack_require__(669)); | ||||
| @ -10119,7 +10838,7 @@ const userAgent = 'actions/tool-cache'; | ||||
|  * @param dest      path to download tool | ||||
|  * @returns         path to downloaded tool | ||||
|  */ | ||||
| function downloadTool(url, dest) { | ||||
| function downloadTool(url, dest, token) { | ||||
|     return __awaiter(this, void 0, void 0, function* () { | ||||
|         dest = dest || path.join(_getTempDirectory(), v4_1.default()); | ||||
|         yield io.mkdirP(path.dirname(dest)); | ||||
| @ -10130,7 +10849,7 @@ function downloadTool(url, dest) { | ||||
|         const maxSeconds = _getGlobal('TEST_DOWNLOAD_TOOL_RETRY_MAX_SECONDS', 20); | ||||
|         const retryHelper = new retry_helper_1.RetryHelper(maxAttempts, minSeconds, maxSeconds); | ||||
|         return yield retryHelper.execute(() => __awaiter(this, void 0, void 0, function* () { | ||||
|             return yield downloadToolAttempt(url, dest || ''); | ||||
|             return yield downloadToolAttempt(url, dest || '', token); | ||||
|         }), (err) => { | ||||
|             if (err instanceof HTTPError && err.httpStatusCode) { | ||||
|                 // Don't retry anything less than 500, except 408 Request Timeout and 429 Too Many Requests
 | ||||
| @ -10146,7 +10865,7 @@ function downloadTool(url, dest) { | ||||
|     }); | ||||
| } | ||||
| exports.downloadTool = downloadTool; | ||||
| function downloadToolAttempt(url, dest) { | ||||
| function downloadToolAttempt(url, dest, token) { | ||||
|     return __awaiter(this, void 0, void 0, function* () { | ||||
|         if (fs.existsSync(dest)) { | ||||
|             throw new Error(`Destination file path ${dest} already exists`); | ||||
| @ -10155,7 +10874,13 @@ function downloadToolAttempt(url, dest) { | ||||
|         const http = new httpm.HttpClient(userAgent, [], { | ||||
|             allowRetries: false | ||||
|         }); | ||||
|         const response = yield http.get(url); | ||||
|         let headers; | ||||
|         if (token) { | ||||
|             headers = { | ||||
|                 authorization: `token ${token}` | ||||
|             }; | ||||
|         } | ||||
|         const response = yield http.get(url, headers); | ||||
|         if (response.message.statusCode !== 200) { | ||||
|             const err = new HTTPError(response.message.statusCode); | ||||
|             core.debug(`Failed to download from "${url}". Code(${response.message.statusCode}) Message(${response.message.statusMessage})`); | ||||
| @ -10483,6 +11208,49 @@ function findAllVersions(toolName, arch) { | ||||
|     return versions; | ||||
| } | ||||
| exports.findAllVersions = findAllVersions; | ||||
| function getManifestFromRepo(owner, repo, token, branch = 'master') { | ||||
|     return __awaiter(this, void 0, void 0, function* () { | ||||
|         let releases = []; | ||||
|         const treeUrl = `https://api.github.com/repos/${owner}/${repo}/git/trees/${branch}`; | ||||
|         const http = new httpm.HttpClient('tool-cache'); | ||||
|         const headers = { | ||||
|             authorization: `token ${token}` | ||||
|         }; | ||||
|         const response = yield http.getJson(treeUrl, headers); | ||||
|         if (!response.result) { | ||||
|             return releases; | ||||
|         } | ||||
|         let manifestUrl = ''; | ||||
|         for (const item of response.result.tree) { | ||||
|             if (item.path === 'versions-manifest.json') { | ||||
|                 manifestUrl = item.url; | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|         headers['accept'] = 'application/vnd.github.VERSION.raw'; | ||||
|         let versionsRaw = yield (yield http.get(manifestUrl, headers)).readBody(); | ||||
|         if (versionsRaw) { | ||||
|             // shouldn't be needed but protects against invalid json saved with BOM
 | ||||
|             versionsRaw = versionsRaw.replace(/^\uFEFF/, ''); | ||||
|             try { | ||||
|                 releases = JSON.parse(versionsRaw); | ||||
|             } | ||||
|             catch (_a) { | ||||
|                 core.debug('Invalid json'); | ||||
|             } | ||||
|         } | ||||
|         return releases; | ||||
|     }); | ||||
| } | ||||
| exports.getManifestFromRepo = getManifestFromRepo; | ||||
| function findFromManifest(versionSpec, stable, manifest, archFilter = os.arch()) { | ||||
|     return __awaiter(this, void 0, void 0, function* () { | ||||
|         // wrap the internal impl
 | ||||
|         const match = yield mm._findMatch(versionSpec, stable, manifest, archFilter); | ||||
|         return match; | ||||
|     }); | ||||
| } | ||||
| exports.findFromManifest = findFromManifest; | ||||
| function _createExtractFolder(dest) { | ||||
|     return __awaiter(this, void 0, void 0, function* () { | ||||
|         if (!dest) { | ||||
| @ -10815,6 +11583,15 @@ class HttpClient { | ||||
|                 // we need to finish reading the response before reassigning response
 | ||||
|                 // which will leak the open socket.
 | ||||
|                 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
 | ||||
|                 info = this._prepareRequest(verb, parsedRedirectUrl, headers); | ||||
|                 response = await this.requestRaw(info, data); | ||||
| @ -12126,33 +12903,52 @@ const path = __importStar(__webpack_require__(622)); | ||||
| const semver = __importStar(__webpack_require__(280)); | ||||
| let osPlat = os.platform(); | ||||
| let osArch = translateArchToDistUrl(os.arch()); | ||||
| function getNode(versionSpec) { | ||||
| function getNode(versionSpec, stable, token) { | ||||
|     return __awaiter(this, void 0, void 0, function* () { | ||||
|         // check cache
 | ||||
|         let info = null; | ||||
|         let toolPath; | ||||
|         toolPath = tc.find('node', versionSpec); | ||||
|         // If not found in cache, download
 | ||||
|         if (!toolPath) { | ||||
|             let version; | ||||
|             const c = semver.clean(versionSpec) || ''; | ||||
|             // If explicit version
 | ||||
|             if (semver.valid(c) != null) { | ||||
|                 // version to download
 | ||||
|                 version = versionSpec; | ||||
|         if (toolPath) { | ||||
|             console.log(`Found in cache @ ${toolPath}`); | ||||
|         } | ||||
|         else { | ||||
|             console.log(`Attempting to download ${versionSpec}...`); | ||||
|             let info = yield getInfoFromManifest(versionSpec, stable, token); | ||||
|             if (!info) { | ||||
|                 console.log('Not found in manifest.  Falling back to download directly from Node'); | ||||
|                 info = yield getInfoFromDist(versionSpec); | ||||
|             } | ||||
|             if (!info) { | ||||
|                 throw new Error(`Unable to find Node version '${versionSpec}' for platform ${osPlat} and architecture ${osArch}.`); | ||||
|             } | ||||
|             console.log(`Acquiring ${info.resolvedVersion} from ${info.downloadUrl}`); | ||||
|             let downloadPath = ""; | ||||
|             try { | ||||
|                 downloadPath = yield tc.downloadTool(info.downloadUrl, undefined, token); | ||||
|             } | ||||
|             catch (err) { | ||||
|                 if (err instanceof tc.HTTPError && err.httpStatusCode == 404) { | ||||
|                     return yield acquireNodeFromFallbackLocation(info.resolvedVersion); | ||||
|                 } | ||||
|                 throw err; | ||||
|             } | ||||
|             //
 | ||||
|             // Extract
 | ||||
|             //
 | ||||
|             let extPath; | ||||
|             if (osPlat == 'win32') { | ||||
|                 let _7zPath = path.join(__dirname, '..', 'externals', '7zr.exe'); | ||||
|                 extPath = yield tc.extract7z(downloadPath, undefined, _7zPath); | ||||
|             } | ||||
|             else { | ||||
|                 // query nodejs.org for a matching version
 | ||||
|                 version = yield queryLatestMatch(versionSpec); | ||||
|                 if (!version) { | ||||
|                     throw new Error(`Unable to find Node version '${versionSpec}' for platform ${osPlat} and architecture ${osArch}.`); | ||||
|                 } | ||||
|                 // check cache
 | ||||
|                 toolPath = tc.find('node', version); | ||||
|             } | ||||
|             if (!toolPath) { | ||||
|                 // download, extract, cache
 | ||||
|                 toolPath = yield acquireNode(version); | ||||
|                 extPath = yield tc.extractTar(downloadPath); | ||||
|             } | ||||
|             //
 | ||||
|             // Install into the local tool cache - node extracts with a root folder that matches the fileName downloaded
 | ||||
|             //
 | ||||
|             toolPath = yield tc.cacheDir(extPath, 'node', info.resolvedVersion); | ||||
|         } | ||||
|         //
 | ||||
|         // a tool installer initimately knows details about the layout of that tool
 | ||||
| @ -12168,7 +12964,81 @@ function getNode(versionSpec) { | ||||
|     }); | ||||
| } | ||||
| exports.getNode = getNode; | ||||
| function queryLatestMatch(versionSpec) { | ||||
| function getInfoFromManifest(versionSpec, stable, token) { | ||||
|     return __awaiter(this, void 0, void 0, function* () { | ||||
|         let info = null; | ||||
|         const releases = yield tc.getManifestFromRepo("actions", "node-versions", token); | ||||
|         console.log(`matching ${versionSpec}...`); | ||||
|         const rel = yield tc.findFromManifest(versionSpec, stable, releases); | ||||
|         if (rel && rel.files.length > 0) { | ||||
|             info = {}; | ||||
|             info.resolvedVersion = rel.version; | ||||
|             info.downloadUrl = rel.files[0].download_url; | ||||
|             info.fileName = rel.files[0].filename; | ||||
|             info.token = token; | ||||
|         } | ||||
|         return info; | ||||
|     }); | ||||
| } | ||||
| function getInfoFromDist(versionSpec) { | ||||
|     return __awaiter(this, void 0, void 0, function* () { | ||||
|         let info = null; | ||||
|         let version; | ||||
|         // If explicit version don't query
 | ||||
|         if (semver.clean(versionSpec) != null) { | ||||
|             // version to download
 | ||||
|             version = versionSpec; | ||||
|         } | ||||
|         else { | ||||
|             // query nodejs.org for a matching version
 | ||||
|             version = yield queryDistForMatch(versionSpec); | ||||
|             if (!version) { | ||||
|                 return null; | ||||
|             } | ||||
|         } | ||||
|         //
 | ||||
|         // Download - a tool installer intimately knows how to get the tool (and construct urls)
 | ||||
|         //
 | ||||
|         version = semver.clean(version) || ''; | ||||
|         let fileName = osPlat == 'win32' | ||||
|             ? `node-v${version}-win-${osArch}` | ||||
|             : `node-v${version}-${osPlat}-${osArch}`; | ||||
|         let urlFileName = osPlat == 'win32' ? `${fileName}.7z` : `${fileName}.tar.gz`; | ||||
|         let url = `https://nodejs.org/dist/v${version}/${urlFileName}`; | ||||
|         return { | ||||
|             downloadUrl: url, | ||||
|             resolvedVersion: version, | ||||
|             fileName: fileName | ||||
|         }; | ||||
|     }); | ||||
| } | ||||
| // TODO - should we just export this from @actions/tool-cache? Lifted directly from there
 | ||||
| function evaluateVersions(versions, versionSpec) { | ||||
|     let version = ''; | ||||
|     core.debug(`evaluating ${versions.length} versions`); | ||||
|     versions = versions.sort((a, b) => { | ||||
|         if (semver.gt(a, b)) { | ||||
|             return 1; | ||||
|         } | ||||
|         return -1; | ||||
|     }); | ||||
|     for (let i = versions.length - 1; i >= 0; i--) { | ||||
|         const potential = versions[i]; | ||||
|         const satisfied = semver.satisfies(potential, versionSpec); | ||||
|         if (satisfied) { | ||||
|             version = potential; | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
|     if (version) { | ||||
|         core.debug(`matched: ${version}`); | ||||
|     } | ||||
|     else { | ||||
|         core.debug('match not found'); | ||||
|     } | ||||
|     return version; | ||||
| } | ||||
| function queryDistForMatch(versionSpec) { | ||||
|     return __awaiter(this, void 0, void 0, function* () { | ||||
|         // node offers a json list of versions
 | ||||
|         let dataFileName; | ||||
| @ -12204,71 +13074,6 @@ function queryLatestMatch(versionSpec) { | ||||
|         return version; | ||||
|     }); | ||||
| } | ||||
| // TODO - should we just export this from @actions/tool-cache? Lifted directly from there
 | ||||
| function evaluateVersions(versions, versionSpec) { | ||||
|     let version = ''; | ||||
|     core.debug(`evaluating ${versions.length} versions`); | ||||
|     versions = versions.sort((a, b) => { | ||||
|         if (semver.gt(a, b)) { | ||||
|             return 1; | ||||
|         } | ||||
|         return -1; | ||||
|     }); | ||||
|     for (let i = versions.length - 1; i >= 0; i--) { | ||||
|         const potential = versions[i]; | ||||
|         const satisfied = semver.satisfies(potential, versionSpec); | ||||
|         if (satisfied) { | ||||
|             version = potential; | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
|     if (version) { | ||||
|         core.debug(`matched: ${version}`); | ||||
|     } | ||||
|     else { | ||||
|         core.debug('match not found'); | ||||
|     } | ||||
|     return version; | ||||
| } | ||||
| function acquireNode(version) { | ||||
|     return __awaiter(this, void 0, void 0, function* () { | ||||
|         //
 | ||||
|         // Download - a tool installer intimately knows how to get the tool (and construct urls)
 | ||||
|         //
 | ||||
|         version = semver.clean(version) || ''; | ||||
|         let fileName = osPlat == 'win32' | ||||
|             ? `node-v${version}-win-${osArch}` | ||||
|             : `node-v${version}-${osPlat}-${osArch}`; | ||||
|         let urlFileName = osPlat == 'win32' ? `${fileName}.7z` : `${fileName}.tar.gz`; | ||||
|         let downloadUrl = `https://nodejs.org/dist/v${version}/${urlFileName}`; | ||||
|         let downloadPath; | ||||
|         try { | ||||
|             downloadPath = yield tc.downloadTool(downloadUrl); | ||||
|         } | ||||
|         catch (err) { | ||||
|             if (err instanceof tc.HTTPError && err.httpStatusCode == 404) { | ||||
|                 return yield acquireNodeFromFallbackLocation(version); | ||||
|             } | ||||
|             throw err; | ||||
|         } | ||||
|         //
 | ||||
|         // Extract
 | ||||
|         //
 | ||||
|         let extPath; | ||||
|         if (osPlat == 'win32') { | ||||
|             let _7zPath = path.join(__dirname, '..', 'externals', '7zr.exe'); | ||||
|             extPath = yield tc.extract7z(downloadPath, undefined, _7zPath); | ||||
|         } | ||||
|         else { | ||||
|             extPath = yield tc.extractTar(downloadPath); | ||||
|         } | ||||
|         //
 | ||||
|         // Install into the local tool cache - node extracts with a root folder that matches the fileName downloaded
 | ||||
|         //
 | ||||
|         let toolRoot = path.join(extPath, fileName); | ||||
|         return yield tc.cacheDir(toolRoot, 'node', version); | ||||
|     }); | ||||
| } | ||||
| // For non LTS versions of Node, the files we need (for Windows) are sometimes located
 | ||||
| // in a different folder than they normally are for other versions.
 | ||||
| // Normally the format is similar to: https://nodejs.org/dist/v5.10.1/node-v5.10.1-win-x64.7z
 | ||||
| @ -15211,12 +16016,15 @@ function run() { | ||||
|             // Version is optional.  If supplied, install / use from the tool cache
 | ||||
|             // If not supplied then task is still used to setup proxy, auth, etc...
 | ||||
|             //
 | ||||
|             let version = core.getInput('version'); | ||||
|             let version = core.getInput('node-version'); | ||||
|             if (!version) { | ||||
|                 version = core.getInput('node-version'); | ||||
|                 version = core.getInput('version'); | ||||
|             } | ||||
|             console.log(`version: ${version}`); | ||||
|             if (version) { | ||||
|                 yield installer.getNode(version); | ||||
|                 let token = core.getInput('token'); | ||||
|                 let stable = (core.getInput('stable') || 'true').toUpperCase() === 'TRUE'; | ||||
|                 yield installer.getNode(version, stable, token); | ||||
|             } | ||||
|             const registryUrl = core.getInput('registry-url'); | ||||
|             const alwaysAuth = core.getInput('always-auth'); | ||||
| @ -15357,7 +16165,7 @@ function validateAuth(auth) { | ||||
| 
 | ||||
| const path = __webpack_require__(622); | ||||
| const childProcess = __webpack_require__(129); | ||||
| const crossSpawn = __webpack_require__(20); | ||||
| const crossSpawn = __webpack_require__(108); | ||||
| const stripEof = __webpack_require__(768); | ||||
| const npmRunPath = __webpack_require__(621); | ||||
| const isStream = __webpack_require__(323); | ||||
|  | ||||
							
								
								
									
										20
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										20
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @ -1,6 +1,6 @@ | ||||
| { | ||||
|   "name": "setup-node", | ||||
|   "version": "1.0.0", | ||||
|   "version": "2.0.0", | ||||
|   "lockfileVersion": 1, | ||||
|   "requires": true, | ||||
|   "dependencies": { | ||||
| @ -40,16 +40,26 @@ | ||||
|       "integrity": "sha512-J8KuFqVPr3p6U8W93DOXlXW6zFvrQAJANdS+vw0YhusLIq+bszW8zmK2Fh1C2kDPX8FMvwIl1OUcFgvJoXLbAg==" | ||||
|     }, | ||||
|     "@actions/tool-cache": { | ||||
|       "version": "1.3.3", | ||||
|       "resolved": "https://registry.npmjs.org/@actions/tool-cache/-/tool-cache-1.3.3.tgz", | ||||
|       "integrity": "sha512-AFVyTLcIxusDVI1gMhbZW8m/On7YNJG+xYaxorV+qic+f7lO7h37aT2mfzxqAq7mwHxtP1YlVFNrXe9QDf/bPg==", | ||||
|       "version": "1.5.2", | ||||
|       "resolved": "https://registry.npmjs.org/@actions/tool-cache/-/tool-cache-1.5.2.tgz", | ||||
|       "integrity": "sha512-40A1St0GEo+QvHV1YRjStEoQcKKMaip+zNXPgGHcjYXCdZ7cl1LGlwOpsVVqwk+6ue/shFTS76KC1A02mVVCQA==", | ||||
|       "requires": { | ||||
|         "@actions/core": "^1.2.0", | ||||
|         "@actions/exec": "^1.0.0", | ||||
|         "@actions/http-client": "^1.0.3", | ||||
|         "@actions/http-client": "^1.0.8", | ||||
|         "@actions/io": "^1.0.1", | ||||
|         "semver": "^6.1.0", | ||||
|         "uuid": "^3.3.2" | ||||
|       }, | ||||
|       "dependencies": { | ||||
|         "@actions/http-client": { | ||||
|           "version": "1.0.8", | ||||
|           "resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-1.0.8.tgz", | ||||
|           "integrity": "sha512-G4JjJ6f9Hb3Zvejj+ewLLKLf99ZC+9v+yCxoYf9vSyH+WkzPLB2LuUtRMGNkooMqdugGBFStIKXOuvH1W+EctA==", | ||||
|           "requires": { | ||||
|             "tunnel": "0.0.6" | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     "@babel/code-frame": { | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| { | ||||
|   "name": "setup-node", | ||||
|   "version": "1.0.0", | ||||
|   "version": "2.0.0", | ||||
|   "private": true, | ||||
|   "description": "setup node action", | ||||
|   "main": "lib/setup-node.js", | ||||
| @ -27,7 +27,7 @@ | ||||
|     "@actions/github": "^1.1.0", | ||||
|     "@actions/http-client": "^1.0.6", | ||||
|     "@actions/io": "^1.0.2", | ||||
|     "@actions/tool-cache": "^1.3.3", | ||||
|     "@actions/tool-cache": "^1.5.2", | ||||
|     "semver": "^6.1.1" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|  | ||||
							
								
								
									
										222
									
								
								src/installer.ts
									
									
									
									
									
								
							
							
						
						
									
										222
									
								
								src/installer.ts
									
									
									
									
									
								
							| @ -6,6 +6,7 @@ import * as tc from '@actions/tool-cache'; | ||||
| import * as os from 'os'; | ||||
| import * as path from 'path'; | ||||
| import * as semver from 'semver'; | ||||
| import { Url } from 'url'; | ||||
| 
 | ||||
| let osPlat: string = os.platform(); | ||||
| let osArch: string = translateArchToDistUrl(os.arch()); | ||||
| @ -19,36 +20,64 @@ interface INodeVersion { | ||||
|   files: string[]; | ||||
| } | ||||
| 
 | ||||
| export async function getNode(versionSpec: string) { | ||||
| interface INodeVersionInfo { | ||||
|   downloadUrl: string; | ||||
|   token: string | null; | ||||
|   resolvedVersion: string; | ||||
|   fileName: string; | ||||
| } | ||||
| 
 | ||||
| export async function getNode(versionSpec: string, stable: boolean, token: string) { | ||||
|   // check cache
 | ||||
|   let info: INodeVersionInfo | null = null; | ||||
|   let toolPath: string; | ||||
|   toolPath = tc.find('node', versionSpec); | ||||
| 
 | ||||
|   // If not found in cache, download
 | ||||
|   if (!toolPath) { | ||||
|     let version: string; | ||||
|     const c = semver.clean(versionSpec) || ''; | ||||
|     // If explicit version
 | ||||
|     if (semver.valid(c) != null) { | ||||
|       // version to download
 | ||||
|       version = versionSpec; | ||||
|     } else { | ||||
|       // query nodejs.org for a matching version
 | ||||
|       version = await queryLatestMatch(versionSpec); | ||||
|       if (!version) { | ||||
|         throw new Error( | ||||
|           `Unable to find Node version '${versionSpec}' for platform ${osPlat} and architecture ${osArch}.` | ||||
|         ); | ||||
|   if (toolPath) { | ||||
|     console.log(`Found in cache @ ${toolPath}`); | ||||
|   } else { | ||||
|     console.log(`Attempting to download ${versionSpec}...`) | ||||
|     let info = await getInfoFromManifest(versionSpec, stable, token); | ||||
|     if (!info) { | ||||
|       console.log('Not found in manifest.  Falling back to download directly from Node') | ||||
|       info = await getInfoFromDist(versionSpec); | ||||
|     }    | ||||
|    | ||||
|     if (!info) { | ||||
|       throw new Error( | ||||
|         `Unable to find Node version '${versionSpec}' for platform ${osPlat} and architecture ${osArch}.` | ||||
|       ); | ||||
|     } | ||||
| 
 | ||||
|     console.log(`Acquiring ${info.resolvedVersion} from ${info.downloadUrl}`); | ||||
| 
 | ||||
|     let downloadPath = "" | ||||
|     try { | ||||
|       downloadPath = await tc.downloadTool(info.downloadUrl, undefined, token); | ||||
|     } catch (err) { | ||||
|       if (err instanceof tc.HTTPError && err.httpStatusCode == 404) { | ||||
|         return await acquireNodeFromFallbackLocation(info.resolvedVersion); | ||||
|       } | ||||
| 
 | ||||
|       // check cache
 | ||||
|       toolPath = tc.find('node', version); | ||||
|       throw err; | ||||
|     } | ||||
| 
 | ||||
|     if (!toolPath) { | ||||
|       // download, extract, cache
 | ||||
|       toolPath = await acquireNode(version); | ||||
|     //
 | ||||
|     // Extract
 | ||||
|     //
 | ||||
|     let extPath: string; | ||||
|     if (osPlat == 'win32') { | ||||
|       let _7zPath = path.join(__dirname, '..', 'externals', '7zr.exe'); | ||||
|       extPath = await tc.extract7z(downloadPath, undefined, _7zPath); | ||||
|     } else { | ||||
|       extPath = await tc.extractTar(downloadPath); | ||||
|     } | ||||
| 
 | ||||
|     //
 | ||||
|     // Install into the local tool cache - node extracts with a root folder that matches the fileName downloaded
 | ||||
|     //
 | ||||
|     toolPath = await tc.cacheDir(extPath, 'node', info.resolvedVersion);     | ||||
|   } | ||||
| 
 | ||||
|   //
 | ||||
| @ -65,7 +94,87 @@ export async function getNode(versionSpec: string) { | ||||
|   core.addPath(toolPath); | ||||
| } | ||||
| 
 | ||||
| async function queryLatestMatch(versionSpec: string): Promise<string> { | ||||
| async function getInfoFromManifest(versionSpec: string, stable: boolean, token: string): Promise<INodeVersionInfo | null> { | ||||
|   let info: INodeVersionInfo | null = null; | ||||
|   const releases = await tc.getManifestFromRepo("actions", "node-versions", token) | ||||
|   console.log(`matching ${versionSpec}...`) | ||||
|   const rel = await tc.findFromManifest(versionSpec, stable, releases); | ||||
|    | ||||
|   if (rel && rel.files.length > 0) { | ||||
|     info = <INodeVersionInfo>{}; | ||||
|     info.resolvedVersion = rel.version; | ||||
|     info.downloadUrl = rel.files[0].download_url; | ||||
|     info.fileName = rel.files[0].filename; | ||||
|     info.token = token; | ||||
|   } | ||||
| 
 | ||||
|   return info; | ||||
| } | ||||
| 
 | ||||
| async function getInfoFromDist(versionSpec: string): Promise<INodeVersionInfo | null> { | ||||
|   let info: INodeVersionInfo | null = null; | ||||
|   let version: string; | ||||
|    | ||||
|   // If explicit version don't query
 | ||||
|   if (semver.clean(versionSpec) != null) { | ||||
|     // version to download
 | ||||
|     version = versionSpec; | ||||
|   } else { | ||||
|     // query nodejs.org for a matching version
 | ||||
|     version = await queryDistForMatch(versionSpec); | ||||
|     if (!version) { | ||||
|       return null; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   //
 | ||||
|   // Download - a tool installer intimately knows how to get the tool (and construct urls)
 | ||||
|   //
 | ||||
|   version = semver.clean(version) || ''; | ||||
|   let fileName: string = | ||||
|     osPlat == 'win32' | ||||
|       ? `node-v${version}-win-${osArch}` | ||||
|       : `node-v${version}-${osPlat}-${osArch}`; | ||||
|   let urlFileName: string = | ||||
|     osPlat == 'win32' ? `${fileName}.7z` : `${fileName}.tar.gz`; | ||||
|   let url = `https://nodejs.org/dist/v${version}/${urlFileName}`; | ||||
| 
 | ||||
|   return <INodeVersionInfo>{ | ||||
|     downloadUrl: url, | ||||
|     resolvedVersion: version, | ||||
|     fileName: fileName | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| // TODO - should we just export this from @actions/tool-cache? Lifted directly from there
 | ||||
| function evaluateVersions(versions: string[], versionSpec: string): string { | ||||
|   let version = ''; | ||||
|   core.debug(`evaluating ${versions.length} versions`); | ||||
|   versions = versions.sort((a, b) => { | ||||
|     if (semver.gt(a, b)) { | ||||
|       return 1; | ||||
|     } | ||||
|     return -1; | ||||
|   }); | ||||
|   for (let i = versions.length - 1; i >= 0; i--) { | ||||
|     const potential: string = versions[i]; | ||||
|     const satisfied: boolean = semver.satisfies(potential, versionSpec); | ||||
|     if (satisfied) { | ||||
|       version = potential; | ||||
|       break; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   if (version) { | ||||
|     core.debug(`matched: ${version}`); | ||||
|   } else { | ||||
|     core.debug('match not found'); | ||||
|   } | ||||
| 
 | ||||
|   return version; | ||||
| } | ||||
| 
 | ||||
| async function queryDistForMatch(versionSpec: string): Promise<string> { | ||||
|   // node offers a json list of versions
 | ||||
|   let dataFileName: string; | ||||
|   switch (osPlat) { | ||||
| @ -102,77 +211,6 @@ async function queryLatestMatch(versionSpec: string): Promise<string> { | ||||
|   return version; | ||||
| } | ||||
| 
 | ||||
| // TODO - should we just export this from @actions/tool-cache? Lifted directly from there
 | ||||
| function evaluateVersions(versions: string[], versionSpec: string): string { | ||||
|   let version = ''; | ||||
|   core.debug(`evaluating ${versions.length} versions`); | ||||
|   versions = versions.sort((a, b) => { | ||||
|     if (semver.gt(a, b)) { | ||||
|       return 1; | ||||
|     } | ||||
|     return -1; | ||||
|   }); | ||||
|   for (let i = versions.length - 1; i >= 0; i--) { | ||||
|     const potential: string = versions[i]; | ||||
|     const satisfied: boolean = semver.satisfies(potential, versionSpec); | ||||
|     if (satisfied) { | ||||
|       version = potential; | ||||
|       break; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   if (version) { | ||||
|     core.debug(`matched: ${version}`); | ||||
|   } else { | ||||
|     core.debug('match not found'); | ||||
|   } | ||||
| 
 | ||||
|   return version; | ||||
| } | ||||
| 
 | ||||
| async function acquireNode(version: string): Promise<string> { | ||||
|   //
 | ||||
|   // Download - a tool installer intimately knows how to get the tool (and construct urls)
 | ||||
|   //
 | ||||
|   version = semver.clean(version) || ''; | ||||
|   let fileName: string = | ||||
|     osPlat == 'win32' | ||||
|       ? `node-v${version}-win-${osArch}` | ||||
|       : `node-v${version}-${osPlat}-${osArch}`; | ||||
|   let urlFileName: string = | ||||
|     osPlat == 'win32' ? `${fileName}.7z` : `${fileName}.tar.gz`; | ||||
|   let downloadUrl = `https://nodejs.org/dist/v${version}/${urlFileName}`; | ||||
| 
 | ||||
|   let downloadPath: string; | ||||
| 
 | ||||
|   try { | ||||
|     downloadPath = await tc.downloadTool(downloadUrl); | ||||
|   } catch (err) { | ||||
|     if (err instanceof tc.HTTPError && err.httpStatusCode == 404) { | ||||
|       return await acquireNodeFromFallbackLocation(version); | ||||
|     } | ||||
| 
 | ||||
|     throw err; | ||||
|   } | ||||
| 
 | ||||
|   //
 | ||||
|   // Extract
 | ||||
|   //
 | ||||
|   let extPath: string; | ||||
|   if (osPlat == 'win32') { | ||||
|     let _7zPath = path.join(__dirname, '..', 'externals', '7zr.exe'); | ||||
|     extPath = await tc.extract7z(downloadPath, undefined, _7zPath); | ||||
|   } else { | ||||
|     extPath = await tc.extractTar(downloadPath); | ||||
|   } | ||||
| 
 | ||||
|   //
 | ||||
|   // Install into the local tool cache - node extracts with a root folder that matches the fileName downloaded
 | ||||
|   //
 | ||||
|   let toolRoot = path.join(extPath, fileName); | ||||
|   return await tc.cacheDir(toolRoot, 'node', version); | ||||
| } | ||||
| 
 | ||||
| // For non LTS versions of Node, the files we need (for Windows) are sometimes located
 | ||||
| // in a different folder than they normally are for other versions.
 | ||||
| // Normally the format is similar to: https://nodejs.org/dist/v5.10.1/node-v5.10.1-win-x64.7z
 | ||||
|  | ||||
| @ -9,12 +9,16 @@ async function run() { | ||||
|     // Version is optional.  If supplied, install / use from the tool cache
 | ||||
|     // If not supplied then task is still used to setup proxy, auth, etc...
 | ||||
|     //
 | ||||
|     let version = core.getInput('version'); | ||||
|     let version = core.getInput('node-version'); | ||||
|     if (!version) { | ||||
|       version = core.getInput('node-version'); | ||||
|       version = core.getInput('version');   | ||||
|     } | ||||
| 
 | ||||
|     console.log(`version: ${version}`); | ||||
|     if (version) { | ||||
|       await installer.getNode(version); | ||||
|       let token = core.getInput('token'); | ||||
|       let stable = (core.getInput('stable') || 'true').toUpperCase() === 'TRUE'; | ||||
|       await installer.getNode(version, stable, token); | ||||
|     } | ||||
| 
 | ||||
|     const registryUrl: string = core.getInput('registry-url'); | ||||
|  | ||||
							
								
								
									
										22
									
								
								validate/test.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										22
									
								
								validate/test.sh
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,22 @@ | ||||
| 
 | ||||
| #/bin/bash | ||||
| 
 | ||||
| set -e | ||||
| 
 | ||||
| rm -rf ./temp | ||||
| rm -rf ./node | ||||
| 
 | ||||
| # uncomment to use charles proxy or other debugging proxy | ||||
| # export NODE_TLS_REJECT_UNAUTHORIZED=0 | ||||
| # export https_proxy=http://127.0.0.1:8888 | ||||
| 
 | ||||
| export RUNNER_TOOL_CACHE=$(pwd) | ||||
| export RUNNER_TEMP="${RUNNER_TOOL_CACHE}/temp" | ||||
| export INPUT_STABLE=true | ||||
| export INPUT_VERSION="12.x" | ||||
| # export your PAT with repo scope before running | ||||
| export INPUT_TOKEN=$GITHUB_TOKEN | ||||
| 
 | ||||
| echo "Getting ${INPUT_VERSION} ($INPUT_STABLE) with ${INPUT_TOKEN}..." | ||||
| 
 | ||||
| node ../dist/index.js | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user