@atomist/sdm-pack-fingerprints
Version:
an Atomist SDM Extension Pack for fingerprinting code
176 lines (173 loc) • 8.24 kB
JavaScript
;
/*
* 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) {
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());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const automation_client_1 = require("@atomist/automation-client");
const clj_editors_1 = require("@atomist/clj-editors");
const sdm_1 = require("@atomist/sdm");
const slack_messages_1 = require("@atomist/slack-messages");
const _ = require("lodash");
const fingerprints_1 = require("../../adhoc/fingerprints");
const preferences_1 = require("../../adhoc/preferences");
const Aspects_1 = require("../../machine/Aspects");
const messages_1 = require("../../support/messages");
const applyFingerprint_1 = require("./applyFingerprint");
function askAboutBroadcast(cli, aspects, fp, msgId) {
const author = _.get(cli.context.source, "slack.user.id") || _.get(cli.context.source, "web.identity.sub");
const aspect = Aspects_1.aspectOf(fp, aspects);
let details;
if (!!aspect && !!aspect.toDisplayableFingerprintName) {
details = `${slack_messages_1.italic(aspect.displayName)}
${slack_messages_1.codeBlock(`${aspect.toDisplayableFingerprintName(fp.name)} (${Aspects_1.displayValue(aspect, fp)})`)}`;
}
else {
details = slack_messages_1.codeLine(fp.name);
}
const id = msgId || automation_client_1.guid();
const message = sdm_1.slackQuestionMessage("Broadcast Policy", `Shall we send every affected repository a nudge or pull request for the new policy?
${details}`, {
actions: [
sdm_1.actionableButton({
text: "Broadcast Nudge",
}, BroadcastFingerprintNudgeName, {
author,
msgId,
sha: fp.sha,
fingerprint: preferences_1.toName(fp.type, fp.name),
}),
automation_client_1.buttonForCommand({
text: "Broadcast PRs",
}, applyFingerprint_1.BroadcastFingerprintMandateName, {
title: messages_1.applyFingerprintTitle(fp, aspects),
body: messages_1.prBodyFromFingerprint(fp, aspects),
branch: "master",
fingerprint: preferences_1.toName(fp.type, fp.name),
msgId: id,
}),
],
});
// always create a new message
return cli.addressChannels(message, { id });
}
exports.askAboutBroadcast = askAboutBroadcast;
function targetUpdateMessage(cli, aspects, type, name) {
const aspect = Aspects_1.aspectOf({ type }, aspects);
let details;
if (!!aspect && !!aspect.toDisplayableFingerprintName) {
details = `${slack_messages_1.italic(aspect.displayName)} ${slack_messages_1.codeLine(aspect.toDisplayableFingerprintName(name))}`;
}
else {
details = slack_messages_1.codeLine(preferences_1.toName(type, name));
}
return `${slack_messages_1.user(cli.parameters.author)} has updated the policy of ${details}.
The reason provided is:
${slack_messages_1.italic(cli.parameters.reason)}`;
}
/**
* send messages to all channels with Repos that might be impacted by this target change
*
* @param cli
*/
function broadcastNudge(aspects) {
return (cli) => __awaiter(this, void 0, void 0, function* () {
const msgId = `broadcastNudge-${cli.parameters.name}-${cli.parameters.sha}`;
return clj_editors_1.broadcastFingerprint((type, name) => __awaiter(this, void 0, void 0, function* () {
const data = yield (fingerprints_1.findTaggedRepos(cli.context.graphClient))(type, name);
automation_client_1.logger.info(`findTaggedRepos(broadcastNudge) ${JSON.stringify(data.headCommitsWithFingerprint)}`);
return data.headCommitsWithFingerprint
.filter(head => !!head.branch && !!head.branch.name && head.branch.name === "master")
.map(x => {
return {
name: x.repo.name,
owner: x.repo.owner,
channels: x.repo.channels,
branches: [{
commit: Object.assign({}, x.commit, { analysis: x.analysis }),
}],
};
});
}), Object.assign({}, preferences_1.fromName(cli.parameters.fingerprint), { sha: cli.parameters.sha }), (owner, repo, channel) => {
const { type, name } = preferences_1.fromName(cli.parameters.fingerprint);
const message = sdm_1.slackWarningMessage("Policy Update", targetUpdateMessage(cli, aspects, type, name), cli.context);
const aspect = Aspects_1.aspectOf({ type }, aspects);
let details;
if (!!aspect && !!aspect.toDisplayableFingerprintName) {
details = `${slack_messages_1.italic(aspect.displayName)} ${slack_messages_1.codeLine(aspect.toDisplayableFingerprintName(name))}`;
}
else {
details = slack_messages_1.codeLine(preferences_1.toName(type, name));
}
message.attachments.push({
text: `Shall we update repository ${slack_messages_1.bold(`${owner}/${repo}`)} to the new policy for ${details}?`,
fallback: `Policy Update`,
actions: [
automation_client_1.buttonForCommand({
text: "Update",
}, applyFingerprint_1.ApplyTargetFingerprintName, {
msgId,
targetfingerprint: cli.parameters.fingerprint,
title: messages_1.applyFingerprintTitle({ name }, aspects),
body: cli.parameters.reason,
}),
],
callback_id: "atm-confirm-done",
});
// each channel with a repo containing this fingerprint gets a message
// use the msgId passed in so all the msgIds across the different channels are the same
return cli.context.messageClient.addressChannels(message, channel, { id: msgId });
});
});
}
const BroadcastFingerprintNudgeName = "BroadcastFingerprintNudge";
function broadcastFingerprintNudge(aspects) {
return {
name: BroadcastFingerprintNudgeName,
description: "message all Channels linked to Repos that contain a particular fingerprint",
parameters: {
fingerprint: { required: true },
sha: {
required: true,
description: "sha of fingerprint to broadcast",
},
reason: {
required: true,
control: "textarea",
pattern: /[\s\S]*/,
description: "always give a reason why we're releasing the nudge",
},
author: {
required: true,
description: "author of the Nudge",
},
msgId: {
required: false,
displayable: false,
},
},
listener: broadcastNudge(aspects),
autoSubmit: true,
};
}
exports.broadcastFingerprintNudge = broadcastFingerprintNudge;
//# sourceMappingURL=broadcast.js.map