mirror of
https://github.com/stCarolas/setup-maven.git
synced 2025-02-25 17:15:47 +00:00
Implement feature versionSpec using SemVer for setup Maven
This commit is contained in:
parent
c970051976
commit
7a818935c0
1
.gitignore
vendored
1
.gitignore
vendored
@ -16,6 +16,7 @@ lerna-debug.log*
|
||||
|
||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||
report.*.*.*.*.json
|
||||
.scannerwork/
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
|
@ -10,7 +10,7 @@ jobs:
|
||||
- name: Set up Maven
|
||||
uses: stCarolas/setup-maven@v5
|
||||
with:
|
||||
maven-version: 3.8.2
|
||||
maven-version: 3.8
|
||||
```
|
||||
|
||||
### Development using [Docker](https://docs.docker.com/)
|
||||
@ -41,5 +41,5 @@ Run `SonarScanner` from [the Docker image](https://hub.docker.com/r/sonarsource/
|
||||
```batch
|
||||
docker run --rm -it --link docker-sonarqube -v "%PWD%:/usr/src/app" -w /usr/src/app ^
|
||||
-e "SONAR_HOST_URL=http://docker-sonarqube:9000" -e "SONAR_LOGIN=<projectToken>" sonarsource/sonar-scanner-cli ^
|
||||
-Dsonar.projectKey=setup-maven -Dsonar.language=js -Dsonar.sources=. "-Dsonar.exclusions=dist/**"
|
||||
-Dsonar.projectKey=setup-maven -Dsonar.sources=. "-Dsonar.exclusions=dist/**,lib/**"
|
||||
```
|
||||
|
@ -1,5 +1,10 @@
|
||||
describe('maven installer tests', () => {
|
||||
it('square root of 4 to equal 2', () => {
|
||||
expect(Math.sqrt(4)).toBe(2);
|
||||
import * as installer from '../src/installer';
|
||||
|
||||
describe('getAvailableVersions', () => {
|
||||
it('load real available versions', async () => {
|
||||
const availableVersions = await installer.getAvailableVersions();
|
||||
|
||||
expect(availableVersions).toBeTruthy();
|
||||
expect(availableVersions).toEqual(expect.arrayContaining(['3.2.5', '3.3.3', '3.8.2']));
|
||||
});
|
||||
});
|
||||
|
@ -5,7 +5,10 @@ inputs:
|
||||
maven-version:
|
||||
description: 'Version Spec of the version to use. Examples: 3.x, 3.1.1, >=3.8.0'
|
||||
required: false
|
||||
default: '3.8.2'
|
||||
default: '3'
|
||||
outputs:
|
||||
version:
|
||||
description: 'Actual version of Apache Maven that has been installed'
|
||||
runs:
|
||||
using: 'node16'
|
||||
main: 'dist/index.js'
|
||||
|
197
dist/index.js
generated
vendored
197
dist/index.js
generated
vendored
@ -4965,37 +4965,81 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||
});
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
exports.getMaven = void 0;
|
||||
exports.findVersionForDownload = exports.downloadMaven = exports.getAvailableVersions = exports.setupMaven = void 0;
|
||||
const path = __importStar(__nccwpck_require__(17));
|
||||
const core = __importStar(__nccwpck_require__(186));
|
||||
const tc = __importStar(__nccwpck_require__(784));
|
||||
const path = __importStar(__nccwpck_require__(17));
|
||||
function getMaven(version) {
|
||||
const http_client_1 = __nccwpck_require__(925);
|
||||
const semver = __importStar(__nccwpck_require__(911));
|
||||
const utils_1 = __nccwpck_require__(314);
|
||||
function setupMaven(versionSpec, installedVersion) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let toolPath = tc.find('maven', version);
|
||||
if (!toolPath) {
|
||||
toolPath = yield downloadMaven(version);
|
||||
let toolPath = tc.find('maven', versionSpec);
|
||||
let resolvedVersion = utils_1.getVersionFromToolcachePath(toolPath);
|
||||
if (installedVersion) {
|
||||
if (!toolPath || semver.gte(installedVersion, resolvedVersion)) {
|
||||
core.info(`Use system Maven version ${installedVersion} instead of the cached one: ${resolvedVersion}`);
|
||||
return installedVersion;
|
||||
}
|
||||
}
|
||||
else if (!toolPath) {
|
||||
resolvedVersion = yield findVersionForDownload(versionSpec);
|
||||
toolPath = yield downloadMaven(resolvedVersion);
|
||||
}
|
||||
core.addPath(path.join(toolPath, 'bin'));
|
||||
return resolvedVersion;
|
||||
});
|
||||
}
|
||||
exports.getMaven = getMaven;
|
||||
exports.setupMaven = setupMaven;
|
||||
const DOWNLOAD_BASE_URL = 'https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven';
|
||||
function downloadMaven(version) {
|
||||
function getAvailableVersions() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const toolDirectoryName = `apache-maven-${version}`;
|
||||
const downloadUrl = `${DOWNLOAD_BASE_URL}/${version}/${toolDirectoryName}-bin.tar.gz`;
|
||||
core.info(`Downloading Maven ${version} from ${downloadUrl} ...`);
|
||||
const resourceUrl = `${DOWNLOAD_BASE_URL}/maven-metadata.xml`;
|
||||
const http = new http_client_1.HttpClient('setup-maven', undefined, { allowRetries: true });
|
||||
core.info(`Downloading Maven versions manifest from ${resourceUrl} ...`);
|
||||
const response = yield http.get(resourceUrl);
|
||||
const body = yield response.readBody();
|
||||
if (response.message.statusCode !== http_client_1.HttpCodes.OK || !body) {
|
||||
throw new Error(`Unable to get available versions from ${resourceUrl}`);
|
||||
}
|
||||
const availableVersions = body.match(/(?<=<version>)[^<>]+(?=<\/version>)/g) || [];
|
||||
core.debug(`Available Maven versions: [${availableVersions}]`);
|
||||
return availableVersions;
|
||||
});
|
||||
}
|
||||
exports.getAvailableVersions = getAvailableVersions;
|
||||
/**
|
||||
* Download and extract a specified Maven version to the tool-cache.
|
||||
*/
|
||||
function downloadMaven(fullVersion) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const toolDirectoryName = `apache-maven-${fullVersion}`;
|
||||
const downloadUrl = `${DOWNLOAD_BASE_URL}/${fullVersion}/${toolDirectoryName}-bin.tar.gz`;
|
||||
core.info(`Downloading Maven ${fullVersion} from ${downloadUrl} ...`);
|
||||
const downloadPath = yield tc.downloadTool(downloadUrl);
|
||||
const extractedPath = yield tc.extractTar(downloadPath);
|
||||
const toolRoot = path.join(extractedPath, toolDirectoryName);
|
||||
return tc.cacheDir(toolRoot, 'maven', version);
|
||||
return tc.cacheDir(toolRoot, 'maven', fullVersion);
|
||||
});
|
||||
}
|
||||
exports.downloadMaven = downloadMaven;
|
||||
function findVersionForDownload(versionSpec) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const availableVersions = yield getAvailableVersions();
|
||||
const resolvedVersion = semver.maxSatisfying(availableVersions, versionSpec);
|
||||
if (!resolvedVersion) {
|
||||
throw new Error(`Could not find satisfied version for SemVer ${versionSpec}`);
|
||||
}
|
||||
core.debug(`Resolved version for download: ${resolvedVersion}`);
|
||||
return resolvedVersion;
|
||||
});
|
||||
}
|
||||
exports.findVersionForDownload = findVersionForDownload;
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 587:
|
||||
/***/ 399:
|
||||
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
|
||||
|
||||
"use strict";
|
||||
@ -5029,23 +5073,115 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||
});
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
exports.run = void 0;
|
||||
const core = __importStar(__nccwpck_require__(186));
|
||||
const installer = __importStar(__nccwpck_require__(574));
|
||||
const semver = __importStar(__nccwpck_require__(911));
|
||||
const utils_1 = __nccwpck_require__(314);
|
||||
const installer_1 = __nccwpck_require__(574);
|
||||
function run() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
try {
|
||||
const version = core.getInput('maven-version');
|
||||
if (version) {
|
||||
yield installer.getMaven(version);
|
||||
const versionSpec = core.getInput('maven-version') || '3';
|
||||
if (!semver.validRange(versionSpec)) {
|
||||
core.setFailed(`Invalid SemVer notation '${versionSpec}' for a Maven version`);
|
||||
return;
|
||||
}
|
||||
let installedVersion = yield utils_1.getActiveMavenVersion();
|
||||
if (installedVersion && !semver.satisfies(installedVersion, versionSpec)) {
|
||||
installedVersion = undefined;
|
||||
}
|
||||
installedVersion = yield installer_1.setupMaven(versionSpec, installedVersion);
|
||||
core.setOutput('version', installedVersion);
|
||||
}
|
||||
catch (error) {
|
||||
core.setFailed(error.message);
|
||||
core.setFailed(error.toString());
|
||||
}
|
||||
});
|
||||
}
|
||||
// noinspection JSIgnoredPromiseFromCall
|
||||
run();
|
||||
exports.run = run;
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ 314:
|
||||
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
exports.getExecOutput = exports.getActiveMavenVersion = exports.getVersionFromToolcachePath = void 0;
|
||||
const path = __importStar(__nccwpck_require__(17));
|
||||
const core = __importStar(__nccwpck_require__(186));
|
||||
const exec = __importStar(__nccwpck_require__(514));
|
||||
function getVersionFromToolcachePath(toolPath) {
|
||||
return !toolPath ? toolPath : path.basename(path.dirname(toolPath));
|
||||
}
|
||||
exports.getVersionFromToolcachePath = getVersionFromToolcachePath;
|
||||
/**
|
||||
* Determine version of the current used Maven.
|
||||
*/
|
||||
function getActiveMavenVersion() {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
try {
|
||||
const { output } = yield getExecOutput('mvn', ['-v']);
|
||||
const found = output.match(/^[^\d]*(\S+)/);
|
||||
const installedVersion = !found ? '' : found[1];
|
||||
core.debug(`Retrieved activated Maven version: ${installedVersion}`);
|
||||
return installedVersion;
|
||||
}
|
||||
catch (error) {
|
||||
core.info(`Failed to get activated Maven version. ${error}`);
|
||||
}
|
||||
return undefined;
|
||||
});
|
||||
}
|
||||
exports.getActiveMavenVersion = getActiveMavenVersion;
|
||||
/**
|
||||
* Exec a command and get the standard output.
|
||||
*
|
||||
* @throws {Error} If the exit-code is non-zero.
|
||||
*/
|
||||
function getExecOutput(command, args) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
let output = '';
|
||||
const exitCode = yield exec.exec(command, args, {
|
||||
silent: true,
|
||||
listeners: {
|
||||
stdout: (data) => (output += data.toString())
|
||||
}
|
||||
});
|
||||
return { exitCode, output };
|
||||
});
|
||||
}
|
||||
exports.getExecOutput = getExecOutput;
|
||||
|
||||
|
||||
/***/ }),
|
||||
@ -5192,12 +5328,19 @@ module.exports = require("util");
|
||||
/******/ if (typeof __nccwpck_require__ !== 'undefined') __nccwpck_require__.ab = __dirname + "/";
|
||||
/******/
|
||||
/************************************************************************/
|
||||
/******/
|
||||
/******/ // startup
|
||||
/******/ // Load entry module and return exports
|
||||
/******/ // This entry module is referenced by other modules so it can't be inlined
|
||||
/******/ var __webpack_exports__ = __nccwpck_require__(587);
|
||||
/******/ module.exports = __webpack_exports__;
|
||||
/******/
|
||||
var __webpack_exports__ = {};
|
||||
// This entry need to be wrapped in an IIFE because it need to be in strict mode.
|
||||
(() => {
|
||||
"use strict";
|
||||
var exports = __webpack_exports__;
|
||||
|
||||
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
||||
const main_1 = __nccwpck_require__(399);
|
||||
// noinspection JSIgnoredPromiseFromCall
|
||||
main_1.run();
|
||||
|
||||
})();
|
||||
|
||||
module.exports = __webpack_exports__;
|
||||
/******/ })()
|
||||
;
|
@ -38,9 +38,10 @@
|
||||
"typescript": "^4.2.3"
|
||||
},
|
||||
"prettier": {
|
||||
"printWidth": 100,
|
||||
"semi": true,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "none",
|
||||
"bracketSpacing": true,
|
||||
"arrowParens": "avoid"
|
||||
},
|
||||
"jest": {
|
||||
|
@ -1,29 +1,77 @@
|
||||
import * as path from 'path';
|
||||
import * as core from '@actions/core';
|
||||
import * as tc from '@actions/tool-cache';
|
||||
import { HttpClient, HttpCodes } from '@actions/http-client';
|
||||
import * as semver from 'semver';
|
||||
|
||||
import * as path from 'path';
|
||||
import { getVersionFromToolcachePath } from './utils';
|
||||
|
||||
export async function getMaven(version: string) {
|
||||
let toolPath = tc.find('maven', version);
|
||||
export async function setupMaven(versionSpec: string, installedVersion?: string): Promise<string> {
|
||||
let toolPath = tc.find('maven', versionSpec);
|
||||
let resolvedVersion = getVersionFromToolcachePath(toolPath);
|
||||
|
||||
if (!toolPath) {
|
||||
toolPath = await downloadMaven(version);
|
||||
if (installedVersion) {
|
||||
if (!toolPath || semver.gte(installedVersion, resolvedVersion)) {
|
||||
core.info(
|
||||
`Use system Maven version ${installedVersion} instead of the cached one: ${resolvedVersion}`
|
||||
);
|
||||
|
||||
return installedVersion;
|
||||
}
|
||||
} else if (!toolPath) {
|
||||
resolvedVersion = await findVersionForDownload(versionSpec);
|
||||
|
||||
toolPath = await downloadMaven(resolvedVersion);
|
||||
}
|
||||
|
||||
core.addPath(path.join(toolPath, 'bin'));
|
||||
return resolvedVersion;
|
||||
}
|
||||
|
||||
const DOWNLOAD_BASE_URL = 'https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven';
|
||||
|
||||
async function downloadMaven(version: string): Promise<string> {
|
||||
const toolDirectoryName = `apache-maven-${version}`;
|
||||
const downloadUrl = `${DOWNLOAD_BASE_URL}/${version}/${toolDirectoryName}-bin.tar.gz`;
|
||||
export async function getAvailableVersions(): Promise<string[]> {
|
||||
const resourceUrl = `${DOWNLOAD_BASE_URL}/maven-metadata.xml`;
|
||||
const http = new HttpClient('setup-maven', undefined, { allowRetries: true });
|
||||
|
||||
core.info(`Downloading Maven ${version} from ${downloadUrl} ...`);
|
||||
core.info(`Downloading Maven versions manifest from ${resourceUrl} ...`);
|
||||
const response = await http.get(resourceUrl);
|
||||
const body = await response.readBody();
|
||||
|
||||
if (response.message.statusCode !== HttpCodes.OK || !body) {
|
||||
throw new Error(`Unable to get available versions from ${resourceUrl}`);
|
||||
}
|
||||
|
||||
const availableVersions = body.match(/(?<=<version>)[^<>]+(?=<\/version>)/g) || [];
|
||||
core.debug(`Available Maven versions: [${availableVersions}]`);
|
||||
|
||||
return availableVersions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Download and extract a specified Maven version to the tool-cache.
|
||||
*/
|
||||
export async function downloadMaven(fullVersion: string): Promise<string> {
|
||||
const toolDirectoryName = `apache-maven-${fullVersion}`;
|
||||
const downloadUrl = `${DOWNLOAD_BASE_URL}/${fullVersion}/${toolDirectoryName}-bin.tar.gz`;
|
||||
|
||||
core.info(`Downloading Maven ${fullVersion} from ${downloadUrl} ...`);
|
||||
const downloadPath = await tc.downloadTool(downloadUrl);
|
||||
|
||||
const extractedPath = await tc.extractTar(downloadPath);
|
||||
|
||||
const toolRoot = path.join(extractedPath, toolDirectoryName);
|
||||
return tc.cacheDir(toolRoot, 'maven', version);
|
||||
return tc.cacheDir(toolRoot, 'maven', fullVersion);
|
||||
}
|
||||
|
||||
export async function findVersionForDownload(versionSpec: string): Promise<string> {
|
||||
const availableVersions = await getAvailableVersions();
|
||||
|
||||
const resolvedVersion = semver.maxSatisfying(availableVersions, versionSpec);
|
||||
if (!resolvedVersion) {
|
||||
throw new Error(`Could not find satisfied version for SemVer ${versionSpec}`);
|
||||
}
|
||||
|
||||
core.debug(`Resolved version for download: ${resolvedVersion}`);
|
||||
return resolvedVersion;
|
||||
}
|
||||
|
26
src/main.ts
Normal file
26
src/main.ts
Normal file
@ -0,0 +1,26 @@
|
||||
import * as core from '@actions/core';
|
||||
import * as semver from 'semver';
|
||||
|
||||
import { getActiveMavenVersion } from './utils';
|
||||
import { setupMaven } from './installer';
|
||||
|
||||
export async function run() {
|
||||
try {
|
||||
const versionSpec = core.getInput('maven-version') || '3';
|
||||
|
||||
if (!semver.validRange(versionSpec)) {
|
||||
core.setFailed(`Invalid SemVer notation '${versionSpec}' for a Maven version`);
|
||||
return;
|
||||
}
|
||||
|
||||
let installedVersion = await getActiveMavenVersion();
|
||||
if (installedVersion && !semver.satisfies(installedVersion, versionSpec)) {
|
||||
installedVersion = undefined;
|
||||
}
|
||||
|
||||
installedVersion = await setupMaven(versionSpec, installedVersion);
|
||||
core.setOutput('version', installedVersion);
|
||||
} catch (error) {
|
||||
core.setFailed(error.toString());
|
||||
}
|
||||
}
|
@ -1,17 +1,4 @@
|
||||
import * as core from '@actions/core';
|
||||
|
||||
import * as installer from './installer';
|
||||
|
||||
async function run() {
|
||||
try {
|
||||
const version = core.getInput('maven-version');
|
||||
if (version) {
|
||||
await installer.getMaven(version);
|
||||
}
|
||||
} catch (error) {
|
||||
core.setFailed(error.message);
|
||||
}
|
||||
}
|
||||
import { run } from './main';
|
||||
|
||||
// noinspection JSIgnoredPromiseFromCall
|
||||
run();
|
||||
|
47
src/utils.ts
Normal file
47
src/utils.ts
Normal file
@ -0,0 +1,47 @@
|
||||
import * as path from 'path';
|
||||
import * as core from '@actions/core';
|
||||
import * as exec from '@actions/exec';
|
||||
|
||||
export function getVersionFromToolcachePath(toolPath: string) {
|
||||
return !toolPath ? toolPath : path.basename(path.dirname(toolPath));
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine version of the current used Maven.
|
||||
*/
|
||||
export async function getActiveMavenVersion(): Promise<string | undefined> {
|
||||
try {
|
||||
const { output } = await getExecOutput('mvn', ['-v']);
|
||||
|
||||
const found = output.match(/^[^\d]*(\S+)/);
|
||||
const installedVersion = !found ? '' : found[1];
|
||||
core.debug(`Retrieved activated Maven version: ${installedVersion}`);
|
||||
|
||||
return installedVersion;
|
||||
} catch (error) {
|
||||
core.info(`Failed to get activated Maven version. ${error}`);
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Exec a command and get the standard output.
|
||||
*
|
||||
* @throws {Error} If the exit-code is non-zero.
|
||||
*/
|
||||
export async function getExecOutput(
|
||||
command: string,
|
||||
args?: string[]
|
||||
): Promise<{ exitCode: number; output: string }> {
|
||||
let output = '';
|
||||
|
||||
const exitCode = await exec.exec(command, args, {
|
||||
silent: true,
|
||||
listeners: {
|
||||
stdout: (data: Buffer) => (output += data.toString())
|
||||
}
|
||||
});
|
||||
|
||||
return { exitCode, output };
|
||||
}
|
Loading…
Reference in New Issue
Block a user