UNPKG

@atomist/sdm

Version:

Atomist Software Delivery Machine SDK

133 lines 5.66 kB
"use strict"; /* * Copyright © 2020 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. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.K8sSync = exports.syncGoals = exports.isSyncRepoCommit = void 0; const child_process_1 = require("@atomist/automation-client/lib/util/child_process"); const logger_1 = require("@atomist/automation-client/lib/util/logger"); const stringify = require("json-stringify-safe"); const _ = require("lodash"); const minimalClone_1 = require("../../../api-helper/goal/minimalClone"); const logInterpreters_1 = require("../../../api-helper/log/logInterpreters"); const goalDsl_1 = require("../../../api/dsl/goalDsl"); const Goals_1 = require("../../../api/goal/Goals"); const GoalWithFulfillment_1 = require("../../../api/goal/GoalWithFulfillment"); const environment_1 = require("../../../api/goal/support/environment"); const PushTest_1 = require("../../../api/mapping/PushTest"); const modes_1 = require("../../../core/machine/modes"); const error_1 = require("../support/error"); const change_1 = require("./change"); const diff_1 = require("./diff"); const repo_1 = require("./repo"); const tag_1 = require("./tag"); function isSyncRepoCommit(sdm) { const syncOptions = _.get(sdm, "configuration.sdm.k8s.options.sync"); if (!syncOptions || !syncOptions.repo) { logger_1.logger.debug(`SDM configuration contains no sync repo, will not create sync repo push test`); return undefined; } return PushTest_1.pushTest("IsSyncRepoCommit", async (p) => { const repo = _.get(sdm, "configuration.sdm.k8s.options.sync.repo"); if (!repo_1.isRemoteRepo(repo) && !modes_1.isInLocalMode()) { throw new Error(`SyncRepoRef did not get converted to proper RemoteRepoRef at startup: ${stringify(repo)}`); } if (modes_1.isInLocalMode() || (p.id.providerType === repo.providerType) && p.id.owner === repo.owner && p.id.repo === repo.repo && p.id.branch === repo.branch) { const tag = tag_1.commitTag(sdm.configuration); return p.push.commits.some(c => !c.message.includes(tag)); } return false; }); } exports.isSyncRepoCommit = isSyncRepoCommit; /** * Add goals for pushes on the sync repo. */ function syncGoals(sdm) { const syncRepoPushTest = isSyncRepoCommit(sdm); if (!syncRepoPushTest) { logger_1.logger.debug(`No sync repo push test, not adding sync repo goals`); return sdm; } const sync = new GoalWithFulfillment_1.GoalWithFulfillment({ uniqueName: "sync", environment: environment_1.IndependentOfEnvironment, displayName: "sync", workingDescription: "Syncing", completedDescription: "Synced", failedDescription: "Sync failed", isolated: true, }).with({ name: "K8sSyncRepo", goalExecutor: exports.K8sSync, logInterpreter: logInterpreters_1.LogSuppressor, }); const syncGoalSet = Goals_1.goals("Sync Kubernetes Resources").plan(sync); sdm.addGoalContributions(goalDsl_1.whenPushSatisfies(syncRepoPushTest).setGoals(syncGoalSet)); return sdm; } exports.syncGoals = syncGoals; /** * Create resources of added specs, update resources of changed specs, * and remove resources of deleted specs. */ const K8sSync = async (gi) => { const push = gi.goalEvent.push; const log = gi.progressLog; const params = { cloneOptions: minimalClone_1.minimalClone(push), context: gi.context, credentials: gi.credentials, id: gi.id, log, readOnly: true, }; const tag = tag_1.commitTag(gi.configuration); return gi.configuration.sdm.projectLoader.doWithProject(params, async (p) => { if (params.cloneOptions.depth > 1) { // work around https://github.com/atomist/sdm/issues/729 try { await child_process_1.execPromise("git", ["fetch", `--depth=${params.cloneOptions.depth}`], { cwd: p.baseDir }); } catch (e) { logger_1.logger.warn(`Failed to undo shallow clone, proceeding anyway: ${e.message}`); } } const changes = await diff_1.diffPush(p, push, tag, log); const errs = []; for (const change of changes) { const verb = (change.change === "delete") ? "Deleting" : "Applying"; log.write(`${verb} '${change.path}' from commit ${change.sha}`); try { await change_1.changeResource(p, change); } catch (e) { e.message = `Failed to ${change.change} '${change.path}' resource for commit ${change.sha}: ${error_1.k8sErrMsg(e)}`; log.write(e.message); errs.push(e); } } if (errs.length > 0) { return { code: errs.length, message: errs.map(e => e.message).join("; ") }; } const message = `Changed ${changes.length} resources`; log.write(message); return { code: 0, message }; }); }; exports.K8sSync = K8sSync; //# sourceMappingURL=goals.js.map