UNPKG

@atomist/sdm-pack-spring

Version:

Atomist software delivery machine extension pack for Spring and Spring Boot applications

193 lines 8.31 kB
"use strict"; /* * Copyright © 2019 Atomist, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ 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 }); const automation_client_1 = require("@atomist/automation-client"); const sdm_1 = require("@atomist/sdm"); const sdm_core_1 = require("@atomist/sdm-core"); const spawn = require("cross-spawn"); const helpers_1 = require("../build/helpers"); const mavenCommand_1 = require("../mavenCommand"); /** * Use Maven to deploy * @param projectLoader use to load projects * @param opts options */ function mavenDeployer(projectLoader, opts) { if (!exports.managedMavenDeployments) { automation_client_1.logger.debug("Created new deployments record"); exports.managedMavenDeployments = new sdm_core_1.ManagedDeployments(opts.lowerPort); } return new MavenSourceDeployer(projectLoader, Object.assign(Object.assign({}, sdm_core_1.DefaultLocalDeployerOptions), opts)); } exports.mavenDeployer = mavenDeployer; /** * Source deployer that uses Maven target */ class MavenSourceDeployer { constructor(projectLoader, opts) { this.projectLoader = projectLoader; this.opts = opts; } findDeployments(id, ti, creds) { return __awaiter(this, void 0, void 0, function* () { const deployedApp = exports.managedMavenDeployments.findDeployment(ti.managedDeploymentKey, this.opts.lookupStrategy || sdm_core_1.LookupStrategy.branch); if (!deployedApp) { return []; } return [deployedApp.deployment]; }); } deploy(da, ti, log, credentials, team) { return __awaiter(this, void 0, void 0, function* () { const id = da.id; if (!id.branch) { throw new Error(`Cannot locally deploy ${JSON.stringify(id)}: Branch must be set`); } const port = yield exports.managedMavenDeployments.findPort(ti.managedDeploymentKey, sdm_core_1.LookupStrategy.branch, this.opts.baseUrl); automation_client_1.logger.info("MavenSourceDeployer: Deploying app [%j],branch=%s on port [%d] for team %s", id, ti.managedDeploymentKey.branch, port, team); yield exports.managedMavenDeployments.terminateIfRunning(ti.managedDeploymentKey, sdm_core_1.LookupStrategy.branch); return [yield this.projectLoader.doWithProject({ credentials, id, readOnly: true }, project => this.deployProject(ti, log, project, port, team))]; }); } undeploy(ti, deployment, log) { return __awaiter(this, void 0, void 0, function* () { yield exports.managedMavenDeployments.terminateIfRunning(ti.managedDeploymentKey, sdm_core_1.LookupStrategy.branch); return; }); } logInterpreter(log) { return springBootRunLogInterpreter(log) || shortLogInterpreter(log); } deployProject(ti, log, project, port, atomistTeam) { return __awaiter(this, void 0, void 0, function* () { const branchId = ti.managedDeploymentKey; const startupInfo = { port, atomistTeam, contextRoot: `/${branchId.owner}/${branchId.repo}/${branchId.branch}`, }; const mvn = yield mavenCommand_1.determineMavenCommand(project); const childProcess = spawn(mvn, [ "spring-boot:run", ...helpers_1.MavenOptions, ].concat(this.opts.commandLineArgumentsFor(startupInfo)), { cwd: project.baseDir, }); if (!childProcess.pid) { throw new Error("Fatal error deploying using Maven--is `mvn` on your automation node path?\n" + `Attempted to execute '${mvn} spring-boot:run' in ${project.baseDir}`); } const deployment = { childProcess, endpoint: `${this.opts.baseUrl}:${port}/${startupInfo.contextRoot}`, }; exports.managedMavenDeployments.recordDeployment({ id: branchId, port, childProcess, deployment, lookupStrategy: sdm_core_1.LookupStrategy.branch, }); const newLineDelimitedLog = new sdm_1.DelimitedWriteProgressLogDecorator(log, "\n"); childProcess.stdout.on("data", what => newLineDelimitedLog.write(what.toString())); childProcess.stderr.on("data", what => newLineDelimitedLog.write(what.toString())); return new Promise((resolve, reject) => { childProcess.stdout.addListener("data", what => { if (!!what && this.opts.successPatterns.some(successPattern => successPattern.test(what.toString()))) { resolve(deployment); } }); childProcess.addListener("exit", () => { reject(new Error("We should have found success message pattern by now!!")); }); childProcess.addListener("error", reject); }); }); } } const shortLogInterpreter = (log) => { if (log.length < 200) { return { relevantPart: log, message: "This is the whole log.", includeFullLog: false, }; } return undefined; }; const springBootRunLogInterpreter = (log) => { automation_client_1.logger.debug("Interpreting log"); if (!log) { automation_client_1.logger.warn("log was empty"); return undefined; } const maybeFailedToStart = appFailedToStart(log); if (maybeFailedToStart) { return { relevantPart: maybeFailedToStart, message: "Application failed to start", includeFullLog: false, }; } // default to maven errors const maybeMavenErrors = mavenErrors(log); if (maybeMavenErrors) { automation_client_1.logger.info("recognized maven error"); return { relevantPart: maybeMavenErrors, message: "Maven errors", }; } // or it could be this problem here if (log.match(/Error checking out artifact/)) { automation_client_1.logger.info("Recognized artifact error"); return { relevantPart: log, message: "I lost the local cache. Please rebuild", includeFullLog: false, }; } automation_client_1.logger.info("Did not find anything to recognize in the log"); return undefined; }; function appFailedToStart(log) { const lines = log.split("\n"); const failedToStartLine = lines.indexOf("APPLICATION FAILED TO START"); if (failedToStartLine < 1) { return undefined; } const likelyLines = lines.slice(failedToStartLine + 3, failedToStartLine + 10); return likelyLines.join("\n"); } function mavenErrors(log) { if (log.match(/^\[ERROR]/m)) { return log.split("\n") .filter(l => l.startsWith("[ERROR]")) .join("\n"); } return undefined; } //# sourceMappingURL=mavenDeployer.js.map