From 465d30b4b6cf4290d9dd5105b06d6533b6b5c46b Mon Sep 17 00:00:00 2001 From: "mergify[bot]" <37929162+mergify[bot]@users.noreply.github.com> Date: Mon, 15 Feb 2021 09:16:02 +0000 Subject: [PATCH] Add releaseNotification step to simplify agent release pipelines (#976) (#981) * Add releaseNotification step to simplify agent release pipelines * REmove imports * update README docs Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> (cherry picked from commit 6e3bb9ad4272e2336a30c5ac6505da24592f4183) Co-authored-by: Victor Martinez --- .../ReleaseNotificationStepTests.groovy | 93 +++++++++++++++++++ vars/README.md | 18 ++++ vars/releaseNotification.groovy | 51 ++++++++++ vars/releaseNotification.txt | 16 ++++ 4 files changed, 178 insertions(+) create mode 100644 src/test/groovy/ReleaseNotificationStepTests.groovy create mode 100644 vars/releaseNotification.groovy create mode 100644 vars/releaseNotification.txt diff --git a/src/test/groovy/ReleaseNotificationStepTests.groovy b/src/test/groovy/ReleaseNotificationStepTests.groovy new file mode 100644 index 000000000..b57f75243 --- /dev/null +++ b/src/test/groovy/ReleaseNotificationStepTests.groovy @@ -0,0 +1,93 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you 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. + +import org.junit.Before +import org.junit.Test +import static org.junit.Assert.assertNull +import static org.junit.Assert.assertTrue + +class ReleaseNotificationStepTests extends ApmBasePipelineTest { + + @Override + @Before + void setUp() throws Exception { + super.setUp() + script = loadScript('vars/releaseNotification.groovy') + } + + @Test + void test_without_arguments() throws Exception { + script.call() + printCallStack() + assertTrue(assertMethodCallOccurrences('emailext', 1)) + assertTrue(assertMethodCallOccurrences('slackSend', 0)) + } + + @Test + void test_without_arguments_and_env_variables() throws Exception { + addEnvVar('SLACK_CHANNEL', '#foo') + addEnvVar('NOTIFY_TO', 'to@acme.com') + script.call() + printCallStack() + assertTrue(assertMethodCallContainsPattern('emailext', 'to@acme.com')) + assertTrue(assertMethodCallContainsPattern('slackSend', '#foo')) + } + + @Test + void test_without_arguments_and_env_variables_all_parameters() throws Exception { + addEnvVar('SLACK_CHANNEL', '#foo') + addEnvVar('NOTIFY_TO', 'to@acme.com') + script.call(slackColor: 'good', + slackCredentialsId: 'credentials', + slackChannel: '#channel', + to: "to@foo.com", + subject: "[example] Release tag *0.1.1* has been created", + body: "Build: () for further details.") + printCallStack() + assertTrue(assertMethodCallContainsPattern('emailext', 'to@foo.com')) + assertTrue(assertMethodCallContainsPattern('slackSend', '#channel')) + assertTrue(assertMethodCallContainsPattern('slackSend', 'good')) + } + + @Test + void test_transformSlackURLFormatToEmailFormat_null() throws Exception { + def ret = script.transformSlackURLFormatToEmailFormat(null) + printCallStack() + assertNull(ret) + } + + @Test + void test_transformSlackURLFormatToEmailFormat_empty() throws Exception { + def ret = script.transformSlackURLFormatToEmailFormat('') + printCallStack() + assertTrue(ret.equals('')) + } + + @Test + void test_transformSlackURLFormatToEmailFormat_foo() throws Exception { + def ret = script.transformSlackURLFormatToEmailFormat('foo') + printCallStack() + assertTrue(ret.equals('foo')) + } + + @Test + void test_transformSlackURLFormatToEmailFormat_url() throws Exception { + def ret = script.transformSlackURLFormatToEmailFormat('()') + printCallStack() + assertTrue(ret.equals('URL')) + } +} diff --git a/vars/README.md b/vars/README.md index 7fef2bfd5..ea9fece7d 100644 --- a/vars/README.md +++ b/vars/README.md @@ -1940,6 +1940,24 @@ def i = randomNumber() def i = randomNumber(min: 1, max: 99) ``` +## releaseNotification +Send notifications with the release status by email and slack. + +If body is slack format based then it will be transformed to the email format + +``` +releaseNotification(slackColor: 'good', + subject: "[${env.REPO}] Release tag *${env.TAG_NAME}* has been created", + body: "Build: (<${env.RUN_DISPLAY_URL}|here>) for further details.") +``` + +* body: this is the body email that will be also added to the subject when using slack notifications. Optional +* slackChannel: the slack channel, multiple channels may be provided as a comma, semicolon, or space delimited string. Default `env.SLACK_CHANNEL` +* slackColor: an optional value that can either be one of good, warning, danger, or any hex color code (eg. #439FE0) +* slackCredentialsId: the slack credentialsId. Default 'jenkins-slack-integration-token' +* subject: this is subject email that will be also aggregated to the body when using slack notifications. Optional +* to: who should receive an email. Default `env.NOTIFY_TO` + ## retryWithSleep Retry a command for a specified number of times until the command exits successfully. diff --git a/vars/releaseNotification.groovy b/vars/releaseNotification.groovy new file mode 100644 index 000000000..304a576aa --- /dev/null +++ b/vars/releaseNotification.groovy @@ -0,0 +1,51 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you 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. + +/** + Send notifications with the release status by email and slack + + releaseNotification(slackColor: 'good', + subject: "[${env.REPO}] Release tag *${env.TAG_NAME}* has been created", + body: "Build: (<${env.RUN_DISPLAY_URL}|here>) for further details.") + +*/ +def call(Map args = [:]) { + def slackChannel = args.get('slackChannel', env.SLACK_CHANNEL) + def slackColor = args.get('slackColor') + def credentialsId = args.get('slackCredentialsId', 'jenkins-slack-integration-token') + def to = args.get('to', env.NOTIFY_TO) + def subject = args.get('subject', '') + def body = args.get('body', '') + + if (slackChannel?.trim()) { + slackSend(channel: slackChannel, + color: slackColor, + message: "${subject}. ${body}", + tokenCredentialId: credentialsId) + } else { + log(level: 'INFO', text: 'releaseNotification: missing slackChannel therefore skipped the slack notification.') + } + + emailext(subject: subject, + to: to, + body: transformSlackURLFormatToEmailFormat(body)) +} + +def transformSlackURLFormatToEmailFormat(String message) { + // transform slack URL format '()' to 'URL'. + return message?.replaceAll('\\(<', '')?.replaceAll('\\|.*>\\)', '') +} diff --git a/vars/releaseNotification.txt b/vars/releaseNotification.txt new file mode 100644 index 000000000..c442d4efe --- /dev/null +++ b/vars/releaseNotification.txt @@ -0,0 +1,16 @@ +Send notifications with the release status by email and slack. + +If body is slack format based then it will be transformed to the email format + +``` +releaseNotification(slackColor: 'good', + subject: "[${env.REPO}] Release tag *${env.TAG_NAME}* has been created", + body: "Build: (<${env.RUN_DISPLAY_URL}|here>) for further details.") +``` + +* body: this is the body email that will be also added to the subject when using slack notifications. Optional +* slackChannel: the slack channel, multiple channels may be provided as a comma, semicolon, or space delimited string. Default `env.SLACK_CHANNEL` +* slackColor: an optional value that can either be one of good, warning, danger, or any hex color code (eg. #439FE0) +* slackCredentialsId: the slack credentialsId. Default 'jenkins-slack-integration-token' +* subject: this is subject email that will be also aggregated to the body when using slack notifications. Optional +* to: who should receive an email. Default `env.NOTIFY_TO`