UNPKG

@atomist/atomist-sdm

Version:

Atomist SDM to deliver our own projects

289 lines 17.2 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) { 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