From a3e6ce2153fa695e13226f8273de18260700ff4e Mon Sep 17 00:00:00 2001 From: Bryan Clark Date: Fri, 15 Nov 2019 16:01:13 -0800 Subject: [PATCH 01/55] Adding maven auth support --- __tests__/auth.test.ts | 36 ++++++++++++++++++++++++++++++++ lib/auth.js | 47 ++++++++++++++++++++++++++++++++++++++++++ lib/setup-java.js | 45 ++++++++++++++++++++++++++++++++++++++++ src/auth.ts | 31 ++++++++++++++++++++++++++++ src/setup-java.ts | 8 +++++++ 5 files changed, 167 insertions(+) create mode 100644 __tests__/auth.test.ts create mode 100644 lib/auth.js create mode 100644 lib/setup-java.js create mode 100644 src/auth.ts diff --git a/__tests__/auth.test.ts b/__tests__/auth.test.ts new file mode 100644 index 0000000..937d119 --- /dev/null +++ b/__tests__/auth.test.ts @@ -0,0 +1,36 @@ +import io = require('@actions/io'); +import fs = require('fs'); +import path = require('path'); +import child_process = require('child_process'); + +const m2Dir = path.join(__dirname, '.m2'); +const settingsFile = path.join(m2Dir, 'settings.xml'); + +import * as auth from '../src/auth'; + +describe('auth tests', () => { + beforeAll(async () => { + await io.rmRF(m2Dir); + }, 300000); + + afterAll(async () => { + try { + await io.rmRF(m2Dir); + } catch { + console.log('Failed to remove test directories'); + } + }, 100000); + + it('Creates settings.xml file with username and password', async () => { + const username = 'bluebottle'; + const password = 'SingleOrigin'; + + await auth.configAuthentication(username, password); + + expect(fs.existsSync(m2Dir)).toBe(true); + expect(fs.existsSync(settingsFile)).toBe(true); + expect(fs.readFileSync(settingsFile, 'utf-8')).toEqual( + auth.generate(username, password) + ); + }, 100000); +}); diff --git a/lib/auth.js b/lib/auth.js new file mode 100644 index 0000000..33e643b --- /dev/null +++ b/lib/auth.js @@ -0,0 +1,47 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + 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) : new P(function (resolve) { resolve(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 fs = __importStar(require("fs")); +const os = __importStar(require("os")); +const path = __importStar(require("path")); +const io = __importStar(require("@actions/io")); +function configAuthentication(username, password) { + return __awaiter(this, void 0, void 0, function* () { + const directory = path.join(os.homedir(), '.m2'); + yield io.mkdirP(directory); + yield write(directory, generate(username, password)); + }); +} +exports.configAuthentication = configAuthentication; +// only exported for testing purposes +function generate(username = '${actions.username}', password = '${actions.password}') { + return ` + + + ${username} + ${password} + + + + `; +} +exports.generate = generate; +function write(directory, settings) { + return __awaiter(this, void 0, void 0, function* () { + return fs.writeFileSync(path.join(directory, 'settings.xml'), settings); + }); +} diff --git a/lib/setup-java.js b/lib/setup-java.js new file mode 100644 index 0000000..1028cf8 --- /dev/null +++ b/lib/setup-java.js @@ -0,0 +1,45 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + 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) : new P(function (resolve) { resolve(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 core = __importStar(require("@actions/core")); +const installer = __importStar(require("./installer")); +const auth = __importStar(require("./auth")); +const path = __importStar(require("path")); +function run() { + return __awaiter(this, void 0, void 0, function* () { + try { + let version = core.getInput('version'); + if (!version) { + version = core.getInput('java-version', { required: true }); + } + const arch = core.getInput('architecture', { required: true }); + const jdkFile = core.getInput('jdkFile', { required: false }) || ''; + yield installer.getJava(version, arch, jdkFile); + const username = core.getInput('username', { required: false }); + const password = core.getInput('password', { required: false }); + if (username && password) { + yield auth.configAuthentication(username, password); + } + const matchersPath = path.join(__dirname, '..', '.github'); + console.log(`##[add-matcher]${path.join(matchersPath, 'java.json')}`); + } + catch (error) { + core.setFailed(error.message); + } + }); +} +run(); diff --git a/src/auth.ts b/src/auth.ts new file mode 100644 index 0000000..328c54f --- /dev/null +++ b/src/auth.ts @@ -0,0 +1,31 @@ +import * as fs from 'fs'; +import * as os from 'os'; +import * as path from 'path'; +import * as core from '@actions/core'; +import * as io from '@actions/io'; + +export async function configAuthentication(username: string, password: string) { + const directory: string = path.join(os.homedir(), '.m2'); + await io.mkdirP(directory); + await write(directory, generate(username, password)); +} + +// only exported for testing purposes +export function generate( + username = '${actions.username}', + password = '${actions.password}' +) { + return ` + + + ${username} + ${password} + + + + `; +} + +async function write(directory: string, settings: string) { + return fs.writeFileSync(path.join(directory, 'settings.xml'), settings); +} diff --git a/src/setup-java.ts b/src/setup-java.ts index 1d26bff..e6b179e 100644 --- a/src/setup-java.ts +++ b/src/setup-java.ts @@ -1,5 +1,6 @@ import * as core from '@actions/core'; import * as installer from './installer'; +import * as auth from './auth'; import * as path from 'path'; async function run() { @@ -14,6 +15,13 @@ async function run() { await installer.getJava(version, arch, jdkFile, javaPackage); + const username = core.getInput('username', {required: false}); + const password = core.getInput('password', {required: false}); + + if (username && password) { + await auth.configAuthentication(username, password); + } + const matchersPath = path.join(__dirname, '..', '.github'); console.log(`##[add-matcher]${path.join(matchersPath, 'java.json')}`); } catch (error) { From 56b5af70cfb7ccc2f15b5c6106ac6b0fb91c1432 Mon Sep 17 00:00:00 2001 From: Bryan Clark Date: Wed, 20 Nov 2019 10:23:50 -0800 Subject: [PATCH 02/55] ignore vscode directory --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 370c1f6..e6dc0cc 100644 --- a/.gitignore +++ b/.gitignore @@ -93,3 +93,4 @@ typings/ # DynamoDB Local files .dynamodb/ +.vscode/ From 56eacf97f5ab81cf3d99d685fb9faf78c9028a0f Mon Sep 17 00:00:00 2001 From: Bryan Clark Date: Wed, 20 Nov 2019 10:25:21 -0800 Subject: [PATCH 03/55] move required parameters to auth module username and password are required from within the auth module now. Update the tests to ensure this is the case. --- __tests__/auth.test.ts | 34 ++++++++++++++++++++++++++----- src/auth.ts | 46 ++++++++++++++++++++++++++---------------- src/setup-java.ts | 4 +--- 3 files changed, 59 insertions(+), 25 deletions(-) diff --git a/__tests__/auth.test.ts b/__tests__/auth.test.ts index 937d119..4a3119d 100644 --- a/__tests__/auth.test.ts +++ b/__tests__/auth.test.ts @@ -1,15 +1,22 @@ import io = require('@actions/io'); import fs = require('fs'); +import os = require('os'); import path = require('path'); -import child_process = require('child_process'); -const m2Dir = path.join(__dirname, '.m2'); -const settingsFile = path.join(m2Dir, 'settings.xml'); +// make the os.homedir() call be local to the tests +jest.doMock('os', () => { + return { + homedir: jest.fn(() => __dirname) + }; +}); import * as auth from '../src/auth'; +const m2Dir = path.join(__dirname, auth.M2_DIR); +const settingsFile = path.join(m2Dir, auth.SETTINGS_FILE); + describe('auth tests', () => { - beforeAll(async () => { + beforeEach(async () => { await io.rmRF(m2Dir); }, 300000); @@ -21,7 +28,7 @@ describe('auth tests', () => { } }, 100000); - it('Creates settings.xml file with username and password', async () => { + it('creates settings.xml with username and password', async () => { const username = 'bluebottle'; const password = 'SingleOrigin'; @@ -33,4 +40,21 @@ describe('auth tests', () => { auth.generate(username, password) ); }, 100000); + + it('does not create settings.xml without username and / or password', async () => { + await auth.configAuthentication('FOO', ''); + + expect(fs.existsSync(m2Dir)).toBe(false); + expect(fs.existsSync(settingsFile)).toBe(false); + + await auth.configAuthentication('', 'BAR'); + + expect(fs.existsSync(m2Dir)).toBe(false); + expect(fs.existsSync(settingsFile)).toBe(false); + + await auth.configAuthentication('', ''); // BAZ!!! + + expect(fs.existsSync(m2Dir)).toBe(false); + expect(fs.existsSync(settingsFile)).toBe(false); + }, 100000); }); diff --git a/src/auth.ts b/src/auth.ts index 328c54f..252423a 100644 --- a/src/auth.ts +++ b/src/auth.ts @@ -4,28 +4,40 @@ import * as path from 'path'; import * as core from '@actions/core'; import * as io from '@actions/io'; +export const M2_DIR = '.m2'; +export const SETTINGS_FILE = 'settings.xml'; + export async function configAuthentication(username: string, password: string) { - const directory: string = path.join(os.homedir(), '.m2'); - await io.mkdirP(directory); - await write(directory, generate(username, password)); + if (username && password) { + core.debug(`configAuthentication with ${username} and a password`); + const directory: string = path.join(os.homedir(), M2_DIR); + await io.mkdirP(directory); + core.debug(`created directory ${directory}`); + await write(directory, generate(username, password)); + } else { + core.debug( + `no auth without username: ${username} and password: ${password}` + ); + } } // only exported for testing purposes -export function generate( - username = '${actions.username}', - password = '${actions.password}' -) { - return ` - - - ${username} - ${password} - - - - `; +export function generate(username: string, password: string) { + return ` + + + + ${username} + ${password} + + + + `; } async function write(directory: string, settings: string) { - return fs.writeFileSync(path.join(directory, 'settings.xml'), settings); + const options = {encoding: 'utf-8'}; + const location = path.join(directory, SETTINGS_FILE); + core.debug(`writing ${location}`); + return fs.writeFileSync(location, settings, options); } diff --git a/src/setup-java.ts b/src/setup-java.ts index e6b179e..9e52f9b 100644 --- a/src/setup-java.ts +++ b/src/setup-java.ts @@ -18,9 +18,7 @@ async function run() { const username = core.getInput('username', {required: false}); const password = core.getInput('password', {required: false}); - if (username && password) { - await auth.configAuthentication(username, password); - } + await auth.configAuthentication(username, password); const matchersPath = path.join(__dirname, '..', '.github'); console.log(`##[add-matcher]${path.join(matchersPath, 'java.json')}`); From 86e89385e588f397a8029c26279d630dee37462a Mon Sep 17 00:00:00 2001 From: Bryan Clark Date: Wed, 20 Nov 2019 10:25:37 -0800 Subject: [PATCH 04/55] Add generated auth and setup-java --- lib/auth.js | 42 ++++++++++++++++++++++++++++-------------- lib/setup-java.js | 4 +--- 2 files changed, 29 insertions(+), 17 deletions(-) diff --git a/lib/auth.js b/lib/auth.js index 33e643b..4bfc3c7 100644 --- a/lib/auth.js +++ b/lib/auth.js @@ -18,30 +18,44 @@ Object.defineProperty(exports, "__esModule", { value: true }); const fs = __importStar(require("fs")); const os = __importStar(require("os")); const path = __importStar(require("path")); +const core = __importStar(require("@actions/core")); const io = __importStar(require("@actions/io")); +exports.M2_DIR = '.m2'; +exports.SETTINGS_FILE = 'settings.xml'; function configAuthentication(username, password) { return __awaiter(this, void 0, void 0, function* () { - const directory = path.join(os.homedir(), '.m2'); - yield io.mkdirP(directory); - yield write(directory, generate(username, password)); + if (username && password) { + core.debug(`configAuthentication with ${username} and a password`); + const directory = path.join(os.homedir(), exports.M2_DIR); + yield io.mkdirP(directory); + core.debug(`created directory ${directory}`); + yield write(directory, generate(username, password)); + } + else { + core.debug(`no auth without username: ${username} and password: ${password}`); + } }); } exports.configAuthentication = configAuthentication; // only exported for testing purposes -function generate(username = '${actions.username}', password = '${actions.password}') { - return ` - - - ${username} - ${password} - - - - `; +function generate(username, password) { + return ` + + + + ${username} + ${password} + + + + `; } exports.generate = generate; function write(directory, settings) { return __awaiter(this, void 0, void 0, function* () { - return fs.writeFileSync(path.join(directory, 'settings.xml'), settings); + const options = { encoding: 'utf-8' }; + const location = path.join(directory, exports.SETTINGS_FILE); + core.debug(`writing ${location}`); + return fs.writeFileSync(location, settings, options); }); } diff --git a/lib/setup-java.js b/lib/setup-java.js index 1028cf8..a000d4e 100644 --- a/lib/setup-java.js +++ b/lib/setup-java.js @@ -31,9 +31,7 @@ function run() { yield installer.getJava(version, arch, jdkFile); const username = core.getInput('username', { required: false }); const password = core.getInput('password', { required: false }); - if (username && password) { - yield auth.configAuthentication(username, password); - } + yield auth.configAuthentication(username, password); const matchersPath = path.join(__dirname, '..', '.github'); console.log(`##[add-matcher]${path.join(matchersPath, 'java.json')}`); } From 1b0417032a879685f08952bdd927ad3015219aee Mon Sep 17 00:00:00 2001 From: Bryan Clark Date: Thu, 28 Nov 2019 09:52:58 -0800 Subject: [PATCH 05/55] Move auth to the bottom of setup --- src/setup-java.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/setup-java.ts b/src/setup-java.ts index 9e52f9b..99026e3 100644 --- a/src/setup-java.ts +++ b/src/setup-java.ts @@ -15,13 +15,16 @@ async function run() { await installer.getJava(version, arch, jdkFile, javaPackage); + const matchersPath = path.join(__dirname, '..', '.github'); + console.log(`##[add-matcher]${path.join(matchersPath, 'java.json')}`); + const username = core.getInput('username', {required: false}); const password = core.getInput('password', {required: false}); - await auth.configAuthentication(username, password); + if (username && password) { + await auth.configAuthentication(username, password); + } - const matchersPath = path.join(__dirname, '..', '.github'); - console.log(`##[add-matcher]${path.join(matchersPath, 'java.json')}`); } catch (error) { core.setFailed(error.message); } From b0e5cf270d5e17b8428c466710bc07c39725573a Mon Sep 17 00:00:00 2001 From: Bryan Clark Date: Thu, 28 Nov 2019 12:40:08 -0800 Subject: [PATCH 06/55] Support ids --- __tests__/auth.test.ts | 16 +++++++++++----- src/auth.ts | 9 +++++---- src/setup-java.ts | 5 +++-- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/__tests__/auth.test.ts b/__tests__/auth.test.ts index 4a3119d..8e5efd4 100644 --- a/__tests__/auth.test.ts +++ b/__tests__/auth.test.ts @@ -29,30 +29,36 @@ describe('auth tests', () => { }, 100000); it('creates settings.xml with username and password', async () => { + const id = 'packages'; const username = 'bluebottle'; const password = 'SingleOrigin'; - await auth.configAuthentication(username, password); + await auth.configAuthentication(id, username, password); expect(fs.existsSync(m2Dir)).toBe(true); expect(fs.existsSync(settingsFile)).toBe(true); expect(fs.readFileSync(settingsFile, 'utf-8')).toEqual( - auth.generate(username, password) + auth.generate(id, username, password) ); }, 100000); it('does not create settings.xml without username and / or password', async () => { - await auth.configAuthentication('FOO', ''); + await auth.configAuthentication('FOO', '', ''); expect(fs.existsSync(m2Dir)).toBe(false); expect(fs.existsSync(settingsFile)).toBe(false); - await auth.configAuthentication('', 'BAR'); + await auth.configAuthentication('', 'BAR', ''); expect(fs.existsSync(m2Dir)).toBe(false); expect(fs.existsSync(settingsFile)).toBe(false); - await auth.configAuthentication('', ''); // BAZ!!! + await auth.configAuthentication('', '', 'BAZ'); + + expect(fs.existsSync(m2Dir)).toBe(false); + expect(fs.existsSync(settingsFile)).toBe(false); + + await auth.configAuthentication('', '', ''); expect(fs.existsSync(m2Dir)).toBe(false); expect(fs.existsSync(settingsFile)).toBe(false); diff --git a/src/auth.ts b/src/auth.ts index 252423a..d3c13bc 100644 --- a/src/auth.ts +++ b/src/auth.ts @@ -7,13 +7,13 @@ import * as io from '@actions/io'; export const M2_DIR = '.m2'; export const SETTINGS_FILE = 'settings.xml'; -export async function configAuthentication(username: string, password: string) { - if (username && password) { +export async function configAuthentication(id: string, username: string, password: string) { + if (id && username && password) { core.debug(`configAuthentication with ${username} and a password`); const directory: string = path.join(os.homedir(), M2_DIR); await io.mkdirP(directory); core.debug(`created directory ${directory}`); - await write(directory, generate(username, password)); + await write(directory, generate(id, username, password)); } else { core.debug( `no auth without username: ${username} and password: ${password}` @@ -22,11 +22,12 @@ export async function configAuthentication(username: string, password: string) { } // only exported for testing purposes -export function generate(username: string, password: string) { +export function generate(id: string, username: string, password: string) { return ` + ${id} ${username} ${password} diff --git a/src/setup-java.ts b/src/setup-java.ts index 99026e3..2a73116 100644 --- a/src/setup-java.ts +++ b/src/setup-java.ts @@ -18,11 +18,12 @@ async function run() { const matchersPath = path.join(__dirname, '..', '.github'); console.log(`##[add-matcher]${path.join(matchersPath, 'java.json')}`); + const id = core.getInput('id', {required: false}); const username = core.getInput('username', {required: false}); const password = core.getInput('password', {required: false}); - if (username && password) { - await auth.configAuthentication(username, password); + if (id && username && password) { + await auth.configAuthentication(id, username, password); } } catch (error) { From dc5f78f54d4e2452492208bb2dd5164231dc2623 Mon Sep 17 00:00:00 2001 From: Bryan Clark Date: Thu, 28 Nov 2019 12:40:45 -0800 Subject: [PATCH 07/55] generated and pretty files --- lib/auth.js | 9 +++++---- lib/setup-java.js | 9 ++++++--- src/auth.ts | 6 +++++- src/setup-java.ts | 1 - 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/lib/auth.js b/lib/auth.js index 4bfc3c7..9b03d1c 100644 --- a/lib/auth.js +++ b/lib/auth.js @@ -22,14 +22,14 @@ const core = __importStar(require("@actions/core")); const io = __importStar(require("@actions/io")); exports.M2_DIR = '.m2'; exports.SETTINGS_FILE = 'settings.xml'; -function configAuthentication(username, password) { +function configAuthentication(id, username, password) { return __awaiter(this, void 0, void 0, function* () { - if (username && password) { + if (id && username && password) { core.debug(`configAuthentication with ${username} and a password`); const directory = path.join(os.homedir(), exports.M2_DIR); yield io.mkdirP(directory); core.debug(`created directory ${directory}`); - yield write(directory, generate(username, password)); + yield write(directory, generate(id, username, password)); } else { core.debug(`no auth without username: ${username} and password: ${password}`); @@ -38,11 +38,12 @@ function configAuthentication(username, password) { } exports.configAuthentication = configAuthentication; // only exported for testing purposes -function generate(username, password) { +function generate(id, username, password) { return ` + ${id} ${username} ${password} diff --git a/lib/setup-java.js b/lib/setup-java.js index a000d4e..ce1e376 100644 --- a/lib/setup-java.js +++ b/lib/setup-java.js @@ -29,11 +29,14 @@ function run() { const arch = core.getInput('architecture', { required: true }); const jdkFile = core.getInput('jdkFile', { required: false }) || ''; yield installer.getJava(version, arch, jdkFile); - const username = core.getInput('username', { required: false }); - const password = core.getInput('password', { required: false }); - yield auth.configAuthentication(username, password); const matchersPath = path.join(__dirname, '..', '.github'); console.log(`##[add-matcher]${path.join(matchersPath, 'java.json')}`); + const id = core.getInput('id', { required: false }); + const username = core.getInput('username', { required: false }); + const password = core.getInput('password', { required: false }); + if (id && username && password) { + yield auth.configAuthentication(id, username, password); + } } catch (error) { core.setFailed(error.message); diff --git a/src/auth.ts b/src/auth.ts index d3c13bc..4979045 100644 --- a/src/auth.ts +++ b/src/auth.ts @@ -7,7 +7,11 @@ import * as io from '@actions/io'; export const M2_DIR = '.m2'; export const SETTINGS_FILE = 'settings.xml'; -export async function configAuthentication(id: string, username: string, password: string) { +export async function configAuthentication( + id: string, + username: string, + password: string +) { if (id && username && password) { core.debug(`configAuthentication with ${username} and a password`); const directory: string = path.join(os.homedir(), M2_DIR); diff --git a/src/setup-java.ts b/src/setup-java.ts index 2a73116..39f5466 100644 --- a/src/setup-java.ts +++ b/src/setup-java.ts @@ -25,7 +25,6 @@ async function run() { if (id && username && password) { await auth.configAuthentication(id, username, password); } - } catch (error) { core.setFailed(error.message); } From 24327359f8649bb465e20dee2b6d8c8cce2c1272 Mon Sep 17 00:00:00 2001 From: Bryan Clark Date: Thu, 28 Nov 2019 12:53:22 -0800 Subject: [PATCH 08/55] use server-id instead of ambigous id --- src/setup-java.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/setup-java.ts b/src/setup-java.ts index 39f5466..419b9ea 100644 --- a/src/setup-java.ts +++ b/src/setup-java.ts @@ -18,7 +18,7 @@ async function run() { const matchersPath = path.join(__dirname, '..', '.github'); console.log(`##[add-matcher]${path.join(matchersPath, 'java.json')}`); - const id = core.getInput('id', {required: false}); + const id = core.getInput('server-id', {required: false}); const username = core.getInput('username', {required: false}); const password = core.getInput('password', {required: false}); From b8a0027e2cdcd55e80a1bd0c14f91d9e18a4273e Mon Sep 17 00:00:00 2001 From: Bryan Clark Date: Thu, 28 Nov 2019 12:54:29 -0800 Subject: [PATCH 09/55] Use console.log where appropriate --- lib/auth.js | 6 +++--- lib/setup-java.js | 2 +- src/auth.ts | 8 +++++--- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/lib/auth.js b/lib/auth.js index 9b03d1c..f8d795a 100644 --- a/lib/auth.js +++ b/lib/auth.js @@ -25,14 +25,14 @@ exports.SETTINGS_FILE = 'settings.xml'; function configAuthentication(id, username, password) { return __awaiter(this, void 0, void 0, function* () { if (id && username && password) { - core.debug(`configAuthentication with ${username} and a password`); + console.log(`creating ${exports.SETTINGS_FILE} with server-id: ${id}, username: ${username}, and a password`); const directory = path.join(os.homedir(), exports.M2_DIR); yield io.mkdirP(directory); core.debug(`created directory ${directory}`); yield write(directory, generate(id, username, password)); } else { - core.debug(`no auth without username: ${username} and password: ${password}`); + core.debug(`no ${exports.SETTINGS_FILE} without server-id: ${id}, username: ${username}, and a password`); } }); } @@ -56,7 +56,7 @@ function write(directory, settings) { return __awaiter(this, void 0, void 0, function* () { const options = { encoding: 'utf-8' }; const location = path.join(directory, exports.SETTINGS_FILE); - core.debug(`writing ${location}`); + console.log(`writing ${location}`); return fs.writeFileSync(location, settings, options); }); } diff --git a/lib/setup-java.js b/lib/setup-java.js index ce1e376..5372cbb 100644 --- a/lib/setup-java.js +++ b/lib/setup-java.js @@ -31,7 +31,7 @@ function run() { yield installer.getJava(version, arch, jdkFile); const matchersPath = path.join(__dirname, '..', '.github'); console.log(`##[add-matcher]${path.join(matchersPath, 'java.json')}`); - const id = core.getInput('id', { required: false }); + const id = core.getInput('server-id', { required: false }); const username = core.getInput('username', { required: false }); const password = core.getInput('password', { required: false }); if (id && username && password) { diff --git a/src/auth.ts b/src/auth.ts index 4979045..b61b357 100644 --- a/src/auth.ts +++ b/src/auth.ts @@ -13,14 +13,16 @@ export async function configAuthentication( password: string ) { if (id && username && password) { - core.debug(`configAuthentication with ${username} and a password`); + console.log( + `creating ${SETTINGS_FILE} with server-id: ${id}, username: ${username}, and a password` + ); const directory: string = path.join(os.homedir(), M2_DIR); await io.mkdirP(directory); core.debug(`created directory ${directory}`); await write(directory, generate(id, username, password)); } else { core.debug( - `no auth without username: ${username} and password: ${password}` + `no ${SETTINGS_FILE} without server-id: ${id}, username: ${username}, and a password` ); } } @@ -43,6 +45,6 @@ export function generate(id: string, username: string, password: string) { async function write(directory: string, settings: string) { const options = {encoding: 'utf-8'}; const location = path.join(directory, SETTINGS_FILE); - core.debug(`writing ${location}`); + console.log(`writing ${location}`); return fs.writeFileSync(location, settings, options); } From 4450e92d7814b023e1185a4c81037df93697bcd4 Mon Sep 17 00:00:00 2001 From: Bryan Clark Date: Thu, 28 Nov 2019 13:00:30 -0800 Subject: [PATCH 10/55] Use gitattributes to ignore generated lib js files --- .gitattributes | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..33c6624 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +lib/*.js -diff -merge +lib/*.js linguist-generated=true From 18983b8d3d6bbec73377e2c02d64915f1d0be621 Mon Sep 17 00:00:00 2001 From: Bryan Clark Date: Thu, 28 Nov 2019 13:10:44 -0800 Subject: [PATCH 11/55] Update gitattributes and remove lib files --- .gitattributes | 4 +- dist/index.js | 175 +++++++++++++++++++++++++++++++++++++++++----- lib/auth.js | 62 ---------------- lib/setup-java.js | 46 ------------ 4 files changed, 161 insertions(+), 126 deletions(-) delete mode 100644 lib/auth.js delete mode 100644 lib/setup-java.js diff --git a/.gitattributes b/.gitattributes index 33c6624..f787af8 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1,2 @@ -lib/*.js -diff -merge -lib/*.js linguist-generated=true +dist/index.js -diff -merge +dist/index.js linguist-generated=true diff --git a/dist/index.js b/dist/index.js index 2ec6b32..b904df6 100644 --- a/dist/index.js +++ b/dist/index.js @@ -34,7 +34,7 @@ module.exports = /******/ // the startup function /******/ function startup() { /******/ // Load entry module and return exports -/******/ return __webpack_require__(264); +/******/ return __webpack_require__(429); /******/ }; /******/ /******/ // run startup @@ -71,7 +71,21 @@ module.exports = require("https"); /***/ }), -/***/ 264: +/***/ 357: +/***/ (function(module) { + +module.exports = require("assert"); + +/***/ }), + +/***/ 417: +/***/ (function(module) { + +module.exports = require("crypto"); + +/***/ }), + +/***/ 429: /***/ (function(module, __unusedexports, __webpack_require__) { module.exports = @@ -150,6 +164,82 @@ module.exports = __webpack_require__(211); /***/ 264: /***/ (function(module, __unusedexports, __nested_webpack_require_1759__) { +module.exports = +/******/ (function(modules, runtime) { // webpackBootstrap +/******/ "use strict"; +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) { +/******/ return installedModules[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ __webpack_require__.ab = __dirname + "/"; +/******/ +/******/ // the startup function +/******/ function startup() { +/******/ // Load entry module and return exports +/******/ return __webpack_require__(264); +/******/ }; +/******/ +/******/ // run startup +/******/ return startup(); +/******/ }) +/************************************************************************/ +/******/ ({ + +/***/ 16: +/***/ (function(module) { + +module.exports = __nested_webpack_require_1759__(16); + +/***/ }), + +/***/ 87: +/***/ (function(module) { + +module.exports = __nested_webpack_require_1759__(87); + +/***/ }), + +/***/ 129: +/***/ (function(module) { + +module.exports = __nested_webpack_require_1759__(129); + +/***/ }), + +/***/ 211: +/***/ (function(module) { + +module.exports = __nested_webpack_require_1759__(211); + +/***/ }), + +/***/ 264: +/***/ (function(module, __unusedexports, __nested_webpack_require_1759__) { + module.exports = /******/ (function(modules, runtime) { // webpackBootstrap /******/ "use strict"; @@ -4910,6 +5000,73 @@ module.exports = __nested_webpack_require_1759__(835); /***/ 357: /***/ (function(module) { +module.exports = __nested_webpack_require_1759__(357); + +/***/ }), + +/***/ 417: +/***/ (function(module) { + +module.exports = __nested_webpack_require_1759__(417); + +/***/ }), + +/***/ 605: +/***/ (function(module) { + +module.exports = __nested_webpack_require_1759__(605); + +/***/ }), + +/***/ 614: +/***/ (function(module) { + +module.exports = __nested_webpack_require_1759__(614); + +/***/ }), + +/***/ 622: +/***/ (function(module) { + +module.exports = __nested_webpack_require_1759__(622); + +/***/ }), + +/***/ 631: +/***/ (function(module) { + +module.exports = __nested_webpack_require_1759__(631); + +/***/ }), + +/***/ 669: +/***/ (function(module) { + +module.exports = __nested_webpack_require_1759__(669); + +/***/ }), + +/***/ 747: +/***/ (function(module) { + +module.exports = __nested_webpack_require_1759__(747); + +/***/ }), + +/***/ 835: +/***/ (function(module) { + +module.exports = __nested_webpack_require_1759__(835); + +/***/ }) + +/******/ }); + +/***/ }), + +/***/ 357: +/***/ (function(module) { + module.exports = __webpack_require__(357); /***/ }), @@ -4974,20 +5131,6 @@ module.exports = __webpack_require__(835); /***/ }), -/***/ 357: -/***/ (function(module) { - -module.exports = require("assert"); - -/***/ }), - -/***/ 417: -/***/ (function(module) { - -module.exports = require("crypto"); - -/***/ }), - /***/ 605: /***/ (function(module) { diff --git a/lib/auth.js b/lib/auth.js deleted file mode 100644 index f8d795a..0000000 --- a/lib/auth.js +++ /dev/null @@ -1,62 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - 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) : new P(function (resolve) { resolve(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 fs = __importStar(require("fs")); -const os = __importStar(require("os")); -const path = __importStar(require("path")); -const core = __importStar(require("@actions/core")); -const io = __importStar(require("@actions/io")); -exports.M2_DIR = '.m2'; -exports.SETTINGS_FILE = 'settings.xml'; -function configAuthentication(id, username, password) { - return __awaiter(this, void 0, void 0, function* () { - if (id && username && password) { - console.log(`creating ${exports.SETTINGS_FILE} with server-id: ${id}, username: ${username}, and a password`); - const directory = path.join(os.homedir(), exports.M2_DIR); - yield io.mkdirP(directory); - core.debug(`created directory ${directory}`); - yield write(directory, generate(id, username, password)); - } - else { - core.debug(`no ${exports.SETTINGS_FILE} without server-id: ${id}, username: ${username}, and a password`); - } - }); -} -exports.configAuthentication = configAuthentication; -// only exported for testing purposes -function generate(id, username, password) { - return ` - - - - ${id} - ${username} - ${password} - - - - `; -} -exports.generate = generate; -function write(directory, settings) { - return __awaiter(this, void 0, void 0, function* () { - const options = { encoding: 'utf-8' }; - const location = path.join(directory, exports.SETTINGS_FILE); - console.log(`writing ${location}`); - return fs.writeFileSync(location, settings, options); - }); -} diff --git a/lib/setup-java.js b/lib/setup-java.js deleted file mode 100644 index 5372cbb..0000000 --- a/lib/setup-java.js +++ /dev/null @@ -1,46 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - 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) : new P(function (resolve) { resolve(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 core = __importStar(require("@actions/core")); -const installer = __importStar(require("./installer")); -const auth = __importStar(require("./auth")); -const path = __importStar(require("path")); -function run() { - return __awaiter(this, void 0, void 0, function* () { - try { - let version = core.getInput('version'); - if (!version) { - version = core.getInput('java-version', { required: true }); - } - const arch = core.getInput('architecture', { required: true }); - const jdkFile = core.getInput('jdkFile', { required: false }) || ''; - yield installer.getJava(version, arch, jdkFile); - const matchersPath = path.join(__dirname, '..', '.github'); - console.log(`##[add-matcher]${path.join(matchersPath, 'java.json')}`); - const id = core.getInput('server-id', { required: false }); - const username = core.getInput('username', { required: false }); - const password = core.getInput('password', { required: false }); - if (id && username && password) { - yield auth.configAuthentication(id, username, password); - } - } - catch (error) { - core.setFailed(error.message); - } - }); -} -run(); From 495409509c39e58df677cd2e8a96dba0f80357d6 Mon Sep 17 00:00:00 2001 From: Bryan Clark Date: Fri, 15 Nov 2019 16:01:13 -0800 Subject: [PATCH 12/55] parent 52c60e0768c1c2fabcab3acf97aa77c5dbc32dfa author Bryan Clark 1573862473 -0800 committer Bryan Clark 1574976093 -0800 Adding maven auth support ignore vscode directory move required parameters to auth module username and password are required from within the auth module now. Update the tests to ensure this is the case. Add generated auth and setup-java Move auth to the bottom of setup Support ids generated and pretty files use server-id instead of ambigous id Use console.log where appropriate Adding maven auth support ignore vscode directory move required parameters to auth module username and password are required from within the auth module now. Update the tests to ensure this is the case. Add generated auth and setup-java Move auth to the bottom of setup generated and pretty files use server-id instead of ambigous id --- lib/auth.js | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 lib/auth.js diff --git a/lib/auth.js b/lib/auth.js new file mode 100644 index 0000000..9b03d1c --- /dev/null +++ b/lib/auth.js @@ -0,0 +1,62 @@ +"use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + 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) : new P(function (resolve) { resolve(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 fs = __importStar(require("fs")); +const os = __importStar(require("os")); +const path = __importStar(require("path")); +const core = __importStar(require("@actions/core")); +const io = __importStar(require("@actions/io")); +exports.M2_DIR = '.m2'; +exports.SETTINGS_FILE = 'settings.xml'; +function configAuthentication(id, username, password) { + return __awaiter(this, void 0, void 0, function* () { + if (id && username && password) { + core.debug(`configAuthentication with ${username} and a password`); + const directory = path.join(os.homedir(), exports.M2_DIR); + yield io.mkdirP(directory); + core.debug(`created directory ${directory}`); + yield write(directory, generate(id, username, password)); + } + else { + core.debug(`no auth without username: ${username} and password: ${password}`); + } + }); +} +exports.configAuthentication = configAuthentication; +// only exported for testing purposes +function generate(id, username, password) { + return ` + + + + ${id} + ${username} + ${password} + + + + `; +} +exports.generate = generate; +function write(directory, settings) { + return __awaiter(this, void 0, void 0, function* () { + const options = { encoding: 'utf-8' }; + const location = path.join(directory, exports.SETTINGS_FILE); + core.debug(`writing ${location}`); + return fs.writeFileSync(location, settings, options); + }); +} From 1085a2b8cf57feaccd2de1c5c7c0429486066290 Mon Sep 17 00:00:00 2001 From: Bryan Clark Date: Thu, 28 Nov 2019 12:54:29 -0800 Subject: [PATCH 13/55] Use console.log where appropriate Update gitattributes and remove lib files --- lib/auth.js | 62 ----------------------------------------------------- 1 file changed, 62 deletions(-) delete mode 100644 lib/auth.js diff --git a/lib/auth.js b/lib/auth.js deleted file mode 100644 index 9b03d1c..0000000 --- a/lib/auth.js +++ /dev/null @@ -1,62 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - 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) : new P(function (resolve) { resolve(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 fs = __importStar(require("fs")); -const os = __importStar(require("os")); -const path = __importStar(require("path")); -const core = __importStar(require("@actions/core")); -const io = __importStar(require("@actions/io")); -exports.M2_DIR = '.m2'; -exports.SETTINGS_FILE = 'settings.xml'; -function configAuthentication(id, username, password) { - return __awaiter(this, void 0, void 0, function* () { - if (id && username && password) { - core.debug(`configAuthentication with ${username} and a password`); - const directory = path.join(os.homedir(), exports.M2_DIR); - yield io.mkdirP(directory); - core.debug(`created directory ${directory}`); - yield write(directory, generate(id, username, password)); - } - else { - core.debug(`no auth without username: ${username} and password: ${password}`); - } - }); -} -exports.configAuthentication = configAuthentication; -// only exported for testing purposes -function generate(id, username, password) { - return ` - - - - ${id} - ${username} - ${password} - - - - `; -} -exports.generate = generate; -function write(directory, settings) { - return __awaiter(this, void 0, void 0, function* () { - const options = { encoding: 'utf-8' }; - const location = path.join(directory, exports.SETTINGS_FILE); - core.debug(`writing ${location}`); - return fs.writeFileSync(location, settings, options); - }); -} From c8f8a264b4ccd08f0ca57e0656f9475f4953cef4 Mon Sep 17 00:00:00 2001 From: Bryan Clark Date: Thu, 28 Nov 2019 14:13:35 -0800 Subject: [PATCH 14/55] Add publish section to README --- README.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/README.md b/README.md index 568fd1b..d57bbdd 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,28 @@ jobs: - run: java -cp java HelloWorldApp ``` +Publising to an Apache Maven Repository: +```yaml +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v1 + - name: Set up JDK 1.8 + uses: actions/setup-java@master + with: + java-version: 1.8 + server-id: github # Value of the distributionManagement/repository/id field of the pom.xml + username: ${{ github.actor }} # username for server authentication + password: ${{ github.token }} # password or token for authentication + - name: Build with Maven + run: mvn -B package --file pom.xml + - name: Publish to GitHub Packages Apache Maven + run: mvn deploy +``` + # License The scripts and documentation in this project are released under the [MIT License](LICENSE) From 7d69f8015bb2278c61cd7a41d97c190353d4d452 Mon Sep 17 00:00:00 2001 From: Bryan Clark Date: Thu, 28 Nov 2019 14:13:43 -0800 Subject: [PATCH 15/55] build index.js --- dist/index.js | 149 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 146 insertions(+), 3 deletions(-) diff --git a/dist/index.js b/dist/index.js index b904df6..a2d7b84 100644 --- a/dist/index.js +++ b/dist/index.js @@ -124,7 +124,7 @@ module.exports = /******/ // the startup function /******/ function startup() { /******/ // Load entry module and return exports -/******/ return __webpack_require__(264); +/******/ return __webpack_require__(429); /******/ }; /******/ /******/ // run startup @@ -161,6 +161,96 @@ module.exports = __webpack_require__(211); /***/ }), +/***/ 357: +/***/ (function(module) { + +module.exports = __webpack_require__(357); + +/***/ }), + +/***/ 417: +/***/ (function(module) { + +module.exports = __webpack_require__(417); + +/***/ }), + +/***/ 429: +/***/ (function(module, __unusedexports, __nested_webpack_require_1931__) { + +module.exports = +/******/ (function(modules, runtime) { // webpackBootstrap +/******/ "use strict"; +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) { +/******/ return installedModules[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ __webpack_require__.ab = __dirname + "/"; +/******/ +/******/ // the startup function +/******/ function startup() { +/******/ // Load entry module and return exports +/******/ return __webpack_require__(264); +/******/ }; +/******/ +/******/ // run startup +/******/ return startup(); +/******/ }) +/************************************************************************/ +/******/ ({ + +/***/ 16: +/***/ (function(module) { + +module.exports = __nested_webpack_require_1931__(16); + +/***/ }), + +/***/ 87: +/***/ (function(module) { + +module.exports = __nested_webpack_require_1931__(87); + +/***/ }), + +/***/ 129: +/***/ (function(module) { + +module.exports = __nested_webpack_require_1931__(129); + +/***/ }), + +/***/ 211: +/***/ (function(module) { + +module.exports = __nested_webpack_require_1931__(211); + +/***/ }), + /***/ 264: /***/ (function(module, __unusedexports, __nested_webpack_require_1759__) { @@ -5067,14 +5157,67 @@ module.exports = __nested_webpack_require_1759__(835); /***/ 357: /***/ (function(module) { -module.exports = __webpack_require__(357); +module.exports = __nested_webpack_require_1931__(357); /***/ }), /***/ 417: /***/ (function(module) { -module.exports = __webpack_require__(417); +module.exports = __nested_webpack_require_1931__(417); + +/***/ }), + +/***/ 605: +/***/ (function(module) { + +module.exports = __nested_webpack_require_1931__(605); + +/***/ }), + +/***/ 614: +/***/ (function(module) { + +module.exports = __nested_webpack_require_1931__(614); + +/***/ }), + +/***/ 622: +/***/ (function(module) { + +module.exports = __nested_webpack_require_1931__(622); + +/***/ }), + +/***/ 631: +/***/ (function(module) { + +module.exports = __nested_webpack_require_1931__(631); + +/***/ }), + +/***/ 669: +/***/ (function(module) { + +module.exports = __nested_webpack_require_1931__(669); + +/***/ }), + +/***/ 747: +/***/ (function(module) { + +module.exports = __nested_webpack_require_1931__(747); + +/***/ }), + +/***/ 835: +/***/ (function(module) { + +module.exports = __nested_webpack_require_1931__(835); + +/***/ }) + +/******/ }); /***/ }), From d1d9006723dec017027b4a6a5d8d5c00edb904e8 Mon Sep 17 00:00:00 2001 From: Bryan Clark Date: Thu, 28 Nov 2019 14:18:30 -0800 Subject: [PATCH 16/55] Add fields to action.yml --- action.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/action.yml b/action.yml index 2bcf1ff..912a09c 100644 --- a/action.yml +++ b/action.yml @@ -16,6 +16,15 @@ inputs: jdkFile: description: 'Path to where the compressed JDK is located. The path could be in your source repository or a local path on the agent.' required: false + server-id: + description: 'ID of the distributionManagement repository in the pom.xml file.' + required: false + username: + description: 'Username for authentication to the Apache Maven server.' + required: false + password: + description: 'Passowrd or token for authentication to the Apache Maven server.' + required: false runs: using: 'node12' main: 'dist/index.js' From cda418e54a15b6290a2659671b1b82c78716d1ff Mon Sep 17 00:00:00 2001 From: Bryan Clark Date: Thu, 28 Nov 2019 14:22:38 -0800 Subject: [PATCH 17/55] Update index.js --- dist/index.js | 143 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) diff --git a/dist/index.js b/dist/index.js index a2d7b84..182c079 100644 --- a/dist/index.js +++ b/dist/index.js @@ -178,6 +178,96 @@ module.exports = __webpack_require__(417); /***/ 429: /***/ (function(module, __unusedexports, __nested_webpack_require_1931__) { +module.exports = +/******/ (function(modules, runtime) { // webpackBootstrap +/******/ "use strict"; +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) { +/******/ return installedModules[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ __webpack_require__.ab = __dirname + "/"; +/******/ +/******/ // the startup function +/******/ function startup() { +/******/ // Load entry module and return exports +/******/ return __webpack_require__(429); +/******/ }; +/******/ +/******/ // run startup +/******/ return startup(); +/******/ }) +/************************************************************************/ +/******/ ({ + +/***/ 16: +/***/ (function(module) { + +module.exports = __nested_webpack_require_1931__(16); + +/***/ }), + +/***/ 87: +/***/ (function(module) { + +module.exports = __nested_webpack_require_1931__(87); + +/***/ }), + +/***/ 129: +/***/ (function(module) { + +module.exports = __nested_webpack_require_1931__(129); + +/***/ }), + +/***/ 211: +/***/ (function(module) { + +module.exports = __nested_webpack_require_1931__(211); + +/***/ }), + +/***/ 357: +/***/ (function(module) { + +module.exports = __nested_webpack_require_1931__(357); + +/***/ }), + +/***/ 417: +/***/ (function(module) { + +module.exports = __nested_webpack_require_1931__(417); + +/***/ }), + +/***/ 429: +/***/ (function(module, __unusedexports, __nested_webpack_require_1931__) { + module.exports = /******/ (function(modules, runtime) { // webpackBootstrap /******/ "use strict"; @@ -5224,6 +5314,59 @@ module.exports = __nested_webpack_require_1931__(835); /***/ 605: /***/ (function(module) { +module.exports = __nested_webpack_require_1931__(605); + +/***/ }), + +/***/ 614: +/***/ (function(module) { + +module.exports = __nested_webpack_require_1931__(614); + +/***/ }), + +/***/ 622: +/***/ (function(module) { + +module.exports = __nested_webpack_require_1931__(622); + +/***/ }), + +/***/ 631: +/***/ (function(module) { + +module.exports = __nested_webpack_require_1931__(631); + +/***/ }), + +/***/ 669: +/***/ (function(module) { + +module.exports = __nested_webpack_require_1931__(669); + +/***/ }), + +/***/ 747: +/***/ (function(module) { + +module.exports = __nested_webpack_require_1931__(747); + +/***/ }), + +/***/ 835: +/***/ (function(module) { + +module.exports = __nested_webpack_require_1931__(835); + +/***/ }) + +/******/ }); + +/***/ }), + +/***/ 605: +/***/ (function(module) { + module.exports = __webpack_require__(605); /***/ }), From d2eada383a9872f380c29fb1527b01a5ed7c8c8a Mon Sep 17 00:00:00 2001 From: Bryan Clark Date: Thu, 28 Nov 2019 14:48:36 -0800 Subject: [PATCH 18/55] direct ncc to setup-java --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index aa088e8..28d0e0b 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "build": "tsc", "format": "prettier --write **/*.ts", "format-check": "prettier --check **/*.ts", - "release": "ncc build && git add -f dist/", + "release": "ncc build lib/setup-java.js && git add -f dist/index.js", "test": "jest" }, "repository": { From ade090c5cf2d27d9efad6eff0763ff6c5f27c632 Mon Sep 17 00:00:00 2001 From: Bryan Clark Date: Thu, 28 Nov 2019 14:48:39 -0800 Subject: [PATCH 19/55] Update index.js --- dist/index.js | 6051 +++++++++++++++++++++---------------------------- 1 file changed, 2635 insertions(+), 3416 deletions(-) diff --git a/dist/index.js b/dist/index.js index 182c079..c01c0f3 100644 --- a/dist/index.js +++ b/dist/index.js @@ -34,7 +34,7 @@ module.exports = /******/ // the startup function /******/ function startup() { /******/ // Load entry module and return exports -/******/ return __webpack_require__(429); +/******/ return __webpack_require__(423); /******/ }; /******/ /******/ // run startup @@ -43,6 +43,882 @@ module.exports = /************************************************************************/ /******/ ({ +/***/ 1: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + 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) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const childProcess = __webpack_require__(129); +const path = __webpack_require__(622); +const util_1 = __webpack_require__(669); +const ioUtil = __webpack_require__(672); +const exec = util_1.promisify(childProcess.exec); +/** + * Copies a file or folder. + * Based off of shelljs - https://github.com/shelljs/shelljs/blob/9237f66c52e5daa40458f94f9565e18e8132f5a6/src/cp.js + * + * @param source source path + * @param dest destination path + * @param options optional. See CopyOptions. + */ +function cp(source, dest, options = {}) { + return __awaiter(this, void 0, void 0, function* () { + const { force, recursive } = readCopyOptions(options); + const destStat = (yield ioUtil.exists(dest)) ? yield ioUtil.stat(dest) : null; + // Dest is an existing file, but not forcing + if (destStat && destStat.isFile() && !force) { + return; + } + // If dest is an existing directory, should copy inside. + const newDest = destStat && destStat.isDirectory() + ? path.join(dest, path.basename(source)) + : dest; + if (!(yield ioUtil.exists(source))) { + throw new Error(`no such file or directory: ${source}`); + } + const sourceStat = yield ioUtil.stat(source); + if (sourceStat.isDirectory()) { + if (!recursive) { + throw new Error(`Failed to copy. ${source} is a directory, but tried to copy without recursive flag.`); + } + else { + yield cpDirRecursive(source, newDest, 0, force); + } + } + else { + if (path.relative(source, newDest) === '') { + // a file cannot be copied to itself + throw new Error(`'${newDest}' and '${source}' are the same file`); + } + yield copyFile(source, newDest, force); + } + }); +} +exports.cp = cp; +/** + * Moves a path. + * + * @param source source path + * @param dest destination path + * @param options optional. See MoveOptions. + */ +function mv(source, dest, options = {}) { + return __awaiter(this, void 0, void 0, function* () { + if (yield ioUtil.exists(dest)) { + let destExists = true; + if (yield ioUtil.isDirectory(dest)) { + // If dest is directory copy src into dest + dest = path.join(dest, path.basename(source)); + destExists = yield ioUtil.exists(dest); + } + if (destExists) { + if (options.force == null || options.force) { + yield rmRF(dest); + } + else { + throw new Error('Destination already exists'); + } + } + } + yield mkdirP(path.dirname(dest)); + yield ioUtil.rename(source, dest); + }); +} +exports.mv = mv; +/** + * Remove a path recursively with force + * + * @param inputPath path to remove + */ +function rmRF(inputPath) { + return __awaiter(this, void 0, void 0, function* () { + if (ioUtil.IS_WINDOWS) { + // Node doesn't provide a delete operation, only an unlink function. This means that if the file is being used by another + // program (e.g. antivirus), it won't be deleted. To address this, we shell out the work to rd/del. + try { + if (yield ioUtil.isDirectory(inputPath, true)) { + yield exec(`rd /s /q "${inputPath}"`); + } + else { + yield exec(`del /f /a "${inputPath}"`); + } + } + catch (err) { + // if you try to delete a file that doesn't exist, desired result is achieved + // other errors are valid + if (err.code !== 'ENOENT') + throw err; + } + // Shelling out fails to remove a symlink folder with missing source, this unlink catches that + try { + yield ioUtil.unlink(inputPath); + } + catch (err) { + // if you try to delete a file that doesn't exist, desired result is achieved + // other errors are valid + if (err.code !== 'ENOENT') + throw err; + } + } + else { + let isDir = false; + try { + isDir = yield ioUtil.isDirectory(inputPath); + } + catch (err) { + // if you try to delete a file that doesn't exist, desired result is achieved + // other errors are valid + if (err.code !== 'ENOENT') + throw err; + return; + } + if (isDir) { + yield exec(`rm -rf "${inputPath}"`); + } + else { + yield ioUtil.unlink(inputPath); + } + } + }); +} +exports.rmRF = rmRF; +/** + * Make a directory. Creates the full path with folders in between + * Will throw if it fails + * + * @param fsPath path to create + * @returns Promise + */ +function mkdirP(fsPath) { + return __awaiter(this, void 0, void 0, function* () { + yield ioUtil.mkdirP(fsPath); + }); +} +exports.mkdirP = mkdirP; +/** + * Returns path of a tool had the tool actually been invoked. Resolves via paths. + * If you check and the tool does not exist, it will throw. + * + * @param tool name of the tool + * @param check whether to check if tool exists + * @returns Promise path to tool + */ +function which(tool, check) { + return __awaiter(this, void 0, void 0, function* () { + if (!tool) { + throw new Error("parameter 'tool' is required"); + } + // recursive when check=true + if (check) { + const result = yield which(tool, false); + if (!result) { + if (ioUtil.IS_WINDOWS) { + throw new Error(`Unable to locate executable file: ${tool}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also verify the file has a valid extension for an executable file.`); + } + else { + throw new Error(`Unable to locate executable file: ${tool}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also check the file mode to verify the file is executable.`); + } + } + } + try { + // build the list of extensions to try + const extensions = []; + if (ioUtil.IS_WINDOWS && process.env.PATHEXT) { + for (const extension of process.env.PATHEXT.split(path.delimiter)) { + if (extension) { + extensions.push(extension); + } + } + } + // if it's rooted, return it if exists. otherwise return empty. + if (ioUtil.isRooted(tool)) { + const filePath = yield ioUtil.tryGetExecutablePath(tool, extensions); + if (filePath) { + return filePath; + } + return ''; + } + // if any path separators, return empty + if (tool.includes('/') || (ioUtil.IS_WINDOWS && tool.includes('\\'))) { + return ''; + } + // build the list of directories + // + // Note, technically "where" checks the current directory on Windows. From a task lib perspective, + // it feels like we should not do this. Checking the current directory seems like more of a use + // case of a shell, and the which() function exposed by the task lib should strive for consistency + // across platforms. + const directories = []; + if (process.env.PATH) { + for (const p of process.env.PATH.split(path.delimiter)) { + if (p) { + directories.push(p); + } + } + } + // return the first match + for (const directory of directories) { + const filePath = yield ioUtil.tryGetExecutablePath(directory + path.sep + tool, extensions); + if (filePath) { + return filePath; + } + } + return ''; + } + catch (err) { + throw new Error(`which failed with message ${err.message}`); + } + }); +} +exports.which = which; +function readCopyOptions(options) { + const force = options.force == null ? true : options.force; + const recursive = Boolean(options.recursive); + return { force, recursive }; +} +function cpDirRecursive(sourceDir, destDir, currentDepth, force) { + return __awaiter(this, void 0, void 0, function* () { + // Ensure there is not a run away recursive copy + if (currentDepth >= 255) + return; + currentDepth++; + yield mkdirP(destDir); + const files = yield ioUtil.readdir(sourceDir); + for (const fileName of files) { + const srcFile = `${sourceDir}/${fileName}`; + const destFile = `${destDir}/${fileName}`; + const srcFileStat = yield ioUtil.lstat(srcFile); + if (srcFileStat.isDirectory()) { + // Recurse + yield cpDirRecursive(srcFile, destFile, currentDepth, force); + } + else { + yield copyFile(srcFile, destFile, force); + } + } + // Change the mode for the newly created directory + yield ioUtil.chmod(destDir, (yield ioUtil.stat(sourceDir)).mode); + }); +} +// Buffered file copy +function copyFile(srcFile, destFile, force) { + return __awaiter(this, void 0, void 0, function* () { + if ((yield ioUtil.lstat(srcFile)).isSymbolicLink()) { + // unlink/re-link it + try { + yield ioUtil.lstat(destFile); + yield ioUtil.unlink(destFile); + } + catch (e) { + // Try to override file permission + if (e.code === 'EPERM') { + yield ioUtil.chmod(destFile, '0666'); + yield ioUtil.unlink(destFile); + } + // other errors = it doesn't exist, no work to do + } + // Copy over symlink + const symlinkFull = yield ioUtil.readlink(srcFile); + yield ioUtil.symlink(symlinkFull, destFile, ioUtil.IS_WINDOWS ? 'junction' : null); + } + else if (!(yield ioUtil.exists(destFile)) || force) { + yield ioUtil.copyFile(srcFile, destFile); + } + }); +} +//# sourceMappingURL=io.js.map + +/***/ }), + +/***/ 9: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + 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) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const os = __webpack_require__(87); +const events = __webpack_require__(614); +const child = __webpack_require__(129); +/* eslint-disable @typescript-eslint/unbound-method */ +const IS_WINDOWS = process.platform === 'win32'; +/* + * Class for running command line tools. Handles quoting and arg parsing in a platform agnostic way. + */ +class ToolRunner extends events.EventEmitter { + constructor(toolPath, args, options) { + super(); + if (!toolPath) { + throw new Error("Parameter 'toolPath' cannot be null or empty."); + } + this.toolPath = toolPath; + this.args = args || []; + this.options = options || {}; + } + _debug(message) { + if (this.options.listeners && this.options.listeners.debug) { + this.options.listeners.debug(message); + } + } + _getCommandString(options, noPrefix) { + const toolPath = this._getSpawnFileName(); + const args = this._getSpawnArgs(options); + let cmd = noPrefix ? '' : '[command]'; // omit prefix when piped to a second tool + if (IS_WINDOWS) { + // Windows + cmd file + if (this._isCmdFile()) { + cmd += toolPath; + for (const a of args) { + cmd += ` ${a}`; + } + } + // Windows + verbatim + else if (options.windowsVerbatimArguments) { + cmd += `"${toolPath}"`; + for (const a of args) { + cmd += ` ${a}`; + } + } + // Windows (regular) + else { + cmd += this._windowsQuoteCmdArg(toolPath); + for (const a of args) { + cmd += ` ${this._windowsQuoteCmdArg(a)}`; + } + } + } + else { + // OSX/Linux - this can likely be improved with some form of quoting. + // creating processes on Unix is fundamentally different than Windows. + // on Unix, execvp() takes an arg array. + cmd += toolPath; + for (const a of args) { + cmd += ` ${a}`; + } + } + return cmd; + } + _processLineBuffer(data, strBuffer, onLine) { + try { + let s = strBuffer + data.toString(); + let n = s.indexOf(os.EOL); + while (n > -1) { + const line = s.substring(0, n); + onLine(line); + // the rest of the string ... + s = s.substring(n + os.EOL.length); + n = s.indexOf(os.EOL); + } + strBuffer = s; + } + catch (err) { + // streaming lines to console is best effort. Don't fail a build. + this._debug(`error processing line. Failed with error ${err}`); + } + } + _getSpawnFileName() { + if (IS_WINDOWS) { + if (this._isCmdFile()) { + return process.env['COMSPEC'] || 'cmd.exe'; + } + } + return this.toolPath; + } + _getSpawnArgs(options) { + if (IS_WINDOWS) { + if (this._isCmdFile()) { + let argline = `/D /S /C "${this._windowsQuoteCmdArg(this.toolPath)}`; + for (const a of this.args) { + argline += ' '; + argline += options.windowsVerbatimArguments + ? a + : this._windowsQuoteCmdArg(a); + } + argline += '"'; + return [argline]; + } + } + return this.args; + } + _endsWith(str, end) { + return str.endsWith(end); + } + _isCmdFile() { + const upperToolPath = this.toolPath.toUpperCase(); + return (this._endsWith(upperToolPath, '.CMD') || + this._endsWith(upperToolPath, '.BAT')); + } + _windowsQuoteCmdArg(arg) { + // for .exe, apply the normal quoting rules that libuv applies + if (!this._isCmdFile()) { + return this._uvQuoteCmdArg(arg); + } + // otherwise apply quoting rules specific to the cmd.exe command line parser. + // the libuv rules are generic and are not designed specifically for cmd.exe + // command line parser. + // + // for a detailed description of the cmd.exe command line parser, refer to + // http://stackoverflow.com/questions/4094699/how-does-the-windows-command-interpreter-cmd-exe-parse-scripts/7970912#7970912 + // need quotes for empty arg + if (!arg) { + return '""'; + } + // determine whether the arg needs to be quoted + const cmdSpecialChars = [ + ' ', + '\t', + '&', + '(', + ')', + '[', + ']', + '{', + '}', + '^', + '=', + ';', + '!', + "'", + '+', + ',', + '`', + '~', + '|', + '<', + '>', + '"' + ]; + let needsQuotes = false; + for (const char of arg) { + if (cmdSpecialChars.some(x => x === char)) { + needsQuotes = true; + break; + } + } + // short-circuit if quotes not needed + if (!needsQuotes) { + return arg; + } + // the following quoting rules are very similar to the rules that by libuv applies. + // + // 1) wrap the string in quotes + // + // 2) double-up quotes - i.e. " => "" + // + // this is different from the libuv quoting rules. libuv replaces " with \", which unfortunately + // doesn't work well with a cmd.exe command line. + // + // note, replacing " with "" also works well if the arg is passed to a downstream .NET console app. + // for example, the command line: + // foo.exe "myarg:""my val""" + // is parsed by a .NET console app into an arg array: + // [ "myarg:\"my val\"" ] + // which is the same end result when applying libuv quoting rules. although the actual + // command line from libuv quoting rules would look like: + // foo.exe "myarg:\"my val\"" + // + // 3) double-up slashes that preceed a quote, + // e.g. hello \world => "hello \world" + // hello\"world => "hello\\""world" + // hello\\"world => "hello\\\\""world" + // hello world\ => "hello world\\" + // + // technically this is not required for a cmd.exe command line, or the batch argument parser. + // the reasons for including this as a .cmd quoting rule are: + // + // a) this is optimized for the scenario where the argument is passed from the .cmd file to an + // external program. many programs (e.g. .NET console apps) rely on the slash-doubling rule. + // + // b) it's what we've been doing previously (by deferring to node default behavior) and we + // haven't heard any complaints about that aspect. + // + // note, a weakness of the quoting rules chosen here, is that % is not escaped. in fact, % cannot be + // escaped when used on the command line directly - even though within a .cmd file % can be escaped + // by using %%. + // + // the saving grace is, on the command line, %var% is left as-is if var is not defined. this contrasts + // the line parsing rules within a .cmd file, where if var is not defined it is replaced with nothing. + // + // one option that was explored was replacing % with ^% - i.e. %var% => ^%var^%. this hack would + // often work, since it is unlikely that var^ would exist, and the ^ character is removed when the + // variable is used. the problem, however, is that ^ is not removed when %* is used to pass the args + // to an external program. + // + // an unexplored potential solution for the % escaping problem, is to create a wrapper .cmd file. + // % can be escaped within a .cmd file. + let reverse = '"'; + let quoteHit = true; + for (let i = arg.length; i > 0; i--) { + // walk the string in reverse + reverse += arg[i - 1]; + if (quoteHit && arg[i - 1] === '\\') { + reverse += '\\'; // double the slash + } + else if (arg[i - 1] === '"') { + quoteHit = true; + reverse += '"'; // double the quote + } + else { + quoteHit = false; + } + } + reverse += '"'; + return reverse + .split('') + .reverse() + .join(''); + } + _uvQuoteCmdArg(arg) { + // Tool runner wraps child_process.spawn() and needs to apply the same quoting as + // Node in certain cases where the undocumented spawn option windowsVerbatimArguments + // is used. + // + // Since this function is a port of quote_cmd_arg from Node 4.x (technically, lib UV, + // see https://github.com/nodejs/node/blob/v4.x/deps/uv/src/win/process.c for details), + // pasting copyright notice from Node within this function: + // + // Copyright Joyent, Inc. and other Node contributors. All rights reserved. + // + // Permission is hereby granted, free of charge, to any person obtaining a copy + // of this software and associated documentation files (the "Software"), to + // deal in the Software without restriction, including without limitation the + // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + // sell copies of the Software, and to permit persons to whom the Software is + // furnished to do so, subject to the following conditions: + // + // The above copyright notice and this permission notice shall be included in + // all copies or substantial portions of the Software. + // + // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + // IN THE SOFTWARE. + if (!arg) { + // Need double quotation for empty argument + return '""'; + } + if (!arg.includes(' ') && !arg.includes('\t') && !arg.includes('"')) { + // No quotation needed + return arg; + } + if (!arg.includes('"') && !arg.includes('\\')) { + // No embedded double quotes or backslashes, so I can just wrap + // quote marks around the whole thing. + return `"${arg}"`; + } + // Expected input/output: + // input : hello"world + // output: "hello\"world" + // input : hello""world + // output: "hello\"\"world" + // input : hello\world + // output: hello\world + // input : hello\\world + // output: hello\\world + // input : hello\"world + // output: "hello\\\"world" + // input : hello\\"world + // output: "hello\\\\\"world" + // input : hello world\ + // output: "hello world\\" - note the comment in libuv actually reads "hello world\" + // but it appears the comment is wrong, it should be "hello world\\" + let reverse = '"'; + let quoteHit = true; + for (let i = arg.length; i > 0; i--) { + // walk the string in reverse + reverse += arg[i - 1]; + if (quoteHit && arg[i - 1] === '\\') { + reverse += '\\'; + } + else if (arg[i - 1] === '"') { + quoteHit = true; + reverse += '\\'; + } + else { + quoteHit = false; + } + } + reverse += '"'; + return reverse + .split('') + .reverse() + .join(''); + } + _cloneExecOptions(options) { + options = options || {}; + const result = { + cwd: options.cwd || process.cwd(), + env: options.env || process.env, + silent: options.silent || false, + windowsVerbatimArguments: options.windowsVerbatimArguments || false, + failOnStdErr: options.failOnStdErr || false, + ignoreReturnCode: options.ignoreReturnCode || false, + delay: options.delay || 10000 + }; + result.outStream = options.outStream || process.stdout; + result.errStream = options.errStream || process.stderr; + return result; + } + _getSpawnOptions(options, toolPath) { + options = options || {}; + const result = {}; + result.cwd = options.cwd; + result.env = options.env; + result['windowsVerbatimArguments'] = + options.windowsVerbatimArguments || this._isCmdFile(); + if (options.windowsVerbatimArguments) { + result.argv0 = `"${toolPath}"`; + } + return result; + } + /** + * Exec a tool. + * Output will be streamed to the live console. + * Returns promise with return code + * + * @param tool path to tool to exec + * @param options optional exec options. See ExecOptions + * @returns number + */ + exec() { + return __awaiter(this, void 0, void 0, function* () { + return new Promise((resolve, reject) => { + this._debug(`exec tool: ${this.toolPath}`); + this._debug('arguments:'); + for (const arg of this.args) { + this._debug(` ${arg}`); + } + const optionsNonNull = this._cloneExecOptions(this.options); + if (!optionsNonNull.silent && optionsNonNull.outStream) { + optionsNonNull.outStream.write(this._getCommandString(optionsNonNull) + os.EOL); + } + const state = new ExecState(optionsNonNull, this.toolPath); + state.on('debug', (message) => { + this._debug(message); + }); + const fileName = this._getSpawnFileName(); + const cp = child.spawn(fileName, this._getSpawnArgs(optionsNonNull), this._getSpawnOptions(this.options, fileName)); + const stdbuffer = ''; + if (cp.stdout) { + cp.stdout.on('data', (data) => { + if (this.options.listeners && this.options.listeners.stdout) { + this.options.listeners.stdout(data); + } + if (!optionsNonNull.silent && optionsNonNull.outStream) { + optionsNonNull.outStream.write(data); + } + this._processLineBuffer(data, stdbuffer, (line) => { + if (this.options.listeners && this.options.listeners.stdline) { + this.options.listeners.stdline(line); + } + }); + }); + } + const errbuffer = ''; + if (cp.stderr) { + cp.stderr.on('data', (data) => { + state.processStderr = true; + if (this.options.listeners && this.options.listeners.stderr) { + this.options.listeners.stderr(data); + } + if (!optionsNonNull.silent && + optionsNonNull.errStream && + optionsNonNull.outStream) { + const s = optionsNonNull.failOnStdErr + ? optionsNonNull.errStream + : optionsNonNull.outStream; + s.write(data); + } + this._processLineBuffer(data, errbuffer, (line) => { + if (this.options.listeners && this.options.listeners.errline) { + this.options.listeners.errline(line); + } + }); + }); + } + cp.on('error', (err) => { + state.processError = err.message; + state.processExited = true; + state.processClosed = true; + state.CheckComplete(); + }); + cp.on('exit', (code) => { + state.processExitCode = code; + state.processExited = true; + this._debug(`Exit code ${code} received from tool '${this.toolPath}'`); + state.CheckComplete(); + }); + cp.on('close', (code) => { + state.processExitCode = code; + state.processExited = true; + state.processClosed = true; + this._debug(`STDIO streams have closed for tool '${this.toolPath}'`); + state.CheckComplete(); + }); + state.on('done', (error, exitCode) => { + if (stdbuffer.length > 0) { + this.emit('stdline', stdbuffer); + } + if (errbuffer.length > 0) { + this.emit('errline', errbuffer); + } + cp.removeAllListeners(); + if (error) { + reject(error); + } + else { + resolve(exitCode); + } + }); + }); + }); + } +} +exports.ToolRunner = ToolRunner; +/** + * Convert an arg string to an array of args. Handles escaping + * + * @param argString string of arguments + * @returns string[] array of arguments + */ +function argStringToArray(argString) { + const args = []; + let inQuotes = false; + let escaped = false; + let arg = ''; + function append(c) { + // we only escape double quotes. + if (escaped && c !== '"') { + arg += '\\'; + } + arg += c; + escaped = false; + } + for (let i = 0; i < argString.length; i++) { + const c = argString.charAt(i); + if (c === '"') { + if (!escaped) { + inQuotes = !inQuotes; + } + else { + append(c); + } + continue; + } + if (c === '\\' && escaped) { + append(c); + continue; + } + if (c === '\\' && inQuotes) { + escaped = true; + continue; + } + if (c === ' ' && !inQuotes) { + if (arg.length > 0) { + args.push(arg); + arg = ''; + } + continue; + } + append(c); + } + if (arg.length > 0) { + args.push(arg.trim()); + } + return args; +} +exports.argStringToArray = argStringToArray; +class ExecState extends events.EventEmitter { + constructor(options, toolPath) { + super(); + this.processClosed = false; // tracks whether the process has exited and stdio is closed + this.processError = ''; + this.processExitCode = 0; + this.processExited = false; // tracks whether the process has exited + this.processStderr = false; // tracks whether stderr was written to + this.delay = 10000; // 10 seconds + this.done = false; + this.timeout = null; + if (!toolPath) { + throw new Error('toolPath must not be empty'); + } + this.options = options; + this.toolPath = toolPath; + if (options.delay) { + this.delay = options.delay; + } + } + CheckComplete() { + if (this.done) { + return; + } + if (this.processClosed) { + this._setResult(); + } + else if (this.processExited) { + this.timeout = setTimeout(ExecState.HandleTimeout, this.delay, this); + } + } + _debug(message) { + this.emit('debug', message); + } + _setResult() { + // determine whether there is an error + let error; + if (this.processExited) { + if (this.processError) { + error = new Error(`There was an error when attempting to execute the process '${this.toolPath}'. This may indicate the process failed to start. Error: ${this.processError}`); + } + else if (this.processExitCode !== 0 && !this.options.ignoreReturnCode) { + error = new Error(`The process '${this.toolPath}' failed with exit code ${this.processExitCode}`); + } + else if (this.processStderr && this.options.failOnStdErr) { + error = new Error(`The process '${this.toolPath}' failed because one or more lines were written to the STDERR stream`); + } + } + // clear the timeout + if (this.timeout) { + clearTimeout(this.timeout); + this.timeout = null; + } + this.done = true; + this.emit('done', error, this.processExitCode); + } + static HandleTimeout(state) { + if (state.done) { + return; + } + if (!state.processClosed && state.processExited) { + const message = `The STDIO streams did not close within ${state.delay / + 1000} seconds of the exit event from process '${state.toolPath}'. This may indicate a child process inherited the STDIO streams and has not yet exited.`; + state._debug(message); + } + state._setResult(); + } +} +//# sourceMappingURL=toolrunner.js.map + +/***/ }), + /***/ 16: /***/ (function(module) { @@ -62,6 +938,276 @@ module.exports = require("os"); module.exports = require("child_process"); +/***/ }), + +/***/ 139: +/***/ (function(module, __unusedexports, __webpack_require__) { + +// Unique ID creation requires a high quality random # generator. In node.js +// this is pretty straight-forward - we use the crypto API. + +var crypto = __webpack_require__(417); + +module.exports = function nodeRNG() { + return crypto.randomBytes(16); +}; + + +/***/ }), + +/***/ 141: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + + +var net = __webpack_require__(631); +var tls = __webpack_require__(16); +var http = __webpack_require__(605); +var https = __webpack_require__(211); +var events = __webpack_require__(614); +var assert = __webpack_require__(357); +var util = __webpack_require__(669); + + +exports.httpOverHttp = httpOverHttp; +exports.httpsOverHttp = httpsOverHttp; +exports.httpOverHttps = httpOverHttps; +exports.httpsOverHttps = httpsOverHttps; + + +function httpOverHttp(options) { + var agent = new TunnelingAgent(options); + agent.request = http.request; + return agent; +} + +function httpsOverHttp(options) { + var agent = new TunnelingAgent(options); + agent.request = http.request; + agent.createSocket = createSecureSocket; + return agent; +} + +function httpOverHttps(options) { + var agent = new TunnelingAgent(options); + agent.request = https.request; + return agent; +} + +function httpsOverHttps(options) { + var agent = new TunnelingAgent(options); + agent.request = https.request; + agent.createSocket = createSecureSocket; + return agent; +} + + +function TunnelingAgent(options) { + var self = this; + self.options = options || {}; + self.proxyOptions = self.options.proxy || {}; + self.maxSockets = self.options.maxSockets || http.Agent.defaultMaxSockets; + self.requests = []; + self.sockets = []; + + self.on('free', function onFree(socket, host, port, localAddress) { + var options = toOptions(host, port, localAddress); + for (var i = 0, len = self.requests.length; i < len; ++i) { + var pending = self.requests[i]; + if (pending.host === options.host && pending.port === options.port) { + // Detect the request to connect same origin server, + // reuse the connection. + self.requests.splice(i, 1); + pending.request.onSocket(socket); + return; + } + } + socket.destroy(); + self.removeSocket(socket); + }); +} +util.inherits(TunnelingAgent, events.EventEmitter); + +TunnelingAgent.prototype.addRequest = function addRequest(req, host, port, localAddress) { + var self = this; + var options = mergeOptions({request: req}, self.options, toOptions(host, port, localAddress)); + + if (self.sockets.length >= this.maxSockets) { + // We are over limit so we'll add it to the queue. + self.requests.push(options); + return; + } + + // If we are under maxSockets create a new one. + self.createSocket(options, function(socket) { + socket.on('free', onFree); + socket.on('close', onCloseOrRemove); + socket.on('agentRemove', onCloseOrRemove); + req.onSocket(socket); + + function onFree() { + self.emit('free', socket, options); + } + + function onCloseOrRemove(err) { + self.removeSocket(socket); + socket.removeListener('free', onFree); + socket.removeListener('close', onCloseOrRemove); + socket.removeListener('agentRemove', onCloseOrRemove); + } + }); +}; + +TunnelingAgent.prototype.createSocket = function createSocket(options, cb) { + var self = this; + var placeholder = {}; + self.sockets.push(placeholder); + + var connectOptions = mergeOptions({}, self.proxyOptions, { + method: 'CONNECT', + path: options.host + ':' + options.port, + agent: false + }); + if (connectOptions.proxyAuth) { + connectOptions.headers = connectOptions.headers || {}; + connectOptions.headers['Proxy-Authorization'] = 'Basic ' + + new Buffer(connectOptions.proxyAuth).toString('base64'); + } + + debug('making CONNECT request'); + var connectReq = self.request(connectOptions); + connectReq.useChunkedEncodingByDefault = false; // for v0.6 + connectReq.once('response', onResponse); // for v0.6 + connectReq.once('upgrade', onUpgrade); // for v0.6 + connectReq.once('connect', onConnect); // for v0.7 or later + connectReq.once('error', onError); + connectReq.end(); + + function onResponse(res) { + // Very hacky. This is necessary to avoid http-parser leaks. + res.upgrade = true; + } + + function onUpgrade(res, socket, head) { + // Hacky. + process.nextTick(function() { + onConnect(res, socket, head); + }); + } + + function onConnect(res, socket, head) { + connectReq.removeAllListeners(); + socket.removeAllListeners(); + + if (res.statusCode === 200) { + assert.equal(head.length, 0); + debug('tunneling connection has established'); + self.sockets[self.sockets.indexOf(placeholder)] = socket; + cb(socket); + } else { + debug('tunneling socket could not be established, statusCode=%d', + res.statusCode); + var error = new Error('tunneling socket could not be established, ' + + 'statusCode=' + res.statusCode); + error.code = 'ECONNRESET'; + options.request.emit('error', error); + self.removeSocket(placeholder); + } + } + + function onError(cause) { + connectReq.removeAllListeners(); + + debug('tunneling socket could not be established, cause=%s\n', + cause.message, cause.stack); + var error = new Error('tunneling socket could not be established, ' + + 'cause=' + cause.message); + error.code = 'ECONNRESET'; + options.request.emit('error', error); + self.removeSocket(placeholder); + } +}; + +TunnelingAgent.prototype.removeSocket = function removeSocket(socket) { + var pos = this.sockets.indexOf(socket) + if (pos === -1) { + return; + } + this.sockets.splice(pos, 1); + + var pending = this.requests.shift(); + if (pending) { + // If we have pending requests and a socket gets closed a new one + // needs to be created to take over in the pool for the one that closed. + this.createSocket(pending, function(socket) { + pending.request.onSocket(socket); + }); + } +}; + +function createSecureSocket(options, cb) { + var self = this; + TunnelingAgent.prototype.createSocket.call(self, options, function(socket) { + var hostHeader = options.request.getHeader('host'); + var tlsOptions = mergeOptions({}, self.options, { + socket: socket, + servername: hostHeader ? hostHeader.replace(/:.*$/, '') : options.host + }); + + // 0 is dummy port for v0.6 + var secureSocket = tls.connect(0, tlsOptions); + self.sockets[self.sockets.indexOf(socket)] = secureSocket; + cb(secureSocket); + }); +} + + +function toOptions(host, port, localAddress) { + if (typeof host === 'string') { // since v0.10 + return { + host: host, + port: port, + localAddress: localAddress + }; + } + return host; // for v0.11 or later +} + +function mergeOptions(target) { + for (var i = 1, len = arguments.length; i < len; ++i) { + var overrides = arguments[i]; + if (typeof overrides === 'object') { + var keys = Object.keys(overrides); + for (var j = 0, keyLen = keys.length; j < keyLen; ++j) { + var k = keys[j]; + if (overrides[k] !== undefined) { + target[k] = overrides[k]; + } + } + } + } + return target; +} + + +var debug; +if (process.env.NODE_DEBUG && /\btunnel\b/.test(process.env.NODE_DEBUG)) { + debug = function() { + var args = Array.prototype.slice.call(arguments); + if (typeof args[0] === 'string') { + args[0] = 'TUNNEL: ' + args[0]; + } else { + args.unshift('TUNNEL:'); + } + console.error.apply(console, args); + } +} else { + debug = function() {}; +} +exports.debug = debug; // for test + + /***/ }), /***/ 211: @@ -71,1086 +1217,7 @@ module.exports = require("https"); /***/ }), -/***/ 357: -/***/ (function(module) { - -module.exports = require("assert"); - -/***/ }), - -/***/ 417: -/***/ (function(module) { - -module.exports = require("crypto"); - -/***/ }), - -/***/ 429: -/***/ (function(module, __unusedexports, __webpack_require__) { - -module.exports = -/******/ (function(modules, runtime) { // webpackBootstrap -/******/ "use strict"; -/******/ // The module cache -/******/ var installedModules = {}; -/******/ -/******/ // The require function -/******/ function __webpack_require__(moduleId) { -/******/ -/******/ // Check if module is in cache -/******/ if(installedModules[moduleId]) { -/******/ return installedModules[moduleId].exports; -/******/ } -/******/ // Create a new module (and put it into the cache) -/******/ var module = installedModules[moduleId] = { -/******/ i: moduleId, -/******/ l: false, -/******/ exports: {} -/******/ }; -/******/ -/******/ // Execute the module function -/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); -/******/ -/******/ // Flag the module as loaded -/******/ module.l = true; -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/******/ -/******/ __webpack_require__.ab = __dirname + "/"; -/******/ -/******/ // the startup function -/******/ function startup() { -/******/ // Load entry module and return exports -/******/ return __webpack_require__(429); -/******/ }; -/******/ -/******/ // run startup -/******/ return startup(); -/******/ }) -/************************************************************************/ -/******/ ({ - -/***/ 16: -/***/ (function(module) { - -module.exports = __webpack_require__(16); - -/***/ }), - -/***/ 87: -/***/ (function(module) { - -module.exports = __webpack_require__(87); - -/***/ }), - -/***/ 129: -/***/ (function(module) { - -module.exports = __webpack_require__(129); - -/***/ }), - -/***/ 211: -/***/ (function(module) { - -module.exports = __webpack_require__(211); - -/***/ }), - -/***/ 357: -/***/ (function(module) { - -module.exports = __webpack_require__(357); - -/***/ }), - -/***/ 417: -/***/ (function(module) { - -module.exports = __webpack_require__(417); - -/***/ }), - -/***/ 429: -/***/ (function(module, __unusedexports, __nested_webpack_require_1931__) { - -module.exports = -/******/ (function(modules, runtime) { // webpackBootstrap -/******/ "use strict"; -/******/ // The module cache -/******/ var installedModules = {}; -/******/ -/******/ // The require function -/******/ function __webpack_require__(moduleId) { -/******/ -/******/ // Check if module is in cache -/******/ if(installedModules[moduleId]) { -/******/ return installedModules[moduleId].exports; -/******/ } -/******/ // Create a new module (and put it into the cache) -/******/ var module = installedModules[moduleId] = { -/******/ i: moduleId, -/******/ l: false, -/******/ exports: {} -/******/ }; -/******/ -/******/ // Execute the module function -/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); -/******/ -/******/ // Flag the module as loaded -/******/ module.l = true; -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/******/ -/******/ __webpack_require__.ab = __dirname + "/"; -/******/ -/******/ // the startup function -/******/ function startup() { -/******/ // Load entry module and return exports -/******/ return __webpack_require__(429); -/******/ }; -/******/ -/******/ // run startup -/******/ return startup(); -/******/ }) -/************************************************************************/ -/******/ ({ - -/***/ 16: -/***/ (function(module) { - -module.exports = __nested_webpack_require_1931__(16); - -/***/ }), - -/***/ 87: -/***/ (function(module) { - -module.exports = __nested_webpack_require_1931__(87); - -/***/ }), - -/***/ 129: -/***/ (function(module) { - -module.exports = __nested_webpack_require_1931__(129); - -/***/ }), - -/***/ 211: -/***/ (function(module) { - -module.exports = __nested_webpack_require_1931__(211); - -/***/ }), - -/***/ 357: -/***/ (function(module) { - -module.exports = __nested_webpack_require_1931__(357); - -/***/ }), - -/***/ 417: -/***/ (function(module) { - -module.exports = __nested_webpack_require_1931__(417); - -/***/ }), - -/***/ 429: -/***/ (function(module, __unusedexports, __nested_webpack_require_1931__) { - -module.exports = -/******/ (function(modules, runtime) { // webpackBootstrap -/******/ "use strict"; -/******/ // The module cache -/******/ var installedModules = {}; -/******/ -/******/ // The require function -/******/ function __webpack_require__(moduleId) { -/******/ -/******/ // Check if module is in cache -/******/ if(installedModules[moduleId]) { -/******/ return installedModules[moduleId].exports; -/******/ } -/******/ // Create a new module (and put it into the cache) -/******/ var module = installedModules[moduleId] = { -/******/ i: moduleId, -/******/ l: false, -/******/ exports: {} -/******/ }; -/******/ -/******/ // Execute the module function -/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); -/******/ -/******/ // Flag the module as loaded -/******/ module.l = true; -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/******/ -/******/ __webpack_require__.ab = __dirname + "/"; -/******/ -/******/ // the startup function -/******/ function startup() { -/******/ // Load entry module and return exports -/******/ return __webpack_require__(264); -/******/ }; -/******/ -/******/ // run startup -/******/ return startup(); -/******/ }) -/************************************************************************/ -/******/ ({ - -/***/ 16: -/***/ (function(module) { - -module.exports = __nested_webpack_require_1931__(16); - -/***/ }), - -/***/ 87: -/***/ (function(module) { - -module.exports = __nested_webpack_require_1931__(87); - -/***/ }), - -/***/ 129: -/***/ (function(module) { - -module.exports = __nested_webpack_require_1931__(129); - -/***/ }), - -/***/ 211: -/***/ (function(module) { - -module.exports = __nested_webpack_require_1931__(211); - -/***/ }), - -/***/ 264: -/***/ (function(module, __unusedexports, __nested_webpack_require_1759__) { - -module.exports = -/******/ (function(modules, runtime) { // webpackBootstrap -/******/ "use strict"; -/******/ // The module cache -/******/ var installedModules = {}; -/******/ -/******/ // The require function -/******/ function __webpack_require__(moduleId) { -/******/ -/******/ // Check if module is in cache -/******/ if(installedModules[moduleId]) { -/******/ return installedModules[moduleId].exports; -/******/ } -/******/ // Create a new module (and put it into the cache) -/******/ var module = installedModules[moduleId] = { -/******/ i: moduleId, -/******/ l: false, -/******/ exports: {} -/******/ }; -/******/ -/******/ // Execute the module function -/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); -/******/ -/******/ // Flag the module as loaded -/******/ module.l = true; -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/******/ -/******/ __webpack_require__.ab = __dirname + "/"; -/******/ -/******/ // the startup function -/******/ function startup() { -/******/ // Load entry module and return exports -/******/ return __webpack_require__(264); -/******/ }; -/******/ -/******/ // run startup -/******/ return startup(); -/******/ }) -/************************************************************************/ -/******/ ({ - -/***/ 16: -/***/ (function(module) { - -module.exports = __nested_webpack_require_1759__(16); - -/***/ }), - -/***/ 87: -/***/ (function(module) { - -module.exports = __nested_webpack_require_1759__(87); - -/***/ }), - -/***/ 129: -/***/ (function(module) { - -module.exports = __nested_webpack_require_1759__(129); - -/***/ }), - -/***/ 211: -/***/ (function(module) { - -module.exports = __nested_webpack_require_1759__(211); - -/***/ }), - -/***/ 264: -/***/ (function(module, __unusedexports, __nested_webpack_require_1759__) { - -module.exports = -/******/ (function(modules, runtime) { // webpackBootstrap -/******/ "use strict"; -/******/ // The module cache -/******/ var installedModules = {}; -/******/ -/******/ // The require function -/******/ function __webpack_require__(moduleId) { -/******/ -/******/ // Check if module is in cache -/******/ if(installedModules[moduleId]) { -/******/ return installedModules[moduleId].exports; -/******/ } -/******/ // Create a new module (and put it into the cache) -/******/ var module = installedModules[moduleId] = { -/******/ i: moduleId, -/******/ l: false, -/******/ exports: {} -/******/ }; -/******/ -/******/ // Execute the module function -/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); -/******/ -/******/ // Flag the module as loaded -/******/ module.l = true; -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/******/ -/******/ __webpack_require__.ab = __dirname + "/"; -/******/ -/******/ // the startup function -/******/ function startup() { -/******/ // Load entry module and return exports -/******/ return __webpack_require__(429); -/******/ }; -/******/ -/******/ // run startup -/******/ return startup(); -/******/ }) -/************************************************************************/ -/******/ ({ - -/***/ 16: -/***/ (function(module) { - -module.exports = __nested_webpack_require_1759__(16); - -/***/ }), - -/***/ 87: -/***/ (function(module) { - -module.exports = __nested_webpack_require_1759__(87); - -/***/ }), - -/***/ 129: -/***/ (function(module) { - -module.exports = __nested_webpack_require_1759__(129); - -/***/ }), - -/***/ 211: -/***/ (function(module) { - -module.exports = __nested_webpack_require_1759__(211); - -/***/ }), - -/***/ 357: -/***/ (function(module) { - -module.exports = __nested_webpack_require_1759__(357); - -/***/ }), - -/***/ 417: -/***/ (function(module) { - -module.exports = __nested_webpack_require_1759__(417); - -/***/ }), - -/***/ 429: -/***/ (function(module, __unusedexports, __nested_webpack_require_1931__) { - -module.exports = -/******/ (function(modules, runtime) { // webpackBootstrap -/******/ "use strict"; -/******/ // The module cache -/******/ var installedModules = {}; -/******/ -/******/ // The require function -/******/ function __webpack_require__(moduleId) { -/******/ -/******/ // Check if module is in cache -/******/ if(installedModules[moduleId]) { -/******/ return installedModules[moduleId].exports; -/******/ } -/******/ // Create a new module (and put it into the cache) -/******/ var module = installedModules[moduleId] = { -/******/ i: moduleId, -/******/ l: false, -/******/ exports: {} -/******/ }; -/******/ -/******/ // Execute the module function -/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); -/******/ -/******/ // Flag the module as loaded -/******/ module.l = true; -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/******/ -/******/ __webpack_require__.ab = __dirname + "/"; -/******/ -/******/ // the startup function -/******/ function startup() { -/******/ // Load entry module and return exports -/******/ return __webpack_require__(606); -/******/ }; -/******/ -/******/ // run startup -/******/ return startup(); -/******/ }) -/************************************************************************/ -/******/ ({ - -/***/ 16: -/***/ (function(module) { - -module.exports = __nested_webpack_require_1931__(16); - -/***/ }), - -/***/ 87: -/***/ (function(module) { - -module.exports = __nested_webpack_require_1931__(87); - -/***/ }), - -/***/ 113: -/***/ (function(__unusedmodule, exports, __nested_webpack_require_1581__) { - -"use strict"; - -// Copyright (c) Microsoft. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - 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) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", { value: true }); -const url = __nested_webpack_require_1581__(835); -const http = __nested_webpack_require_1581__(605); -const https = __nested_webpack_require_1581__(211); -let fs; -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["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 = {})); -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((resolve, reject) => __awaiter(this, void 0, void 0, function* () { - let output = ''; - this.message.on('data', (chunk) => { - output += chunk; - }); - this.message.on('end', () => { - resolve(output); - }); - })); - } -} -exports.HttpClientResponse = HttpClientResponse; -function isHttps(requestUrl) { - let parsedUrl = url.parse(requestUrl); - return parsedUrl.protocol === 'https:'; -} -exports.isHttps = isHttps; -var EnvironmentVariables; -(function (EnvironmentVariables) { - EnvironmentVariables["HTTP_PROXY"] = "HTTP_PROXY"; - EnvironmentVariables["HTTPS_PROXY"] = "HTTPS_PROXY"; -})(EnvironmentVariables || (EnvironmentVariables = {})); -class HttpClient { - constructor(userAgent, handlers, requestOptions) { - this._ignoreSslError = false; - this._allowRedirects = true; - 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; - this._httpProxy = requestOptions.proxy; - if (requestOptions.proxy && requestOptions.proxy.proxyBypassHosts) { - this._httpProxyBypassHosts = []; - requestOptions.proxy.proxyBypassHosts.forEach(bypass => { - this._httpProxyBypassHosts.push(new RegExp(bypass, 'i')); - }); - } - this._certConfig = requestOptions.cert; - if (this._certConfig) { - // If using cert, need fs - fs = __nested_webpack_require_1581__(747); - // cache the cert content into memory, so we don't have to read it from disk every time - if (this._certConfig.caFile && fs.existsSync(this._certConfig.caFile)) { - this._ca = fs.readFileSync(this._certConfig.caFile, 'utf8'); - } - if (this._certConfig.certFile && fs.existsSync(this._certConfig.certFile)) { - this._cert = fs.readFileSync(this._certConfig.certFile, 'utf8'); - } - if (this._certConfig.keyFile && fs.existsSync(this._certConfig.keyFile)) { - this._key = fs.readFileSync(this._certConfig.keyFile, 'utf8'); - } - } - if (requestOptions.allowRedirects != null) { - this._allowRedirects = requestOptions.allowRedirects; - } - 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); - } - /** - * Makes a raw http request. - * All other methods such as get, post, patch, and request ultimately call this. - * Prefer get, del, post and patch - */ - request(verb, requestUrl, data, headers) { - return __awaiter(this, void 0, void 0, function* () { - if (this._disposed) { - throw new Error("Client has already been disposed."); - } - let info = this._prepareRequest(verb, requestUrl, 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 = yield 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; - } - // we need to finish reading the response before reassigning response - // which will leak the open socket. - yield response.readBody(); - // let's make the request with the new redirectUrl - info = this._prepareRequest(verb, redirectUrl, headers); - response = yield 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) { - yield response.readBody(); - yield 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; - let isDataString = typeof (data) === 'string'; - 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(); - } - } - _prepareRequest(method, requestUrl, headers) { - const info = {}; - info.parsedUrl = url.parse(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); - info.options.headers["user-agent"] = this.userAgent; - info.options.agent = this._getAgent(requestUrl); - // gives handlers an opportunity to participate - if (this.handlers && !this._isPresigned(requestUrl)) { - this.handlers.forEach((handler) => { - handler.prepareRequest(info.options); - }); - } - return info; - } - _isPresigned(requestUrl) { - if (this.requestOptions && this.requestOptions.presignedUrlPatterns) { - const patterns = this.requestOptions.presignedUrlPatterns; - for (let i = 0; i < patterns.length; i++) { - if (requestUrl.match(patterns[i])) { - return true; - } - } - } - return false; - } - _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 || {}); - } - _getAgent(requestUrl) { - let agent; - let proxy = this._getProxy(requestUrl); - let useProxy = proxy.proxyUrl && proxy.proxyUrl.hostname && !this._isBypassProxy(requestUrl); - 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; - } - let parsedUrl = url.parse(requestUrl); - 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 = __nested_webpack_require_1581__(802); - } - const agentOptions = { - maxSockets: maxSockets, - keepAlive: this._keepAlive, - proxy: { - proxyAuth: proxy.proxyAuth, - host: proxy.proxyUrl.hostname, - port: proxy.proxyUrl.port - }, - }; - let tunnelAgent; - const overHttps = proxy.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 }); - } - if (usingSsl && this._certConfig) { - agent.options = Object.assign(agent.options || {}, { ca: this._ca, cert: this._cert, key: this._key, passphrase: this._certConfig.passphrase }); - } - return agent; - } - _getProxy(requestUrl) { - const parsedUrl = url.parse(requestUrl); - let usingSsl = parsedUrl.protocol === 'https:'; - let proxyConfig = this._httpProxy; - // fallback to http_proxy and https_proxy env - let https_proxy = process.env[EnvironmentVariables.HTTPS_PROXY]; - let http_proxy = process.env[EnvironmentVariables.HTTP_PROXY]; - if (!proxyConfig) { - if (https_proxy && usingSsl) { - proxyConfig = { - proxyUrl: https_proxy - }; - } - else if (http_proxy) { - proxyConfig = { - proxyUrl: http_proxy - }; - } - } - let proxyUrl; - let proxyAuth; - if (proxyConfig) { - if (proxyConfig.proxyUrl.length > 0) { - proxyUrl = url.parse(proxyConfig.proxyUrl); - } - if (proxyConfig.proxyUsername || proxyConfig.proxyPassword) { - proxyAuth = proxyConfig.proxyUsername + ":" + proxyConfig.proxyPassword; - } - } - return { proxyUrl: proxyUrl, proxyAuth: proxyAuth }; - } - _isBypassProxy(requestUrl) { - if (!this._httpProxyBypassHosts) { - return false; - } - let bypass = false; - this._httpProxyBypassHosts.forEach(bypassHost => { - if (bypassHost.test(requestUrl)) { - bypass = true; - } - }); - return bypass; - } - _performExponentialBackoff(retryNumber) { - retryNumber = Math.min(ExponentialBackoffCeiling, retryNumber); - const ms = ExponentialBackoffTimeSlice * Math.pow(2, retryNumber); - return new Promise(resolve => setTimeout(() => resolve(), ms)); - } -} -exports.HttpClient = HttpClient; - - -/***/ }), - -/***/ 129: -/***/ (function(module) { - -module.exports = __nested_webpack_require_1931__(129); - -/***/ }), - -/***/ 146: -/***/ (function(module) { - -/** - * Convert array of 16 byte values to UUID string format of the form: - * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX - */ -var byteToHex = []; -for (var i = 0; i < 256; ++i) { - byteToHex[i] = (i + 0x100).toString(16).substr(1); -} - -function bytesToUuid(buf, offset) { - var i = offset || 0; - var bth = byteToHex; - // join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4 - return ([bth[buf[i++]], bth[buf[i++]], - bth[buf[i++]], bth[buf[i++]], '-', - bth[buf[i++]], bth[buf[i++]], '-', - bth[buf[i++]], bth[buf[i++]], '-', - bth[buf[i++]], bth[buf[i++]], '-', - bth[buf[i++]], bth[buf[i++]], - bth[buf[i++]], bth[buf[i++]], - bth[buf[i++]], bth[buf[i++]]]).join(''); -} - -module.exports = bytesToUuid; - - -/***/ }), - -/***/ 211: -/***/ (function(module) { - -module.exports = __nested_webpack_require_1931__(211); - -/***/ }), - -/***/ 227: -/***/ (function(__unusedmodule, exports, __nested_webpack_require_22880__) { - -"use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const os = __nested_webpack_require_22880__(87); -/** - * Commands - * - * Command Format: - * ##[name key=value;key=value]message - * - * Examples: - * ##[warning]This is the user warning message - * ##[set-secret name=mypassword]definatelyNotAPassword! - */ -function issueCommand(command, properties, message) { - const cmd = new Command(command, properties, message); - process.stdout.write(cmd.toString() + os.EOL); -} -exports.issueCommand = issueCommand; -function issue(name, message) { - issueCommand(name, {}, message); -} -exports.issue = issue; -const CMD_PREFIX = '##['; -class Command { - constructor(command, properties, message) { - if (!command) { - command = 'missing.command'; - } - this.command = command; - this.properties = properties; - this.message = message; - } - toString() { - let cmdStr = CMD_PREFIX + this.command; - if (this.properties && Object.keys(this.properties).length > 0) { - cmdStr += ' '; - for (const key in this.properties) { - if (this.properties.hasOwnProperty(key)) { - const val = this.properties[key]; - if (val) { - // safely append the val - avoid blowing up when attempting to - // call .replace() if message is not a string for some reason - cmdStr += `${key}=${escape(`${val || ''}`)};`; - } - } - } - } - cmdStr += ']'; - // safely append the message - avoid blowing up when attempting to - // call .replace() if message is not a string for some reason - const message = `${this.message || ''}`; - cmdStr += escapeData(message); - return cmdStr; - } -} -function escapeData(s) { - return s.replace(/\r/g, '%0D').replace(/\n/g, '%0A'); -} -function escape(s) { - return s - .replace(/\r/g, '%0D') - .replace(/\n/g, '%0A') - .replace(/]/g, '%5D') - .replace(/;/g, '%3B'); -} -//# sourceMappingURL=command.js.map - -/***/ }), - -/***/ 284: +/***/ 280: /***/ (function(module, exports) { exports = module.exports = SemVer @@ -2756,69 +2823,27 @@ function coerce (version, options) { /***/ 357: /***/ (function(module) { -module.exports = __nested_webpack_require_1931__(357); +module.exports = require("assert"); + +/***/ }), + +/***/ 413: +/***/ (function(module, __unusedexports, __webpack_require__) { + +module.exports = __webpack_require__(141); + /***/ }), /***/ 417: /***/ (function(module) { -module.exports = __nested_webpack_require_1931__(417); +module.exports = require("crypto"); /***/ }), -/***/ 430: -/***/ (function(__unusedmodule, exports, __nested_webpack_require_69116__) { - -"use strict"; - -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - 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) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", { value: true }); -const tr = __nested_webpack_require_69116__(654); -/** - * Exec a command. - * Output will be streamed to the live console. - * Returns promise with return code - * - * @param commandLine command to execute (can include additional args). Must be correctly escaped. - * @param args optional arguments for tool. Escaping is handled by the lib. - * @param options optional exec options. See ExecOptions - * @returns Promise exit code - */ -function exec(commandLine, args, options) { - return __awaiter(this, void 0, void 0, function* () { - const commandArgs = tr.argStringToArray(commandLine); - if (commandArgs.length === 0) { - throw new Error(`Parameter 'commandLine' cannot be null or empty.`); - } - // Path to tool to execute should be first arg - const toolPath = commandArgs[0]; - args = commandArgs.slice(1).concat(args || []); - const runner = new tr.ToolRunner(toolPath, args, options); - return runner.exec(); - }); -} -exports.exec = exec; -//# sourceMappingURL=exec.js.map - -/***/ }), - -/***/ 605: -/***/ (function(module) { - -module.exports = __nested_webpack_require_1931__(605); - -/***/ }), - -/***/ 606: -/***/ (function(__unusedmodule, exports, __nested_webpack_require_71081__) { +/***/ 423: +/***/ (function(__unusedmodule, exports, __webpack_require__) { "use strict"; @@ -2838,9 +2863,10 @@ var __importStar = (this && this.__importStar) || function (mod) { return result; }; Object.defineProperty(exports, "__esModule", { value: true }); -const core = __importStar(__nested_webpack_require_71081__(694)); -const installer = __importStar(__nested_webpack_require_71081__(938)); -const path = __importStar(__nested_webpack_require_71081__(622)); +const core = __importStar(__webpack_require__(470)); +const installer = __importStar(__webpack_require__(749)); +const auth = __importStar(__webpack_require__(827)); +const path = __importStar(__webpack_require__(622)); function run() { return __awaiter(this, void 0, void 0, function* () { try { @@ -2854,6 +2880,12 @@ function run() { yield installer.getJava(version, arch, jdkFile, javaPackage); const matchersPath = path.join(__dirname, '..', '.github'); console.log(`##[add-matcher]${path.join(matchersPath, 'java.json')}`); + const id = core.getInput('server-id', { required: false }); + const username = core.getInput('username', { required: false }); + const password = core.getInput('password', { required: false }); + if (id && username && password) { + yield auth.configAuthentication(id, username, password); + } } catch (error) { core.setFailed(error.message); @@ -2863,1026 +2895,910 @@ function run() { run(); +/***/ }), + +/***/ 431: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const os = __webpack_require__(87); +/** + * Commands + * + * Command Format: + * ##[name key=value;key=value]message + * + * Examples: + * ##[warning]This is the user warning message + * ##[set-secret name=mypassword]definatelyNotAPassword! + */ +function issueCommand(command, properties, message) { + const cmd = new Command(command, properties, message); + process.stdout.write(cmd.toString() + os.EOL); +} +exports.issueCommand = issueCommand; +function issue(name, message) { + issueCommand(name, {}, message); +} +exports.issue = issue; +const CMD_PREFIX = '##['; +class Command { + constructor(command, properties, message) { + if (!command) { + command = 'missing.command'; + } + this.command = command; + this.properties = properties; + this.message = message; + } + toString() { + let cmdStr = CMD_PREFIX + this.command; + if (this.properties && Object.keys(this.properties).length > 0) { + cmdStr += ' '; + for (const key in this.properties) { + if (this.properties.hasOwnProperty(key)) { + const val = this.properties[key]; + if (val) { + // safely append the val - avoid blowing up when attempting to + // call .replace() if message is not a string for some reason + cmdStr += `${key}=${escape(`${val || ''}`)};`; + } + } + } + } + cmdStr += ']'; + // safely append the message - avoid blowing up when attempting to + // call .replace() if message is not a string for some reason + const message = `${this.message || ''}`; + cmdStr += escapeData(message); + return cmdStr; + } +} +function escapeData(s) { + return s.replace(/\r/g, '%0D').replace(/\n/g, '%0A'); +} +function escape(s) { + return s + .replace(/\r/g, '%0D') + .replace(/\n/g, '%0A') + .replace(/]/g, '%5D') + .replace(/;/g, '%3B'); +} +//# sourceMappingURL=command.js.map + +/***/ }), + +/***/ 470: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +const command_1 = __webpack_require__(431); +const path = __webpack_require__(622); +/** + * The code to exit an action + */ +var ExitCode; +(function (ExitCode) { + /** + * A code indicating that the action was successful + */ + ExitCode[ExitCode["Success"] = 0] = "Success"; + /** + * A code indicating that the action was a failure + */ + ExitCode[ExitCode["Failure"] = 1] = "Failure"; +})(ExitCode = exports.ExitCode || (exports.ExitCode = {})); +//----------------------------------------------------------------------- +// Variables +//----------------------------------------------------------------------- +/** + * sets env variable for this action and future actions in the job + * @param name the name of the variable to set + * @param val the value of the variable + */ +function exportVariable(name, val) { + process.env[name] = val; + command_1.issueCommand('set-env', { name }, val); +} +exports.exportVariable = exportVariable; +/** + * exports the variable and registers a secret which will get masked from logs + * @param name the name of the variable to set + * @param val value of the secret + */ +function exportSecret(name, val) { + exportVariable(name, val); + command_1.issueCommand('set-secret', {}, val); +} +exports.exportSecret = exportSecret; +/** + * Prepends inputPath to the PATH (for this action and future actions) + * @param inputPath + */ +function addPath(inputPath) { + command_1.issueCommand('add-path', {}, inputPath); + process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`; +} +exports.addPath = addPath; +/** + * Gets the value of an input. The value is also trimmed. + * + * @param name name of the input to get + * @param options optional. See InputOptions. + * @returns string + */ +function getInput(name, options) { + const val = process.env[`INPUT_${name.replace(' ', '_').toUpperCase()}`] || ''; + if (options && options.required && !val) { + throw new Error(`Input required and not supplied: ${name}`); + } + return val.trim(); +} +exports.getInput = getInput; +/** + * Sets the value of an output. + * + * @param name name of the output to set + * @param value value to store + */ +function setOutput(name, value) { + command_1.issueCommand('set-output', { name }, value); +} +exports.setOutput = setOutput; +//----------------------------------------------------------------------- +// Results +//----------------------------------------------------------------------- +/** + * Sets the action status to failed. + * When the action exits it will be with an exit code of 1 + * @param message add error issue message + */ +function setFailed(message) { + process.exitCode = ExitCode.Failure; + error(message); +} +exports.setFailed = setFailed; +//----------------------------------------------------------------------- +// Logging Commands +//----------------------------------------------------------------------- +/** + * Writes debug message to user log + * @param message debug message + */ +function debug(message) { + command_1.issueCommand('debug', {}, message); +} +exports.debug = debug; +/** + * Adds an error issue + * @param message error issue message + */ +function error(message) { + command_1.issue('error', message); +} +exports.error = error; +/** + * Adds an warning issue + * @param message warning issue message + */ +function warning(message) { + command_1.issue('warning', message); +} +exports.warning = warning; +//# sourceMappingURL=core.js.map + +/***/ }), + +/***/ 533: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + 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) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const core = __webpack_require__(470); +const io = __webpack_require__(1); +const fs = __webpack_require__(747); +const os = __webpack_require__(87); +const path = __webpack_require__(622); +const httpm = __webpack_require__(874); +const semver = __webpack_require__(280); +const uuidV4 = __webpack_require__(826); +const exec_1 = __webpack_require__(986); +const assert_1 = __webpack_require__(357); +class HTTPError extends Error { + constructor(httpStatusCode) { + super(`Unexpected HTTP response: ${httpStatusCode}`); + this.httpStatusCode = httpStatusCode; + Object.setPrototypeOf(this, new.target.prototype); + } +} +exports.HTTPError = HTTPError; +const IS_WINDOWS = process.platform === 'win32'; +const userAgent = 'actions/tool-cache'; +// On load grab temp directory and cache directory and remove them from env (currently don't want to expose this) +let tempDirectory = process.env['RUNNER_TEMP'] || ''; +let cacheRoot = process.env['RUNNER_TOOL_CACHE'] || ''; +// If directories not found, place them in common temp locations +if (!tempDirectory || !cacheRoot) { + let baseLocation; + if (IS_WINDOWS) { + // On windows use the USERPROFILE env variable + baseLocation = process.env['USERPROFILE'] || 'C:\\'; + } + else { + if (process.platform === 'darwin') { + baseLocation = '/Users'; + } + else { + baseLocation = '/home'; + } + } + if (!tempDirectory) { + tempDirectory = path.join(baseLocation, 'actions', 'temp'); + } + if (!cacheRoot) { + cacheRoot = path.join(baseLocation, 'actions', 'cache'); + } +} +/** + * Download a tool from an url and stream it into a file + * + * @param url url of tool to download + * @returns path to downloaded tool + */ +function downloadTool(url) { + return __awaiter(this, void 0, void 0, function* () { + // Wrap in a promise so that we can resolve from within stream callbacks + return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () { + try { + const http = new httpm.HttpClient(userAgent, [], { + allowRetries: true, + maxRetries: 3 + }); + const destPath = path.join(tempDirectory, uuidV4()); + yield io.mkdirP(tempDirectory); + core.debug(`Downloading ${url}`); + core.debug(`Downloading ${destPath}`); + if (fs.existsSync(destPath)) { + throw new Error(`Destination file path ${destPath} already exists`); + } + const response = yield http.get(url); + 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})`); + throw err; + } + const file = fs.createWriteStream(destPath); + file.on('open', () => __awaiter(this, void 0, void 0, function* () { + try { + const stream = response.message.pipe(file); + stream.on('close', () => { + core.debug('download complete'); + resolve(destPath); + }); + } + catch (err) { + core.debug(`Failed to download from "${url}". Code(${response.message.statusCode}) Message(${response.message.statusMessage})`); + reject(err); + } + })); + file.on('error', err => { + file.end(); + reject(err); + }); + } + catch (err) { + reject(err); + } + })); + }); +} +exports.downloadTool = downloadTool; +/** + * Extract a .7z file + * + * @param file path to the .7z file + * @param dest destination directory. Optional. + * @param _7zPath path to 7zr.exe. Optional, for long path support. Most .7z archives do not have this + * problem. If your .7z archive contains very long paths, you can pass the path to 7zr.exe which will + * gracefully handle long paths. By default 7zdec.exe is used because it is a very small program and is + * bundled with the tool lib. However it does not support long paths. 7zr.exe is the reduced command line + * interface, it is smaller than the full command line interface, and it does support long paths. At the + * time of this writing, it is freely available from the LZMA SDK that is available on the 7zip website. + * Be sure to check the current license agreement. If 7zr.exe is bundled with your action, then the path + * to 7zr.exe can be pass to this function. + * @returns path to the destination directory + */ +function extract7z(file, dest, _7zPath) { + return __awaiter(this, void 0, void 0, function* () { + assert_1.ok(IS_WINDOWS, 'extract7z() not supported on current OS'); + assert_1.ok(file, 'parameter "file" is required'); + dest = dest || (yield _createExtractFolder(dest)); + const originalCwd = process.cwd(); + process.chdir(dest); + if (_7zPath) { + try { + const args = [ + 'x', + '-bb1', + '-bd', + '-sccUTF-8', + file + ]; + const options = { + silent: true + }; + yield exec_1.exec(`"${_7zPath}"`, args, options); + } + finally { + process.chdir(originalCwd); + } + } + else { + const escapedScript = path + .join(__dirname, '..', 'scripts', 'Invoke-7zdec.ps1') + .replace(/'/g, "''") + .replace(/"|\n|\r/g, ''); // double-up single quotes, remove double quotes and newlines + const escapedFile = file.replace(/'/g, "''").replace(/"|\n|\r/g, ''); + const escapedTarget = dest.replace(/'/g, "''").replace(/"|\n|\r/g, ''); + const command = `& '${escapedScript}' -Source '${escapedFile}' -Target '${escapedTarget}'`; + const args = [ + '-NoLogo', + '-Sta', + '-NoProfile', + '-NonInteractive', + '-ExecutionPolicy', + 'Unrestricted', + '-Command', + command + ]; + const options = { + silent: true + }; + try { + const powershellPath = yield io.which('powershell', true); + yield exec_1.exec(`"${powershellPath}"`, args, options); + } + finally { + process.chdir(originalCwd); + } + } + return dest; + }); +} +exports.extract7z = extract7z; +/** + * Extract a tar + * + * @param file path to the tar + * @param dest destination directory. Optional. + * @returns path to the destination directory + */ +function extractTar(file, dest) { + return __awaiter(this, void 0, void 0, function* () { + if (!file) { + throw new Error("parameter 'file' is required"); + } + dest = dest || (yield _createExtractFolder(dest)); + const tarPath = yield io.which('tar', true); + yield exec_1.exec(`"${tarPath}"`, ['xzC', dest, '-f', file]); + return dest; + }); +} +exports.extractTar = extractTar; +/** + * Extract a zip + * + * @param file path to the zip + * @param dest destination directory. Optional. + * @returns path to the destination directory + */ +function extractZip(file, dest) { + return __awaiter(this, void 0, void 0, function* () { + if (!file) { + throw new Error("parameter 'file' is required"); + } + dest = dest || (yield _createExtractFolder(dest)); + if (IS_WINDOWS) { + yield extractZipWin(file, dest); + } + else { + yield extractZipNix(file, dest); + } + return dest; + }); +} +exports.extractZip = extractZip; +function extractZipWin(file, dest) { + return __awaiter(this, void 0, void 0, function* () { + // build the powershell command + const escapedFile = file.replace(/'/g, "''").replace(/"|\n|\r/g, ''); // double-up single quotes, remove double quotes and newlines + const escapedDest = dest.replace(/'/g, "''").replace(/"|\n|\r/g, ''); + const command = `$ErrorActionPreference = 'Stop' ; try { Add-Type -AssemblyName System.IO.Compression.FileSystem } catch { } ; [System.IO.Compression.ZipFile]::ExtractToDirectory('${escapedFile}', '${escapedDest}')`; + // run powershell + const powershellPath = yield io.which('powershell'); + const args = [ + '-NoLogo', + '-Sta', + '-NoProfile', + '-NonInteractive', + '-ExecutionPolicy', + 'Unrestricted', + '-Command', + command + ]; + yield exec_1.exec(`"${powershellPath}"`, args); + }); +} +function extractZipNix(file, dest) { + return __awaiter(this, void 0, void 0, function* () { + const unzipPath = __webpack_require__.ab + "unzip"; + yield exec_1.exec(`"${unzipPath}"`, [file], { cwd: dest }); + }); +} +/** + * Caches a directory and installs it into the tool cacheDir + * + * @param sourceDir the directory to cache into tools + * @param tool tool name + * @param version version of the tool. semver format + * @param arch architecture of the tool. Optional. Defaults to machine architecture + */ +function cacheDir(sourceDir, tool, version, arch) { + return __awaiter(this, void 0, void 0, function* () { + version = semver.clean(version) || version; + arch = arch || os.arch(); + core.debug(`Caching tool ${tool} ${version} ${arch}`); + core.debug(`source dir: ${sourceDir}`); + if (!fs.statSync(sourceDir).isDirectory()) { + throw new Error('sourceDir is not a directory'); + } + // Create the tool dir + const destPath = yield _createToolPath(tool, version, arch); + // copy each child item. do not move. move can fail on Windows + // due to anti-virus software having an open handle on a file. + for (const itemName of fs.readdirSync(sourceDir)) { + const s = path.join(sourceDir, itemName); + yield io.cp(s, destPath, { recursive: true }); + } + // write .complete + _completeToolPath(tool, version, arch); + return destPath; + }); +} +exports.cacheDir = cacheDir; +/** + * Caches a downloaded file (GUID) and installs it + * into the tool cache with a given targetName + * + * @param sourceFile the file to cache into tools. Typically a result of downloadTool which is a guid. + * @param targetFile the name of the file name in the tools directory + * @param tool tool name + * @param version version of the tool. semver format + * @param arch architecture of the tool. Optional. Defaults to machine architecture + */ +function cacheFile(sourceFile, targetFile, tool, version, arch) { + return __awaiter(this, void 0, void 0, function* () { + version = semver.clean(version) || version; + arch = arch || os.arch(); + core.debug(`Caching tool ${tool} ${version} ${arch}`); + core.debug(`source file: ${sourceFile}`); + if (!fs.statSync(sourceFile).isFile()) { + throw new Error('sourceFile is not a file'); + } + // create the tool dir + const destFolder = yield _createToolPath(tool, version, arch); + // copy instead of move. move can fail on Windows due to + // anti-virus software having an open handle on a file. + const destPath = path.join(destFolder, targetFile); + core.debug(`destination file ${destPath}`); + yield io.cp(sourceFile, destPath); + // write .complete + _completeToolPath(tool, version, arch); + return destFolder; + }); +} +exports.cacheFile = cacheFile; +/** + * Finds the path to a tool version in the local installed tool cache + * + * @param toolName name of the tool + * @param versionSpec version of the tool + * @param arch optional arch. defaults to arch of computer + */ +function find(toolName, versionSpec, arch) { + if (!toolName) { + throw new Error('toolName parameter is required'); + } + if (!versionSpec) { + throw new Error('versionSpec parameter is required'); + } + arch = arch || os.arch(); + // attempt to resolve an explicit version + if (!_isExplicitVersion(versionSpec)) { + const localVersions = findAllVersions(toolName, arch); + const match = _evaluateVersions(localVersions, versionSpec); + versionSpec = match; + } + // check for the explicit version in the cache + let toolPath = ''; + if (versionSpec) { + versionSpec = semver.clean(versionSpec) || ''; + const cachePath = path.join(cacheRoot, toolName, versionSpec, arch); + core.debug(`checking cache: ${cachePath}`); + if (fs.existsSync(cachePath) && fs.existsSync(`${cachePath}.complete`)) { + core.debug(`Found tool in cache ${toolName} ${versionSpec} ${arch}`); + toolPath = cachePath; + } + else { + core.debug('not found'); + } + } + return toolPath; +} +exports.find = find; +/** + * Finds the paths to all versions of a tool that are installed in the local tool cache + * + * @param toolName name of the tool + * @param arch optional arch. defaults to arch of computer + */ +function findAllVersions(toolName, arch) { + const versions = []; + arch = arch || os.arch(); + const toolPath = path.join(cacheRoot, toolName); + if (fs.existsSync(toolPath)) { + const children = fs.readdirSync(toolPath); + for (const child of children) { + if (_isExplicitVersion(child)) { + const fullPath = path.join(toolPath, child, arch || ''); + if (fs.existsSync(fullPath) && fs.existsSync(`${fullPath}.complete`)) { + versions.push(child); + } + } + } + } + return versions; +} +exports.findAllVersions = findAllVersions; +function _createExtractFolder(dest) { + return __awaiter(this, void 0, void 0, function* () { + if (!dest) { + // create a temp dir + dest = path.join(tempDirectory, uuidV4()); + } + yield io.mkdirP(dest); + return dest; + }); +} +function _createToolPath(tool, version, arch) { + return __awaiter(this, void 0, void 0, function* () { + const folderPath = path.join(cacheRoot, tool, semver.clean(version) || version, arch || ''); + core.debug(`destination ${folderPath}`); + const markerPath = `${folderPath}.complete`; + yield io.rmRF(folderPath); + yield io.rmRF(markerPath); + yield io.mkdirP(folderPath); + return folderPath; + }); +} +function _completeToolPath(tool, version, arch) { + const folderPath = path.join(cacheRoot, tool, semver.clean(version) || version, arch || ''); + const markerPath = `${folderPath}.complete`; + fs.writeFileSync(markerPath, ''); + core.debug('finished caching tool'); +} +function _isExplicitVersion(versionSpec) { + const c = semver.clean(versionSpec) || ''; + core.debug(`isExplicit: ${c}`); + const valid = semver.valid(c) != null; + core.debug(`explicit? ${valid}`); + return valid; +} +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; +} +//# sourceMappingURL=tool-cache.js.map + +/***/ }), + +/***/ 605: +/***/ (function(module) { + +module.exports = require("http"); + /***/ }), /***/ 614: /***/ (function(module) { -module.exports = __nested_webpack_require_1931__(614); +module.exports = require("events"); /***/ }), /***/ 622: /***/ (function(module) { -module.exports = __nested_webpack_require_1931__(622); +module.exports = require("path"); /***/ }), /***/ 631: /***/ (function(module) { -module.exports = __nested_webpack_require_1931__(631); - -/***/ }), - -/***/ 654: -/***/ (function(__unusedmodule, exports, __nested_webpack_require_73421__) { - -"use strict"; - -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - 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) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", { value: true }); -const os = __nested_webpack_require_73421__(87); -const events = __nested_webpack_require_73421__(614); -const child = __nested_webpack_require_73421__(129); -/* eslint-disable @typescript-eslint/unbound-method */ -const IS_WINDOWS = process.platform === 'win32'; -/* - * Class for running command line tools. Handles quoting and arg parsing in a platform agnostic way. - */ -class ToolRunner extends events.EventEmitter { - constructor(toolPath, args, options) { - super(); - if (!toolPath) { - throw new Error("Parameter 'toolPath' cannot be null or empty."); - } - this.toolPath = toolPath; - this.args = args || []; - this.options = options || {}; - } - _debug(message) { - if (this.options.listeners && this.options.listeners.debug) { - this.options.listeners.debug(message); - } - } - _getCommandString(options, noPrefix) { - const toolPath = this._getSpawnFileName(); - const args = this._getSpawnArgs(options); - let cmd = noPrefix ? '' : '[command]'; // omit prefix when piped to a second tool - if (IS_WINDOWS) { - // Windows + cmd file - if (this._isCmdFile()) { - cmd += toolPath; - for (const a of args) { - cmd += ` ${a}`; - } - } - // Windows + verbatim - else if (options.windowsVerbatimArguments) { - cmd += `"${toolPath}"`; - for (const a of args) { - cmd += ` ${a}`; - } - } - // Windows (regular) - else { - cmd += this._windowsQuoteCmdArg(toolPath); - for (const a of args) { - cmd += ` ${this._windowsQuoteCmdArg(a)}`; - } - } - } - else { - // OSX/Linux - this can likely be improved with some form of quoting. - // creating processes on Unix is fundamentally different than Windows. - // on Unix, execvp() takes an arg array. - cmd += toolPath; - for (const a of args) { - cmd += ` ${a}`; - } - } - return cmd; - } - _processLineBuffer(data, strBuffer, onLine) { - try { - let s = strBuffer + data.toString(); - let n = s.indexOf(os.EOL); - while (n > -1) { - const line = s.substring(0, n); - onLine(line); - // the rest of the string ... - s = s.substring(n + os.EOL.length); - n = s.indexOf(os.EOL); - } - strBuffer = s; - } - catch (err) { - // streaming lines to console is best effort. Don't fail a build. - this._debug(`error processing line. Failed with error ${err}`); - } - } - _getSpawnFileName() { - if (IS_WINDOWS) { - if (this._isCmdFile()) { - return process.env['COMSPEC'] || 'cmd.exe'; - } - } - return this.toolPath; - } - _getSpawnArgs(options) { - if (IS_WINDOWS) { - if (this._isCmdFile()) { - let argline = `/D /S /C "${this._windowsQuoteCmdArg(this.toolPath)}`; - for (const a of this.args) { - argline += ' '; - argline += options.windowsVerbatimArguments - ? a - : this._windowsQuoteCmdArg(a); - } - argline += '"'; - return [argline]; - } - } - return this.args; - } - _endsWith(str, end) { - return str.endsWith(end); - } - _isCmdFile() { - const upperToolPath = this.toolPath.toUpperCase(); - return (this._endsWith(upperToolPath, '.CMD') || - this._endsWith(upperToolPath, '.BAT')); - } - _windowsQuoteCmdArg(arg) { - // for .exe, apply the normal quoting rules that libuv applies - if (!this._isCmdFile()) { - return this._uvQuoteCmdArg(arg); - } - // otherwise apply quoting rules specific to the cmd.exe command line parser. - // the libuv rules are generic and are not designed specifically for cmd.exe - // command line parser. - // - // for a detailed description of the cmd.exe command line parser, refer to - // http://stackoverflow.com/questions/4094699/how-does-the-windows-command-interpreter-cmd-exe-parse-scripts/7970912#7970912 - // need quotes for empty arg - if (!arg) { - return '""'; - } - // determine whether the arg needs to be quoted - const cmdSpecialChars = [ - ' ', - '\t', - '&', - '(', - ')', - '[', - ']', - '{', - '}', - '^', - '=', - ';', - '!', - "'", - '+', - ',', - '`', - '~', - '|', - '<', - '>', - '"' - ]; - let needsQuotes = false; - for (const char of arg) { - if (cmdSpecialChars.some(x => x === char)) { - needsQuotes = true; - break; - } - } - // short-circuit if quotes not needed - if (!needsQuotes) { - return arg; - } - // the following quoting rules are very similar to the rules that by libuv applies. - // - // 1) wrap the string in quotes - // - // 2) double-up quotes - i.e. " => "" - // - // this is different from the libuv quoting rules. libuv replaces " with \", which unfortunately - // doesn't work well with a cmd.exe command line. - // - // note, replacing " with "" also works well if the arg is passed to a downstream .NET console app. - // for example, the command line: - // foo.exe "myarg:""my val""" - // is parsed by a .NET console app into an arg array: - // [ "myarg:\"my val\"" ] - // which is the same end result when applying libuv quoting rules. although the actual - // command line from libuv quoting rules would look like: - // foo.exe "myarg:\"my val\"" - // - // 3) double-up slashes that preceed a quote, - // e.g. hello \world => "hello \world" - // hello\"world => "hello\\""world" - // hello\\"world => "hello\\\\""world" - // hello world\ => "hello world\\" - // - // technically this is not required for a cmd.exe command line, or the batch argument parser. - // the reasons for including this as a .cmd quoting rule are: - // - // a) this is optimized for the scenario where the argument is passed from the .cmd file to an - // external program. many programs (e.g. .NET console apps) rely on the slash-doubling rule. - // - // b) it's what we've been doing previously (by deferring to node default behavior) and we - // haven't heard any complaints about that aspect. - // - // note, a weakness of the quoting rules chosen here, is that % is not escaped. in fact, % cannot be - // escaped when used on the command line directly - even though within a .cmd file % can be escaped - // by using %%. - // - // the saving grace is, on the command line, %var% is left as-is if var is not defined. this contrasts - // the line parsing rules within a .cmd file, where if var is not defined it is replaced with nothing. - // - // one option that was explored was replacing % with ^% - i.e. %var% => ^%var^%. this hack would - // often work, since it is unlikely that var^ would exist, and the ^ character is removed when the - // variable is used. the problem, however, is that ^ is not removed when %* is used to pass the args - // to an external program. - // - // an unexplored potential solution for the % escaping problem, is to create a wrapper .cmd file. - // % can be escaped within a .cmd file. - let reverse = '"'; - let quoteHit = true; - for (let i = arg.length; i > 0; i--) { - // walk the string in reverse - reverse += arg[i - 1]; - if (quoteHit && arg[i - 1] === '\\') { - reverse += '\\'; // double the slash - } - else if (arg[i - 1] === '"') { - quoteHit = true; - reverse += '"'; // double the quote - } - else { - quoteHit = false; - } - } - reverse += '"'; - return reverse - .split('') - .reverse() - .join(''); - } - _uvQuoteCmdArg(arg) { - // Tool runner wraps child_process.spawn() and needs to apply the same quoting as - // Node in certain cases where the undocumented spawn option windowsVerbatimArguments - // is used. - // - // Since this function is a port of quote_cmd_arg from Node 4.x (technically, lib UV, - // see https://github.com/nodejs/node/blob/v4.x/deps/uv/src/win/process.c for details), - // pasting copyright notice from Node within this function: - // - // Copyright Joyent, Inc. and other Node contributors. All rights reserved. - // - // Permission is hereby granted, free of charge, to any person obtaining a copy - // of this software and associated documentation files (the "Software"), to - // deal in the Software without restriction, including without limitation the - // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - // sell copies of the Software, and to permit persons to whom the Software is - // furnished to do so, subject to the following conditions: - // - // The above copyright notice and this permission notice shall be included in - // all copies or substantial portions of the Software. - // - // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - // IN THE SOFTWARE. - if (!arg) { - // Need double quotation for empty argument - return '""'; - } - if (!arg.includes(' ') && !arg.includes('\t') && !arg.includes('"')) { - // No quotation needed - return arg; - } - if (!arg.includes('"') && !arg.includes('\\')) { - // No embedded double quotes or backslashes, so I can just wrap - // quote marks around the whole thing. - return `"${arg}"`; - } - // Expected input/output: - // input : hello"world - // output: "hello\"world" - // input : hello""world - // output: "hello\"\"world" - // input : hello\world - // output: hello\world - // input : hello\\world - // output: hello\\world - // input : hello\"world - // output: "hello\\\"world" - // input : hello\\"world - // output: "hello\\\\\"world" - // input : hello world\ - // output: "hello world\\" - note the comment in libuv actually reads "hello world\" - // but it appears the comment is wrong, it should be "hello world\\" - let reverse = '"'; - let quoteHit = true; - for (let i = arg.length; i > 0; i--) { - // walk the string in reverse - reverse += arg[i - 1]; - if (quoteHit && arg[i - 1] === '\\') { - reverse += '\\'; - } - else if (arg[i - 1] === '"') { - quoteHit = true; - reverse += '\\'; - } - else { - quoteHit = false; - } - } - reverse += '"'; - return reverse - .split('') - .reverse() - .join(''); - } - _cloneExecOptions(options) { - options = options || {}; - const result = { - cwd: options.cwd || process.cwd(), - env: options.env || process.env, - silent: options.silent || false, - windowsVerbatimArguments: options.windowsVerbatimArguments || false, - failOnStdErr: options.failOnStdErr || false, - ignoreReturnCode: options.ignoreReturnCode || false, - delay: options.delay || 10000 - }; - result.outStream = options.outStream || process.stdout; - result.errStream = options.errStream || process.stderr; - return result; - } - _getSpawnOptions(options, toolPath) { - options = options || {}; - const result = {}; - result.cwd = options.cwd; - result.env = options.env; - result['windowsVerbatimArguments'] = - options.windowsVerbatimArguments || this._isCmdFile(); - if (options.windowsVerbatimArguments) { - result.argv0 = `"${toolPath}"`; - } - return result; - } - /** - * Exec a tool. - * Output will be streamed to the live console. - * Returns promise with return code - * - * @param tool path to tool to exec - * @param options optional exec options. See ExecOptions - * @returns number - */ - exec() { - return __awaiter(this, void 0, void 0, function* () { - return new Promise((resolve, reject) => { - this._debug(`exec tool: ${this.toolPath}`); - this._debug('arguments:'); - for (const arg of this.args) { - this._debug(` ${arg}`); - } - const optionsNonNull = this._cloneExecOptions(this.options); - if (!optionsNonNull.silent && optionsNonNull.outStream) { - optionsNonNull.outStream.write(this._getCommandString(optionsNonNull) + os.EOL); - } - const state = new ExecState(optionsNonNull, this.toolPath); - state.on('debug', (message) => { - this._debug(message); - }); - const fileName = this._getSpawnFileName(); - const cp = child.spawn(fileName, this._getSpawnArgs(optionsNonNull), this._getSpawnOptions(this.options, fileName)); - const stdbuffer = ''; - if (cp.stdout) { - cp.stdout.on('data', (data) => { - if (this.options.listeners && this.options.listeners.stdout) { - this.options.listeners.stdout(data); - } - if (!optionsNonNull.silent && optionsNonNull.outStream) { - optionsNonNull.outStream.write(data); - } - this._processLineBuffer(data, stdbuffer, (line) => { - if (this.options.listeners && this.options.listeners.stdline) { - this.options.listeners.stdline(line); - } - }); - }); - } - const errbuffer = ''; - if (cp.stderr) { - cp.stderr.on('data', (data) => { - state.processStderr = true; - if (this.options.listeners && this.options.listeners.stderr) { - this.options.listeners.stderr(data); - } - if (!optionsNonNull.silent && - optionsNonNull.errStream && - optionsNonNull.outStream) { - const s = optionsNonNull.failOnStdErr - ? optionsNonNull.errStream - : optionsNonNull.outStream; - s.write(data); - } - this._processLineBuffer(data, errbuffer, (line) => { - if (this.options.listeners && this.options.listeners.errline) { - this.options.listeners.errline(line); - } - }); - }); - } - cp.on('error', (err) => { - state.processError = err.message; - state.processExited = true; - state.processClosed = true; - state.CheckComplete(); - }); - cp.on('exit', (code) => { - state.processExitCode = code; - state.processExited = true; - this._debug(`Exit code ${code} received from tool '${this.toolPath}'`); - state.CheckComplete(); - }); - cp.on('close', (code) => { - state.processExitCode = code; - state.processExited = true; - state.processClosed = true; - this._debug(`STDIO streams have closed for tool '${this.toolPath}'`); - state.CheckComplete(); - }); - state.on('done', (error, exitCode) => { - if (stdbuffer.length > 0) { - this.emit('stdline', stdbuffer); - } - if (errbuffer.length > 0) { - this.emit('errline', errbuffer); - } - cp.removeAllListeners(); - if (error) { - reject(error); - } - else { - resolve(exitCode); - } - }); - }); - }); - } -} -exports.ToolRunner = ToolRunner; -/** - * Convert an arg string to an array of args. Handles escaping - * - * @param argString string of arguments - * @returns string[] array of arguments - */ -function argStringToArray(argString) { - const args = []; - let inQuotes = false; - let escaped = false; - let arg = ''; - function append(c) { - // we only escape double quotes. - if (escaped && c !== '"') { - arg += '\\'; - } - arg += c; - escaped = false; - } - for (let i = 0; i < argString.length; i++) { - const c = argString.charAt(i); - if (c === '"') { - if (!escaped) { - inQuotes = !inQuotes; - } - else { - append(c); - } - continue; - } - if (c === '\\' && escaped) { - append(c); - continue; - } - if (c === '\\' && inQuotes) { - escaped = true; - continue; - } - if (c === ' ' && !inQuotes) { - if (arg.length > 0) { - args.push(arg); - arg = ''; - } - continue; - } - append(c); - } - if (arg.length > 0) { - args.push(arg.trim()); - } - return args; -} -exports.argStringToArray = argStringToArray; -class ExecState extends events.EventEmitter { - constructor(options, toolPath) { - super(); - this.processClosed = false; // tracks whether the process has exited and stdio is closed - this.processError = ''; - this.processExitCode = 0; - this.processExited = false; // tracks whether the process has exited - this.processStderr = false; // tracks whether stderr was written to - this.delay = 10000; // 10 seconds - this.done = false; - this.timeout = null; - if (!toolPath) { - throw new Error('toolPath must not be empty'); - } - this.options = options; - this.toolPath = toolPath; - if (options.delay) { - this.delay = options.delay; - } - } - CheckComplete() { - if (this.done) { - return; - } - if (this.processClosed) { - this._setResult(); - } - else if (this.processExited) { - this.timeout = setTimeout(ExecState.HandleTimeout, this.delay, this); - } - } - _debug(message) { - this.emit('debug', message); - } - _setResult() { - // determine whether there is an error - let error; - if (this.processExited) { - if (this.processError) { - error = new Error(`There was an error when attempting to execute the process '${this.toolPath}'. This may indicate the process failed to start. Error: ${this.processError}`); - } - else if (this.processExitCode !== 0 && !this.options.ignoreReturnCode) { - error = new Error(`The process '${this.toolPath}' failed with exit code ${this.processExitCode}`); - } - else if (this.processStderr && this.options.failOnStdErr) { - error = new Error(`The process '${this.toolPath}' failed because one or more lines were written to the STDERR stream`); - } - } - // clear the timeout - if (this.timeout) { - clearTimeout(this.timeout); - this.timeout = null; - } - this.done = true; - this.emit('done', error, this.processExitCode); - } - static HandleTimeout(state) { - if (state.done) { - return; - } - if (!state.processClosed && state.processExited) { - const message = `The STDIO streams did not close within ${state.delay / - 1000} seconds of the exit event from process '${state.toolPath}'. This may indicate a child process inherited the STDIO streams and has not yet exited.`; - state._debug(message); - } - state._setResult(); - } -} -//# sourceMappingURL=toolrunner.js.map +module.exports = require("net"); /***/ }), /***/ 669: /***/ (function(module) { -module.exports = __nested_webpack_require_1931__(669); +module.exports = require("util"); /***/ }), -/***/ 683: -/***/ (function(module, __unusedexports, __nested_webpack_require_97006__) { - -var rng = __nested_webpack_require_97006__(853); -var bytesToUuid = __nested_webpack_require_97006__(146); - -function v4(options, buf, offset) { - var i = buf && offset || 0; - - if (typeof(options) == 'string') { - buf = options === 'binary' ? new Array(16) : null; - options = null; - } - options = options || {}; - - var rnds = options.random || (options.rng || rng)(); - - // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` - rnds[6] = (rnds[6] & 0x0f) | 0x40; - rnds[8] = (rnds[8] & 0x3f) | 0x80; - - // Copy bytes to buffer, if provided - if (buf) { - for (var ii = 0; ii < 16; ++ii) { - buf[i + ii] = rnds[ii]; - } - } - - return buf || bytesToUuid(rnds); -} - -module.exports = v4; - - -/***/ }), - -/***/ 694: -/***/ (function(__unusedmodule, exports, __nested_webpack_require_97804__) { +/***/ 672: +/***/ (function(__unusedmodule, exports, __webpack_require__) { "use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -const command_1 = __nested_webpack_require_97804__(227); -const path = __nested_webpack_require_97804__(622); -/** - * The code to exit an action - */ -var ExitCode; -(function (ExitCode) { - /** - * A code indicating that the action was successful - */ - ExitCode[ExitCode["Success"] = 0] = "Success"; - /** - * A code indicating that the action was a failure - */ - ExitCode[ExitCode["Failure"] = 1] = "Failure"; -})(ExitCode = exports.ExitCode || (exports.ExitCode = {})); -//----------------------------------------------------------------------- -// Variables -//----------------------------------------------------------------------- -/** - * sets env variable for this action and future actions in the job - * @param name the name of the variable to set - * @param val the value of the variable - */ -function exportVariable(name, val) { - process.env[name] = val; - command_1.issueCommand('set-env', { name }, val); -} -exports.exportVariable = exportVariable; -/** - * exports the variable and registers a secret which will get masked from logs - * @param name the name of the variable to set - * @param val value of the secret - */ -function exportSecret(name, val) { - exportVariable(name, val); - command_1.issueCommand('set-secret', {}, val); -} -exports.exportSecret = exportSecret; -/** - * Prepends inputPath to the PATH (for this action and future actions) - * @param inputPath - */ -function addPath(inputPath) { - command_1.issueCommand('add-path', {}, inputPath); - process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`; -} -exports.addPath = addPath; -/** - * Gets the value of an input. The value is also trimmed. - * - * @param name name of the input to get - * @param options optional. See InputOptions. - * @returns string - */ -function getInput(name, options) { - const val = process.env[`INPUT_${name.replace(' ', '_').toUpperCase()}`] || ''; - if (options && options.required && !val) { - throw new Error(`Input required and not supplied: ${name}`); - } - return val.trim(); -} -exports.getInput = getInput; -/** - * Sets the value of an output. - * - * @param name name of the output to set - * @param value value to store - */ -function setOutput(name, value) { - command_1.issueCommand('set-output', { name }, value); -} -exports.setOutput = setOutput; -//----------------------------------------------------------------------- -// Results -//----------------------------------------------------------------------- -/** - * Sets the action status to failed. - * When the action exits it will be with an exit code of 1 - * @param message add error issue message - */ -function setFailed(message) { - process.exitCode = ExitCode.Failure; - error(message); -} -exports.setFailed = setFailed; -//----------------------------------------------------------------------- -// Logging Commands -//----------------------------------------------------------------------- -/** - * Writes debug message to user log - * @param message debug message - */ -function debug(message) { - command_1.issueCommand('debug', {}, message); -} -exports.debug = debug; -/** - * Adds an error issue - * @param message error issue message - */ -function error(message) { - command_1.issue('error', message); -} -exports.error = error; -/** - * Adds an warning issue - * @param message warning issue message - */ -function warning(message) { - command_1.issue('warning', message); -} -exports.warning = warning; -//# sourceMappingURL=core.js.map + +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + 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) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var _a; +Object.defineProperty(exports, "__esModule", { value: true }); +const assert_1 = __webpack_require__(357); +const fs = __webpack_require__(747); +const path = __webpack_require__(622); +_a = fs.promises, exports.chmod = _a.chmod, exports.copyFile = _a.copyFile, exports.lstat = _a.lstat, exports.mkdir = _a.mkdir, exports.readdir = _a.readdir, exports.readlink = _a.readlink, exports.rename = _a.rename, exports.rmdir = _a.rmdir, exports.stat = _a.stat, exports.symlink = _a.symlink, exports.unlink = _a.unlink; +exports.IS_WINDOWS = process.platform === 'win32'; +function exists(fsPath) { + return __awaiter(this, void 0, void 0, function* () { + try { + yield exports.stat(fsPath); + } + catch (err) { + if (err.code === 'ENOENT') { + return false; + } + throw err; + } + return true; + }); +} +exports.exists = exists; +function isDirectory(fsPath, useStat = false) { + return __awaiter(this, void 0, void 0, function* () { + const stats = useStat ? yield exports.stat(fsPath) : yield exports.lstat(fsPath); + return stats.isDirectory(); + }); +} +exports.isDirectory = isDirectory; +/** + * On OSX/Linux, true if path starts with '/'. On Windows, true for paths like: + * \, \hello, \\hello\share, C:, and C:\hello (and corresponding alternate separator cases). + */ +function isRooted(p) { + p = normalizeSeparators(p); + if (!p) { + throw new Error('isRooted() parameter "p" cannot be empty'); + } + if (exports.IS_WINDOWS) { + return (p.startsWith('\\') || /^[A-Z]:/i.test(p) // e.g. \ or \hello or \\hello + ); // e.g. C: or C:\hello + } + return p.startsWith('/'); +} +exports.isRooted = isRooted; +/** + * Recursively create a directory at `fsPath`. + * + * This implementation is optimistic, meaning it attempts to create the full + * path first, and backs up the path stack from there. + * + * @param fsPath The path to create + * @param maxDepth The maximum recursion depth + * @param depth The current recursion depth + */ +function mkdirP(fsPath, maxDepth = 1000, depth = 1) { + return __awaiter(this, void 0, void 0, function* () { + assert_1.ok(fsPath, 'a path argument must be provided'); + fsPath = path.resolve(fsPath); + if (depth >= maxDepth) + return exports.mkdir(fsPath); + try { + yield exports.mkdir(fsPath); + return; + } + catch (err) { + switch (err.code) { + case 'ENOENT': { + yield mkdirP(path.dirname(fsPath), maxDepth, depth + 1); + yield exports.mkdir(fsPath); + return; + } + default: { + let stats; + try { + stats = yield exports.stat(fsPath); + } + catch (err2) { + throw err; + } + if (!stats.isDirectory()) + throw err; + } + } + } + }); +} +exports.mkdirP = mkdirP; +/** + * Best effort attempt to determine whether a file exists and is executable. + * @param filePath file path to check + * @param extensions additional file extensions to try + * @return if file exists and is executable, returns the file path. otherwise empty string. + */ +function tryGetExecutablePath(filePath, extensions) { + return __awaiter(this, void 0, void 0, function* () { + let stats = undefined; + try { + // test file exists + stats = yield exports.stat(filePath); + } + catch (err) { + if (err.code !== 'ENOENT') { + // eslint-disable-next-line no-console + console.log(`Unexpected error attempting to determine if executable file exists '${filePath}': ${err}`); + } + } + if (stats && stats.isFile()) { + if (exports.IS_WINDOWS) { + // on Windows, test for valid extension + const upperExt = path.extname(filePath).toUpperCase(); + if (extensions.some(validExt => validExt.toUpperCase() === upperExt)) { + return filePath; + } + } + else { + if (isUnixExecutable(stats)) { + return filePath; + } + } + } + // try each extension + const originalFilePath = filePath; + for (const extension of extensions) { + filePath = originalFilePath + extension; + stats = undefined; + try { + stats = yield exports.stat(filePath); + } + catch (err) { + if (err.code !== 'ENOENT') { + // eslint-disable-next-line no-console + console.log(`Unexpected error attempting to determine if executable file exists '${filePath}': ${err}`); + } + } + if (stats && stats.isFile()) { + if (exports.IS_WINDOWS) { + // preserve the case of the actual file (since an extension was appended) + try { + const directory = path.dirname(filePath); + const upperName = path.basename(filePath).toUpperCase(); + for (const actualName of yield exports.readdir(directory)) { + if (upperName === actualName.toUpperCase()) { + filePath = path.join(directory, actualName); + break; + } + } + } + catch (err) { + // eslint-disable-next-line no-console + console.log(`Unexpected error attempting to determine the actual case of the file '${filePath}': ${err}`); + } + return filePath; + } + else { + if (isUnixExecutable(stats)) { + return filePath; + } + } + } + } + return ''; + }); +} +exports.tryGetExecutablePath = tryGetExecutablePath; +function normalizeSeparators(p) { + p = p || ''; + if (exports.IS_WINDOWS) { + // convert slashes on Windows + p = p.replace(/\//g, '\\'); + // remove redundant slashes + return p.replace(/\\\\+/g, '\\'); + } + // remove redundant slashes + return p.replace(/\/\/+/g, '/'); +} +// on Mac/Linux, test the execute bit +// R W X R W X R W X +// 256 128 64 32 16 8 4 2 1 +function isUnixExecutable(stats) { + return ((stats.mode & 1) > 0 || + ((stats.mode & 8) > 0 && stats.gid === process.getgid()) || + ((stats.mode & 64) > 0 && stats.uid === process.getuid())); +} +//# sourceMappingURL=io-util.js.map /***/ }), -/***/ 725: -/***/ (function(__unusedmodule, exports, __nested_webpack_require_101530__) { +/***/ 722: +/***/ (function(module) { -"use strict"; - - -var net = __nested_webpack_require_101530__(631); -var tls = __nested_webpack_require_101530__(16); -var http = __nested_webpack_require_101530__(605); -var https = __nested_webpack_require_101530__(211); -var events = __nested_webpack_require_101530__(614); -var assert = __nested_webpack_require_101530__(357); -var util = __nested_webpack_require_101530__(669); - - -exports.httpOverHttp = httpOverHttp; -exports.httpsOverHttp = httpsOverHttp; -exports.httpOverHttps = httpOverHttps; -exports.httpsOverHttps = httpsOverHttps; - - -function httpOverHttp(options) { - var agent = new TunnelingAgent(options); - agent.request = http.request; - return agent; +/** + * Convert array of 16 byte values to UUID string format of the form: + * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX + */ +var byteToHex = []; +for (var i = 0; i < 256; ++i) { + byteToHex[i] = (i + 0x100).toString(16).substr(1); } -function httpsOverHttp(options) { - var agent = new TunnelingAgent(options); - agent.request = http.request; - agent.createSocket = createSecureSocket; - return agent; +function bytesToUuid(buf, offset) { + var i = offset || 0; + var bth = byteToHex; + // join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4 + return ([bth[buf[i++]], bth[buf[i++]], + bth[buf[i++]], bth[buf[i++]], '-', + bth[buf[i++]], bth[buf[i++]], '-', + bth[buf[i++]], bth[buf[i++]], '-', + bth[buf[i++]], bth[buf[i++]], '-', + bth[buf[i++]], bth[buf[i++]], + bth[buf[i++]], bth[buf[i++]], + bth[buf[i++]], bth[buf[i++]]]).join(''); } -function httpOverHttps(options) { - var agent = new TunnelingAgent(options); - agent.request = https.request; - return agent; -} - -function httpsOverHttps(options) { - var agent = new TunnelingAgent(options); - agent.request = https.request; - agent.createSocket = createSecureSocket; - return agent; -} - - -function TunnelingAgent(options) { - var self = this; - self.options = options || {}; - self.proxyOptions = self.options.proxy || {}; - self.maxSockets = self.options.maxSockets || http.Agent.defaultMaxSockets; - self.requests = []; - self.sockets = []; - - self.on('free', function onFree(socket, host, port, localAddress) { - var options = toOptions(host, port, localAddress); - for (var i = 0, len = self.requests.length; i < len; ++i) { - var pending = self.requests[i]; - if (pending.host === options.host && pending.port === options.port) { - // Detect the request to connect same origin server, - // reuse the connection. - self.requests.splice(i, 1); - pending.request.onSocket(socket); - return; - } - } - socket.destroy(); - self.removeSocket(socket); - }); -} -util.inherits(TunnelingAgent, events.EventEmitter); - -TunnelingAgent.prototype.addRequest = function addRequest(req, host, port, localAddress) { - var self = this; - var options = mergeOptions({request: req}, self.options, toOptions(host, port, localAddress)); - - if (self.sockets.length >= this.maxSockets) { - // We are over limit so we'll add it to the queue. - self.requests.push(options); - return; - } - - // If we are under maxSockets create a new one. - self.createSocket(options, function(socket) { - socket.on('free', onFree); - socket.on('close', onCloseOrRemove); - socket.on('agentRemove', onCloseOrRemove); - req.onSocket(socket); - - function onFree() { - self.emit('free', socket, options); - } - - function onCloseOrRemove(err) { - self.removeSocket(socket); - socket.removeListener('free', onFree); - socket.removeListener('close', onCloseOrRemove); - socket.removeListener('agentRemove', onCloseOrRemove); - } - }); -}; - -TunnelingAgent.prototype.createSocket = function createSocket(options, cb) { - var self = this; - var placeholder = {}; - self.sockets.push(placeholder); - - var connectOptions = mergeOptions({}, self.proxyOptions, { - method: 'CONNECT', - path: options.host + ':' + options.port, - agent: false - }); - if (connectOptions.proxyAuth) { - connectOptions.headers = connectOptions.headers || {}; - connectOptions.headers['Proxy-Authorization'] = 'Basic ' + - new Buffer(connectOptions.proxyAuth).toString('base64'); - } - - debug('making CONNECT request'); - var connectReq = self.request(connectOptions); - connectReq.useChunkedEncodingByDefault = false; // for v0.6 - connectReq.once('response', onResponse); // for v0.6 - connectReq.once('upgrade', onUpgrade); // for v0.6 - connectReq.once('connect', onConnect); // for v0.7 or later - connectReq.once('error', onError); - connectReq.end(); - - function onResponse(res) { - // Very hacky. This is necessary to avoid http-parser leaks. - res.upgrade = true; - } - - function onUpgrade(res, socket, head) { - // Hacky. - process.nextTick(function() { - onConnect(res, socket, head); - }); - } - - function onConnect(res, socket, head) { - connectReq.removeAllListeners(); - socket.removeAllListeners(); - - if (res.statusCode === 200) { - assert.equal(head.length, 0); - debug('tunneling connection has established'); - self.sockets[self.sockets.indexOf(placeholder)] = socket; - cb(socket); - } else { - debug('tunneling socket could not be established, statusCode=%d', - res.statusCode); - var error = new Error('tunneling socket could not be established, ' + - 'statusCode=' + res.statusCode); - error.code = 'ECONNRESET'; - options.request.emit('error', error); - self.removeSocket(placeholder); - } - } - - function onError(cause) { - connectReq.removeAllListeners(); - - debug('tunneling socket could not be established, cause=%s\n', - cause.message, cause.stack); - var error = new Error('tunneling socket could not be established, ' + - 'cause=' + cause.message); - error.code = 'ECONNRESET'; - options.request.emit('error', error); - self.removeSocket(placeholder); - } -}; - -TunnelingAgent.prototype.removeSocket = function removeSocket(socket) { - var pos = this.sockets.indexOf(socket) - if (pos === -1) { - return; - } - this.sockets.splice(pos, 1); - - var pending = this.requests.shift(); - if (pending) { - // If we have pending requests and a socket gets closed a new one - // needs to be created to take over in the pool for the one that closed. - this.createSocket(pending, function(socket) { - pending.request.onSocket(socket); - }); - } -}; - -function createSecureSocket(options, cb) { - var self = this; - TunnelingAgent.prototype.createSocket.call(self, options, function(socket) { - var hostHeader = options.request.getHeader('host'); - var tlsOptions = mergeOptions({}, self.options, { - socket: socket, - servername: hostHeader ? hostHeader.replace(/:.*$/, '') : options.host - }); - - // 0 is dummy port for v0.6 - var secureSocket = tls.connect(0, tlsOptions); - self.sockets[self.sockets.indexOf(socket)] = secureSocket; - cb(secureSocket); - }); -} - - -function toOptions(host, port, localAddress) { - if (typeof host === 'string') { // since v0.10 - return { - host: host, - port: port, - localAddress: localAddress - }; - } - return host; // for v0.11 or later -} - -function mergeOptions(target) { - for (var i = 1, len = arguments.length; i < len; ++i) { - var overrides = arguments[i]; - if (typeof overrides === 'object') { - var keys = Object.keys(overrides); - for (var j = 0, keyLen = keys.length; j < keyLen; ++j) { - var k = keys[j]; - if (overrides[k] !== undefined) { - target[k] = overrides[k]; - } - } - } - } - return target; -} - - -var debug; -if (process.env.NODE_DEBUG && /\btunnel\b/.test(process.env.NODE_DEBUG)) { - debug = function() { - var args = Array.prototype.slice.call(arguments); - if (typeof args[0] === 'string') { - args[0] = 'TUNNEL: ' + args[0]; - } else { - args.unshift('TUNNEL:'); - } - console.error.apply(console, args); - } -} else { - debug = function() {}; -} -exports.debug = debug; // for test +module.exports = bytesToUuid; /***/ }), @@ -3890,485 +3806,12 @@ exports.debug = debug; // for test /***/ 747: /***/ (function(module) { -module.exports = __nested_webpack_require_1931__(747); +module.exports = require("fs"); /***/ }), -/***/ 802: -/***/ (function(module, __unusedexports, __nested_webpack_require_109150__) { - -module.exports = __nested_webpack_require_109150__(725); - - -/***/ }), - -/***/ 835: -/***/ (function(module) { - -module.exports = __nested_webpack_require_1931__(835); - -/***/ }), - -/***/ 853: -/***/ (function(module, __unusedexports, __nested_webpack_require_109366__) { - -// Unique ID creation requires a high quality random # generator. In node.js -// this is pretty straight-forward - we use the crypto API. - -var crypto = __nested_webpack_require_109366__(417); - -module.exports = function nodeRNG() { - return crypto.randomBytes(16); -}; - - -/***/ }), - -/***/ 871: -/***/ (function(__unusedmodule, exports, __nested_webpack_require_109716__) { - -"use strict"; - -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - 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) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -Object.defineProperty(exports, "__esModule", { value: true }); -const core = __nested_webpack_require_109716__(694); -const io = __nested_webpack_require_109716__(999); -const fs = __nested_webpack_require_109716__(747); -const os = __nested_webpack_require_109716__(87); -const path = __nested_webpack_require_109716__(622); -const httpm = __nested_webpack_require_109716__(113); -const semver = __nested_webpack_require_109716__(284); -const uuidV4 = __nested_webpack_require_109716__(683); -const exec_1 = __nested_webpack_require_109716__(430); -const assert_1 = __nested_webpack_require_109716__(357); -class HTTPError extends Error { - constructor(httpStatusCode) { - super(`Unexpected HTTP response: ${httpStatusCode}`); - this.httpStatusCode = httpStatusCode; - Object.setPrototypeOf(this, new.target.prototype); - } -} -exports.HTTPError = HTTPError; -const IS_WINDOWS = process.platform === 'win32'; -const userAgent = 'actions/tool-cache'; -// On load grab temp directory and cache directory and remove them from env (currently don't want to expose this) -let tempDirectory = process.env['RUNNER_TEMP'] || ''; -let cacheRoot = process.env['RUNNER_TOOL_CACHE'] || ''; -// If directories not found, place them in common temp locations -if (!tempDirectory || !cacheRoot) { - let baseLocation; - if (IS_WINDOWS) { - // On windows use the USERPROFILE env variable - baseLocation = process.env['USERPROFILE'] || 'C:\\'; - } - else { - if (process.platform === 'darwin') { - baseLocation = '/Users'; - } - else { - baseLocation = '/home'; - } - } - if (!tempDirectory) { - tempDirectory = path.join(baseLocation, 'actions', 'temp'); - } - if (!cacheRoot) { - cacheRoot = path.join(baseLocation, 'actions', 'cache'); - } -} -/** - * Download a tool from an url and stream it into a file - * - * @param url url of tool to download - * @returns path to downloaded tool - */ -function downloadTool(url) { - return __awaiter(this, void 0, void 0, function* () { - // Wrap in a promise so that we can resolve from within stream callbacks - return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () { - try { - const http = new httpm.HttpClient(userAgent, [], { - allowRetries: true, - maxRetries: 3 - }); - const destPath = path.join(tempDirectory, uuidV4()); - yield io.mkdirP(tempDirectory); - core.debug(`Downloading ${url}`); - core.debug(`Downloading ${destPath}`); - if (fs.existsSync(destPath)) { - throw new Error(`Destination file path ${destPath} already exists`); - } - const response = yield http.get(url); - 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})`); - throw err; - } - const file = fs.createWriteStream(destPath); - file.on('open', () => __awaiter(this, void 0, void 0, function* () { - try { - const stream = response.message.pipe(file); - stream.on('close', () => { - core.debug('download complete'); - resolve(destPath); - }); - } - catch (err) { - core.debug(`Failed to download from "${url}". Code(${response.message.statusCode}) Message(${response.message.statusMessage})`); - reject(err); - } - })); - file.on('error', err => { - file.end(); - reject(err); - }); - } - catch (err) { - reject(err); - } - })); - }); -} -exports.downloadTool = downloadTool; -/** - * Extract a .7z file - * - * @param file path to the .7z file - * @param dest destination directory. Optional. - * @param _7zPath path to 7zr.exe. Optional, for long path support. Most .7z archives do not have this - * problem. If your .7z archive contains very long paths, you can pass the path to 7zr.exe which will - * gracefully handle long paths. By default 7zdec.exe is used because it is a very small program and is - * bundled with the tool lib. However it does not support long paths. 7zr.exe is the reduced command line - * interface, it is smaller than the full command line interface, and it does support long paths. At the - * time of this writing, it is freely available from the LZMA SDK that is available on the 7zip website. - * Be sure to check the current license agreement. If 7zr.exe is bundled with your action, then the path - * to 7zr.exe can be pass to this function. - * @returns path to the destination directory - */ -function extract7z(file, dest, _7zPath) { - return __awaiter(this, void 0, void 0, function* () { - assert_1.ok(IS_WINDOWS, 'extract7z() not supported on current OS'); - assert_1.ok(file, 'parameter "file" is required'); - dest = dest || (yield _createExtractFolder(dest)); - const originalCwd = process.cwd(); - process.chdir(dest); - if (_7zPath) { - try { - const args = [ - 'x', - '-bb1', - '-bd', - '-sccUTF-8', - file - ]; - const options = { - silent: true - }; - yield exec_1.exec(`"${_7zPath}"`, args, options); - } - finally { - process.chdir(originalCwd); - } - } - else { - const escapedScript = path - .join(__dirname, '..', 'scripts', 'Invoke-7zdec.ps1') - .replace(/'/g, "''") - .replace(/"|\n|\r/g, ''); // double-up single quotes, remove double quotes and newlines - const escapedFile = file.replace(/'/g, "''").replace(/"|\n|\r/g, ''); - const escapedTarget = dest.replace(/'/g, "''").replace(/"|\n|\r/g, ''); - const command = `& '${escapedScript}' -Source '${escapedFile}' -Target '${escapedTarget}'`; - const args = [ - '-NoLogo', - '-Sta', - '-NoProfile', - '-NonInteractive', - '-ExecutionPolicy', - 'Unrestricted', - '-Command', - command - ]; - const options = { - silent: true - }; - try { - const powershellPath = yield io.which('powershell', true); - yield exec_1.exec(`"${powershellPath}"`, args, options); - } - finally { - process.chdir(originalCwd); - } - } - return dest; - }); -} -exports.extract7z = extract7z; -/** - * Extract a tar - * - * @param file path to the tar - * @param dest destination directory. Optional. - * @returns path to the destination directory - */ -function extractTar(file, dest) { - return __awaiter(this, void 0, void 0, function* () { - if (!file) { - throw new Error("parameter 'file' is required"); - } - dest = dest || (yield _createExtractFolder(dest)); - const tarPath = yield io.which('tar', true); - yield exec_1.exec(`"${tarPath}"`, ['xzC', dest, '-f', file]); - return dest; - }); -} -exports.extractTar = extractTar; -/** - * Extract a zip - * - * @param file path to the zip - * @param dest destination directory. Optional. - * @returns path to the destination directory - */ -function extractZip(file, dest) { - return __awaiter(this, void 0, void 0, function* () { - if (!file) { - throw new Error("parameter 'file' is required"); - } - dest = dest || (yield _createExtractFolder(dest)); - if (IS_WINDOWS) { - yield extractZipWin(file, dest); - } - else { - yield extractZipNix(file, dest); - } - return dest; - }); -} -exports.extractZip = extractZip; -function extractZipWin(file, dest) { - return __awaiter(this, void 0, void 0, function* () { - // build the powershell command - const escapedFile = file.replace(/'/g, "''").replace(/"|\n|\r/g, ''); // double-up single quotes, remove double quotes and newlines - const escapedDest = dest.replace(/'/g, "''").replace(/"|\n|\r/g, ''); - const command = `$ErrorActionPreference = 'Stop' ; try { Add-Type -AssemblyName System.IO.Compression.FileSystem } catch { } ; [System.IO.Compression.ZipFile]::ExtractToDirectory('${escapedFile}', '${escapedDest}')`; - // run powershell - const powershellPath = yield io.which('powershell'); - const args = [ - '-NoLogo', - '-Sta', - '-NoProfile', - '-NonInteractive', - '-ExecutionPolicy', - 'Unrestricted', - '-Command', - command - ]; - yield exec_1.exec(`"${powershellPath}"`, args); - }); -} -function extractZipNix(file, dest) { - return __awaiter(this, void 0, void 0, function* () { - const unzipPath = __nested_webpack_require_109716__.ab + "unzip"; - yield exec_1.exec(`"${unzipPath}"`, [file], { cwd: dest }); - }); -} -/** - * Caches a directory and installs it into the tool cacheDir - * - * @param sourceDir the directory to cache into tools - * @param tool tool name - * @param version version of the tool. semver format - * @param arch architecture of the tool. Optional. Defaults to machine architecture - */ -function cacheDir(sourceDir, tool, version, arch) { - return __awaiter(this, void 0, void 0, function* () { - version = semver.clean(version) || version; - arch = arch || os.arch(); - core.debug(`Caching tool ${tool} ${version} ${arch}`); - core.debug(`source dir: ${sourceDir}`); - if (!fs.statSync(sourceDir).isDirectory()) { - throw new Error('sourceDir is not a directory'); - } - // Create the tool dir - const destPath = yield _createToolPath(tool, version, arch); - // copy each child item. do not move. move can fail on Windows - // due to anti-virus software having an open handle on a file. - for (const itemName of fs.readdirSync(sourceDir)) { - const s = path.join(sourceDir, itemName); - yield io.cp(s, destPath, { recursive: true }); - } - // write .complete - _completeToolPath(tool, version, arch); - return destPath; - }); -} -exports.cacheDir = cacheDir; -/** - * Caches a downloaded file (GUID) and installs it - * into the tool cache with a given targetName - * - * @param sourceFile the file to cache into tools. Typically a result of downloadTool which is a guid. - * @param targetFile the name of the file name in the tools directory - * @param tool tool name - * @param version version of the tool. semver format - * @param arch architecture of the tool. Optional. Defaults to machine architecture - */ -function cacheFile(sourceFile, targetFile, tool, version, arch) { - return __awaiter(this, void 0, void 0, function* () { - version = semver.clean(version) || version; - arch = arch || os.arch(); - core.debug(`Caching tool ${tool} ${version} ${arch}`); - core.debug(`source file: ${sourceFile}`); - if (!fs.statSync(sourceFile).isFile()) { - throw new Error('sourceFile is not a file'); - } - // create the tool dir - const destFolder = yield _createToolPath(tool, version, arch); - // copy instead of move. move can fail on Windows due to - // anti-virus software having an open handle on a file. - const destPath = path.join(destFolder, targetFile); - core.debug(`destination file ${destPath}`); - yield io.cp(sourceFile, destPath); - // write .complete - _completeToolPath(tool, version, arch); - return destFolder; - }); -} -exports.cacheFile = cacheFile; -/** - * Finds the path to a tool version in the local installed tool cache - * - * @param toolName name of the tool - * @param versionSpec version of the tool - * @param arch optional arch. defaults to arch of computer - */ -function find(toolName, versionSpec, arch) { - if (!toolName) { - throw new Error('toolName parameter is required'); - } - if (!versionSpec) { - throw new Error('versionSpec parameter is required'); - } - arch = arch || os.arch(); - // attempt to resolve an explicit version - if (!_isExplicitVersion(versionSpec)) { - const localVersions = findAllVersions(toolName, arch); - const match = _evaluateVersions(localVersions, versionSpec); - versionSpec = match; - } - // check for the explicit version in the cache - let toolPath = ''; - if (versionSpec) { - versionSpec = semver.clean(versionSpec) || ''; - const cachePath = path.join(cacheRoot, toolName, versionSpec, arch); - core.debug(`checking cache: ${cachePath}`); - if (fs.existsSync(cachePath) && fs.existsSync(`${cachePath}.complete`)) { - core.debug(`Found tool in cache ${toolName} ${versionSpec} ${arch}`); - toolPath = cachePath; - } - else { - core.debug('not found'); - } - } - return toolPath; -} -exports.find = find; -/** - * Finds the paths to all versions of a tool that are installed in the local tool cache - * - * @param toolName name of the tool - * @param arch optional arch. defaults to arch of computer - */ -function findAllVersions(toolName, arch) { - const versions = []; - arch = arch || os.arch(); - const toolPath = path.join(cacheRoot, toolName); - if (fs.existsSync(toolPath)) { - const children = fs.readdirSync(toolPath); - for (const child of children) { - if (_isExplicitVersion(child)) { - const fullPath = path.join(toolPath, child, arch || ''); - if (fs.existsSync(fullPath) && fs.existsSync(`${fullPath}.complete`)) { - versions.push(child); - } - } - } - } - return versions; -} -exports.findAllVersions = findAllVersions; -function _createExtractFolder(dest) { - return __awaiter(this, void 0, void 0, function* () { - if (!dest) { - // create a temp dir - dest = path.join(tempDirectory, uuidV4()); - } - yield io.mkdirP(dest); - return dest; - }); -} -function _createToolPath(tool, version, arch) { - return __awaiter(this, void 0, void 0, function* () { - const folderPath = path.join(cacheRoot, tool, semver.clean(version) || version, arch || ''); - core.debug(`destination ${folderPath}`); - const markerPath = `${folderPath}.complete`; - yield io.rmRF(folderPath); - yield io.rmRF(markerPath); - yield io.mkdirP(folderPath); - return folderPath; - }); -} -function _completeToolPath(tool, version, arch) { - const folderPath = path.join(cacheRoot, tool, semver.clean(version) || version, arch || ''); - const markerPath = `${folderPath}.complete`; - fs.writeFileSync(markerPath, ''); - core.debug('finished caching tool'); -} -function _isExplicitVersion(versionSpec) { - const c = semver.clean(versionSpec) || ''; - core.debug(`isExplicit: ${c}`); - const valid = semver.valid(c) != null; - core.debug(`explicit? ${valid}`); - return valid; -} -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; -} -//# sourceMappingURL=tool-cache.js.map - -/***/ }), - -/***/ 938: -/***/ (function(__unusedmodule, exports, __nested_webpack_require_127205__) { +/***/ 749: +/***/ (function(__unusedmodule, exports, __webpack_require__) { "use strict"; @@ -4389,14 +3832,14 @@ var __importStar = (this && this.__importStar) || function (mod) { }; Object.defineProperty(exports, "__esModule", { value: true }); let tempDirectory = process.env['RUNNER_TEMP'] || ''; -const core = __importStar(__nested_webpack_require_127205__(694)); -const io = __importStar(__nested_webpack_require_127205__(999)); -const exec = __importStar(__nested_webpack_require_127205__(430)); -const tc = __importStar(__nested_webpack_require_127205__(871)); -const fs = __importStar(__nested_webpack_require_127205__(747)); -const path = __importStar(__nested_webpack_require_127205__(622)); -const semver = __importStar(__nested_webpack_require_127205__(284)); -const httpm = __importStar(__nested_webpack_require_127205__(113)); +const core = __importStar(__webpack_require__(470)); +const io = __importStar(__webpack_require__(1)); +const exec = __importStar(__webpack_require__(986)); +const tc = __importStar(__webpack_require__(533)); +const fs = __importStar(__webpack_require__(747)); +const path = __importStar(__webpack_require__(622)); +const semver = __importStar(__webpack_require__(280)); +const httpm = __importStar(__webpack_require__(874)); const IS_WINDOWS = process.platform === 'win32'; if (!tempDirectory) { let baseLocation; @@ -4623,8 +4066,44 @@ function normalizeVersion(version) { /***/ }), -/***/ 960: -/***/ (function(__unusedmodule, exports, __nested_webpack_require_137410__) { +/***/ 826: +/***/ (function(module, __unusedexports, __webpack_require__) { + +var rng = __webpack_require__(139); +var bytesToUuid = __webpack_require__(722); + +function v4(options, buf, offset) { + var i = buf && offset || 0; + + if (typeof(options) == 'string') { + buf = options === 'binary' ? new Array(16) : null; + options = null; + } + options = options || {}; + + var rnds = options.random || (options.rng || rng)(); + + // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` + rnds[6] = (rnds[6] & 0x0f) | 0x40; + rnds[8] = (rnds[8] & 0x3f) | 0x80; + + // Copy bytes to buffer, if provided + if (buf) { + for (var ii = 0; ii < 16; ++ii) { + buf[i + ii] = rnds[ii]; + } + } + + return buf || bytesToUuid(rnds); +} + +module.exports = v4; + + +/***/ }), + +/***/ 827: +/***/ (function(__unusedmodule, exports, __webpack_require__) { "use strict"; @@ -4636,826 +4115,60 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; -var _a; -Object.defineProperty(exports, "__esModule", { value: true }); -const assert_1 = __nested_webpack_require_137410__(357); -const fs = __nested_webpack_require_137410__(747); -const path = __nested_webpack_require_137410__(622); -_a = fs.promises, exports.chmod = _a.chmod, exports.copyFile = _a.copyFile, exports.lstat = _a.lstat, exports.mkdir = _a.mkdir, exports.readdir = _a.readdir, exports.readlink = _a.readlink, exports.rename = _a.rename, exports.rmdir = _a.rmdir, exports.stat = _a.stat, exports.symlink = _a.symlink, exports.unlink = _a.unlink; -exports.IS_WINDOWS = process.platform === 'win32'; -function exists(fsPath) { - return __awaiter(this, void 0, void 0, function* () { - try { - yield exports.stat(fsPath); - } - catch (err) { - if (err.code === 'ENOENT') { - return false; - } - throw err; - } - return true; - }); -} -exports.exists = exists; -function isDirectory(fsPath, useStat = false) { - return __awaiter(this, void 0, void 0, function* () { - const stats = useStat ? yield exports.stat(fsPath) : yield exports.lstat(fsPath); - return stats.isDirectory(); - }); -} -exports.isDirectory = isDirectory; -/** - * On OSX/Linux, true if path starts with '/'. On Windows, true for paths like: - * \, \hello, \\hello\share, C:, and C:\hello (and corresponding alternate separator cases). - */ -function isRooted(p) { - p = normalizeSeparators(p); - if (!p) { - throw new Error('isRooted() parameter "p" cannot be empty'); - } - if (exports.IS_WINDOWS) { - return (p.startsWith('\\') || /^[A-Z]:/i.test(p) // e.g. \ or \hello or \\hello - ); // e.g. C: or C:\hello - } - return p.startsWith('/'); -} -exports.isRooted = isRooted; -/** - * Recursively create a directory at `fsPath`. - * - * This implementation is optimistic, meaning it attempts to create the full - * path first, and backs up the path stack from there. - * - * @param fsPath The path to create - * @param maxDepth The maximum recursion depth - * @param depth The current recursion depth - */ -function mkdirP(fsPath, maxDepth = 1000, depth = 1) { - return __awaiter(this, void 0, void 0, function* () { - assert_1.ok(fsPath, 'a path argument must be provided'); - fsPath = path.resolve(fsPath); - if (depth >= maxDepth) - return exports.mkdir(fsPath); - try { - yield exports.mkdir(fsPath); - return; - } - catch (err) { - switch (err.code) { - case 'ENOENT': { - yield mkdirP(path.dirname(fsPath), maxDepth, depth + 1); - yield exports.mkdir(fsPath); - return; - } - default: { - let stats; - try { - stats = yield exports.stat(fsPath); - } - catch (err2) { - throw err; - } - if (!stats.isDirectory()) - throw err; - } - } - } - }); -} -exports.mkdirP = mkdirP; -/** - * Best effort attempt to determine whether a file exists and is executable. - * @param filePath file path to check - * @param extensions additional file extensions to try - * @return if file exists and is executable, returns the file path. otherwise empty string. - */ -function tryGetExecutablePath(filePath, extensions) { - return __awaiter(this, void 0, void 0, function* () { - let stats = undefined; - try { - // test file exists - stats = yield exports.stat(filePath); - } - catch (err) { - if (err.code !== 'ENOENT') { - // eslint-disable-next-line no-console - console.log(`Unexpected error attempting to determine if executable file exists '${filePath}': ${err}`); - } - } - if (stats && stats.isFile()) { - if (exports.IS_WINDOWS) { - // on Windows, test for valid extension - const upperExt = path.extname(filePath).toUpperCase(); - if (extensions.some(validExt => validExt.toUpperCase() === upperExt)) { - return filePath; - } - } - else { - if (isUnixExecutable(stats)) { - return filePath; - } - } - } - // try each extension - const originalFilePath = filePath; - for (const extension of extensions) { - filePath = originalFilePath + extension; - stats = undefined; - try { - stats = yield exports.stat(filePath); - } - catch (err) { - if (err.code !== 'ENOENT') { - // eslint-disable-next-line no-console - console.log(`Unexpected error attempting to determine if executable file exists '${filePath}': ${err}`); - } - } - if (stats && stats.isFile()) { - if (exports.IS_WINDOWS) { - // preserve the case of the actual file (since an extension was appended) - try { - const directory = path.dirname(filePath); - const upperName = path.basename(filePath).toUpperCase(); - for (const actualName of yield exports.readdir(directory)) { - if (upperName === actualName.toUpperCase()) { - filePath = path.join(directory, actualName); - break; - } - } - } - catch (err) { - // eslint-disable-next-line no-console - console.log(`Unexpected error attempting to determine the actual case of the file '${filePath}': ${err}`); - } - return filePath; - } - else { - if (isUnixExecutable(stats)) { - return filePath; - } - } - } - } - return ''; - }); -} -exports.tryGetExecutablePath = tryGetExecutablePath; -function normalizeSeparators(p) { - p = p || ''; - if (exports.IS_WINDOWS) { - // convert slashes on Windows - p = p.replace(/\//g, '\\'); - // remove redundant slashes - return p.replace(/\\\\+/g, '\\'); - } - // remove redundant slashes - return p.replace(/\/\/+/g, '/'); -} -// on Mac/Linux, test the execute bit -// R W X R W X R W X -// 256 128 64 32 16 8 4 2 1 -function isUnixExecutable(stats) { - return ((stats.mode & 1) > 0 || - ((stats.mode & 8) > 0 && stats.gid === process.getgid()) || - ((stats.mode & 64) > 0 && stats.uid === process.getuid())); -} -//# sourceMappingURL=io-util.js.map - -/***/ }), - -/***/ 999: -/***/ (function(__unusedmodule, exports, __nested_webpack_require_145200__) { - -"use strict"; - -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - 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) : new P(function (resolve) { resolve(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 childProcess = __nested_webpack_require_145200__(129); -const path = __nested_webpack_require_145200__(622); -const util_1 = __nested_webpack_require_145200__(669); -const ioUtil = __nested_webpack_require_145200__(960); -const exec = util_1.promisify(childProcess.exec); -/** - * Copies a file or folder. - * Based off of shelljs - https://github.com/shelljs/shelljs/blob/9237f66c52e5daa40458f94f9565e18e8132f5a6/src/cp.js - * - * @param source source path - * @param dest destination path - * @param options optional. See CopyOptions. - */ -function cp(source, dest, options = {}) { +const fs = __importStar(__webpack_require__(747)); +const os = __importStar(__webpack_require__(87)); +const path = __importStar(__webpack_require__(622)); +const core = __importStar(__webpack_require__(470)); +const io = __importStar(__webpack_require__(1)); +exports.M2_DIR = '.m2'; +exports.SETTINGS_FILE = 'settings.xml'; +function configAuthentication(id, username, password) { return __awaiter(this, void 0, void 0, function* () { - const { force, recursive } = readCopyOptions(options); - const destStat = (yield ioUtil.exists(dest)) ? yield ioUtil.stat(dest) : null; - // Dest is an existing file, but not forcing - if (destStat && destStat.isFile() && !force) { - return; - } - // If dest is an existing directory, should copy inside. - const newDest = destStat && destStat.isDirectory() - ? path.join(dest, path.basename(source)) - : dest; - if (!(yield ioUtil.exists(source))) { - throw new Error(`no such file or directory: ${source}`); - } - const sourceStat = yield ioUtil.stat(source); - if (sourceStat.isDirectory()) { - if (!recursive) { - throw new Error(`Failed to copy. ${source} is a directory, but tried to copy without recursive flag.`); - } - else { - yield cpDirRecursive(source, newDest, 0, force); - } + if (id && username && password) { + console.log(`creating ${exports.SETTINGS_FILE} with server-id: ${id}, username: ${username}, and a password`); + const directory = path.join(os.homedir(), exports.M2_DIR); + yield io.mkdirP(directory); + core.debug(`created directory ${directory}`); + yield write(directory, generate(id, username, password)); } else { - if (path.relative(source, newDest) === '') { - // a file cannot be copied to itself - throw new Error(`'${newDest}' and '${source}' are the same file`); - } - yield copyFile(source, newDest, force); + core.debug(`no ${exports.SETTINGS_FILE} without server-id: ${id}, username: ${username}, and a password`); } }); } -exports.cp = cp; -/** - * Moves a path. - * - * @param source source path - * @param dest destination path - * @param options optional. See MoveOptions. - */ -function mv(source, dest, options = {}) { +exports.configAuthentication = configAuthentication; +// only exported for testing purposes +function generate(id, username, password) { + return ` + + + + ${id} + ${username} + ${password} + + + + `; +} +exports.generate = generate; +function write(directory, settings) { return __awaiter(this, void 0, void 0, function* () { - if (yield ioUtil.exists(dest)) { - let destExists = true; - if (yield ioUtil.isDirectory(dest)) { - // If dest is directory copy src into dest - dest = path.join(dest, path.basename(source)); - destExists = yield ioUtil.exists(dest); - } - if (destExists) { - if (options.force == null || options.force) { - yield rmRF(dest); - } - else { - throw new Error('Destination already exists'); - } - } - } - yield mkdirP(path.dirname(dest)); - yield ioUtil.rename(source, dest); + const options = { encoding: 'utf-8' }; + const location = path.join(directory, exports.SETTINGS_FILE); + console.log(`writing ${location}`); + return fs.writeFileSync(location, settings, options); }); } -exports.mv = mv; -/** - * Remove a path recursively with force - * - * @param inputPath path to remove - */ -function rmRF(inputPath) { - return __awaiter(this, void 0, void 0, function* () { - if (ioUtil.IS_WINDOWS) { - // Node doesn't provide a delete operation, only an unlink function. This means that if the file is being used by another - // program (e.g. antivirus), it won't be deleted. To address this, we shell out the work to rd/del. - try { - if (yield ioUtil.isDirectory(inputPath, true)) { - yield exec(`rd /s /q "${inputPath}"`); - } - else { - yield exec(`del /f /a "${inputPath}"`); - } - } - catch (err) { - // if you try to delete a file that doesn't exist, desired result is achieved - // other errors are valid - if (err.code !== 'ENOENT') - throw err; - } - // Shelling out fails to remove a symlink folder with missing source, this unlink catches that - try { - yield ioUtil.unlink(inputPath); - } - catch (err) { - // if you try to delete a file that doesn't exist, desired result is achieved - // other errors are valid - if (err.code !== 'ENOENT') - throw err; - } - } - else { - let isDir = false; - try { - isDir = yield ioUtil.isDirectory(inputPath); - } - catch (err) { - // if you try to delete a file that doesn't exist, desired result is achieved - // other errors are valid - if (err.code !== 'ENOENT') - throw err; - return; - } - if (isDir) { - yield exec(`rm -rf "${inputPath}"`); - } - else { - yield ioUtil.unlink(inputPath); - } - } - }); -} -exports.rmRF = rmRF; -/** - * Make a directory. Creates the full path with folders in between - * Will throw if it fails - * - * @param fsPath path to create - * @returns Promise - */ -function mkdirP(fsPath) { - return __awaiter(this, void 0, void 0, function* () { - yield ioUtil.mkdirP(fsPath); - }); -} -exports.mkdirP = mkdirP; -/** - * Returns path of a tool had the tool actually been invoked. Resolves via paths. - * If you check and the tool does not exist, it will throw. - * - * @param tool name of the tool - * @param check whether to check if tool exists - * @returns Promise path to tool - */ -function which(tool, check) { - return __awaiter(this, void 0, void 0, function* () { - if (!tool) { - throw new Error("parameter 'tool' is required"); - } - // recursive when check=true - if (check) { - const result = yield which(tool, false); - if (!result) { - if (ioUtil.IS_WINDOWS) { - throw new Error(`Unable to locate executable file: ${tool}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also verify the file has a valid extension for an executable file.`); - } - else { - throw new Error(`Unable to locate executable file: ${tool}. Please verify either the file path exists or the file can be found within a directory specified by the PATH environment variable. Also check the file mode to verify the file is executable.`); - } - } - } - try { - // build the list of extensions to try - const extensions = []; - if (ioUtil.IS_WINDOWS && process.env.PATHEXT) { - for (const extension of process.env.PATHEXT.split(path.delimiter)) { - if (extension) { - extensions.push(extension); - } - } - } - // if it's rooted, return it if exists. otherwise return empty. - if (ioUtil.isRooted(tool)) { - const filePath = yield ioUtil.tryGetExecutablePath(tool, extensions); - if (filePath) { - return filePath; - } - return ''; - } - // if any path separators, return empty - if (tool.includes('/') || (ioUtil.IS_WINDOWS && tool.includes('\\'))) { - return ''; - } - // build the list of directories - // - // Note, technically "where" checks the current directory on Windows. From a task lib perspective, - // it feels like we should not do this. Checking the current directory seems like more of a use - // case of a shell, and the which() function exposed by the task lib should strive for consistency - // across platforms. - const directories = []; - if (process.env.PATH) { - for (const p of process.env.PATH.split(path.delimiter)) { - if (p) { - directories.push(p); - } - } - } - // return the first match - for (const directory of directories) { - const filePath = yield ioUtil.tryGetExecutablePath(directory + path.sep + tool, extensions); - if (filePath) { - return filePath; - } - } - return ''; - } - catch (err) { - throw new Error(`which failed with message ${err.message}`); - } - }); -} -exports.which = which; -function readCopyOptions(options) { - const force = options.force == null ? true : options.force; - const recursive = Boolean(options.recursive); - return { force, recursive }; -} -function cpDirRecursive(sourceDir, destDir, currentDepth, force) { - return __awaiter(this, void 0, void 0, function* () { - // Ensure there is not a run away recursive copy - if (currentDepth >= 255) - return; - currentDepth++; - yield mkdirP(destDir); - const files = yield ioUtil.readdir(sourceDir); - for (const fileName of files) { - const srcFile = `${sourceDir}/${fileName}`; - const destFile = `${destDir}/${fileName}`; - const srcFileStat = yield ioUtil.lstat(srcFile); - if (srcFileStat.isDirectory()) { - // Recurse - yield cpDirRecursive(srcFile, destFile, currentDepth, force); - } - else { - yield copyFile(srcFile, destFile, force); - } - } - // Change the mode for the newly created directory - yield ioUtil.chmod(destDir, (yield ioUtil.stat(sourceDir)).mode); - }); -} -// Buffered file copy -function copyFile(srcFile, destFile, force) { - return __awaiter(this, void 0, void 0, function* () { - if ((yield ioUtil.lstat(srcFile)).isSymbolicLink()) { - // unlink/re-link it - try { - yield ioUtil.lstat(destFile); - yield ioUtil.unlink(destFile); - } - catch (e) { - // Try to override file permission - if (e.code === 'EPERM') { - yield ioUtil.chmod(destFile, '0666'); - yield ioUtil.unlink(destFile); - } - // other errors = it doesn't exist, no work to do - } - // Copy over symlink - const symlinkFull = yield ioUtil.readlink(srcFile); - yield ioUtil.symlink(symlinkFull, destFile, ioUtil.IS_WINDOWS ? 'junction' : null); - } - else if (!(yield ioUtil.exists(destFile)) || force) { - yield ioUtil.copyFile(srcFile, destFile); - } - }); -} -//# sourceMappingURL=io.js.map -/***/ }) - -/******/ }); - -/***/ }), - -/***/ 605: -/***/ (function(module) { - -module.exports = __nested_webpack_require_1759__(605); - -/***/ }), - -/***/ 614: -/***/ (function(module) { - -module.exports = __nested_webpack_require_1759__(614); - -/***/ }), - -/***/ 622: -/***/ (function(module) { - -module.exports = __nested_webpack_require_1759__(622); - -/***/ }), - -/***/ 631: -/***/ (function(module) { - -module.exports = __nested_webpack_require_1759__(631); - -/***/ }), - -/***/ 669: -/***/ (function(module) { - -module.exports = __nested_webpack_require_1759__(669); - -/***/ }), - -/***/ 747: -/***/ (function(module) { - -module.exports = __nested_webpack_require_1759__(747); - -/***/ }), - -/***/ 835: -/***/ (function(module) { - -module.exports = __nested_webpack_require_1759__(835); - -/***/ }) - -/******/ }); - -/***/ }), - -/***/ 357: -/***/ (function(module) { - -module.exports = __nested_webpack_require_1759__(357); - -/***/ }), - -/***/ 417: -/***/ (function(module) { - -module.exports = __nested_webpack_require_1759__(417); - -/***/ }), - -/***/ 605: -/***/ (function(module) { - -module.exports = __nested_webpack_require_1759__(605); - -/***/ }), - -/***/ 614: -/***/ (function(module) { - -module.exports = __nested_webpack_require_1759__(614); - -/***/ }), - -/***/ 622: -/***/ (function(module) { - -module.exports = __nested_webpack_require_1759__(622); - -/***/ }), - -/***/ 631: -/***/ (function(module) { - -module.exports = __nested_webpack_require_1759__(631); - -/***/ }), - -/***/ 669: -/***/ (function(module) { - -module.exports = __nested_webpack_require_1759__(669); - -/***/ }), - -/***/ 747: -/***/ (function(module) { - -module.exports = __nested_webpack_require_1759__(747); - -/***/ }), - -/***/ 835: -/***/ (function(module) { - -module.exports = __nested_webpack_require_1759__(835); - -/***/ }) - -/******/ }); - -/***/ }), - -/***/ 357: -/***/ (function(module) { - -module.exports = __nested_webpack_require_1931__(357); - -/***/ }), - -/***/ 417: -/***/ (function(module) { - -module.exports = __nested_webpack_require_1931__(417); - -/***/ }), - -/***/ 605: -/***/ (function(module) { - -module.exports = __nested_webpack_require_1931__(605); - -/***/ }), - -/***/ 614: -/***/ (function(module) { - -module.exports = __nested_webpack_require_1931__(614); - -/***/ }), - -/***/ 622: -/***/ (function(module) { - -module.exports = __nested_webpack_require_1931__(622); - -/***/ }), - -/***/ 631: -/***/ (function(module) { - -module.exports = __nested_webpack_require_1931__(631); - -/***/ }), - -/***/ 669: -/***/ (function(module) { - -module.exports = __nested_webpack_require_1931__(669); - -/***/ }), - -/***/ 747: -/***/ (function(module) { - -module.exports = __nested_webpack_require_1931__(747); - -/***/ }), - -/***/ 835: -/***/ (function(module) { - -module.exports = __nested_webpack_require_1931__(835); - -/***/ }) - -/******/ }); - -/***/ }), - -/***/ 605: -/***/ (function(module) { - -module.exports = __nested_webpack_require_1931__(605); - -/***/ }), - -/***/ 614: -/***/ (function(module) { - -module.exports = __nested_webpack_require_1931__(614); - -/***/ }), - -/***/ 622: -/***/ (function(module) { - -module.exports = __nested_webpack_require_1931__(622); - -/***/ }), - -/***/ 631: -/***/ (function(module) { - -module.exports = __nested_webpack_require_1931__(631); - -/***/ }), - -/***/ 669: -/***/ (function(module) { - -module.exports = __nested_webpack_require_1931__(669); - -/***/ }), - -/***/ 747: -/***/ (function(module) { - -module.exports = __nested_webpack_require_1931__(747); - -/***/ }), - -/***/ 835: -/***/ (function(module) { - -module.exports = __nested_webpack_require_1931__(835); - -/***/ }) - -/******/ }); - -/***/ }), - -/***/ 605: -/***/ (function(module) { - -module.exports = __webpack_require__(605); - -/***/ }), - -/***/ 614: -/***/ (function(module) { - -module.exports = __webpack_require__(614); - -/***/ }), - -/***/ 622: -/***/ (function(module) { - -module.exports = __webpack_require__(622); - -/***/ }), - -/***/ 631: -/***/ (function(module) { - -module.exports = __webpack_require__(631); - -/***/ }), - -/***/ 669: -/***/ (function(module) { - -module.exports = __webpack_require__(669); - -/***/ }), - -/***/ 747: -/***/ (function(module) { - -module.exports = __webpack_require__(747); - -/***/ }), - -/***/ 835: -/***/ (function(module) { - -module.exports = __webpack_require__(835); - -/***/ }) - -/******/ }); - -/***/ }), - -/***/ 605: -/***/ (function(module) { - -module.exports = require("http"); - -/***/ }), - -/***/ 614: -/***/ (function(module) { - -module.exports = require("events"); - -/***/ }), - -/***/ 622: -/***/ (function(module) { - -module.exports = require("path"); - -/***/ }), - -/***/ 631: -/***/ (function(module) { - -module.exports = require("net"); - -/***/ }), - -/***/ 669: -/***/ (function(module) { - -module.exports = require("util"); - -/***/ }), - -/***/ 747: -/***/ (function(module) { - -module.exports = require("fs"); /***/ }), @@ -5464,6 +4177,512 @@ module.exports = require("fs"); module.exports = require("url"); +/***/ }), + +/***/ 874: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +// Copyright (c) Microsoft. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + 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) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const url = __webpack_require__(835); +const http = __webpack_require__(605); +const https = __webpack_require__(211); +let fs; +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["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 = {})); +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((resolve, reject) => __awaiter(this, void 0, void 0, function* () { + let output = ''; + this.message.on('data', (chunk) => { + output += chunk; + }); + this.message.on('end', () => { + resolve(output); + }); + })); + } +} +exports.HttpClientResponse = HttpClientResponse; +function isHttps(requestUrl) { + let parsedUrl = url.parse(requestUrl); + return parsedUrl.protocol === 'https:'; +} +exports.isHttps = isHttps; +var EnvironmentVariables; +(function (EnvironmentVariables) { + EnvironmentVariables["HTTP_PROXY"] = "HTTP_PROXY"; + EnvironmentVariables["HTTPS_PROXY"] = "HTTPS_PROXY"; +})(EnvironmentVariables || (EnvironmentVariables = {})); +class HttpClient { + constructor(userAgent, handlers, requestOptions) { + this._ignoreSslError = false; + this._allowRedirects = true; + 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; + this._httpProxy = requestOptions.proxy; + if (requestOptions.proxy && requestOptions.proxy.proxyBypassHosts) { + this._httpProxyBypassHosts = []; + requestOptions.proxy.proxyBypassHosts.forEach(bypass => { + this._httpProxyBypassHosts.push(new RegExp(bypass, 'i')); + }); + } + this._certConfig = requestOptions.cert; + if (this._certConfig) { + // If using cert, need fs + fs = __webpack_require__(747); + // cache the cert content into memory, so we don't have to read it from disk every time + if (this._certConfig.caFile && fs.existsSync(this._certConfig.caFile)) { + this._ca = fs.readFileSync(this._certConfig.caFile, 'utf8'); + } + if (this._certConfig.certFile && fs.existsSync(this._certConfig.certFile)) { + this._cert = fs.readFileSync(this._certConfig.certFile, 'utf8'); + } + if (this._certConfig.keyFile && fs.existsSync(this._certConfig.keyFile)) { + this._key = fs.readFileSync(this._certConfig.keyFile, 'utf8'); + } + } + if (requestOptions.allowRedirects != null) { + this._allowRedirects = requestOptions.allowRedirects; + } + 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); + } + /** + * Makes a raw http request. + * All other methods such as get, post, patch, and request ultimately call this. + * Prefer get, del, post and patch + */ + request(verb, requestUrl, data, headers) { + return __awaiter(this, void 0, void 0, function* () { + if (this._disposed) { + throw new Error("Client has already been disposed."); + } + let info = this._prepareRequest(verb, requestUrl, 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 = yield 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; + } + // we need to finish reading the response before reassigning response + // which will leak the open socket. + yield response.readBody(); + // let's make the request with the new redirectUrl + info = this._prepareRequest(verb, redirectUrl, headers); + response = yield 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) { + yield response.readBody(); + yield 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; + let isDataString = typeof (data) === 'string'; + 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(); + } + } + _prepareRequest(method, requestUrl, headers) { + const info = {}; + info.parsedUrl = url.parse(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); + info.options.headers["user-agent"] = this.userAgent; + info.options.agent = this._getAgent(requestUrl); + // gives handlers an opportunity to participate + if (this.handlers && !this._isPresigned(requestUrl)) { + this.handlers.forEach((handler) => { + handler.prepareRequest(info.options); + }); + } + return info; + } + _isPresigned(requestUrl) { + if (this.requestOptions && this.requestOptions.presignedUrlPatterns) { + const patterns = this.requestOptions.presignedUrlPatterns; + for (let i = 0; i < patterns.length; i++) { + if (requestUrl.match(patterns[i])) { + return true; + } + } + } + return false; + } + _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 || {}); + } + _getAgent(requestUrl) { + let agent; + let proxy = this._getProxy(requestUrl); + let useProxy = proxy.proxyUrl && proxy.proxyUrl.hostname && !this._isBypassProxy(requestUrl); + 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; + } + let parsedUrl = url.parse(requestUrl); + 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: proxy.proxyAuth, + host: proxy.proxyUrl.hostname, + port: proxy.proxyUrl.port + }, + }; + let tunnelAgent; + const overHttps = proxy.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 }); + } + if (usingSsl && this._certConfig) { + agent.options = Object.assign(agent.options || {}, { ca: this._ca, cert: this._cert, key: this._key, passphrase: this._certConfig.passphrase }); + } + return agent; + } + _getProxy(requestUrl) { + const parsedUrl = url.parse(requestUrl); + let usingSsl = parsedUrl.protocol === 'https:'; + let proxyConfig = this._httpProxy; + // fallback to http_proxy and https_proxy env + let https_proxy = process.env[EnvironmentVariables.HTTPS_PROXY]; + let http_proxy = process.env[EnvironmentVariables.HTTP_PROXY]; + if (!proxyConfig) { + if (https_proxy && usingSsl) { + proxyConfig = { + proxyUrl: https_proxy + }; + } + else if (http_proxy) { + proxyConfig = { + proxyUrl: http_proxy + }; + } + } + let proxyUrl; + let proxyAuth; + if (proxyConfig) { + if (proxyConfig.proxyUrl.length > 0) { + proxyUrl = url.parse(proxyConfig.proxyUrl); + } + if (proxyConfig.proxyUsername || proxyConfig.proxyPassword) { + proxyAuth = proxyConfig.proxyUsername + ":" + proxyConfig.proxyPassword; + } + } + return { proxyUrl: proxyUrl, proxyAuth: proxyAuth }; + } + _isBypassProxy(requestUrl) { + if (!this._httpProxyBypassHosts) { + return false; + } + let bypass = false; + this._httpProxyBypassHosts.forEach(bypassHost => { + if (bypassHost.test(requestUrl)) { + bypass = true; + } + }); + return bypass; + } + _performExponentialBackoff(retryNumber) { + retryNumber = Math.min(ExponentialBackoffCeiling, retryNumber); + const ms = ExponentialBackoffTimeSlice * Math.pow(2, retryNumber); + return new Promise(resolve => setTimeout(() => resolve(), ms)); + } +} +exports.HttpClient = HttpClient; + + +/***/ }), + +/***/ 986: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + 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) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const tr = __webpack_require__(9); +/** + * Exec a command. + * Output will be streamed to the live console. + * Returns promise with return code + * + * @param commandLine command to execute (can include additional args). Must be correctly escaped. + * @param args optional arguments for tool. Escaping is handled by the lib. + * @param options optional exec options. See ExecOptions + * @returns Promise exit code + */ +function exec(commandLine, args, options) { + return __awaiter(this, void 0, void 0, function* () { + const commandArgs = tr.argStringToArray(commandLine); + if (commandArgs.length === 0) { + throw new Error(`Parameter 'commandLine' cannot be null or empty.`); + } + // Path to tool to execute should be first arg + const toolPath = commandArgs[0]; + args = commandArgs.slice(1).concat(args || []); + const runner = new tr.ToolRunner(toolPath, args, options); + return runner.exec(); + }); +} +exports.exec = exec; +//# sourceMappingURL=exec.js.map + /***/ }) /******/ }); \ No newline at end of file From 210fba7587cd00868a83df177f484772153c94fa Mon Sep 17 00:00:00 2001 From: Bryan Clark Date: Thu, 28 Nov 2019 14:52:51 -0800 Subject: [PATCH 20/55] Add note about pom.xml to README --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index d57bbdd..38e9b94 100644 --- a/README.md +++ b/README.md @@ -77,6 +77,7 @@ jobs: - name: Publish to GitHub Packages Apache Maven run: mvn deploy ``` +See the help docs on [Publishing a Package](https://help.github.com/en/github/managing-packages-with-github-packages/configuring-apache-maven-for-use-with-github-packages#publishing-a-package) for more information on the `pom.xml` file. # License From d5150a6a6702411fd3470e7e813b49fa0c1cf51a Mon Sep 17 00:00:00 2001 From: Bryan Clark Date: Fri, 29 Nov 2019 09:26:29 -0800 Subject: [PATCH 21/55] Add publish to Maven Central example to README --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index 38e9b94..9c94aef 100644 --- a/README.md +++ b/README.md @@ -76,6 +76,15 @@ jobs: run: mvn -B package --file pom.xml - name: Publish to GitHub Packages Apache Maven run: mvn deploy + - name: Set up Apache Maven Central + uses: actions/setup-java@master + with: # running setup-java again overwrites the settings.xml + java-version: 1.8 + server-id: maven + username: maven_username + password: ${{ secrets.MAVEN_CENTRAL_TOKEN }} # password from secrets store + - name: Publish to Apache Maven Central + run: mvn deploy ``` See the help docs on [Publishing a Package](https://help.github.com/en/github/managing-packages-with-github-packages/configuring-apache-maven-for-use-with-github-packages#publishing-a-package) for more information on the `pom.xml` file. From c1c11bbc1b2c22f330c066444efe1634d201f15a Mon Sep 17 00:00:00 2001 From: Bryan Clark Date: Wed, 4 Dec 2019 23:22:47 -0500 Subject: [PATCH 22/55] Examples use v1 instead of master Co-Authored-By: Konrad Pabjan --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9c94aef..95fec46 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,7 @@ jobs: steps: - uses: actions/checkout@v1 - name: Set up JDK 1.8 - uses: actions/setup-java@master + uses: actions/setup-java@v1 with: java-version: 1.8 server-id: github # Value of the distributionManagement/repository/id field of the pom.xml @@ -77,7 +77,7 @@ jobs: - name: Publish to GitHub Packages Apache Maven run: mvn deploy - name: Set up Apache Maven Central - uses: actions/setup-java@master + uses: actions/setup-java@v1 with: # running setup-java again overwrites the settings.xml java-version: 1.8 server-id: maven From bfbec53132fb4c4369c9a47a2bd7aee544453438 Mon Sep 17 00:00:00 2001 From: Bryan Clark Date: Wed, 4 Dec 2019 23:54:21 -0500 Subject: [PATCH 23/55] log when we overwrite the file --- dist/index.js | 17 ++++++++++++++--- src/auth.ts | 16 +++++++++++++--- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/dist/index.js b/dist/index.js index c01c0f3..32058f3 100644 --- a/dist/index.js +++ b/dist/index.js @@ -4134,7 +4134,8 @@ function configAuthentication(id, username, password) { return __awaiter(this, void 0, void 0, function* () { if (id && username && password) { console.log(`creating ${exports.SETTINGS_FILE} with server-id: ${id}, username: ${username}, and a password`); - const directory = path.join(os.homedir(), exports.M2_DIR); + const home = process.env['GITHUB_WORKSPACE'] || os.homedir(); + const directory = path.join(home, exports.M2_DIR); yield io.mkdirP(directory); core.debug(`created directory ${directory}`); yield write(directory, generate(id, username, password)); @@ -4162,10 +4163,20 @@ function generate(id, username, password) { exports.generate = generate; function write(directory, settings) { return __awaiter(this, void 0, void 0, function* () { - const options = { encoding: 'utf-8' }; + const options = { encoding: 'utf-8', flag: 'wx' }; // 'wx': Like 'w' but fails if path exists const location = path.join(directory, exports.SETTINGS_FILE); console.log(`writing ${location}`); - return fs.writeFileSync(location, settings, options); + try { + return fs.writeFileSync(location, settings, options); + } + catch (e) { + if (!e.code) + throw e; + if (e.code == fs.constants.O_EXCL) { + console.log(`overwriting existing file ${location}`); + return fs.writeFileSync(location, settings, { encoding: 'utf-8' }); + } + } }); } diff --git a/src/auth.ts b/src/auth.ts index b61b357..875c6b4 100644 --- a/src/auth.ts +++ b/src/auth.ts @@ -16,7 +16,8 @@ export async function configAuthentication( console.log( `creating ${SETTINGS_FILE} with server-id: ${id}, username: ${username}, and a password` ); - const directory: string = path.join(os.homedir(), M2_DIR); + const home: string = process.env['GITHUB_WORKSPACE'] || os.homedir(); + const directory: string = path.join(home, M2_DIR); await io.mkdirP(directory); core.debug(`created directory ${directory}`); await write(directory, generate(id, username, password)); @@ -43,8 +44,17 @@ export function generate(id: string, username: string, password: string) { } async function write(directory: string, settings: string) { - const options = {encoding: 'utf-8'}; + const options = {encoding: 'utf-8', flag: 'wx'}; // 'wx': Like 'w' but fails if path exists const location = path.join(directory, SETTINGS_FILE); console.log(`writing ${location}`); - return fs.writeFileSync(location, settings, options); + try { + return fs.writeFileSync(location, settings, options); + } catch (e) { + if (e.code == fs.constants.O_EXCL) { + console.log(`overwriting existing file ${location}`); + // default flag is 'w' + return fs.writeFileSync(location, settings, {encoding: 'utf-8'}); + } + throw e; + } } From 12896dfb0f4c3c1a4c5d7186e5f2b6dace62da03 Mon Sep 17 00:00:00 2001 From: Bryan Clark Date: Thu, 5 Dec 2019 00:41:50 -0500 Subject: [PATCH 24/55] logging options --- dist/index.js | 8 ++++---- src/auth.ts | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/dist/index.js b/dist/index.js index 32058f3..22c99c9 100644 --- a/dist/index.js +++ b/dist/index.js @@ -4165,17 +4165,17 @@ function write(directory, settings) { return __awaiter(this, void 0, void 0, function* () { const options = { encoding: 'utf-8', flag: 'wx' }; // 'wx': Like 'w' but fails if path exists const location = path.join(directory, exports.SETTINGS_FILE); - console.log(`writing ${location}`); + console.log(`writing ${location} with options ${options}`); try { - return fs.writeFileSync(location, settings, options); + fs.writeFileSync(location, settings, options); } catch (e) { - if (!e.code) - throw e; if (e.code == fs.constants.O_EXCL) { console.log(`overwriting existing file ${location}`); + // default flag is 'w' return fs.writeFileSync(location, settings, { encoding: 'utf-8' }); } + throw e; } }); } diff --git a/src/auth.ts b/src/auth.ts index 875c6b4..2e83ede 100644 --- a/src/auth.ts +++ b/src/auth.ts @@ -46,9 +46,9 @@ export function generate(id: string, username: string, password: string) { async function write(directory: string, settings: string) { const options = {encoding: 'utf-8', flag: 'wx'}; // 'wx': Like 'w' but fails if path exists const location = path.join(directory, SETTINGS_FILE); - console.log(`writing ${location}`); + console.log(`writing ${location} with options ${options}`); try { - return fs.writeFileSync(location, settings, options); + fs.writeFileSync(location, settings, options); } catch (e) { if (e.code == fs.constants.O_EXCL) { console.log(`overwriting existing file ${location}`); From 96236d7072cf35fe951ee34da7850be147cd261d Mon Sep 17 00:00:00 2001 From: Bryan Clark Date: Thu, 5 Dec 2019 00:43:41 -0500 Subject: [PATCH 25/55] return but shoudl still fail --- dist/index.js | 2 +- src/auth.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dist/index.js b/dist/index.js index 22c99c9..3f1a2e3 100644 --- a/dist/index.js +++ b/dist/index.js @@ -4167,7 +4167,7 @@ function write(directory, settings) { const location = path.join(directory, exports.SETTINGS_FILE); console.log(`writing ${location} with options ${options}`); try { - fs.writeFileSync(location, settings, options); + return fs.writeFileSync(location, settings, options); } catch (e) { if (e.code == fs.constants.O_EXCL) { diff --git a/src/auth.ts b/src/auth.ts index 2e83ede..f0d1197 100644 --- a/src/auth.ts +++ b/src/auth.ts @@ -48,7 +48,7 @@ async function write(directory: string, settings: string) { const location = path.join(directory, SETTINGS_FILE); console.log(`writing ${location} with options ${options}`); try { - fs.writeFileSync(location, settings, options); + return fs.writeFileSync(location, settings, options); } catch (e) { if (e.code == fs.constants.O_EXCL) { console.log(`overwriting existing file ${location}`); From 2b05c0051416301757a657e4d41bd5a6c987bda1 Mon Sep 17 00:00:00 2001 From: Bryan Clark Date: Thu, 5 Dec 2019 00:45:56 -0500 Subject: [PATCH 26/55] logging code --- dist/index.js | 1 + src/auth.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/dist/index.js b/dist/index.js index 3f1a2e3..e31c4d7 100644 --- a/dist/index.js +++ b/dist/index.js @@ -4175,6 +4175,7 @@ function write(directory, settings) { // default flag is 'w' return fs.writeFileSync(location, settings, { encoding: 'utf-8' }); } + console.log(`code ${e.code} and O_EXCL ${fs.constants.O_EXCL}`); throw e; } }); diff --git a/src/auth.ts b/src/auth.ts index f0d1197..1e0c4f8 100644 --- a/src/auth.ts +++ b/src/auth.ts @@ -55,6 +55,7 @@ async function write(directory: string, settings: string) { // default flag is 'w' return fs.writeFileSync(location, settings, {encoding: 'utf-8'}); } + console.log(`code ${e.code} and O_EXCL ${fs.constants.O_EXCL}`); throw e; } } From 948db7588e0a08c59b27f2e17e782e15d31084e4 Mon Sep 17 00:00:00 2001 From: Bryan Clark Date: Thu, 5 Dec 2019 00:48:15 -0500 Subject: [PATCH 27/55] strringify the logs --- dist/index.js | 2 +- src/auth.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dist/index.js b/dist/index.js index e31c4d7..0ff2524 100644 --- a/dist/index.js +++ b/dist/index.js @@ -4175,7 +4175,7 @@ function write(directory, settings) { // default flag is 'w' return fs.writeFileSync(location, settings, { encoding: 'utf-8' }); } - console.log(`code ${e.code} and O_EXCL ${fs.constants.O_EXCL}`); + console.log(`error ${JSON.stringify(e)} and O_EXCL ${fs.constants.O_EXCL}`); throw e; } }); diff --git a/src/auth.ts b/src/auth.ts index 1e0c4f8..f716261 100644 --- a/src/auth.ts +++ b/src/auth.ts @@ -55,7 +55,7 @@ async function write(directory: string, settings: string) { // default flag is 'w' return fs.writeFileSync(location, settings, {encoding: 'utf-8'}); } - console.log(`code ${e.code} and O_EXCL ${fs.constants.O_EXCL}`); + console.log(`error ${JSON.stringify(e)} and O_EXCL ${fs.constants.O_EXCL}`); throw e; } } From 797045350f7883bf56a4ec7728e71f079f9676d9 Mon Sep 17 00:00:00 2001 From: Bryan Clark Date: Thu, 5 Dec 2019 00:54:26 -0500 Subject: [PATCH 28/55] code == EEXIST --- dist/index.js | 3 +-- src/auth.ts | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/dist/index.js b/dist/index.js index 0ff2524..92274cd 100644 --- a/dist/index.js +++ b/dist/index.js @@ -4170,12 +4170,11 @@ function write(directory, settings) { return fs.writeFileSync(location, settings, options); } catch (e) { - if (e.code == fs.constants.O_EXCL) { + if (e.code == "EEXIST") { console.log(`overwriting existing file ${location}`); // default flag is 'w' return fs.writeFileSync(location, settings, { encoding: 'utf-8' }); } - console.log(`error ${JSON.stringify(e)} and O_EXCL ${fs.constants.O_EXCL}`); throw e; } }); diff --git a/src/auth.ts b/src/auth.ts index f716261..6068341 100644 --- a/src/auth.ts +++ b/src/auth.ts @@ -50,12 +50,11 @@ async function write(directory: string, settings: string) { try { return fs.writeFileSync(location, settings, options); } catch (e) { - if (e.code == fs.constants.O_EXCL) { + if (e.code == "EEXIST") { console.log(`overwriting existing file ${location}`); // default flag is 'w' return fs.writeFileSync(location, settings, {encoding: 'utf-8'}); } - console.log(`error ${JSON.stringify(e)} and O_EXCL ${fs.constants.O_EXCL}`); throw e; } } From 1dac4fef0556b71a2568cc210af66d63263c08bc Mon Sep 17 00:00:00 2001 From: Bryan Clark Date: Fri, 6 Dec 2019 14:25:41 -0500 Subject: [PATCH 29/55] Use $HOME directory --- src/auth.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/auth.ts b/src/auth.ts index 6068341..09a1f78 100644 --- a/src/auth.ts +++ b/src/auth.ts @@ -16,8 +16,7 @@ export async function configAuthentication( console.log( `creating ${SETTINGS_FILE} with server-id: ${id}, username: ${username}, and a password` ); - const home: string = process.env['GITHUB_WORKSPACE'] || os.homedir(); - const directory: string = path.join(home, M2_DIR); + const directory: string = path.join(os.homedir(), M2_DIR); await io.mkdirP(directory); core.debug(`created directory ${directory}`); await write(directory, generate(id, username, password)); From 5e29577d7bda754152759cac220bfb4e1967ea40 Mon Sep 17 00:00:00 2001 From: Bryan Clark Date: Fri, 6 Dec 2019 14:28:17 -0500 Subject: [PATCH 30/55] Remote options from log --- src/auth.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/auth.ts b/src/auth.ts index 09a1f78..7ebbe83 100644 --- a/src/auth.ts +++ b/src/auth.ts @@ -45,7 +45,7 @@ export function generate(id: string, username: string, password: string) { async function write(directory: string, settings: string) { const options = {encoding: 'utf-8', flag: 'wx'}; // 'wx': Like 'w' but fails if path exists const location = path.join(directory, SETTINGS_FILE); - console.log(`writing ${location} with options ${options}`); + console.log(`writing ${location}`); try { return fs.writeFileSync(location, settings, options); } catch (e) { From 8940139ee84ca9e5eeaa73fc5c7cf5e9947a14b8 Mon Sep 17 00:00:00 2001 From: Bryan Clark Date: Fri, 6 Dec 2019 14:28:34 -0500 Subject: [PATCH 31/55] Be explicit about second flag --- src/auth.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/auth.ts b/src/auth.ts index 7ebbe83..2e6605d 100644 --- a/src/auth.ts +++ b/src/auth.ts @@ -50,9 +50,8 @@ async function write(directory: string, settings: string) { return fs.writeFileSync(location, settings, options); } catch (e) { if (e.code == "EEXIST") { - console.log(`overwriting existing file ${location}`); - // default flag is 'w' - return fs.writeFileSync(location, settings, {encoding: 'utf-8'}); + console.warn(`overwriting existing file ${location}`); + return fs.writeFileSync(location, settings, {encoding: 'utf-8', flag: 'w'}); } throw e; } From 4b6ff8caf0490546ece91408c70199e239e79353 Mon Sep 17 00:00:00 2001 From: Bryan Clark Date: Fri, 6 Dec 2019 14:32:51 -0500 Subject: [PATCH 32/55] Format auth --- src/auth.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/auth.ts b/src/auth.ts index 2e6605d..1001b2c 100644 --- a/src/auth.ts +++ b/src/auth.ts @@ -49,9 +49,12 @@ async function write(directory: string, settings: string) { try { return fs.writeFileSync(location, settings, options); } catch (e) { - if (e.code == "EEXIST") { + if (e.code == 'EEXIST') { console.warn(`overwriting existing file ${location}`); - return fs.writeFileSync(location, settings, {encoding: 'utf-8', flag: 'w'}); + return fs.writeFileSync(location, settings, { + encoding: 'utf-8', + flag: 'w' + }); } throw e; } From 540a98ac020a18cc64370d8c5a5ade3f026164ff Mon Sep 17 00:00:00 2001 From: Bryan Clark Date: Fri, 6 Dec 2019 14:33:05 -0500 Subject: [PATCH 33/55] Wrap long lines in action.yml --- action.yml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/action.yml b/action.yml index 912a09c..0034c96 100644 --- a/action.yml +++ b/action.yml @@ -1,9 +1,11 @@ name: 'Setup Java JDK' -description: 'Set up a specific version of the Java JDK and add the command-line tools to the PATH' +description: 'Set up a specific version of the Java JDK and add the command-line tools + to the PATH' author: 'GitHub' inputs: java-version: - description: 'The Java version to make available on the path. Takes a whole or semver Java version, or 1.x syntax (e.g. 1.8 => Java 8.x)' + description: 'The Java version to make available on the path. Takes a whole or + semver Java version, or 1.x syntax (e.g. 1.8 => Java 8.x)' required: true java-package: description: 'The package type (jre, jdk, jdk+fx)' @@ -14,7 +16,8 @@ inputs: required: false default: 'x64' jdkFile: - description: 'Path to where the compressed JDK is located. The path could be in your source repository or a local path on the agent.' + description: 'Path to where the compressed JDK is located. The path could be + in your source repository or a local path on the agent.' required: false server-id: description: 'ID of the distributionManagement repository in the pom.xml file.' From dbeab7ccf21319c27d1b5bccc1661f7124e0b82f Mon Sep 17 00:00:00 2001 From: Bryan Clark Date: Fri, 6 Dec 2019 14:35:32 -0500 Subject: [PATCH 34/55] Remove trailing spaces and long lines --- action.yml | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/action.yml b/action.yml index 0034c96..c82b0ec 100644 --- a/action.yml +++ b/action.yml @@ -1,11 +1,11 @@ name: 'Setup Java JDK' -description: 'Set up a specific version of the Java JDK and add the command-line tools - to the PATH' +description: 'Set up a specific version of the Java JDK and add the + command-line tools to the PATH' author: 'GitHub' inputs: java-version: - description: 'The Java version to make available on the path. Takes a whole or - semver Java version, or 1.x syntax (e.g. 1.8 => Java 8.x)' + description: 'The Java version to make available on the path. Takes a whole + or semver Java version, or 1.x syntax (e.g. 1.8 => Java 8.x)' required: true java-package: description: 'The package type (jre, jdk, jdk+fx)' @@ -16,17 +16,19 @@ inputs: required: false default: 'x64' jdkFile: - description: 'Path to where the compressed JDK is located. The path could be - in your source repository or a local path on the agent.' + description: 'Path to where the compressed JDK is located. The path could + be in your source repository or a local path on the agent.' required: false server-id: - description: 'ID of the distributionManagement repository in the pom.xml file.' + description: 'ID of the distributionManagement repository in the pom.xml + file.' required: false username: description: 'Username for authentication to the Apache Maven server.' required: false password: - description: 'Passowrd or token for authentication to the Apache Maven server.' + description: 'Passowrd or token for authentication to the Apache Maven + server.' required: false runs: using: 'node12' From b7e70417f9c68e1094a7086d3dcce5ee28353440 Mon Sep 17 00:00:00 2001 From: Bryan Clark Date: Fri, 6 Dec 2019 14:36:32 -0500 Subject: [PATCH 35/55] Remove last trailing space --- action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/action.yml b/action.yml index c82b0ec..eaf3aeb 100644 --- a/action.yml +++ b/action.yml @@ -2,7 +2,7 @@ name: 'Setup Java JDK' description: 'Set up a specific version of the Java JDK and add the command-line tools to the PATH' author: 'GitHub' -inputs: +inputs: java-version: description: 'The Java version to make available on the path. Takes a whole or semver Java version, or 1.x syntax (e.g. 1.8 => Java 8.x)' From 6ae690c576a37d52f0a1d35f4d8f15ca4b233ae0 Mon Sep 17 00:00:00 2001 From: Bryan Clark Date: Fri, 6 Dec 2019 14:46:35 -0500 Subject: [PATCH 36/55] Add test for overwrite --- __tests__/auth.test.ts | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/__tests__/auth.test.ts b/__tests__/auth.test.ts index 8e5efd4..ec54bce 100644 --- a/__tests__/auth.test.ts +++ b/__tests__/auth.test.ts @@ -42,7 +42,26 @@ describe('auth tests', () => { ); }, 100000); - it('does not create settings.xml without username and / or password', async () => { + it('overwrites existing settings.xml files', async () => { + const id = 'packages'; + const username = 'bluebottle'; + const password = 'SingleOrigin'; + + fs.mkdirSync(m2Dir, {recursive: true}); + fs.writeFileSync(settingsFile, "FAKE FILE"); + expect(fs.existsSync(m2Dir)).toBe(true); + expect(fs.existsSync(settingsFile)).toBe(true); + + await auth.configAuthentication(id, username, password); + + expect(fs.existsSync(m2Dir)).toBe(true); + expect(fs.existsSync(settingsFile)).toBe(true); + expect(fs.readFileSync(settingsFile, 'utf-8')).toEqual( + auth.generate(id, username, password) + ); + }, 100000); + + it('does not create settings.xml without required parameters', async () => { await auth.configAuthentication('FOO', '', ''); expect(fs.existsSync(m2Dir)).toBe(false); From f33acc6b4f056fff50e7b30f9ccb5c4571191c82 Mon Sep 17 00:00:00 2001 From: Bryan Clark Date: Fri, 6 Dec 2019 14:46:43 -0500 Subject: [PATCH 37/55] build release --- dist/index.js | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/dist/index.js b/dist/index.js index 92274cd..7d9c7bb 100644 --- a/dist/index.js +++ b/dist/index.js @@ -4134,8 +4134,7 @@ function configAuthentication(id, username, password) { return __awaiter(this, void 0, void 0, function* () { if (id && username && password) { console.log(`creating ${exports.SETTINGS_FILE} with server-id: ${id}, username: ${username}, and a password`); - const home = process.env['GITHUB_WORKSPACE'] || os.homedir(); - const directory = path.join(home, exports.M2_DIR); + const directory = path.join(os.homedir(), exports.M2_DIR); yield io.mkdirP(directory); core.debug(`created directory ${directory}`); yield write(directory, generate(id, username, password)); @@ -4165,15 +4164,17 @@ function write(directory, settings) { return __awaiter(this, void 0, void 0, function* () { const options = { encoding: 'utf-8', flag: 'wx' }; // 'wx': Like 'w' but fails if path exists const location = path.join(directory, exports.SETTINGS_FILE); - console.log(`writing ${location} with options ${options}`); + console.log(`writing ${location}`); try { return fs.writeFileSync(location, settings, options); } catch (e) { - if (e.code == "EEXIST") { - console.log(`overwriting existing file ${location}`); - // default flag is 'w' - return fs.writeFileSync(location, settings, { encoding: 'utf-8' }); + if (e.code == 'EEXIST') { + console.warn(`overwriting existing file ${location}`); + return fs.writeFileSync(location, settings, { + encoding: 'utf-8', + flag: 'w' + }); } throw e; } From ddf78adea0a00c0f59c71944fbdd38b35921889d Mon Sep 17 00:00:00 2001 From: Bryan Clark Date: Fri, 6 Dec 2019 14:50:30 -0500 Subject: [PATCH 38/55] Add note about $HOME directory usage --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 95fec46..2f6521d 100644 --- a/README.md +++ b/README.md @@ -86,6 +86,9 @@ jobs: - name: Publish to Apache Maven Central run: mvn deploy ``` + +***NOTE: The `settings.xml` is created in the Actons $HOME directory by default and will overwrite existing files.*** + See the help docs on [Publishing a Package](https://help.github.com/en/github/managing-packages-with-github-packages/configuring-apache-maven-for-use-with-github-packages#publishing-a-package) for more information on the `pom.xml` file. # License From 70aff31eb73fad306647407eb2135e5271071c30 Mon Sep 17 00:00:00 2001 From: Bryan Clark Date: Fri, 6 Dec 2019 15:31:28 -0500 Subject: [PATCH 39/55] Apply suggestions from code review Co-Authored-By: Konrad Pabjan --- action.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/action.yml b/action.yml index eaf3aeb..1f952a8 100644 --- a/action.yml +++ b/action.yml @@ -24,11 +24,11 @@ inputs: file.' required: false username: - description: 'Username for authentication to the Apache Maven server.' + description: 'Username for authentication to the Apache Maven repository.' required: false password: - description: 'Passowrd or token for authentication to the Apache Maven - server.' + description: 'Password or token for authentication to the Apache Maven + repository.' required: false runs: using: 'node12' From 203550b5425c7f308974addc549848e67d7cfd70 Mon Sep 17 00:00:00 2001 From: Bryan Clark Date: Fri, 6 Dec 2019 16:21:27 -0500 Subject: [PATCH 40/55] Add Gradle example to README --- README.md | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 2f6521d..a6acabf 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ jobs: - run: java -cp java HelloWorldApp ``` -Publising to an Apache Maven Repository: +Publishing using Apache Maven: ```yaml jobs: build: @@ -91,6 +91,33 @@ jobs: See the help docs on [Publishing a Package](https://help.github.com/en/github/managing-packages-with-github-packages/configuring-apache-maven-for-use-with-github-packages#publishing-a-package) for more information on the `pom.xml` file. +Publishing using Gradle: +```yaml +jobs: + + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v1 + + - name: Set up JDK 1.8 + uses: actions/setup-java@v1 + + - name: Build with Gradle + run: gradle build + + - name: Publish to GitHub Packages + run: gradle publish + env: + USERNAME: ${{ github.actor }} + PASSWORD: ${{ secrets.GITHUB_TOKEN }} +``` + +***NOTE: The `USERNAME` and `PASSWORD` need to correspond to the credentials environment variables used in the publishing section of your `build.gradle`..*** + +See the help docs on [Publishing a Package with Gradle](https://help.github.com/en/github/managing-packages-with-github-packages/configuring-gradle-for-use-with-github-packages#example-using-gradle-groovy-for-a-single-package-in-a-repository) for more information on the `build.gradle` configuration file. + # License The scripts and documentation in this project are released under the [MIT License](LICENSE) From 8ccac94e40f51d001ee914a334172da354e5780b Mon Sep 17 00:00:00 2001 From: Bryan Clark Date: Mon, 9 Dec 2019 12:16:15 -0500 Subject: [PATCH 41/55] README Small spelling fix. Also some rewording Co-Authored-By: Konrad Pabjan --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a6acabf..24fc35f 100644 --- a/README.md +++ b/README.md @@ -87,7 +87,7 @@ jobs: run: mvn deploy ``` -***NOTE: The `settings.xml` is created in the Actons $HOME directory by default and will overwrite existing files.*** +***NOTE: The `settings.xml` file is created in the Actions $HOME directory. If you have an existing `settings.xml` file at that location, it will be overwritten*** See the help docs on [Publishing a Package](https://help.github.com/en/github/managing-packages-with-github-packages/configuring-apache-maven-for-use-with-github-packages#publishing-a-package) for more information on the `pom.xml` file. From 9d56a3bd350a62870fa2229f7513bb2b96d8afa6 Mon Sep 17 00:00:00 2001 From: Bryan Clark Date: Tue, 10 Dec 2019 09:26:42 -0800 Subject: [PATCH 42/55] prettier fixup --- __tests__/auth.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/__tests__/auth.test.ts b/__tests__/auth.test.ts index ec54bce..3fa739c 100644 --- a/__tests__/auth.test.ts +++ b/__tests__/auth.test.ts @@ -48,7 +48,7 @@ describe('auth tests', () => { const password = 'SingleOrigin'; fs.mkdirSync(m2Dir, {recursive: true}); - fs.writeFileSync(settingsFile, "FAKE FILE"); + fs.writeFileSync(settingsFile, 'FAKE FILE'); expect(fs.existsSync(m2Dir)).toBe(true); expect(fs.existsSync(settingsFile)).toBe(true); From 551e2a2770b8079e2141a6b4728a7b96ae33ae50 Mon Sep 17 00:00:00 2001 From: Bryan Clark Date: Tue, 10 Dec 2019 09:26:51 -0800 Subject: [PATCH 43/55] sanitzie XML characters --- __tests__/auth.test.ts | 18 ++++++++++++++++++ dist/index.js | 14 +++++++++++--- src/auth.ts | 15 ++++++++++++--- 3 files changed, 41 insertions(+), 6 deletions(-) diff --git a/__tests__/auth.test.ts b/__tests__/auth.test.ts index 3fa739c..7134e5c 100644 --- a/__tests__/auth.test.ts +++ b/__tests__/auth.test.ts @@ -82,4 +82,22 @@ describe('auth tests', () => { expect(fs.existsSync(m2Dir)).toBe(false); expect(fs.existsSync(settingsFile)).toBe(false); }, 100000); + + it('escapes invalid XML inputs', () => { + const id = 'packages'; + const username = 'bluebottle'; + const password = '&<>"\'\'"><&'; + + expect(auth.generate(id, username, password)).toEqual(` + + + + ${id} + ${username} + &<>"''"><& + + + + `); + }); }); diff --git a/dist/index.js b/dist/index.js index 7d9c7bb..c7b1f98 100644 --- a/dist/index.js +++ b/dist/index.js @@ -4145,15 +4145,23 @@ function configAuthentication(id, username, password) { }); } exports.configAuthentication = configAuthentication; +function escapeXML(value) { + return value + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"') + .replace(/'/g, '''); +} // only exported for testing purposes function generate(id, username, password) { return ` - ${id} - ${username} - ${password} + ${escapeXML(id)} + ${escapeXML(username)} + ${escapeXML(password)} diff --git a/src/auth.ts b/src/auth.ts index 1001b2c..ca43c20 100644 --- a/src/auth.ts +++ b/src/auth.ts @@ -27,15 +27,24 @@ export async function configAuthentication( } } +function escapeXML(value: string) { + return value + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"') + .replace(/'/g, '''); +} + // only exported for testing purposes export function generate(id: string, username: string, password: string) { return ` - ${id} - ${username} - ${password} + ${escapeXML(id)} + ${escapeXML(username)} + ${escapeXML(password)} From 4757680fc9fb500faa11db2c790410b69e0d6dc9 Mon Sep 17 00:00:00 2001 From: Bryan Clark Date: Tue, 10 Dec 2019 09:37:07 -0800 Subject: [PATCH 44/55] Add Shared Runner to README Be the docs for the feature you want to see. #docsdrivendevelopment --- README.md | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 24fc35f..1e376b5 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ This action sets up a java environment for use in actions by: See [action.yml](action.yml) -Basic: +## Basic ```yaml steps: - uses: actions/checkout@v1 @@ -25,7 +25,7 @@ steps: - run: java -cp java HelloWorldApp ``` -From local file: +## Local file ```yaml steps: - uses: actions/checkout@v1 @@ -37,7 +37,7 @@ steps: - run: java -cp java HelloWorldApp ``` -Matrix Testing: +## Matrix Testing ```yaml jobs: build: @@ -56,7 +56,7 @@ jobs: - run: java -cp java HelloWorldApp ``` -Publishing using Apache Maven: +## Publishing using Apache Maven ```yaml jobs: build: @@ -91,7 +91,7 @@ jobs: See the help docs on [Publishing a Package](https://help.github.com/en/github/managing-packages-with-github-packages/configuring-apache-maven-for-use-with-github-packages#publishing-a-package) for more information on the `pom.xml` file. -Publishing using Gradle: +## Publishing using Gradle ```yaml jobs: @@ -118,6 +118,32 @@ jobs: See the help docs on [Publishing a Package with Gradle](https://help.github.com/en/github/managing-packages-with-github-packages/configuring-gradle-for-use-with-github-packages#example-using-gradle-groovy-for-a-single-package-in-a-repository) for more information on the `build.gradle` configuration file. +## Apache Maven within a Shared Runner + +When using an Actions shared runner the default `$HOME` directory can be shared by a number of workflows at the same time which could overwrite existing settings file. Setting the `m2-home` variable allows you to choose a unique location for your settings file. + +```yaml +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v1 + - name: Set up JDK 1.8 for Shared Runner + uses: actions/setup-java@v1 + with: + java-version: 1.8 + server-id: github # Value of the distributionManagement/repository/id field of the pom.xml + username: ${{ github.actor }} # username for server authentication + password: ${{ github.token }} # password or token for authentication + m2-home: ${{ $GITHUB_WORKSPACE }} # location of the .m2 directory + - name: Build with Maven + run: mvn -B package --file pom.xml + - name: Publish to GitHub Packages Apache Maven + run: mvn deploy +``` + # License The scripts and documentation in this project are released under the [MIT License](LICENSE) From ae11e1a1b65b1ac2350dbf764d37e0970ef02725 Mon Sep 17 00:00:00 2001 From: Bryan Clark Date: Tue, 10 Dec 2019 10:03:33 -0800 Subject: [PATCH 45/55] Allow for alternate settings.xml file location Use the m2-home to specify a new location for the settings.xml file --- README.md | 4 ++-- __tests__/auth.test.ts | 25 +++++++++++++++++++++++++ dist/index.js | 4 +++- src/auth.ts | 7 ++++++- 4 files changed, 36 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 1e376b5..a98d883 100644 --- a/README.md +++ b/README.md @@ -137,11 +137,11 @@ jobs: server-id: github # Value of the distributionManagement/repository/id field of the pom.xml username: ${{ github.actor }} # username for server authentication password: ${{ github.token }} # password or token for authentication - m2-home: ${{ $GITHUB_WORKSPACE }} # location of the .m2 directory + m2-home: ${{ $GITHUB_WORKSPACE }} # location for the settings.xml file - name: Build with Maven run: mvn -B package --file pom.xml - name: Publish to GitHub Packages Apache Maven - run: mvn deploy + run: mvn deploy -s ${{ $GITHUB_WORKSPACE }}/settings.xml ``` # License diff --git a/__tests__/auth.test.ts b/__tests__/auth.test.ts index 7134e5c..ce13ef7 100644 --- a/__tests__/auth.test.ts +++ b/__tests__/auth.test.ts @@ -28,6 +28,31 @@ describe('auth tests', () => { } }, 100000); + it('creates settings.xml in alternate locations', async () => { + const id = 'packages'; + const username = 'bluebottle'; + const password = 'SingleOrigin'; + + const altHome = path.join(__dirname, 'runner', 'settings'); + const altSettingsFile = path.join(altHome, auth.SETTINGS_FILE); + process.env[`INPUT_M2-HOME`] = altHome; + await io.rmRF(altHome); // ensure it doesn't already exist + + await auth.configAuthentication(id, username, password); + + expect(fs.existsSync(m2Dir)).toBe(false); + expect(fs.existsSync(settingsFile)).toBe(false); + + expect(fs.existsSync(altHome)).toBe(true); + expect(fs.existsSync(altSettingsFile)).toBe(true); + expect(fs.readFileSync(altSettingsFile, 'utf-8')).toEqual( + auth.generate(id, username, password) + ); + + delete process.env[`INPUT_M2-HOME`]; + await io.rmRF(altHome); + }, 100000); + it('creates settings.xml with username and password', async () => { const id = 'packages'; const username = 'bluebottle'; diff --git a/dist/index.js b/dist/index.js index c7b1f98..f4ff8d1 100644 --- a/dist/index.js +++ b/dist/index.js @@ -4134,7 +4134,9 @@ function configAuthentication(id, username, password) { return __awaiter(this, void 0, void 0, function* () { if (id && username && password) { console.log(`creating ${exports.SETTINGS_FILE} with server-id: ${id}, username: ${username}, and a password`); - const directory = path.join(os.homedir(), exports.M2_DIR); + // when an alternate m2 location is specified use only that location (no .m2 directory) + // otherwise use the home/.m2/ path + const directory = path.join(core.getInput('m2-home') || os.homedir(), core.getInput('m2-home') ? '' : exports.M2_DIR); yield io.mkdirP(directory); core.debug(`created directory ${directory}`); yield write(directory, generate(id, username, password)); diff --git a/src/auth.ts b/src/auth.ts index ca43c20..9cfa69a 100644 --- a/src/auth.ts +++ b/src/auth.ts @@ -16,7 +16,12 @@ export async function configAuthentication( console.log( `creating ${SETTINGS_FILE} with server-id: ${id}, username: ${username}, and a password` ); - const directory: string = path.join(os.homedir(), M2_DIR); + // when an alternate m2 location is specified use only that location (no .m2 directory) + // otherwise use the home/.m2/ path + const directory: string = path.join( + core.getInput('m2-home') || os.homedir(), + core.getInput('m2-home') ? '' : M2_DIR + ); await io.mkdirP(directory); core.debug(`created directory ${directory}`); await write(directory, generate(id, username, password)); From ce88feea9475f3d2dae95300fed6de40719d1c64 Mon Sep 17 00:00:00 2001 From: Bryan Clark Date: Tue, 10 Dec 2019 13:02:21 -0800 Subject: [PATCH 46/55] Move to settings-path --- README.md | 8 ++++---- __tests__/auth.test.ts | 4 ++-- action.yml | 3 +++ dist/index.js | 2 +- src/auth.ts | 4 ++-- 5 files changed, 12 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index a98d883..ca4d07e 100644 --- a/README.md +++ b/README.md @@ -118,9 +118,9 @@ jobs: See the help docs on [Publishing a Package with Gradle](https://help.github.com/en/github/managing-packages-with-github-packages/configuring-gradle-for-use-with-github-packages#example-using-gradle-groovy-for-a-single-package-in-a-repository) for more information on the `build.gradle` configuration file. -## Apache Maven within a Shared Runner +## Apache Maven within a self-hosted runner -When using an Actions shared runner the default `$HOME` directory can be shared by a number of workflows at the same time which could overwrite existing settings file. Setting the `m2-home` variable allows you to choose a unique location for your settings file. +When using an Actions self-hosted runner with multiple shared runners the default `$HOME` directory can be shared by a number runners at the same time which could overwrite existing settings file. Setting the `settings-path` variable allows you to choose a unique location for your settings file. ```yaml jobs: @@ -137,11 +137,11 @@ jobs: server-id: github # Value of the distributionManagement/repository/id field of the pom.xml username: ${{ github.actor }} # username for server authentication password: ${{ github.token }} # password or token for authentication - m2-home: ${{ $GITHUB_WORKSPACE }} # location for the settings.xml file + settings-path: ./config # location for the settings.xml file - name: Build with Maven run: mvn -B package --file pom.xml - name: Publish to GitHub Packages Apache Maven - run: mvn deploy -s ${{ $GITHUB_WORKSPACE }}/settings.xml + run: mvn deploy -s ./config/settings.xml ``` # License diff --git a/__tests__/auth.test.ts b/__tests__/auth.test.ts index ce13ef7..1d5cee9 100644 --- a/__tests__/auth.test.ts +++ b/__tests__/auth.test.ts @@ -35,7 +35,7 @@ describe('auth tests', () => { const altHome = path.join(__dirname, 'runner', 'settings'); const altSettingsFile = path.join(altHome, auth.SETTINGS_FILE); - process.env[`INPUT_M2-HOME`] = altHome; + process.env[`INPUT_SETTINGS-PATH`] = altHome; await io.rmRF(altHome); // ensure it doesn't already exist await auth.configAuthentication(id, username, password); @@ -49,7 +49,7 @@ describe('auth tests', () => { auth.generate(id, username, password) ); - delete process.env[`INPUT_M2-HOME`]; + delete process.env[`INPUT_SETTINGS-PATH`]; await io.rmRF(altHome); }, 100000); diff --git a/action.yml b/action.yml index 1f952a8..a67838c 100644 --- a/action.yml +++ b/action.yml @@ -30,6 +30,9 @@ inputs: description: 'Password or token for authentication to the Apache Maven repository.' required: false + settings-path: + description: 'Path to where the settings.xml file will be written.' + required: false runs: using: 'node12' main: 'dist/index.js' diff --git a/dist/index.js b/dist/index.js index f4ff8d1..cad2731 100644 --- a/dist/index.js +++ b/dist/index.js @@ -4136,7 +4136,7 @@ function configAuthentication(id, username, password) { console.log(`creating ${exports.SETTINGS_FILE} with server-id: ${id}, username: ${username}, and a password`); // when an alternate m2 location is specified use only that location (no .m2 directory) // otherwise use the home/.m2/ path - const directory = path.join(core.getInput('m2-home') || os.homedir(), core.getInput('m2-home') ? '' : exports.M2_DIR); + const directory = path.join(core.getInput('settings-path') || os.homedir(), core.getInput('settings-path') ? '' : exports.M2_DIR); yield io.mkdirP(directory); core.debug(`created directory ${directory}`); yield write(directory, generate(id, username, password)); diff --git a/src/auth.ts b/src/auth.ts index 9cfa69a..f50ab7d 100644 --- a/src/auth.ts +++ b/src/auth.ts @@ -19,8 +19,8 @@ export async function configAuthentication( // when an alternate m2 location is specified use only that location (no .m2 directory) // otherwise use the home/.m2/ path const directory: string = path.join( - core.getInput('m2-home') || os.homedir(), - core.getInput('m2-home') ? '' : M2_DIR + core.getInput('settings-path') || os.homedir(), + core.getInput('settings-path') ? '' : M2_DIR ); await io.mkdirP(directory); core.debug(`created directory ${directory}`); From 2e749e50a69d4402354c38df0dc5b9e021cae9d8 Mon Sep 17 00:00:00 2001 From: Bryan Clark Date: Tue, 10 Dec 2019 14:25:15 -0800 Subject: [PATCH 47/55] Update settings-path for github.workspace --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index ca4d07e..e725c55 100644 --- a/README.md +++ b/README.md @@ -118,7 +118,7 @@ jobs: See the help docs on [Publishing a Package with Gradle](https://help.github.com/en/github/managing-packages-with-github-packages/configuring-gradle-for-use-with-github-packages#example-using-gradle-groovy-for-a-single-package-in-a-repository) for more information on the `build.gradle` configuration file. -## Apache Maven within a self-hosted runner +## Apache Maven with a settings path When using an Actions self-hosted runner with multiple shared runners the default `$HOME` directory can be shared by a number runners at the same time which could overwrite existing settings file. Setting the `settings-path` variable allows you to choose a unique location for your settings file. @@ -137,11 +137,11 @@ jobs: server-id: github # Value of the distributionManagement/repository/id field of the pom.xml username: ${{ github.actor }} # username for server authentication password: ${{ github.token }} # password or token for authentication - settings-path: ./config # location for the settings.xml file + settings-path: ${{ github.workspace }} # location for the settings.xml file - name: Build with Maven run: mvn -B package --file pom.xml - name: Publish to GitHub Packages Apache Maven - run: mvn deploy -s ./config/settings.xml + run: mvn deploy -s $GITHUB_WORKSPACE/settings.xml ``` # License From 998be8d08f04ae06317cde62fff9b14edd5df851 Mon Sep 17 00:00:00 2001 From: Bryan Clark Date: Wed, 18 Dec 2019 11:05:01 -0800 Subject: [PATCH 48/55] Add default to settings-path description Co-Authored-By: Chris Patterson --- action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/action.yml b/action.yml index a67838c..c6c5284 100644 --- a/action.yml +++ b/action.yml @@ -31,7 +31,7 @@ inputs: repository.' required: false settings-path: - description: 'Path to where the settings.xml file will be written.' + description: 'Path to where the settings.xml file will be written. Default is ~/.m2.' required: false runs: using: 'node12' From 6924f73ee016582f21bae0cec5f0e818642eb1d5 Mon Sep 17 00:00:00 2001 From: Bryan Clark Date: Thu, 19 Dec 2019 08:52:26 -0800 Subject: [PATCH 49/55] Address latest review feedback --- README.md | 18 +- action.yml | 4 +- dist/index.js | 722 +++++++++++++++++++++++----------------------- package.json | 5 +- src/auth.ts | 22 +- src/setup-java.ts | 6 +- 6 files changed, 390 insertions(+), 387 deletions(-) diff --git a/README.md b/README.md index e725c55..f6d6a44 100644 --- a/README.md +++ b/README.md @@ -72,22 +72,26 @@ jobs: server-id: github # Value of the distributionManagement/repository/id field of the pom.xml username: ${{ github.actor }} # username for server authentication password: ${{ github.token }} # password or token for authentication + - name: Build with Maven run: mvn -B package --file pom.xml + - name: Publish to GitHub Packages Apache Maven run: mvn deploy + - name: Set up Apache Maven Central uses: actions/setup-java@v1 with: # running setup-java again overwrites the settings.xml java-version: 1.8 server-id: maven - username: maven_username - password: ${{ secrets.MAVEN_CENTRAL_TOKEN }} # password from secrets store + server-username: maven_username + server-password: ${{ secrets.MAVEN_CENTRAL_TOKEN }} # password from secrets store + - name: Publish to Apache Maven Central run: mvn deploy ``` -***NOTE: The `settings.xml` file is created in the Actions $HOME directory. If you have an existing `settings.xml` file at that location, it will be overwritten*** +***NOTE: The `settings.xml` file is created in the Actions $HOME directory. If you have an existing `settings.xml` file at that location, it will be overwritten. See below for using the `settings-path` to change your `settings.xml` file location.*** See the help docs on [Publishing a Package](https://help.github.com/en/github/managing-packages-with-github-packages/configuring-apache-maven-for-use-with-github-packages#publishing-a-package) for more information on the `pom.xml` file. @@ -114,7 +118,7 @@ jobs: PASSWORD: ${{ secrets.GITHUB_TOKEN }} ``` -***NOTE: The `USERNAME` and `PASSWORD` need to correspond to the credentials environment variables used in the publishing section of your `build.gradle`..*** +***NOTE: The `USERNAME` and `PASSWORD` need to correspond to the credentials environment variables used in the publishing section of your `build.gradle`.*** See the help docs on [Publishing a Package with Gradle](https://help.github.com/en/github/managing-packages-with-github-packages/configuring-gradle-for-use-with-github-packages#example-using-gradle-groovy-for-a-single-package-in-a-repository) for more information on the `build.gradle` configuration file. @@ -135,11 +139,13 @@ jobs: with: java-version: 1.8 server-id: github # Value of the distributionManagement/repository/id field of the pom.xml - username: ${{ github.actor }} # username for server authentication - password: ${{ github.token }} # password or token for authentication + server-username: ${{ github.actor }} # username for server authentication + server-password: ${{ github.token }} # password or token for authentication settings-path: ${{ github.workspace }} # location for the settings.xml file + - name: Build with Maven run: mvn -B package --file pom.xml + - name: Publish to GitHub Packages Apache Maven run: mvn deploy -s $GITHUB_WORKSPACE/settings.xml ``` diff --git a/action.yml b/action.yml index c6c5284..df1a2c1 100644 --- a/action.yml +++ b/action.yml @@ -23,10 +23,10 @@ inputs: description: 'ID of the distributionManagement repository in the pom.xml file.' required: false - username: + server-username: description: 'Username for authentication to the Apache Maven repository.' required: false - password: + server-password: description: 'Password or token for authentication to the Apache Maven repository.' required: false diff --git a/dist/index.js b/dist/index.js index cad2731..e9e7cc3 100644 --- a/dist/index.js +++ b/dist/index.js @@ -34,7 +34,7 @@ module.exports = /******/ // the startup function /******/ function startup() { /******/ // Load entry module and return exports -/******/ return __webpack_require__(423); +/******/ return __webpack_require__(811); /******/ }; /******/ /******/ // run startup @@ -2820,29 +2820,7 @@ function coerce (version, options) { /***/ }), -/***/ 357: -/***/ (function(module) { - -module.exports = require("assert"); - -/***/ }), - -/***/ 413: -/***/ (function(module, __unusedexports, __webpack_require__) { - -module.exports = __webpack_require__(141); - - -/***/ }), - -/***/ 417: -/***/ (function(module) { - -module.exports = require("crypto"); - -/***/ }), - -/***/ 423: +/***/ 331: /***/ (function(__unusedmodule, exports, __webpack_require__) { "use strict"; @@ -2863,38 +2841,92 @@ var __importStar = (this && this.__importStar) || function (mod) { return result; }; Object.defineProperty(exports, "__esModule", { value: true }); -const core = __importStar(__webpack_require__(470)); -const installer = __importStar(__webpack_require__(749)); -const auth = __importStar(__webpack_require__(827)); +const fs = __importStar(__webpack_require__(747)); +const os = __importStar(__webpack_require__(87)); const path = __importStar(__webpack_require__(622)); -function run() { +const core = __importStar(__webpack_require__(470)); +const io = __importStar(__webpack_require__(1)); +exports.M2_DIR = '.m2'; +exports.SETTINGS_FILE = 'settings.xml'; +function configAuthentication(id, username, password) { return __awaiter(this, void 0, void 0, function* () { - try { - let version = core.getInput('version'); - if (!version) { - version = core.getInput('java-version', { required: true }); - } - const arch = core.getInput('architecture', { required: true }); - const javaPackage = core.getInput('java-package', { required: true }); - const jdkFile = core.getInput('jdkFile', { required: false }) || ''; - yield installer.getJava(version, arch, jdkFile, javaPackage); - const matchersPath = path.join(__dirname, '..', '.github'); - console.log(`##[add-matcher]${path.join(matchersPath, 'java.json')}`); - const id = core.getInput('server-id', { required: false }); - const username = core.getInput('username', { required: false }); - const password = core.getInput('password', { required: false }); - if (id && username && password) { - yield auth.configAuthentication(id, username, password); - } + if (id && username && password) { + console.log(`creating ${exports.SETTINGS_FILE} with server-id: ${id}, username: ${username}, and a password`); + // when an alternate m2 location is specified use only that location (no .m2 directory) + // otherwise use the home/.m2/ path + const directory = path.join(core.getInput('settings-path') || os.homedir(), core.getInput('settings-path') ? '' : exports.M2_DIR); + yield io.mkdirP(directory); + core.debug(`created directory ${directory}`); + yield write(directory, generate(id, username, password)); } - catch (error) { - core.setFailed(error.message); + else { + core.debug(`no ${exports.SETTINGS_FILE} without server-id: ${id}, username: ${username}, and a password`); } }); } -run(); +exports.configAuthentication = configAuthentication; +function escapeXML(value) { + return value + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"') + .replace(/'/g, '''); +} +// only exported for testing purposes +function generate(id, username, password) { + return ` + + + + ${escapeXML(id)} + ${escapeXML(username)} + ${escapeXML(password)} + + + + `; +} +exports.generate = generate; +function write(directory, settings) { + return __awaiter(this, void 0, void 0, function* () { + const location = path.join(directory, exports.SETTINGS_FILE); + if (fs.existsSync(location)) { + console.warn(`overwriting existing file ${location}`); + } + else { + console.log(`writing ${location}`); + } + return fs.writeFileSync(location, settings, { + encoding: 'utf-8', + flag: 'w' + }); + }); +} +/***/ }), + +/***/ 357: +/***/ (function(module) { + +module.exports = require("assert"); + +/***/ }), + +/***/ 413: +/***/ (function(module, __unusedexports, __webpack_require__) { + +module.exports = __webpack_require__(141); + + +/***/ }), + +/***/ 417: +/***/ (function(module) { + +module.exports = require("crypto"); + /***/ }), /***/ 431: @@ -3810,7 +3842,7 @@ module.exports = require("fs"); /***/ }), -/***/ 749: +/***/ 811: /***/ (function(__unusedmodule, exports, __webpack_require__) { "use strict"; @@ -3831,237 +3863,39 @@ var __importStar = (this && this.__importStar) || function (mod) { return result; }; Object.defineProperty(exports, "__esModule", { value: true }); -let tempDirectory = process.env['RUNNER_TEMP'] || ''; const core = __importStar(__webpack_require__(470)); -const io = __importStar(__webpack_require__(1)); -const exec = __importStar(__webpack_require__(986)); -const tc = __importStar(__webpack_require__(533)); -const fs = __importStar(__webpack_require__(747)); +const installer = __importStar(__webpack_require__(923)); +const auth = __importStar(__webpack_require__(331)); const path = __importStar(__webpack_require__(622)); -const semver = __importStar(__webpack_require__(280)); -const httpm = __importStar(__webpack_require__(874)); -const IS_WINDOWS = process.platform === 'win32'; -if (!tempDirectory) { - let baseLocation; - if (IS_WINDOWS) { - // On windows use the USERPROFILE env variable - baseLocation = process.env['USERPROFILE'] || 'C:\\'; - } - else { - if (process.platform === 'darwin') { - baseLocation = '/Users'; - } - else { - baseLocation = '/home'; - } - } - tempDirectory = path.join(baseLocation, 'actions', 'temp'); -} -function getJava(version, arch, jdkFile, javaPackage) { +function run() { return __awaiter(this, void 0, void 0, function* () { - let toolPath = tc.find(javaPackage, version); - if (toolPath) { - core.debug(`Tool found in cache ${toolPath}`); - } - else { - let compressedFileExtension = ''; - if (!jdkFile) { - core.debug('Downloading Jdk from Azul'); - let http = new httpm.HttpClient('setup-java'); - let contents = yield (yield http.get('https://static.azul.com/zulu/bin/')).readBody(); - let refs = contents.match(//gi) || []; - const downloadInfo = getDownloadInfo(refs, version, javaPackage); - jdkFile = yield tc.downloadTool(downloadInfo.url); - version = downloadInfo.version; - compressedFileExtension = IS_WINDOWS ? '.zip' : '.tar.gz'; + try { + let version = core.getInput('version'); + if (!version) { + version = core.getInput('java-version', { required: true }); } - else { - core.debug('Retrieving Jdk from local path'); + const arch = core.getInput('architecture', { required: true }); + const javaPackage = core.getInput('java-package', { required: true }); + const jdkFile = core.getInput('jdkFile', { required: false }) || ''; + yield installer.getJava(version, arch, jdkFile, javaPackage); + const matchersPath = path.join(__dirname, '..', '.github'); + console.log(`##[add-matcher]${path.join(matchersPath, 'java.json')}`); + const id = core.getInput('server-id', { required: false }); + const username = core.getInput('server-username', { required: false }); + const password = core.getInput('server-password', { required: false }); + if (id && username && password) { + yield auth.configAuthentication(id, username, password); } - compressedFileExtension = compressedFileExtension || getFileEnding(jdkFile); - let tempDir = path.join(tempDirectory, 'temp_' + Math.floor(Math.random() * 2000000000)); - const jdkDir = yield unzipJavaDownload(jdkFile, compressedFileExtension, tempDir); - core.debug(`jdk extracted to ${jdkDir}`); - toolPath = yield tc.cacheDir(jdkDir, javaPackage, getCacheVersionString(version), arch); - } - let extendedJavaHome = 'JAVA_HOME_' + version + '_' + arch; - core.exportVariable('JAVA_HOME', toolPath); - core.exportVariable(extendedJavaHome, toolPath); - core.addPath(path.join(toolPath, 'bin')); - }); -} -exports.getJava = getJava; -function getCacheVersionString(version) { - const versionArray = version.split('.'); - const major = versionArray[0]; - const minor = versionArray.length > 1 ? versionArray[1] : '0'; - const patch = versionArray.length > 2 ? versionArray[2] : '0'; - return `${major}.${minor}.${patch}`; -} -function getFileEnding(file) { - let fileEnding = ''; - if (file.endsWith('.tar')) { - fileEnding = '.tar'; - } - else if (file.endsWith('.tar.gz')) { - fileEnding = '.tar.gz'; - } - else if (file.endsWith('.zip')) { - fileEnding = '.zip'; - } - else if (file.endsWith('.7z')) { - fileEnding = '.7z'; - } - else { - throw new Error(`${file} has an unsupported file extension`); - } - return fileEnding; -} -function extractFiles(file, fileEnding, destinationFolder) { - return __awaiter(this, void 0, void 0, function* () { - const stats = fs.statSync(file); - if (!stats) { - throw new Error(`Failed to extract ${file} - it doesn't exist`); - } - else if (stats.isDirectory()) { - throw new Error(`Failed to extract ${file} - it is a directory`); - } - if ('.tar' === fileEnding || '.tar.gz' === fileEnding) { - yield tc.extractTar(file, destinationFolder); - } - else if ('.zip' === fileEnding) { - yield tc.extractZip(file, destinationFolder); - } - else { - // fall through and use sevenZip - yield tc.extract7z(file, destinationFolder); - } - }); -} -// This method recursively finds all .pack files under fsPath and unpacks them with the unpack200 tool -function unpackJars(fsPath, javaBinPath) { - return __awaiter(this, void 0, void 0, function* () { - if (fs.existsSync(fsPath)) { - if (fs.lstatSync(fsPath).isDirectory()) { - for (const file in fs.readdirSync(fsPath)) { - const curPath = path.join(fsPath, file); - yield unpackJars(curPath, javaBinPath); - } - } - else if (path.extname(fsPath).toLowerCase() === '.pack') { - // Unpack the pack file synchonously - const p = path.parse(fsPath); - const toolName = IS_WINDOWS ? 'unpack200.exe' : 'unpack200'; - const args = IS_WINDOWS ? '-r -v -l ""' : ''; - const name = path.join(p.dir, p.name); - yield exec.exec(`"${path.join(javaBinPath, toolName)}"`, [ - `${args} "${name}.pack" "${name}.jar"` - ]); + else if (id || username || password) { + console.warn('All 3 server-(id, username, and password) are required.'); } } - }); -} -function unzipJavaDownload(repoRoot, fileEnding, destinationFolder, extension) { - return __awaiter(this, void 0, void 0, function* () { - // Create the destination folder if it doesn't exist - yield io.mkdirP(destinationFolder); - const jdkFile = path.normalize(repoRoot); - const stats = fs.statSync(jdkFile); - if (stats.isFile()) { - yield extractFiles(jdkFile, fileEnding, destinationFolder); - const jdkDirectory = path.join(destinationFolder, fs.readdirSync(destinationFolder)[0]); - yield unpackJars(jdkDirectory, path.join(jdkDirectory, 'bin')); - return jdkDirectory; - } - else { - throw new Error(`Jdk argument ${jdkFile} is not a file`); + catch (error) { + core.setFailed(error.message); } }); } -function getDownloadInfo(refs, version, javaPackage) { - version = normalizeVersion(version); - let extension = ''; - if (IS_WINDOWS) { - extension = `-win_x64.zip`; - } - else { - if (process.platform === 'darwin') { - extension = `-macosx_x64.tar.gz`; - } - else { - extension = `-linux_x64.tar.gz`; - } - } - let pkgRegexp = new RegExp(''); - let pkgTypeLength = 0; - if (javaPackage === 'jdk') { - pkgRegexp = /jdk.*-/gi; - pkgTypeLength = 'jdk'.length; - } - else if (javaPackage == 'jre') { - pkgRegexp = /jre.*-/gi; - pkgTypeLength = 'jre'.length; - } - else if (javaPackage == 'jdk+fx') { - pkgRegexp = /fx-jdk.*-/gi; - pkgTypeLength = 'fx-jdk'.length; - } - else { - throw new Error(`package argument ${javaPackage} is not in [jdk | jre | jdk+fx]`); - } - // Maps version to url - let versionMap = new Map(); - // Filter by platform - refs.forEach(ref => { - if (!ref.endsWith(extension + '">')) { - return; - } - // If we haven't returned, means we're looking at the correct platform - let versions = ref.match(pkgRegexp) || []; - if (versions.length > 1) { - throw new Error(`Invalid ref received from https://static.azul.com/zulu/bin/: ${ref}`); - } - if (versions.length == 0) { - return; - } - const refVersion = versions[0].slice(pkgTypeLength, versions[0].length - 1); - if (semver.satisfies(refVersion, version)) { - versionMap.set(refVersion, 'https://static.azul.com/zulu/bin/' + - ref.slice(''.length)); - } - }); - // Choose the most recent satisfying version - let curVersion = '0.0.0'; - let curUrl = ''; - for (const entry of versionMap.entries()) { - const entryVersion = entry[0]; - const entryUrl = entry[1]; - if (semver.gt(entryVersion, curVersion)) { - curUrl = entryUrl; - curVersion = entryVersion; - } - } - if (curUrl == '') { - throw new Error(`No valid download found for version ${version} and package ${javaPackage}. Check https://static.azul.com/zulu/bin/ for a list of valid versions or download your own jdk file and add the jdkFile argument`); - } - return { version: curVersion, url: curUrl }; -} -function normalizeVersion(version) { - if (version.slice(0, 2) === '1.') { - // Trim leading 1. for versions like 1.8 - version = version.slice(2); - if (!version) { - throw new Error('1. is not a valid version'); - } - } - // Add trailing .x if it is missing - if (version.split('.').length != 3) { - if (version[version.length - 1] != 'x') { - version = version + '.x'; - } - } - return version; -} +run(); /***/ }), @@ -4100,98 +3934,6 @@ function v4(options, buf, offset) { module.exports = v4; -/***/ }), - -/***/ 827: -/***/ (function(__unusedmodule, exports, __webpack_require__) { - -"use strict"; - -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - 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) : new P(function (resolve) { resolve(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 fs = __importStar(__webpack_require__(747)); -const os = __importStar(__webpack_require__(87)); -const path = __importStar(__webpack_require__(622)); -const core = __importStar(__webpack_require__(470)); -const io = __importStar(__webpack_require__(1)); -exports.M2_DIR = '.m2'; -exports.SETTINGS_FILE = 'settings.xml'; -function configAuthentication(id, username, password) { - return __awaiter(this, void 0, void 0, function* () { - if (id && username && password) { - console.log(`creating ${exports.SETTINGS_FILE} with server-id: ${id}, username: ${username}, and a password`); - // when an alternate m2 location is specified use only that location (no .m2 directory) - // otherwise use the home/.m2/ path - const directory = path.join(core.getInput('settings-path') || os.homedir(), core.getInput('settings-path') ? '' : exports.M2_DIR); - yield io.mkdirP(directory); - core.debug(`created directory ${directory}`); - yield write(directory, generate(id, username, password)); - } - else { - core.debug(`no ${exports.SETTINGS_FILE} without server-id: ${id}, username: ${username}, and a password`); - } - }); -} -exports.configAuthentication = configAuthentication; -function escapeXML(value) { - return value - .replace(/&/g, '&') - .replace(//g, '>') - .replace(/"/g, '"') - .replace(/'/g, '''); -} -// only exported for testing purposes -function generate(id, username, password) { - return ` - - - - ${escapeXML(id)} - ${escapeXML(username)} - ${escapeXML(password)} - - - - `; -} -exports.generate = generate; -function write(directory, settings) { - return __awaiter(this, void 0, void 0, function* () { - const options = { encoding: 'utf-8', flag: 'wx' }; // 'wx': Like 'w' but fails if path exists - const location = path.join(directory, exports.SETTINGS_FILE); - console.log(`writing ${location}`); - try { - return fs.writeFileSync(location, settings, options); - } - catch (e) { - if (e.code == 'EEXIST') { - console.warn(`overwriting existing file ${location}`); - return fs.writeFileSync(location, settings, { - encoding: 'utf-8', - flag: 'w' - }); - } - throw e; - } - }); -} - - /***/ }), /***/ 835: @@ -4662,6 +4404,262 @@ class HttpClient { exports.HttpClient = HttpClient; +/***/ }), + +/***/ 923: +/***/ (function(__unusedmodule, exports, __webpack_require__) { + +"use strict"; + +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + 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) : new P(function (resolve) { resolve(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 }); +let tempDirectory = process.env['RUNNER_TEMP'] || ''; +const core = __importStar(__webpack_require__(470)); +const io = __importStar(__webpack_require__(1)); +const exec = __importStar(__webpack_require__(986)); +const tc = __importStar(__webpack_require__(533)); +const fs = __importStar(__webpack_require__(747)); +const path = __importStar(__webpack_require__(622)); +const semver = __importStar(__webpack_require__(280)); +const httpm = __importStar(__webpack_require__(874)); +const IS_WINDOWS = process.platform === 'win32'; +if (!tempDirectory) { + let baseLocation; + if (IS_WINDOWS) { + // On windows use the USERPROFILE env variable + baseLocation = process.env['USERPROFILE'] || 'C:\\'; + } + else { + if (process.platform === 'darwin') { + baseLocation = '/Users'; + } + else { + baseLocation = '/home'; + } + } + tempDirectory = path.join(baseLocation, 'actions', 'temp'); +} +function getJava(version, arch, jdkFile, javaPackage) { + return __awaiter(this, void 0, void 0, function* () { + let toolPath = tc.find(javaPackage, version); + if (toolPath) { + core.debug(`Tool found in cache ${toolPath}`); + } + else { + let compressedFileExtension = ''; + if (!jdkFile) { + core.debug('Downloading Jdk from Azul'); + let http = new httpm.HttpClient('setup-java'); + let contents = yield (yield http.get('https://static.azul.com/zulu/bin/')).readBody(); + let refs = contents.match(//gi) || []; + const downloadInfo = getDownloadInfo(refs, version, javaPackage); + jdkFile = yield tc.downloadTool(downloadInfo.url); + version = downloadInfo.version; + compressedFileExtension = IS_WINDOWS ? '.zip' : '.tar.gz'; + } + else { + core.debug('Retrieving Jdk from local path'); + } + compressedFileExtension = compressedFileExtension || getFileEnding(jdkFile); + let tempDir = path.join(tempDirectory, 'temp_' + Math.floor(Math.random() * 2000000000)); + const jdkDir = yield unzipJavaDownload(jdkFile, compressedFileExtension, tempDir); + core.debug(`jdk extracted to ${jdkDir}`); + toolPath = yield tc.cacheDir(jdkDir, javaPackage, getCacheVersionString(version), arch); + } + let extendedJavaHome = 'JAVA_HOME_' + version + '_' + arch; + core.exportVariable('JAVA_HOME', toolPath); + core.exportVariable(extendedJavaHome, toolPath); + core.addPath(path.join(toolPath, 'bin')); + }); +} +exports.getJava = getJava; +function getCacheVersionString(version) { + const versionArray = version.split('.'); + const major = versionArray[0]; + const minor = versionArray.length > 1 ? versionArray[1] : '0'; + const patch = versionArray.length > 2 ? versionArray[2] : '0'; + return `${major}.${minor}.${patch}`; +} +function getFileEnding(file) { + let fileEnding = ''; + if (file.endsWith('.tar')) { + fileEnding = '.tar'; + } + else if (file.endsWith('.tar.gz')) { + fileEnding = '.tar.gz'; + } + else if (file.endsWith('.zip')) { + fileEnding = '.zip'; + } + else if (file.endsWith('.7z')) { + fileEnding = '.7z'; + } + else { + throw new Error(`${file} has an unsupported file extension`); + } + return fileEnding; +} +function extractFiles(file, fileEnding, destinationFolder) { + return __awaiter(this, void 0, void 0, function* () { + const stats = fs.statSync(file); + if (!stats) { + throw new Error(`Failed to extract ${file} - it doesn't exist`); + } + else if (stats.isDirectory()) { + throw new Error(`Failed to extract ${file} - it is a directory`); + } + if ('.tar' === fileEnding || '.tar.gz' === fileEnding) { + yield tc.extractTar(file, destinationFolder); + } + else if ('.zip' === fileEnding) { + yield tc.extractZip(file, destinationFolder); + } + else { + // fall through and use sevenZip + yield tc.extract7z(file, destinationFolder); + } + }); +} +// This method recursively finds all .pack files under fsPath and unpacks them with the unpack200 tool +function unpackJars(fsPath, javaBinPath) { + return __awaiter(this, void 0, void 0, function* () { + if (fs.existsSync(fsPath)) { + if (fs.lstatSync(fsPath).isDirectory()) { + for (const file in fs.readdirSync(fsPath)) { + const curPath = path.join(fsPath, file); + yield unpackJars(curPath, javaBinPath); + } + } + else if (path.extname(fsPath).toLowerCase() === '.pack') { + // Unpack the pack file synchonously + const p = path.parse(fsPath); + const toolName = IS_WINDOWS ? 'unpack200.exe' : 'unpack200'; + const args = IS_WINDOWS ? '-r -v -l ""' : ''; + const name = path.join(p.dir, p.name); + yield exec.exec(`"${path.join(javaBinPath, toolName)}"`, [ + `${args} "${name}.pack" "${name}.jar"` + ]); + } + } + }); +} +function unzipJavaDownload(repoRoot, fileEnding, destinationFolder, extension) { + return __awaiter(this, void 0, void 0, function* () { + // Create the destination folder if it doesn't exist + yield io.mkdirP(destinationFolder); + const jdkFile = path.normalize(repoRoot); + const stats = fs.statSync(jdkFile); + if (stats.isFile()) { + yield extractFiles(jdkFile, fileEnding, destinationFolder); + const jdkDirectory = path.join(destinationFolder, fs.readdirSync(destinationFolder)[0]); + yield unpackJars(jdkDirectory, path.join(jdkDirectory, 'bin')); + return jdkDirectory; + } + else { + throw new Error(`Jdk argument ${jdkFile} is not a file`); + } + }); +} +function getDownloadInfo(refs, version, javaPackage) { + version = normalizeVersion(version); + let extension = ''; + if (IS_WINDOWS) { + extension = `-win_x64.zip`; + } + else { + if (process.platform === 'darwin') { + extension = `-macosx_x64.tar.gz`; + } + else { + extension = `-linux_x64.tar.gz`; + } + } + let pkgRegexp = new RegExp(''); + let pkgTypeLength = 0; + if (javaPackage === 'jdk') { + pkgRegexp = /jdk.*-/gi; + pkgTypeLength = 'jdk'.length; + } + else if (javaPackage == 'jre') { + pkgRegexp = /jre.*-/gi; + pkgTypeLength = 'jre'.length; + } + else if (javaPackage == 'jdk+fx') { + pkgRegexp = /fx-jdk.*-/gi; + pkgTypeLength = 'fx-jdk'.length; + } + else { + throw new Error(`package argument ${javaPackage} is not in [jdk | jre | jdk+fx]`); + } + // Maps version to url + let versionMap = new Map(); + // Filter by platform + refs.forEach(ref => { + if (!ref.endsWith(extension + '">')) { + return; + } + // If we haven't returned, means we're looking at the correct platform + let versions = ref.match(pkgRegexp) || []; + if (versions.length > 1) { + throw new Error(`Invalid ref received from https://static.azul.com/zulu/bin/: ${ref}`); + } + if (versions.length == 0) { + return; + } + const refVersion = versions[0].slice(pkgTypeLength, versions[0].length - 1); + if (semver.satisfies(refVersion, version)) { + versionMap.set(refVersion, 'https://static.azul.com/zulu/bin/' + + ref.slice(''.length)); + } + }); + // Choose the most recent satisfying version + let curVersion = '0.0.0'; + let curUrl = ''; + for (const entry of versionMap.entries()) { + const entryVersion = entry[0]; + const entryUrl = entry[1]; + if (semver.gt(entryVersion, curVersion)) { + curUrl = entryUrl; + curVersion = entryVersion; + } + } + if (curUrl == '') { + throw new Error(`No valid download found for version ${version} and package ${javaPackage}. Check https://static.azul.com/zulu/bin/ for a list of valid versions or download your own jdk file and add the jdkFile argument`); + } + return { version: curVersion, url: curUrl }; +} +function normalizeVersion(version) { + if (version.slice(0, 2) === '1.') { + // Trim leading 1. for versions like 1.8 + version = version.slice(2); + if (!version) { + throw new Error('1. is not a valid version'); + } + } + // Add trailing .x if it is missing + if (version.split('.').length != 3) { + if (version[version.length - 1] != 'x') { + version = version + '.x'; + } + } + return version; +} + + /***/ }), /***/ 986: diff --git a/package.json b/package.json index 28d0e0b..00922b4 100644 --- a/package.json +++ b/package.json @@ -5,10 +5,11 @@ "description": "setup java action", "main": "dist/index.js", "scripts": { - "build": "tsc", + "build": "ncc build src/setup-java.ts", "format": "prettier --write **/*.ts", "format-check": "prettier --check **/*.ts", - "release": "ncc build lib/setup-java.js && git add -f dist/index.js", + "prerelease": "npm run-script build", + "release": "git add -f dist/index.js", "test": "jest" }, "repository": { diff --git a/src/auth.ts b/src/auth.ts index f50ab7d..0e95ed0 100644 --- a/src/auth.ts +++ b/src/auth.ts @@ -57,19 +57,15 @@ export function generate(id: string, username: string, password: string) { } async function write(directory: string, settings: string) { - const options = {encoding: 'utf-8', flag: 'wx'}; // 'wx': Like 'w' but fails if path exists const location = path.join(directory, SETTINGS_FILE); - console.log(`writing ${location}`); - try { - return fs.writeFileSync(location, settings, options); - } catch (e) { - if (e.code == 'EEXIST') { - console.warn(`overwriting existing file ${location}`); - return fs.writeFileSync(location, settings, { - encoding: 'utf-8', - flag: 'w' - }); - } - throw e; + if (fs.existsSync(location)) { + console.warn(`overwriting existing file ${location}`); + } else { + console.log(`writing ${location}`); } + + return fs.writeFileSync(location, settings, { + encoding: 'utf-8', + flag: 'w' + }); } diff --git a/src/setup-java.ts b/src/setup-java.ts index 419b9ea..9300eef 100644 --- a/src/setup-java.ts +++ b/src/setup-java.ts @@ -19,11 +19,13 @@ async function run() { console.log(`##[add-matcher]${path.join(matchersPath, 'java.json')}`); const id = core.getInput('server-id', {required: false}); - const username = core.getInput('username', {required: false}); - const password = core.getInput('password', {required: false}); + const username = core.getInput('server-username', {required: false}); + const password = core.getInput('server-password', {required: false}); if (id && username && password) { await auth.configAuthentication(id, username, password); + } else if (id || username || password) { + console.warn('All 3 server-(id, username, and password) are required.'); } } catch (error) { core.setFailed(error.message); From 1bba665156038da9842f9a4e4267811c72bcc159 Mon Sep 17 00:00:00 2001 From: Bryan Clark Date: Thu, 19 Dec 2019 11:28:11 -0800 Subject: [PATCH 50/55] Try env variables --- README.md | 18 +++++++------- __tests__/auth.test.ts | 54 ++++++++++++++++++++++++++---------------- action.yml | 7 +++--- dist/index.js | 37 ++++++++++++----------------- src/auth.ts | 51 ++++++++++++++++++++------------------- src/setup-java.ts | 6 +---- 6 files changed, 90 insertions(+), 83 deletions(-) diff --git a/README.md b/README.md index f6d6a44..977a4bb 100644 --- a/README.md +++ b/README.md @@ -69,9 +69,8 @@ jobs: uses: actions/setup-java@v1 with: java-version: 1.8 - server-id: github # Value of the distributionManagement/repository/id field of the pom.xml - username: ${{ github.actor }} # username for server authentication - password: ${{ github.token }} # password or token for authentication + env: + GITHUB_TOKEN: ${{ github.token }} - name: Build with Maven run: mvn -B package --file pom.xml @@ -83,9 +82,12 @@ jobs: uses: actions/setup-java@v1 with: # running setup-java again overwrites the settings.xml java-version: 1.8 - server-id: maven - server-username: maven_username - server-password: ${{ secrets.MAVEN_CENTRAL_TOKEN }} # password from secrets store + server-id: maven # Value of the distributionManagement/repository/id field of the pom.xml + server-username: MAVEN_USERNAME # env variable for username below + server-password: MAVEN_CENTRAL_TOKEN # env variable for token below + env: + MAVEN_CENTRAL_TOKEN: ${{ secrets.MAVEN_CENTRAL_TOKEN }} + MAVEN_USERNAME: maven_username123 - name: Publish to Apache Maven Central run: mvn deploy @@ -139,9 +141,9 @@ jobs: with: java-version: 1.8 server-id: github # Value of the distributionManagement/repository/id field of the pom.xml - server-username: ${{ github.actor }} # username for server authentication - server-password: ${{ github.token }} # password or token for authentication settings-path: ${{ github.workspace }} # location for the settings.xml file + env: + GITHUB_TOKEN: ${{ github.token }} - name: Build with Maven run: mvn -B package --file pom.xml diff --git a/__tests__/auth.test.ts b/__tests__/auth.test.ts index 1d5cee9..5a31e27 100644 --- a/__tests__/auth.test.ts +++ b/__tests__/auth.test.ts @@ -30,8 +30,8 @@ describe('auth tests', () => { it('creates settings.xml in alternate locations', async () => { const id = 'packages'; - const username = 'bluebottle'; - const password = 'SingleOrigin'; + const username = 'UNAMI'; + const password = 'TOLKIEN'; const altHome = path.join(__dirname, 'runner', 'settings'); const altSettingsFile = path.join(altHome, auth.SETTINGS_FILE); @@ -55,8 +55,8 @@ describe('auth tests', () => { it('creates settings.xml with username and password', async () => { const id = 'packages'; - const username = 'bluebottle'; - const password = 'SingleOrigin'; + const username = 'UNAME'; + const password = 'TOKEN'; await auth.configAuthentication(id, username, password); @@ -69,8 +69,8 @@ describe('auth tests', () => { it('overwrites existing settings.xml files', async () => { const id = 'packages'; - const username = 'bluebottle'; - const password = 'SingleOrigin'; + const username = 'USERNAME'; + const password = 'PASSWORD'; fs.mkdirSync(m2Dir, {recursive: true}); fs.writeFileSync(settingsFile, 'FAKE FILE'); @@ -87,30 +87,42 @@ describe('auth tests', () => { }, 100000); it('does not create settings.xml without required parameters', async () => { - await auth.configAuthentication('FOO', '', ''); + await auth.configAuthentication('FOO'); - expect(fs.existsSync(m2Dir)).toBe(false); - expect(fs.existsSync(settingsFile)).toBe(false); + expect(fs.existsSync(m2Dir)).toBe(true); + expect(fs.existsSync(settingsFile)).toBe(true); + expect(fs.readFileSync(settingsFile, 'utf-8')).toEqual( + auth.generate('FOO') + ); - await auth.configAuthentication('', 'BAR', ''); + await auth.configAuthentication(undefined, 'BAR', undefined); - expect(fs.existsSync(m2Dir)).toBe(false); - expect(fs.existsSync(settingsFile)).toBe(false); + expect(fs.existsSync(m2Dir)).toBe(true); + expect(fs.existsSync(settingsFile)).toBe(true); + expect(fs.readFileSync(settingsFile, 'utf-8')).toEqual( + auth.generate(undefined, 'BAR', undefined) + ); - await auth.configAuthentication('', '', 'BAZ'); + await auth.configAuthentication(undefined, undefined, 'BAZ'); - expect(fs.existsSync(m2Dir)).toBe(false); - expect(fs.existsSync(settingsFile)).toBe(false); + expect(fs.existsSync(m2Dir)).toBe(true); + expect(fs.existsSync(settingsFile)).toBe(true); + expect(fs.readFileSync(settingsFile, 'utf-8')).toEqual( + auth.generate(undefined, undefined, 'BAZ') + ); - await auth.configAuthentication('', '', ''); + await auth.configAuthentication(); - expect(fs.existsSync(m2Dir)).toBe(false); - expect(fs.existsSync(settingsFile)).toBe(false); + expect(fs.existsSync(m2Dir)).toBe(true); + expect(fs.existsSync(settingsFile)).toBe(true); + expect(fs.readFileSync(settingsFile, 'utf-8')).toEqual( + auth.generate(undefined, undefined, undefined) + ); }, 100000); it('escapes invalid XML inputs', () => { const id = 'packages'; - const username = 'bluebottle'; + const username = 'USER'; const password = '&<>"\'\'"><&'; expect(auth.generate(id, username, password)).toEqual(` @@ -118,8 +130,8 @@ describe('auth tests', () => { ${id} - ${username} - &<>"''"><& + \${env.${username}} + \${env.&<>"''"><&} diff --git a/action.yml b/action.yml index df1a2c1..d310ebd 100644 --- a/action.yml +++ b/action.yml @@ -24,11 +24,12 @@ inputs: file.' required: false server-username: - description: 'Username for authentication to the Apache Maven repository.' + description: 'Environment variable name for the username for authentication + to the Apache Maven repository.' required: false server-password: - description: 'Password or token for authentication to the Apache Maven - repository.' + description: 'Environment variable name for password or token for + authentication to the Apache Maven repository.' required: false settings-path: description: 'Path to where the settings.xml file will be written. Default is ~/.m2.' diff --git a/dist/index.js b/dist/index.js index e9e7cc3..be71c59 100644 --- a/dist/index.js +++ b/dist/index.js @@ -2848,20 +2848,18 @@ const core = __importStar(__webpack_require__(470)); const io = __importStar(__webpack_require__(1)); exports.M2_DIR = '.m2'; exports.SETTINGS_FILE = 'settings.xml'; -function configAuthentication(id, username, password) { +exports.DEFAULT_ID = 'github'; +exports.DEFAULT_USERNAME = 'GITHUB_ACTOR'; +exports.DEFAULT_PASSWORD = 'GITHUB_TOKEN'; +function configAuthentication(id = exports.DEFAULT_ID, username = exports.DEFAULT_USERNAME, password = exports.DEFAULT_PASSWORD) { return __awaiter(this, void 0, void 0, function* () { - if (id && username && password) { - console.log(`creating ${exports.SETTINGS_FILE} with server-id: ${id}, username: ${username}, and a password`); - // when an alternate m2 location is specified use only that location (no .m2 directory) - // otherwise use the home/.m2/ path - const directory = path.join(core.getInput('settings-path') || os.homedir(), core.getInput('settings-path') ? '' : exports.M2_DIR); - yield io.mkdirP(directory); - core.debug(`created directory ${directory}`); - yield write(directory, generate(id, username, password)); - } - else { - core.debug(`no ${exports.SETTINGS_FILE} without server-id: ${id}, username: ${username}, and a password`); - } + console.log(`creating ${exports.SETTINGS_FILE} with server-id: ${id};`, `environment variables: username=\$${username} and password=\$${password}`); + // when an alternate m2 location is specified use only that location (no .m2 directory) + // otherwise use the home/.m2/ path + const directory = path.join(core.getInput('settings-path') || os.homedir(), core.getInput('settings-path') ? '' : exports.M2_DIR); + yield io.mkdirP(directory); + core.debug(`created directory ${directory}`); + yield write(directory, generate(id, username, password)); }); } exports.configAuthentication = configAuthentication; @@ -2874,14 +2872,14 @@ function escapeXML(value) { .replace(/'/g, '''); } // only exported for testing purposes -function generate(id, username, password) { +function generate(id = exports.DEFAULT_ID, username = exports.DEFAULT_USERNAME, password = exports.DEFAULT_PASSWORD) { return ` ${escapeXML(id)} - ${escapeXML(username)} - ${escapeXML(password)} + \${env.${escapeXML(username)}} + \${env.${escapeXML(password)}} @@ -3883,12 +3881,7 @@ function run() { const id = core.getInput('server-id', { required: false }); const username = core.getInput('server-username', { required: false }); const password = core.getInput('server-password', { required: false }); - if (id && username && password) { - yield auth.configAuthentication(id, username, password); - } - else if (id || username || password) { - console.warn('All 3 server-(id, username, and password) are required.'); - } + yield auth.configAuthentication(id, username, password); } catch (error) { core.setFailed(error.message); diff --git a/src/auth.ts b/src/auth.ts index 0e95ed0..2e7c6e8 100644 --- a/src/auth.ts +++ b/src/auth.ts @@ -7,29 +7,28 @@ import * as io from '@actions/io'; export const M2_DIR = '.m2'; export const SETTINGS_FILE = 'settings.xml'; +export const DEFAULT_ID = 'github'; +export const DEFAULT_USERNAME = 'GITHUB_ACTOR'; +export const DEFAULT_PASSWORD = 'GITHUB_TOKEN'; + export async function configAuthentication( - id: string, - username: string, - password: string + id = DEFAULT_ID, + username = DEFAULT_USERNAME, + password = DEFAULT_PASSWORD ) { - if (id && username && password) { - console.log( - `creating ${SETTINGS_FILE} with server-id: ${id}, username: ${username}, and a password` - ); - // when an alternate m2 location is specified use only that location (no .m2 directory) - // otherwise use the home/.m2/ path - const directory: string = path.join( - core.getInput('settings-path') || os.homedir(), - core.getInput('settings-path') ? '' : M2_DIR - ); - await io.mkdirP(directory); - core.debug(`created directory ${directory}`); - await write(directory, generate(id, username, password)); - } else { - core.debug( - `no ${SETTINGS_FILE} without server-id: ${id}, username: ${username}, and a password` - ); - } + console.log( + `creating ${SETTINGS_FILE} with server-id: ${id};`, + `environment variables: username=\$${username} and password=\$${password}` + ); + // when an alternate m2 location is specified use only that location (no .m2 directory) + // otherwise use the home/.m2/ path + const directory: string = path.join( + core.getInput('settings-path') || os.homedir(), + core.getInput('settings-path') ? '' : M2_DIR + ); + await io.mkdirP(directory); + core.debug(`created directory ${directory}`); + await write(directory, generate(id, username, password)); } function escapeXML(value: string) { @@ -42,14 +41,18 @@ function escapeXML(value: string) { } // only exported for testing purposes -export function generate(id: string, username: string, password: string) { +export function generate( + id = DEFAULT_ID, + username = DEFAULT_USERNAME, + password = DEFAULT_PASSWORD +) { return ` ${escapeXML(id)} - ${escapeXML(username)} - ${escapeXML(password)} + \${env.${escapeXML(username)}} + \${env.${escapeXML(password)}} diff --git a/src/setup-java.ts b/src/setup-java.ts index 9300eef..a50ff55 100644 --- a/src/setup-java.ts +++ b/src/setup-java.ts @@ -22,11 +22,7 @@ async function run() { const username = core.getInput('server-username', {required: false}); const password = core.getInput('server-password', {required: false}); - if (id && username && password) { - await auth.configAuthentication(id, username, password); - } else if (id || username || password) { - console.warn('All 3 server-(id, username, and password) are required.'); - } + await auth.configAuthentication(id, username, password); } catch (error) { core.setFailed(error.message); } From 0e5545ead5014c85875fdd4d6febc455d52030e8 Mon Sep 17 00:00:00 2001 From: Bryan Clark Date: Thu, 19 Dec 2019 14:18:54 -0800 Subject: [PATCH 51/55] improve tests --- __tests__/auth.test.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/__tests__/auth.test.ts b/__tests__/auth.test.ts index 5a31e27..1350968 100644 --- a/__tests__/auth.test.ts +++ b/__tests__/auth.test.ts @@ -92,7 +92,7 @@ describe('auth tests', () => { expect(fs.existsSync(m2Dir)).toBe(true); expect(fs.existsSync(settingsFile)).toBe(true); expect(fs.readFileSync(settingsFile, 'utf-8')).toEqual( - auth.generate('FOO') + auth.generate('FOO', auth.DEFAULT_USERNAME, auth.DEFAULT_PASSWORD) ); await auth.configAuthentication(undefined, 'BAR', undefined); @@ -100,7 +100,7 @@ describe('auth tests', () => { expect(fs.existsSync(m2Dir)).toBe(true); expect(fs.existsSync(settingsFile)).toBe(true); expect(fs.readFileSync(settingsFile, 'utf-8')).toEqual( - auth.generate(undefined, 'BAR', undefined) + auth.generate(auth.DEFAULT_ID, 'BAR', auth.DEFAULT_PASSWORD) ); await auth.configAuthentication(undefined, undefined, 'BAZ'); @@ -108,7 +108,7 @@ describe('auth tests', () => { expect(fs.existsSync(m2Dir)).toBe(true); expect(fs.existsSync(settingsFile)).toBe(true); expect(fs.readFileSync(settingsFile, 'utf-8')).toEqual( - auth.generate(undefined, undefined, 'BAZ') + auth.generate(auth.DEFAULT_ID, auth.DEFAULT_USERNAME, 'BAZ') ); await auth.configAuthentication(); @@ -116,7 +116,11 @@ describe('auth tests', () => { expect(fs.existsSync(m2Dir)).toBe(true); expect(fs.existsSync(settingsFile)).toBe(true); expect(fs.readFileSync(settingsFile, 'utf-8')).toEqual( - auth.generate(undefined, undefined, undefined) + auth.generate( + auth.DEFAULT_ID, + auth.DEFAULT_USERNAME, + auth.DEFAULT_PASSWORD + ) ); }, 100000); From 7e36086f368f03a37df27d38609ef98df42adb15 Mon Sep 17 00:00:00 2001 From: Bryan Clark Date: Thu, 19 Dec 2019 14:20:17 -0800 Subject: [PATCH 52/55] Pass undefined when empty --- dist/index.js | 6 +++--- src/setup-java.ts | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/dist/index.js b/dist/index.js index be71c59..4fb758e 100644 --- a/dist/index.js +++ b/dist/index.js @@ -3878,9 +3878,9 @@ function run() { yield installer.getJava(version, arch, jdkFile, javaPackage); const matchersPath = path.join(__dirname, '..', '.github'); console.log(`##[add-matcher]${path.join(matchersPath, 'java.json')}`); - const id = core.getInput('server-id', { required: false }); - const username = core.getInput('server-username', { required: false }); - const password = core.getInput('server-password', { required: false }); + const id = core.getInput('server-id', { required: false }) || undefined; + const username = core.getInput('server-username', { required: false }) || undefined; + const password = core.getInput('server-password', { required: false }) || undefined; yield auth.configAuthentication(id, username, password); } catch (error) { diff --git a/src/setup-java.ts b/src/setup-java.ts index a50ff55..7614f03 100644 --- a/src/setup-java.ts +++ b/src/setup-java.ts @@ -18,9 +18,9 @@ async function run() { const matchersPath = path.join(__dirname, '..', '.github'); console.log(`##[add-matcher]${path.join(matchersPath, 'java.json')}`); - const id = core.getInput('server-id', {required: false}); - const username = core.getInput('server-username', {required: false}); - const password = core.getInput('server-password', {required: false}); + const id = core.getInput('server-id', {required: false}) || undefined; + const username = core.getInput('server-username', {required: false}) || undefined; + const password = core.getInput('server-password', {required: false}) || undefined; await auth.configAuthentication(id, username, password); } catch (error) { From c05b45bb9156e7a0d3ed6a39e72b1debd3d0a780 Mon Sep 17 00:00:00 2001 From: Bryan Clark Date: Thu, 19 Dec 2019 15:39:48 -0800 Subject: [PATCH 53/55] Update README with env sections --- README.md | 18 +++++++++--------- src/setup-java.ts | 6 ++++-- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 977a4bb..9a1915a 100644 --- a/README.md +++ b/README.md @@ -69,28 +69,28 @@ jobs: uses: actions/setup-java@v1 with: java-version: 1.8 - env: - GITHUB_TOKEN: ${{ github.token }} - name: Build with Maven run: mvn -B package --file pom.xml - name: Publish to GitHub Packages Apache Maven run: mvn deploy + env: + GITHUB_TOKEN: ${{ github.token }} # GITHUB_TOKEN is the default env for the password - name: Set up Apache Maven Central uses: actions/setup-java@v1 with: # running setup-java again overwrites the settings.xml java-version: 1.8 server-id: maven # Value of the distributionManagement/repository/id field of the pom.xml - server-username: MAVEN_USERNAME # env variable for username below - server-password: MAVEN_CENTRAL_TOKEN # env variable for token below - env: - MAVEN_CENTRAL_TOKEN: ${{ secrets.MAVEN_CENTRAL_TOKEN }} - MAVEN_USERNAME: maven_username123 + server-username: MAVEN_USERNAME # env variable for username in deploy + server-password: MAVEN_CENTRAL_TOKEN # env variable for token in deploy - name: Publish to Apache Maven Central run: mvn deploy + env: + MAVEN_CENTRAL_TOKEN: ${{ secrets.MAVEN_CENTRAL_TOKEN }} + MAVEN_USERNAME: maven_username123 ``` ***NOTE: The `settings.xml` file is created in the Actions $HOME directory. If you have an existing `settings.xml` file at that location, it will be overwritten. See below for using the `settings-path` to change your `settings.xml` file location.*** @@ -142,14 +142,14 @@ jobs: java-version: 1.8 server-id: github # Value of the distributionManagement/repository/id field of the pom.xml settings-path: ${{ github.workspace }} # location for the settings.xml file - env: - GITHUB_TOKEN: ${{ github.token }} - name: Build with Maven run: mvn -B package --file pom.xml - name: Publish to GitHub Packages Apache Maven run: mvn deploy -s $GITHUB_WORKSPACE/settings.xml + env: + GITHUB_TOKEN: ${{ github.token }} ``` # License diff --git a/src/setup-java.ts b/src/setup-java.ts index 7614f03..d039217 100644 --- a/src/setup-java.ts +++ b/src/setup-java.ts @@ -19,8 +19,10 @@ async function run() { console.log(`##[add-matcher]${path.join(matchersPath, 'java.json')}`); const id = core.getInput('server-id', {required: false}) || undefined; - const username = core.getInput('server-username', {required: false}) || undefined; - const password = core.getInput('server-password', {required: false}) || undefined; + const username = + core.getInput('server-username', {required: false}) || undefined; + const password = + core.getInput('server-password', {required: false}) || undefined; await auth.configAuthentication(id, username, password); } catch (error) { From 2ccd1ad1251d6f44910aa33afb44208934d783bc Mon Sep 17 00:00:00 2001 From: Bryan Clark Date: Thu, 19 Dec 2019 15:44:10 -0800 Subject: [PATCH 54/55] Add examples of the settings.xml file generated --- README.md | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9a1915a..944809a 100644 --- a/README.md +++ b/README.md @@ -89,8 +89,32 @@ jobs: - name: Publish to Apache Maven Central run: mvn deploy env: - MAVEN_CENTRAL_TOKEN: ${{ secrets.MAVEN_CENTRAL_TOKEN }} MAVEN_USERNAME: maven_username123 + MAVEN_CENTRAL_TOKEN: ${{ secrets.MAVEN_CENTRAL_TOKEN }} +``` + +The two `settings.xml` files created from the above example look like the following. + +`settings.xml` file created for the first deploy to GitHub Packages +```xml + + + github + ${env.GITHUB_ACTOR} + ${env.GITHUB_TOKEN} + + +``` + +`settings.xml` file created for the second deploy to Apache Maven Central +```xml + + + maven + ${env.MAVEN_USERNAME} + ${env.MAVEN_CENTRAL_TOKEN} + + ``` ***NOTE: The `settings.xml` file is created in the Actions $HOME directory. If you have an existing `settings.xml` file at that location, it will be overwritten. See below for using the `settings-path` to change your `settings.xml` file location.*** From 9b11fe4b5ddd6e533908f148a4273e9685c007e1 Mon Sep 17 00:00:00 2001 From: Bryan Clark Date: Fri, 20 Dec 2019 08:35:06 -0800 Subject: [PATCH 55/55] Add defaults descriptions to actions.yml --- action.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/action.yml b/action.yml index d310ebd..6337613 100644 --- a/action.yml +++ b/action.yml @@ -21,15 +21,15 @@ inputs: required: false server-id: description: 'ID of the distributionManagement repository in the pom.xml - file.' + file. Default is `github`' required: false server-username: description: 'Environment variable name for the username for authentication - to the Apache Maven repository.' + to the Apache Maven repository. Default is $GITHUB_ACTOR' required: false server-password: description: 'Environment variable name for password or token for - authentication to the Apache Maven repository.' + authentication to the Apache Maven repository. Default is $GITHUB_TOKEN' required: false settings-path: description: 'Path to where the settings.xml file will be written. Default is ~/.m2.'