From 6fa8ff8bf63b7e781a87198da8d58eb75969e072 Mon Sep 17 00:00:00 2001 From: Pavel Gonchukov Date: Mon, 22 Feb 2021 21:36:35 +0100 Subject: [PATCH] Add functionality to setup maven binary Add functionality to setup maven in order to use for project building --- .gitattributes | 3 +- README.md | 19 +++++++ __tests__/installer.test.ts | 20 +++++++ action.yml | 3 + dist/cleanup/index.js | 3 +- dist/setup/index.js | 108 ++++++++++++++++++++++++------------ package-lock.json | 45 +-------------- package.json | 2 +- src/constants.ts | 2 + src/installer.ts | 50 ++++++++++++++++- src/maven.ts | 64 ++++++++++----------- src/setup-java.ts | 30 +++++++--- 12 files changed, 222 insertions(+), 127 deletions(-) diff --git a/.gitattributes b/.gitattributes index bff632db..55005de2 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,3 +1,2 @@ -dist/index.js -diff -merge -dist/index.js linguist-generated=true .licenses/** -diff linguist-generated=true +dist/** -diff linguist-generated=true diff --git a/README.md b/README.md index 14e6d77e..3e526c37 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,25 @@ This action sets up a java environment for use in actions by: See [action.yml](action.yml) +## MTLS Basic +```yaml +steps: +- uses: tradeshift/actions-setup-java@master + with: + # standard github actions parameters + # possible values explained in sections below + java-version: 11 + # mvn and MTLS related parameters + maven-version: "3.6.3" + maven-ca-cert-b64: ${{ secrets.MTLS_CACERT }} + maven-keystore-p12-b64: ${{ secrets.MAVEN_P12 }} + maven-keystore-password: ${{ secrets.MAVEN_P12_PASSWORD }} + maven-settings-b64: ${{ secrets.MAVEN_SETTINGS }} + maven-security-settings-b64: ${{ secrets.MAVEN_SECURITY }} +- run: | + mvn -B compile +``` + ## Basic ```yaml steps: diff --git a/__tests__/installer.test.ts b/__tests__/installer.test.ts index ff2d61b5..d72d6dfd 100644 --- a/__tests__/installer.test.ts +++ b/__tests__/installer.test.ts @@ -156,4 +156,24 @@ describe('installer tests', () => { expect(thrown).toBe(true); return; }); + + it('throws error when given invalid maven version', async () => { + expect(installer.getMaven('2-3-4')).rejects.toThrow(); + }); + + it('Installs version of Maven and stores it to cache', async () => { + await installer.getMaven('3.6.3'); + const mvnDir = path.join(toolDir, 'mvn', '3.6.3', 'x64'); + + expect(fs.existsSync(`${mvnDir}.complete`)).toBe(true); + expect(fs.existsSync(path.join(mvnDir))).toBe(true); + }, 100000); + + it('Uses version of Maven installed in cache', async () => { + const mvnDir: string = path.join(toolDir, 'mvn', '3.6.3', 'x64'); + await io.mkdirP(mvnDir); + fs.writeFileSync(`${mvnDir}.complete`, 'hello'); + // This will throw if it doesn't find it in the cache (because no such version exists) + await installer.getMaven('3.6.3'); + }); }); diff --git a/action.yml b/action.yml index 8212ec95..fadbd711 100644 --- a/action.yml +++ b/action.yml @@ -9,6 +9,9 @@ inputs: Early access versions can be specified in the form of e.g. 14-ea, 14.0.0-ea, or 14.0.0-ea.28' required: true + maven-version: + description: 'Version of maven. You have to provide version in order to setup maven. + Check available versions here https://downloads.apache.org/maven/' maven-ca-cert-b64: description: 'CA cert in the format of a base64 blob used to connect to private maven repo protected by MTLS' diff --git a/dist/cleanup/index.js b/dist/cleanup/index.js index 87609ede..e5e52d2d 100644 --- a/dist/cleanup/index.js +++ b/dist/cleanup/index.js @@ -1029,7 +1029,7 @@ module.exports = require("child_process"); "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.STATE_GPG_PRIVATE_KEY_FINGERPRINT = exports.INPUT_DEFAULT_GPG_PASSPHRASE = exports.INPUT_DEFAULT_GPG_PRIVATE_KEY = exports.INPUT_MAVEN_SECURITY_SETTINGS_B64 = exports.INPUT_MAVEN_SETTINGS_B64 = exports.INPUT_MAVEN_KEYSTORE_PASSWORD = exports.INPUT_MAVEN_KEYSTORE_P12_B64 = exports.INPUT_MAVEN_CA_CERT_B64 = exports.INPUT_GPG_PASSPHRASE = exports.INPUT_GPG_PRIVATE_KEY = exports.INPUT_SETTINGS_PATH = exports.INPUT_SERVER_PASSWORD = exports.INPUT_SERVER_USERNAME = exports.INPUT_SERVER_ID = exports.INPUT_JDK_FILE = exports.INPUT_JAVA_PACKAGE = exports.INPUT_ARCHITECTURE = exports.INPUT_JAVA_VERSION = exports.INPUT_VERSION = void 0; +exports.STATE_GPG_PRIVATE_KEY_FINGERPRINT = exports.INPUT_DEFAULT_GPG_PASSPHRASE = exports.INPUT_DEFAULT_GPG_PRIVATE_KEY = exports.INPUT_MAVEN_VERSION = exports.INPUT_MAVEN_SECURITY_SETTINGS_B64 = exports.INPUT_MAVEN_SETTINGS_B64 = exports.INPUT_MAVEN_KEYSTORE_PASSWORD = exports.INPUT_MAVEN_KEYSTORE_P12_B64 = exports.INPUT_MAVEN_CA_CERT_B64 = exports.INPUT_GPG_PASSPHRASE = exports.INPUT_GPG_PRIVATE_KEY = exports.INPUT_SETTINGS_PATH = exports.INPUT_SERVER_PASSWORD = exports.INPUT_SERVER_USERNAME = exports.INPUT_SERVER_ID = exports.INPUT_JDK_FILE = exports.INPUT_JAVA_PACKAGE = exports.INPUT_ARCHITECTURE = exports.INPUT_JAVA_VERSION = exports.INPUT_VERSION = void 0; exports.INPUT_VERSION = 'version'; exports.INPUT_JAVA_VERSION = 'java-version'; exports.INPUT_ARCHITECTURE = 'architecture'; @@ -1046,6 +1046,7 @@ exports.INPUT_MAVEN_KEYSTORE_P12_B64 = 'maven-keystore-p12-b64'; exports.INPUT_MAVEN_KEYSTORE_PASSWORD = 'maven-keystore-password'; exports.INPUT_MAVEN_SETTINGS_B64 = 'maven-settings-b64'; exports.INPUT_MAVEN_SECURITY_SETTINGS_B64 = 'maven-security-settings-b64'; +exports.INPUT_MAVEN_VERSION = 'maven-version'; exports.INPUT_DEFAULT_GPG_PRIVATE_KEY = undefined; exports.INPUT_DEFAULT_GPG_PASSPHRASE = 'GPG_PASSPHRASE'; exports.STATE_GPG_PRIVATE_KEY_FINGERPRINT = 'gpg-private-key-fingerprint'; diff --git a/dist/setup/index.js b/dist/setup/index.js index 8ee7ae36..891909d9 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -11056,29 +11056,25 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge }); }; Object.defineProperty(exports, "__esModule", { value: true }); -exports.setupMaven = exports.validateOptions = void 0; +exports.setupMaven = exports.isValidOptions = void 0; const core = __importStar(__webpack_require__(470)); const fs = __importStar(__webpack_require__(747)); const path = __importStar(__webpack_require__(622)); const constants = __importStar(__webpack_require__(694)); const os = __importStar(__webpack_require__(87)); +const exec = __importStar(__webpack_require__(986)); const io = __importStar(__webpack_require__(1)); -function validateOptions(opts) { - if ((opts.caCert === '' || - opts.keystore === '' || - opts.password === '' || - opts.securitySettings === '', - opts.settings === '')) { - core.debug('maven options set is not valid: some field is empty'); - return false; - } - return true; +function isValidOptions(mvnOpts) { + return (mvnOpts.caCert !== '' && + mvnOpts.keystore !== '' && + mvnOpts.password !== '' && + mvnOpts.securitySettings !== '' && + mvnOpts.settings !== ''); } -exports.validateOptions = validateOptions; +exports.isValidOptions = isValidOptions; function setupMaven(opts) { return __awaiter(this, void 0, void 0, function* () { const settingsDir = path.join(core.getInput(constants.INPUT_SETTINGS_PATH) || os.homedir(), core.getInput(constants.INPUT_SETTINGS_PATH) ? '' : '.m2'); - const certDir = path.join(os.homedir(), 'certs'); fs.writeFileSync(path.join(settingsDir, 'settings.xml'), btoa(opts.settings), { encoding: 'utf-8', flag: 'w' @@ -11087,26 +11083,35 @@ function setupMaven(opts) { encoding: 'utf-8', flag: 'w' }); + const certDir = path.join(os.homedir(), 'certs'); + const rooCaPath = path.join(certDir, 'rootca.crt'); yield io.mkdirP(certDir); - fs.writeFileSync(path.join(certDir, 'rootca.crt'), btoa(opts.caCert), { + fs.writeFileSync(rooCaPath, btoa(opts.caCert), { encoding: 'utf-8', flag: 'w' }); const p12Path = path.join(certDir, 'certificate.p12'); - fs.writeFileSync(p12Path, btoa(opts.keystore), { - encoding: 'utf-8', - flag: 'w' - }); - const password = btoa(opts.password); - core.exportVariable('MAVEN_OPTS', `-Djavax.net.ssl.keyStore=${p12Path} -Djavax.net.ssl.keyStoreType=pkcs12 -Djavax.net.ssl.keyStorePassword=${password}`); + fs.writeFileSync(p12Path, Buffer.from(opts.keystore, 'base64')); + core.exportVariable('MAVEN_OPTS', `-Djavax.net.ssl.keyStore=${p12Path} -Djavax.net.ssl.keyStoreType=pkcs12 -Djavax.net.ssl.keyStorePassword=${opts.password}`); + yield exec.exec(path.join(opts.javaPath, 'bin/keytool'), [ + '-importcert', + '-cacerts', + '-storepass', + 'changeit', + '-noprompt', + '-alias', + 'mycert', + '-file', + rooCaPath + ]); core.debug(`added maven opts for MTLS access`); }); } exports.setupMaven = setupMaven; -const btoa = function (str) { +const atob = function (str) { return Buffer.from(str, 'binary').toString('base64'); }; -const atob = function (str) { +const btoa = function (str) { return Buffer.from(str, 'base64').toString('binary'); }; @@ -30166,7 +30171,7 @@ exports.StaticRangeImpl = StaticRangeImpl; "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.STATE_GPG_PRIVATE_KEY_FINGERPRINT = exports.INPUT_DEFAULT_GPG_PASSPHRASE = exports.INPUT_DEFAULT_GPG_PRIVATE_KEY = exports.INPUT_MAVEN_SECURITY_SETTINGS_B64 = exports.INPUT_MAVEN_SETTINGS_B64 = exports.INPUT_MAVEN_KEYSTORE_PASSWORD = exports.INPUT_MAVEN_KEYSTORE_P12_B64 = exports.INPUT_MAVEN_CA_CERT_B64 = exports.INPUT_GPG_PASSPHRASE = exports.INPUT_GPG_PRIVATE_KEY = exports.INPUT_SETTINGS_PATH = exports.INPUT_SERVER_PASSWORD = exports.INPUT_SERVER_USERNAME = exports.INPUT_SERVER_ID = exports.INPUT_JDK_FILE = exports.INPUT_JAVA_PACKAGE = exports.INPUT_ARCHITECTURE = exports.INPUT_JAVA_VERSION = exports.INPUT_VERSION = void 0; +exports.STATE_GPG_PRIVATE_KEY_FINGERPRINT = exports.INPUT_DEFAULT_GPG_PASSPHRASE = exports.INPUT_DEFAULT_GPG_PRIVATE_KEY = exports.INPUT_MAVEN_VERSION = exports.INPUT_MAVEN_SECURITY_SETTINGS_B64 = exports.INPUT_MAVEN_SETTINGS_B64 = exports.INPUT_MAVEN_KEYSTORE_PASSWORD = exports.INPUT_MAVEN_KEYSTORE_P12_B64 = exports.INPUT_MAVEN_CA_CERT_B64 = exports.INPUT_GPG_PASSPHRASE = exports.INPUT_GPG_PRIVATE_KEY = exports.INPUT_SETTINGS_PATH = exports.INPUT_SERVER_PASSWORD = exports.INPUT_SERVER_USERNAME = exports.INPUT_SERVER_ID = exports.INPUT_JDK_FILE = exports.INPUT_JAVA_PACKAGE = exports.INPUT_ARCHITECTURE = exports.INPUT_JAVA_VERSION = exports.INPUT_VERSION = void 0; exports.INPUT_VERSION = 'version'; exports.INPUT_JAVA_VERSION = 'java-version'; exports.INPUT_ARCHITECTURE = 'architecture'; @@ -30183,6 +30188,7 @@ exports.INPUT_MAVEN_KEYSTORE_P12_B64 = 'maven-keystore-p12-b64'; exports.INPUT_MAVEN_KEYSTORE_PASSWORD = 'maven-keystore-password'; exports.INPUT_MAVEN_SETTINGS_B64 = 'maven-settings-b64'; exports.INPUT_MAVEN_SECURITY_SETTINGS_B64 = 'maven-security-settings-b64'; +exports.INPUT_MAVEN_VERSION = 'maven-version'; exports.INPUT_DEFAULT_GPG_PRIVATE_KEY = undefined; exports.INPUT_DEFAULT_GPG_PASSPHRASE = 'GPG_PASSPHRASE'; exports.STATE_GPG_PRIVATE_KEY_FINGERPRINT = 'gpg-private-key-fingerprint'; @@ -33356,21 +33362,15 @@ function run() { if (!version) { version = core.getInput(constants.INPUT_JAVA_VERSION, { required: true }); } - const mvnOpts = { + let mvnOpts = { caCert: core.getInput(constants.INPUT_MAVEN_CA_CERT_B64), keystore: core.getInput(constants.INPUT_MAVEN_KEYSTORE_P12_B64), password: core.getInput(constants.INPUT_MAVEN_KEYSTORE_PASSWORD), settings: core.getInput(constants.INPUT_MAVEN_SETTINGS_B64), - securitySettings: core.getInput(constants.INPUT_MAVEN_SECURITY_SETTINGS_B64) + securitySettings: core.getInput(constants.INPUT_MAVEN_SECURITY_SETTINGS_B64), + javaPath: '' }; - if ((mvnOpts.caCert !== '' || - mvnOpts.keystore !== '' || - mvnOpts.password !== '' || - mvnOpts.securitySettings !== '', - mvnOpts.settings !== '') && - !maven_1.validateOptions(mvnOpts)) { - throw new Error('Some of the Maven options is empty: please check maven-* parameters'); - } + const mvnVersion = core.getInput(constants.INPUT_MAVEN_VERSION); const arch = core.getInput(constants.INPUT_ARCHITECTURE, { required: true }); if (!['x86', 'x64'].includes(arch)) { throw new Error(`architecture "${arch}" is not in [x86 | x64]`); @@ -33379,7 +33379,17 @@ function run() { required: true }); const jdkFile = core.getInput(constants.INPUT_JDK_FILE, { required: false }); - yield installer.getJava(version, arch, jdkFile, javaPackage); + const javaPath = yield installer.getJava(version, arch, jdkFile, javaPackage); + if (mvnVersion !== '') { + if (!maven_1.isValidOptions(mvnOpts)) { + throw new Error('Some of the Maven options is empty: please check maven-* parameters'); + } + mvnOpts.javaPath = javaPath; + yield installer.getMaven(mvnVersion); + } + else { + mvnOpts = undefined; + } const matchersPath = path.join(__dirname, '..', '..', '.github'); core.info(`##[add-matcher]${path.join(matchersPath, 'java.json')}`); const id = core.getInput(constants.INPUT_SERVER_ID, { required: false }); @@ -38708,7 +38718,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge }); }; Object.defineProperty(exports, "__esModule", { value: true }); -exports.getJava = void 0; +exports.getJava = exports.getMaven = void 0; const core = __importStar(__webpack_require__(470)); const io = __importStar(__webpack_require__(1)); const exec = __importStar(__webpack_require__(986)); @@ -38720,6 +38730,33 @@ const semver = __importStar(__webpack_require__(280)); const util = __importStar(__webpack_require__(322)); const tempDirectory = util.getTempDir(); const IS_WINDOWS = util.isWindows(); +function getMaven(version) { + return __awaiter(this, void 0, void 0, function* () { + if (semver.valid(version) === null) { + throw new Error(`wrong version is set(${version}): supported version template: major.minor.patch`); + } + const majorVersion = semver.major(version); + let toolPath = tc.find('mvn', version); + if (toolPath) { + core.debug(`Tool found in cache ${toolPath}`); + } + else { + core.debug(`Downloading Maven from https://downloads.apache.org/maven/maven-${majorVersion}`); + const url = path.join(`https:///downloads.apache.org/maven/maven-${majorVersion}`, version, `binaries/apache-maven-${version}-bin.tar.gz`); + console.log(url); + const mvnTarFile = yield tc.downloadTool(url); + let tempDir = path.join(tempDirectory, 'temp_' + Math.floor(Math.random() * 2000000000)); + yield extractFiles(mvnTarFile, '.tar.gz', tempDir); + core.debug(`maven extracted to ${tempDir}`); + toolPath = yield tc.cacheDir(path.join(tempDir, `apache-maven-${version}`), 'mvn', version, 'x64'); + } + core.exportVariable('MAVEN_HOME', toolPath); + core.addPath(path.join(toolPath, 'bin')); + core.setOutput('path', toolPath); + core.setOutput('version', version); + }); +} +exports.getMaven = getMaven; function getJava(version, arch, jdkFile, javaPackage) { return __awaiter(this, void 0, void 0, function* () { let toolPath = tc.find(javaPackage, version); @@ -38776,6 +38813,7 @@ function getJava(version, arch, jdkFile, javaPackage) { core.addPath(path.join(toolPath, 'bin')); core.setOutput('path', toolPath); core.setOutput('version', version); + return toolPath; }); } exports.getJava = getJava; diff --git a/package-lock.json b/package-lock.json index e818bc19..325bd29c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,6 +5,7 @@ "requires": true, "packages": { "": { + "name": "setup-java", "version": "1.0.0", "license": "MIT", "dependencies": { @@ -13,8 +14,7 @@ "@actions/http-client": "^1.0.9", "@actions/io": "^1.0.0", "@actions/tool-cache": "^1.6.1", - "@tradeshift/actions-credentials-yaml": "^0.7.0", - "semver": "^6.1.1", + "semver": "^6.3.0", "xmlbuilder2": "^2.4.0" }, "devDependencies": { @@ -603,15 +603,6 @@ "node": ">=8.0" } }, - "node_modules/@tradeshift/actions-credentials-yaml": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@tradeshift/actions-credentials-yaml/-/actions-credentials-yaml-0.7.0.tgz", - "integrity": "sha512-FBHqPvlnqL71DQJJB8aV0WUR/hDoeL3Mf+wpTD1DoxgoPH93LvwiChyNa2NybqENJB9nm85ylK+4pgUxwUoRBw==", - "dependencies": { - "js-base64": "^3.6.0", - "yaml": "^1.10.0" - } - }, "node_modules/@types/babel__core": { "version": "7.1.12", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.12.tgz", @@ -3425,11 +3416,6 @@ "node": ">=6" } }, - "node_modules/js-base64": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.6.0.tgz", - "integrity": "sha512-wVdUBYQeY2gY73RIlPrysvpYx+2vheGo8Y1SNQv/BzHToWpAZzJU7Z6uheKMAe+GLSBig5/Ps2nxg/8tRB73xg==" - }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -5872,14 +5858,6 @@ "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", "dev": true }, - "node_modules/yaml": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.0.tgz", - "integrity": "sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg==", - "engines": { - "node": ">= 6" - } - }, "node_modules/yargs": { "version": "13.3.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", @@ -6434,15 +6412,6 @@ "resolved": "https://registry.npmjs.org/@oozcitak/util/-/util-8.3.8.tgz", "integrity": "sha512-T8TbSnGsxo6TDBJx/Sgv/BlVJL3tshxZP7Aq5R1mSnM5OcHY2dQaxLMu2+E8u3gN0MLOzdjurqN4ZRVuzQycOQ==" }, - "@tradeshift/actions-credentials-yaml": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@tradeshift/actions-credentials-yaml/-/actions-credentials-yaml-0.7.0.tgz", - "integrity": "sha512-FBHqPvlnqL71DQJJB8aV0WUR/hDoeL3Mf+wpTD1DoxgoPH93LvwiChyNa2NybqENJB9nm85ylK+4pgUxwUoRBw==", - "requires": { - "js-base64": "^3.6.0", - "yaml": "^1.10.0" - } - }, "@types/babel__core": { "version": "7.1.12", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.12.tgz", @@ -8701,11 +8670,6 @@ } } }, - "js-base64": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.6.0.tgz", - "integrity": "sha512-wVdUBYQeY2gY73RIlPrysvpYx+2vheGo8Y1SNQv/BzHToWpAZzJU7Z6uheKMAe+GLSBig5/Ps2nxg/8tRB73xg==" - }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -10683,11 +10647,6 @@ "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", "dev": true }, - "yaml": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.0.tgz", - "integrity": "sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg==" - }, "yargs": { "version": "13.3.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", diff --git a/package.json b/package.json index d3299388..8de14293 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "@actions/http-client": "^1.0.9", "@actions/io": "^1.0.0", "@actions/tool-cache": "^1.6.1", - "semver": "^6.1.1", + "semver": "^6.3.0", "xmlbuilder2": "^2.4.0" }, "devDependencies": { diff --git a/src/constants.ts b/src/constants.ts index a8dcfb44..cbbdbe8a 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -9,11 +9,13 @@ export const INPUT_SERVER_PASSWORD = 'server-password'; export const INPUT_SETTINGS_PATH = 'settings-path'; export const INPUT_GPG_PRIVATE_KEY = 'gpg-private-key'; export const INPUT_GPG_PASSPHRASE = 'gpg-passphrase'; + export const INPUT_MAVEN_CA_CERT_B64 = 'maven-ca-cert-b64'; export const INPUT_MAVEN_KEYSTORE_P12_B64 = 'maven-keystore-p12-b64'; export const INPUT_MAVEN_KEYSTORE_PASSWORD = 'maven-keystore-password'; export const INPUT_MAVEN_SETTINGS_B64 = 'maven-settings-b64'; export const INPUT_MAVEN_SECURITY_SETTINGS_B64 = 'maven-security-settings-b64'; +export const INPUT_MAVEN_VERSION = 'maven-version'; export const INPUT_DEFAULT_GPG_PRIVATE_KEY = undefined; export const INPUT_DEFAULT_GPG_PASSPHRASE = 'GPG_PASSPHRASE'; diff --git a/src/installer.ts b/src/installer.ts index b48eeb0b..292f945d 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -11,12 +11,58 @@ import * as util from './util'; const tempDirectory = util.getTempDir(); const IS_WINDOWS = util.isWindows(); +export async function getMaven(version: string): Promise { + if (semver.valid(version) === null) { + throw new Error( + `wrong version is set(${version}): supported version template: major.minor.patch` + ); + } + const majorVersion = semver.major(version); + let toolPath = tc.find('mvn', version); + + if (toolPath) { + core.debug(`Tool found in cache ${toolPath}`); + } else { + core.debug( + `Downloading Maven from https://downloads.apache.org/maven/maven-${majorVersion}` + ); + + const url = path.join( + `https:///downloads.apache.org/maven/maven-${majorVersion}`, + version, + `binaries/apache-maven-${version}-bin.tar.gz` + ); + + console.log(url); + const mvnTarFile = await tc.downloadTool(url); + + let tempDir: string = path.join( + tempDirectory, + 'temp_' + Math.floor(Math.random() * 2000000000) + ); + await extractFiles(mvnTarFile, '.tar.gz', tempDir); + + core.debug(`maven extracted to ${tempDir}`); + toolPath = await tc.cacheDir( + path.join(tempDir, `apache-maven-${version}`), + 'mvn', + version, + 'x64' + ); + } + + core.exportVariable('MAVEN_HOME', toolPath); + core.addPath(path.join(toolPath, 'bin')); + core.setOutput('path', toolPath); + core.setOutput('version', version); +} + export async function getJava( version: string, arch: string, jdkFile: string, javaPackage: string -): Promise { +): Promise { let toolPath = tc.find(javaPackage, version); if (toolPath) { @@ -83,6 +129,8 @@ export async function getJava( core.addPath(path.join(toolPath, 'bin')); core.setOutput('path', toolPath); core.setOutput('version', version); + + return toolPath; } function getCacheVersionString(version: string) { diff --git a/src/maven.ts b/src/maven.ts index e6b4763b..1cab5dc0 100644 --- a/src/maven.ts +++ b/src/maven.ts @@ -3,6 +3,7 @@ import * as fs from 'fs'; import * as path from 'path'; import * as constants from './constants'; import * as os from 'os'; +import * as exec from '@actions/exec'; import * as io from '@actions/io'; export interface MavenOpts { @@ -11,35 +12,17 @@ export interface MavenOpts { password: string; settings: string; securitySettings: string; -} - -export function validateOptions(opts: MavenOpts): boolean { - if ( - (opts.caCert === '' || - opts.keystore === '' || - opts.password === '' || - opts.securitySettings === '', - opts.settings === '') - ) { - core.debug('maven options set is not valid: some field is empty'); - return false; - } - return true; + javaPath: string; } export function isValidOptions(mvnOpts: MavenOpts): boolean { - if ( - (mvnOpts.caCert !== '' || - mvnOpts.keystore !== '' || - mvnOpts.password !== '' || - mvnOpts.securitySettings !== '', - mvnOpts.settings !== '') && - !validateOptions(mvnOpts) - ) { - return false; - } - - return true; + return ( + mvnOpts.caCert !== '' && + mvnOpts.keystore !== '' && + mvnOpts.password !== '' && + mvnOpts.securitySettings !== '' && + mvnOpts.settings !== '' + ); } export async function setupMaven(opts: MavenOpts): Promise { @@ -47,7 +30,6 @@ export async function setupMaven(opts: MavenOpts): Promise { core.getInput(constants.INPUT_SETTINGS_PATH) || os.homedir(), core.getInput(constants.INPUT_SETTINGS_PATH) ? '' : '.m2' ); - const certDir = path.join(os.homedir(), 'certs'); fs.writeFileSync( path.join(settingsDir, 'settings.xml'), @@ -67,31 +49,41 @@ export async function setupMaven(opts: MavenOpts): Promise { } ); + const certDir = path.join(os.homedir(), 'certs'); + const rooCaPath = path.join(certDir, 'rootca.crt'); await io.mkdirP(certDir); - fs.writeFileSync(path.join(certDir, 'rootca.crt'), btoa(opts.caCert), { + fs.writeFileSync(rooCaPath, btoa(opts.caCert), { encoding: 'utf-8', flag: 'w' }); const p12Path = path.join(certDir, 'certificate.p12'); - fs.writeFileSync(p12Path, btoa(opts.keystore), { - encoding: 'utf-8', - flag: 'w' - }); + fs.writeFileSync(p12Path, Buffer.from(opts.keystore, 'base64')); - const password = btoa(opts.password); core.exportVariable( 'MAVEN_OPTS', - `-Djavax.net.ssl.keyStore=${p12Path} -Djavax.net.ssl.keyStoreType=pkcs12 -Djavax.net.ssl.keyStorePassword=${password}` + `-Djavax.net.ssl.keyStore=${p12Path} -Djavax.net.ssl.keyStoreType=pkcs12 -Djavax.net.ssl.keyStorePassword=${opts.password}` ); + await exec.exec(path.join(opts.javaPath, 'bin/keytool'), [ + '-importcert', + '-cacerts', + '-storepass', + 'changeit', + '-noprompt', + '-alias', + 'mycert', + '-file', + rooCaPath + ]); + core.debug(`added maven opts for MTLS access`); } -const btoa = function(str: string) { +const atob = function(str: string) { return Buffer.from(str, 'binary').toString('base64'); }; -const atob = function(str: string) { +const btoa = function(str: string) { return Buffer.from(str, 'base64').toString('binary'); }; diff --git a/src/setup-java.ts b/src/setup-java.ts index ffdf39ce..082137ab 100644 --- a/src/setup-java.ts +++ b/src/setup-java.ts @@ -13,21 +13,18 @@ async function run() { version = core.getInput(constants.INPUT_JAVA_VERSION, {required: true}); } - const mvnOpts: MavenOpts = { + let mvnOpts: MavenOpts | undefined = { caCert: core.getInput(constants.INPUT_MAVEN_CA_CERT_B64), keystore: core.getInput(constants.INPUT_MAVEN_KEYSTORE_P12_B64), password: core.getInput(constants.INPUT_MAVEN_KEYSTORE_PASSWORD), settings: core.getInput(constants.INPUT_MAVEN_SETTINGS_B64), securitySettings: core.getInput( constants.INPUT_MAVEN_SECURITY_SETTINGS_B64 - ) + ), + javaPath: '' }; - if (!isValidOptions(mvnOpts)) { - throw new Error( - 'Some of the Maven options is empty: please check maven-* parameters' - ); - } + const mvnVersion = core.getInput(constants.INPUT_MAVEN_VERSION); const arch = core.getInput(constants.INPUT_ARCHITECTURE, {required: true}); if (!['x86', 'x64'].includes(arch)) { @@ -39,7 +36,24 @@ async function run() { }); const jdkFile = core.getInput(constants.INPUT_JDK_FILE, {required: false}); - await installer.getJava(version, arch, jdkFile, javaPackage); + const javaPath = await installer.getJava( + version, + arch, + jdkFile, + javaPackage + ); + if (mvnVersion !== '') { + if (!isValidOptions(mvnOpts)) { + throw new Error( + 'Some of the Maven options is empty: please check maven-* parameters' + ); + } + mvnOpts.javaPath = javaPath; + + await installer.getMaven(mvnVersion); + } else { + mvnOpts = undefined; + } const matchersPath = path.join(__dirname, '..', '..', '.github'); core.info(`##[add-matcher]${path.join(matchersPath, 'java.json')}`);