From 433a0627a62fb56aa43f50cfadfd06600055d3cc Mon Sep 17 00:00:00 2001 From: Nicolas Vuillamy Date: Thu, 2 Jan 2025 14:02:39 +0100 Subject: [PATCH] notify v0 --- src/commands/hardis/org/monitor/backup.ts | 17 ++- src/commands/hardis/project/deploy/notify.ts | 107 +++++++++++++++++++ 2 files changed, 120 insertions(+), 4 deletions(-) create mode 100644 src/commands/hardis/project/deploy/notify.ts diff --git a/src/commands/hardis/org/monitor/backup.ts b/src/commands/hardis/org/monitor/backup.ts index 7017063fc..4b5837f00 100644 --- a/src/commands/hardis/org/monitor/backup.ts +++ b/src/commands/hardis/org/monitor/backup.ts @@ -91,6 +91,10 @@ If Flow history doc always display a single state, you probably need to update y default: false, description: 'If mode --full is activated, apply filters of manifest/package-skip-items.xml and MONITORING_BACKUP_SKIP_METADATA_TYPES anyway', }), + "skip-doc": Flags.boolean({ + default: false, + description: 'Skip the generation of project documentation at the end of the command', + }), outputfile: Flags.string({ char: 'f', description: 'Force the path and name of output report file. Must end with .csv', @@ -121,6 +125,7 @@ If Flow history doc always display a single state, you probably need to update y protected maxByChunk: number = 3000; protected excludeNamespaces: boolean = false; protected fullApplyFilters: boolean = false; + protected skipDoc: boolean = false; protected packageXmlToRemove: string | null = null; protected extractPackageXmlChunks: any[] = []; @@ -141,6 +146,7 @@ If Flow history doc always display a single state, you probably need to update y this.maxByChunk = flags["max-by-chunk"] || 3000; this.excludeNamespaces = flags["exclude-namespaces"] === true ? true : false; this.fullApplyFilters = flags["full-apply-filters"] === true ? true : false; + this.skipDoc = flags["skip-doc"] === true ? true : false; this.outputFile = flags.outputfile || null; this.debugMode = flags.debug || false; @@ -259,10 +265,13 @@ If Flow history doc always display a single state, you probably need to update y }); // Run project documentation generation - try { - await Project2Markdown.run(["--diff-only", "--with-history"]); - } catch (e: any) { - uxLog(this, c.yellow("Error while generating project documentation " + e.message)); + if (this.skipDoc !== true) { + try { + await Project2Markdown.run(["--diff-only", "--with-history"]); + uxLog(this, c.cyan("Documentation generated from retrieved sources. If you want to skip it, use option --skip-doc")); + } catch (e: any) { + uxLog(this, c.yellow("Error while generating project documentation " + e.message)); + } } return { outputString: 'BackUp processed on org ' + flags['target-org'].getConnection().instanceUrl }; diff --git a/src/commands/hardis/project/deploy/notify.ts b/src/commands/hardis/project/deploy/notify.ts new file mode 100644 index 000000000..5f8cac661 --- /dev/null +++ b/src/commands/hardis/project/deploy/notify.ts @@ -0,0 +1,107 @@ +/* jscpd:ignore-start */ +import { SfCommand, Flags, requiredOrgFlagWithDeprecations } from '@salesforce/sf-plugins-core'; +import { Messages } from '@salesforce/core'; +import { AnyJson } from '@salesforce/ts-types'; +import { CONSTANTS } from '../../../../config/index.js'; +import { buildCheckDeployCommitSummary, handlePostDeploymentNotifications } from '../../../../common/utils/gitUtils.js'; +import { GitProvider } from '../../../../common/gitProvider/index.js'; + +Messages.importMessagesDirectoryFromMetaUrl(import.meta.url); +const messages = Messages.loadMessages('sfdx-hardis', 'org'); + +export default class DeployNotify extends SfCommand { + public static title = 'Deployment Notifications'; + + public static description = `Post notifications related to: + + - Deployment simulation + - Deployment process + + According to the [integrations you configured](${CONSTANTS.DOC_URL_ROOT}/salesforce-ci-cd-setup-integrations-home/), notifications can contain deployment informations and [Flow Visual Git Diff](${CONSTANTS.DOC_URL_ROOT}/salesforce-deployment-assistant-home/#flow-visual-git-diff) + + - GitHub, Gitlab, Azure DevOps, Bitbucket comments on Pull Requests + - Slack, Microsoft Teams, Email deployment summary + - JIRA tags and comments on tickets that just has been deployed + + This command is for custom SF Cli pipelines, if you are a sfdx-hardis user, it is already embedded in sf hardis:deploy:smart. + + You can also use [sfdx-hardis wrapper commands of SF deployment commands](${CONSTANTS.DOC_URL_ROOT}/salesforce-deployment-assistant-setup/#using-custom-cicd-pipeline) + ` + + public static examples = ['$ sf hardis:project:audit:apiversion']; + + public static flags: any = { + "check-only": Flags.boolean({ + char: 'c', + default: false, + description: `Use this option to send notifications from a Deployment simulation job`, + }), + "deploy-status": Flags.string({ + char: 's', + options: ["valid", "invalid", "unknown"], + default: "unknown", + description: `Send success, failure or unknown (default) to indicate if the deployment or deployment simulation is in success or not`, + }), + message: Flags.string({ + char: "m", + default: "", + description: "Custom message that you want to be added in notifications (string or markdown format)" + }), + debug: Flags.boolean({ + char: 'd', + default: false, + description: messages.getMessage('debugMode'), + }), + websocket: Flags.string({ + description: messages.getMessage('websocket'), + }), + skipauth: Flags.boolean({ + description: 'Skip authentication check when a default username is required', + }), + 'target-org': requiredOrgFlagWithDeprecations, + }; + + // Set this to true if your command requires a project workspace; 'requiresProject' is false by default + public static requiresProject = true; + /* jscpd:ignore-end */ + + protected checkOnly = false; + protected message = ""; + protected debugMode = false; + protected deployStatus: "valid" | "invalid" | "unknown" = "unknown" + + public async run(): Promise { + const { flags } = await this.parse(DeployNotify); + this.checkOnly = flags["check-only"] === true ? true : false; + this.deployStatus = flags.status || "unknown"; + this.debugMode = flags.debug || false; + + // Compute commitsSummary and store it in globalThis.pullRequestData.commitsSummary + if (this.checkOnly) { + await buildCheckDeployCommitSummary(); + } + + // Add deployment info + const prData: any = { + messageKey: "deployment", + title: + (this.checkOnly && this.deployStatus === "valid") ? "✅ Deployment check success" : + (!this.checkOnly && this.deployStatus === "valid") ? "✅ Deployment success" : + (this.checkOnly && this.deployStatus === "invalid") ? "❌ Deployment check failure" : + (!this.checkOnly && this.deployStatus === "invalid") ? "❌ Deployment failure" : + (this.checkOnly && this.deployStatus === "unknown") ? "🤷 Deployment check status unknown" : + "🤷 Deployment status unknown", + deployErrorsMarkdownBody: this.message, + deployStatus: this.deployStatus, + }; + globalThis.pullRequestData = Object.assign(globalThis.pullRequestData || {}, prData); + + if (this.checkOnly === false) { + await handlePostDeploymentNotifications(flags, flags["target-org"].getUsername(), false, false, this.debugMode); + } + + await GitProvider.managePostPullRequestComment(); + + return { message: "Processed notifications" } + } +} \ No newline at end of file