@atomist/atomist-sdm
Version:
Atomist SDM to deliver our own projects
289 lines • 17.2 kB
JavaScript
"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) {
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 sdm_1 = require("@atomist/sdm");
const sdm_core_1 = require("@atomist/sdm-core");
const sdm_pack_build_1 = require("@atomist/sdm-pack-build");
const changelog_1 = require("@atomist/sdm-pack-changelog/lib/changelog");
const sdm_pack_docker_1 = require("@atomist/sdm-pack-docker");
const sdm_pack_issue_1 = require("@atomist/sdm-pack-issue");
const sdm_pack_node_1 = require("@atomist/sdm-pack-node");
const sdm_pack_s3_1 = require("@atomist/sdm-pack-s3");
const sdm_pack_spring_1 = require("@atomist/sdm-pack-spring");
const configurationTests_1 = require("@atomist/sdm/lib/api-helper/pushtest/configuration/configurationTests");
const slack_messages_1 = require("@atomist/slack-messages");
const approval_1 = require("../command/approval");
const badge_1 = require("../command/badge");
const changelog_2 = require("../command/changelog");
const tag_1 = require("../command/tag");
const identityPushTests_1 = require("../support/identityPushTests");
const materialChangeToNodeRepo_1 = require("../support/materialChangeToNodeRepo");
const dockerSupport_1 = require("./dockerSupport");
const githubSupport_1 = require("./githubSupport");
const goals_1 = require("./goals");
const goSupport_1 = require("./goSupport");
const homebrewSupport_1 = require("./homebrewSupport");
const k8sSupport_1 = require("./k8sSupport");
const mavenSupport_1 = require("./mavenSupport");
const nodeSupport_1 = require("./nodeSupport");
const release_1 = require("./release");
const teamPolicies_1 = require("./teamPolicies");
const version_1 = require("./version");
const webSupport_1 = require("./webSupport");
const AtomistHQWorkspace = "T095SFFBK";
const AtomistCustomerWorkspace = "A62C8F8L8";
function machine(configuration) {
goals_1.stagingDeploy.with(k8sSupport_1.kubernetesDeployRegistrationProd);
goals_1.productionDeploy.with(k8sSupport_1.kubernetesDeployRegistrationProd);
goals_1.productionDeployWithApproval.with(k8sSupport_1.kubernetesDeployRegistrationProd);
goals_1.globalStagingDeploy.with(k8sSupport_1.kubernetesDeployRegistrationGlobal);
goals_1.globalProductionDeploy.with(k8sSupport_1.kubernetesDeployRegistrationGlobal);
goals_1.demoProductionDeploy.with(k8sSupport_1.kubernetesDeployRegistrationDemo);
const publishS3Images = new sdm_pack_s3_1.PublishToS3({
uniqueName: "publish s3-images to s3",
bucketName: "images-atomist",
region: "us-east-1",
filesToPublish: ["images/**/*"],
paramsExt: ".s3params",
pathTranslation: filepath => filepath.replace("images/", ""),
pathToIndex: "images/",
sync: true,
isolated: true,
});
const S3ImagesGoals = sdm_1.goals("Image Publish").plan(publishS3Images);
const buildWeb = new sdm_pack_build_1.Build()
.with({
name: "web-npm-build",
builder: webSupport_1.webBuilder("public"),
pushTest: sdm_pack_node_1.IsNode,
})
.with({
name: "web-jekyll-build",
builder: webSupport_1.webBuilder("_site"),
pushTest: webSupport_1.IsJekyllProject,
});
const WebBuildGoals = sdm_1.goals("Web Build")
.plan(goals_1.autofix)
.plan(goals_1.version).after(goals_1.autofix)
.plan(buildWeb).after(goals_1.version)
.plan(goals_1.tag).after(buildWeb);
goals_1.autoCodeInspection.with(webSupport_1.htmltestInspection("_site"));
const publishWebAppToStaging = new sdm_pack_s3_1.PublishToS3({
environment: sdm_1.StagingEnvironment,
uniqueName: "publish web-app to staging s3 bucket",
bucketName: "app-staging.atomist.services",
region: "us-east-1",
filesToPublish: ["public/**/*"],
pathTranslation: filepath => filepath.replace("public/", ""),
pathToIndex: "public/",
sync: true,
isolated: true,
}).withProjectListener(webSupport_1.WebNpmBuildAfterCheckout);
const publishWebAppToProduction = new sdm_pack_s3_1.PublishToS3({
environment: sdm_1.ProductionEnvironment,
uniqueName: "publish web-app to production s3 bucket",
bucketName: "app.atomist.com",
region: "us-east-1",
filesToPublish: ["public/**/*"],
pathTranslation: filepath => filepath.replace("public/", ""),
pathToIndex: "public/",
sync: true,
isolated: true,
preApprovalRequired: true,
}).withProjectListener(webSupport_1.WebNpmBuildAfterCheckout);
const WebAppGoals = sdm_1.goals("Web App Build with Release")
.plan(WebBuildGoals)
.plan(publishWebAppToStaging).after(buildWeb)
.plan(publishWebAppToProduction).after(publishWebAppToStaging)
.plan(goals_1.releaseTag, goals_1.releaseVersion).after(publishWebAppToProduction);
const publishWebSiteToStaging = new sdm_pack_s3_1.PublishToS3({
environment: sdm_1.StagingEnvironment,
uniqueName: "publish web-site to staging s3 bucket",
bucketName: "www-staging.atomist.services",
region: "us-east-1",
filesToPublish: ["_site/**/*"],
paramsExt: ".s3params",
pathTranslation: filepath => filepath.replace("_site/", ""),
pathToIndex: "_site/",
sync: true,
isolated: true,
}).withProjectListener(webSupport_1.JekyllBuildAfterCheckout);
const publishWebSiteToProduction = new sdm_pack_s3_1.PublishToS3({
environment: sdm_1.ProductionEnvironment,
uniqueName: "publish web-site to production s3 bucket",
bucketName: "atomist.com",
region: "us-east-1",
filesToPublish: ["_site/**/*"],
paramsExt: ".s3params",
pathTranslation: filepath => filepath.replace("_site/", ""),
pathToIndex: "_site/",
sync: true,
isolated: true,
preApprovalRequired: true,
}).withProjectListener(webSupport_1.JekyllBuildAfterCheckout);
const WebSiteGoals = sdm_1.goals("Web Site Build with Release")
.plan(WebBuildGoals)
.plan(publishWebSiteToStaging, goals_1.autoCodeInspection).after(buildWeb)
.plan(publishWebSiteToProduction).after(publishWebSiteToStaging)
.plan(goals_1.releaseTag, goals_1.releaseVersion).after(publishWebSiteToProduction);
const sdm = sdm_core_1.createSoftwareDeliveryMachine({
name: "Atomist Software Delivery Machine",
configuration,
}, sdm_1.whenPushSatisfies(identityPushTests_1.isOrgNamed("atomist-playground"))
.setGoals(sdm_1.goals("No Goals")), sdm_1.whenPushSatisfies(identityPushTests_1.isOrgNamed("atomist-seeds"), sdm_1.not(identityPushTests_1.nameMatches(/sdm/)))
.itMeans("Non-Atomist seed")
.setGoals(sdm_1.goals("No Goals")), sdm_1.whenPushSatisfies(identityPushTests_1.isOrgNamed("sdd-manifesto"), identityPushTests_1.isNamed("manifesto", "manifesto-app"))
.itMeans("Manifesto repository")
.setGoals(sdm_1.goals("No Goals")), sdm_1.whenPushSatisfies(release_1.IsReleaseCommit)
.itMeans("Release commit")
.setGoals(sdm_1.goals("No Goals")), sdm_1.whenPushSatisfies(sdm_pack_node_1.IsNode, sdm_core_1.IsInLocalMode)
.itMeans("Node repository in local mode")
.setGoals(goals_1.LocalGoals), sdm_1.whenPushSatisfies(identityPushTests_1.isOrgNamed("atomisthq"), identityPushTests_1.isNamed("s3-images"), sdm_1.ToDefaultBranch)
.itMeans("Images Site Deploy")
.setGoals(S3ImagesGoals), sdm_1.whenPushSatisfies(identityPushTests_1.isOrgNamed("atomisthq"), identityPushTests_1.isNamed("web-app"), sdm_1.ToDefaultBranch)
.itMeans("Web App Deploy")
.setGoals(WebAppGoals), sdm_1.whenPushSatisfies(identityPushTests_1.isOrgNamed("atomisthq"), identityPushTests_1.isNamed("web-site"), sdm_1.ToDefaultBranch)
.itMeans("Web Site Deploy")
.setGoals(WebSiteGoals), sdm_1.whenPushSatisfies(identityPushTests_1.isOrgNamed("atomisthq"), identityPushTests_1.isNamed("web-app", "web-app"))
.itMeans("Web Build")
.setGoals(WebBuildGoals), sdm_1.whenPushSatisfies(sdm_1.not(configurationTests_1.isSdmEnabled(configuration.name)), identityPushTests_1.isTeam(AtomistHQWorkspace))
.itMeans("Disabled repository in atomisthq workspace")
.setGoals(sdm_1.goals("No Goals")), sdm_1.whenPushSatisfies(identityPushTests_1.isTeam(AtomistHQWorkspace), identityPushTests_1.nameMatches(/poc-sdm/))
.itMeans("POC SDM in atomisthq")
.setGoals(sdm_1.goals("No Goals")), sdm_1.whenPushSatisfies(identityPushTests_1.isTeam(AtomistCustomerWorkspace), identityPushTests_1.nameMatches(/poc-sdm/))
.itMeans("POC SDM in atomist-customer")
.setGoals(goals_1.CheckGoals),
// Node
sdm_1.whenPushSatisfies(sdm_pack_node_1.IsNode, sdm_1.not(sdm_pack_spring_1.IsMaven), sdm_1.not(materialChangeToNodeRepo_1.MaterialChangeToNodeRepo))
.itMeans("No Material Change")
.setGoals(goals_1.FixGoals),
// Maven
sdm_1.whenPushSatisfies(sdm_pack_spring_1.IsMaven, sdm_1.not(sdm_pack_spring_1.MaterialChangeToJavaRepo))
.itMeans("No Material Change")
.setGoals(goals_1.FixGoals), sdm_1.whenPushSatisfies(sdm_pack_spring_1.IsMaven, sdm_pack_spring_1.MaterialChangeToJavaRepo, sdm_1.not(sdm_1.ToDefaultBranch))
.itMeans("Build Java")
.setGoals(goals_1.MavenBuildGoals), sdm_1.whenPushSatisfies(sdm_pack_spring_1.IsMaven, sdm_pack_spring_1.MaterialChangeToJavaRepo, sdm_pack_docker_1.HasDockerfile, sdm_1.ToDefaultBranch)
.itMeans("Maven Docker Release Build")
.setGoals(goals_1.MavenDockerReleaseGoals),
// Simplified deployment goal set for atomist-sdm, k8-automation; we are skipping
// testing for these and deploying straight into their respective namespaces
sdm_1.whenPushSatisfies(sdm_pack_node_1.IsNode, sdm_pack_docker_1.HasDockerfile, sdm_1.ToDefaultBranch, sdm_pack_node_1.IsAtomistAutomationClient, identityPushTests_1.isNamed("atomist-sdm", "docs-sdm", "manifesto-sdm"))
.itMeans("Simplified Deploy")
.setGoals(goals_1.SimplifiedKubernetesDeployGoals),
// Deploy assets to "global" Kubernetes cluster
sdm_1.whenPushSatisfies(sdm_pack_node_1.IsNode, sdm_pack_docker_1.HasDockerfile, sdm_1.ToDefaultBranch, sdm_pack_node_1.IsAtomistAutomationClient, identityPushTests_1.isNamed("global-sdm"))
.itMeans("Global Deploy")
.setGoals(goals_1.GlobalKubernetesDeployGoals),
// Deploy k8s-sdm to all the clusters
sdm_1.whenPushSatisfies(sdm_1.anySatisfied(sdm_1.allSatisfied(sdm_pack_node_1.IsNode, sdm_pack_docker_1.HasDockerfile, sdm_1.ToDefaultBranch, sdm_pack_node_1.IsAtomistAutomationClient, identityPushTests_1.isNamed("k8s-sdm")), sdm_1.allSatisfied(goSupport_1.IsGoMakeDocker, sdm_1.ToDefaultBranch, identityPushTests_1.isNamed("k8vent"))))
.itMeans("Multi Cluster Deploy")
.setGoals(goals_1.MultiKubernetesDeployGoals),
// Deploy demo-sdm to demo cluster
sdm_1.whenPushSatisfies(sdm_pack_node_1.IsNode, sdm_pack_docker_1.HasDockerfile, sdm_1.ToDefaultBranch, sdm_pack_node_1.IsAtomistAutomationClient, identityPushTests_1.isNamed("demo-sdm"))
.itMeans("Demo Cluster Deploy")
.setGoals(goals_1.DemoKubernetesDeployGoals), sdm_1.whenPushSatisfies(identityPushTests_1.isNamed("cli"), sdm_pack_node_1.IsNode, sdm_1.ToDefaultBranch)
.itMeans("CLI Release Build")
.setGoals(goals_1.DockerReleaseAndHomebrewGoals), sdm_1.whenPushSatisfies(sdm_pack_node_1.IsNode, sdm_pack_docker_1.HasDockerfile, sdm_1.ToDefaultBranch, sdm_1.IsDeployEnabled)
.itMeans("Deploy")
.setGoals(goals_1.KubernetesDeployGoals), sdm_1.whenPushSatisfies(sdm_pack_node_1.IsNode, sdm_pack_docker_1.HasDockerfile, sdm_1.ToDefaultBranch)
.itMeans("Docker Release Build")
.setGoals(goals_1.DockerReleaseGoals), sdm_1.whenPushSatisfies(sdm_pack_node_1.IsNode, sdm_pack_docker_1.HasDockerfile)
.itMeans("Docker Build")
.setGoals(goals_1.DockerGoals), sdm_1.whenPushSatisfies(sdm_pack_docker_1.HasDockerfile, identityPushTests_1.isOrgNamed("atomist"))
.itMeans("Simple Docker Release Build")
.setGoals(goals_1.SimpleDockerReleaseGoals), sdm_1.whenPushSatisfies(sdm_pack_node_1.IsNode, sdm_1.not(sdm_pack_docker_1.HasDockerfile), sdm_1.ToDefaultBranch)
.itMeans("Release Build")
.setGoals(goals_1.BuildReleaseGoals), sdm_1.whenPushSatisfies(sdm_pack_node_1.IsNode, sdm_1.not(sdm_pack_docker_1.HasDockerfile))
.itMeans("Build")
.setGoals(goals_1.BuildGoals));
sdm.addCommand(sdm_core_1.EnableDeploy)
.addCommand(sdm_core_1.DisableDeploy)
.addCommand(tag_1.CreateTag)
.addCommand(changelog_2.GenerateChangelog);
githubSupport_1.addGithubSupport(sdm);
dockerSupport_1.addDockerSupport(sdm);
mavenSupport_1.addMavenSupport(sdm);
nodeSupport_1.addNodeSupport(sdm);
homebrewSupport_1.addHomebrewSupport(sdm);
teamPolicies_1.addTeamPolicies(sdm);
version_1.addFileVersionerSupport(sdm);
goSupport_1.addGoSupport(sdm);
sdm.addExtensionPacks(sdm_core_1.k8sGoalSchedulingSupport(), changelog_1.changelogSupport(), badge_1.BadgeSupport, sdm_pack_build_1.buildAwareCodeTransforms({
buildGoal: goals_1.build,
issueCreation: {
issueRouter: {
raiseIssue: () => __awaiter(this, void 0, void 0, function* () { }),
},
},
}), sdm_core_1.goalStateSupport(), sdm_core_1.githubGoalStatusSupport(), sdm_core_1.notificationSupport(), sdm_pack_issue_1.issueSupport({
labelIssuesOnDeployment: true,
closeCodeInspectionIssuesOnBranchDeletion: {
enabled: true,
source: sdm.configuration.name,
},
}));
sdm.addGoalApprovalRequestVoter(sdm_1.gitHubTeamVoter("atomist-automation"));
sdm.addGoalApprovalRequestVoter((gi) => __awaiter(this, void 0, void 0, function* () {
if (gi.goal.data) {
const data = JSON.parse(gi.goal.data);
if (data.approved) {
return {
vote: sdm_1.GoalApprovalRequestVote.Granted,
};
}
}
if (!gi.goal.approval) {
return {
vote: sdm_1.GoalApprovalRequestVote.Granted,
};
}
const msgId = automation_client_1.guid();
const channelLink = (gi.goal.approval.channelId) ? ` \u00B7 ${slack_messages_1.channel(gi.goal.approval.channelId)}` : "";
const msg = sdm_1.slackQuestionMessage("Goal Approval", `Goal ${slack_messages_1.italic(gi.goal.url ? slack_messages_1.url(gi.goal.url, gi.goal.name) : gi.goal.name)} on ${slack_messages_1.codeLine(gi.goal.sha.slice(0, 7))} of ${slack_messages_1.bold(`${gi.goal.repo.owner}/${gi.goal.repo.name}/${gi.goal.branch}`)} requires your confirmation to approve`, {
actions: [automation_client_1.buttonForCommand({ text: "Approve" }, "ApproveSdmGoalCommand", {
goalSetId: gi.goal.goalSetId,
goalUniqueName: gi.goal.uniqueName,
goalState: gi.goal.state,
msgId,
}), automation_client_1.buttonForCommand({ text: "Cancel" }, "CancelApproveSdmGoalCommand", {
goalSetId: gi.goal.goalSetId,
goalUniqueName: gi.goal.uniqueName,
goalState: gi.goal.state,
msgId,
})],
footer: `${sdm_1.slackFooter()} \u00B7 ${gi.goal.goalSetId.slice(0, 7)}${channelLink}`,
});
yield gi.context.messageClient.addressUsers(msg, gi.goal.approval.userId, { id: msgId });
return {
vote: sdm_1.GoalApprovalRequestVote.Abstain,
};
}));
sdm.addCommand(approval_1.ApprovalCommand)
.addCommand(approval_1.CancelApprovalCommand);
return sdm;
}
exports.machine = machine;
//# sourceMappingURL=machine.js.map