From 6924f73ee016582f21bae0cec5f0e818642eb1d5 Mon Sep 17 00:00:00 2001 From: Bryan Clark Date: Thu, 19 Dec 2019 08:52:26 -0800 Subject: [PATCH] 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);