From 31adb517214b0e2ae8a9b86eba1757afd51337da Mon Sep 17 00:00:00 2001 From: Ryo Tagami Date: Thu, 14 Apr 2016 20:25:29 +0900 Subject: [PATCH] Be able to handle Slack Plugin 2.0 configuration Slack Plugin 2.0 changed its configuration structure, and no longer puts any configuration in properties section, instead puts all configuration in publishers section. This commit will check the plugin version, and if it detects version >= 2.0, it will put additional configurations in publishers section. If it detects version < 2.0 or did not detect version (happens when run in test mode without specifying actual Jenkins instance), it will emit warning logs and not add those configurations. Change-Id: I6d7d92a5a6fd1ceff9b67721d6e401f2772d0575 Signed-off-by: Ryo Tagami --- jenkins_jobs/modules/properties.py | 18 ++- jenkins_jobs/modules/publishers.py | 106 ++++++++++++++++-- .../fixtures/slack003.plugins_info.yaml | 3 + tests/publishers/fixtures/slack003.xml | 23 ++++ tests/publishers/fixtures/slack003.yaml | 2 + .../fixtures/slack004.plugins_info.yaml | 3 + tests/publishers/fixtures/slack004.xml | 23 ++++ tests/publishers/fixtures/slack004.yaml | 18 +++ 8 files changed, 186 insertions(+), 10 deletions(-) create mode 100644 tests/publishers/fixtures/slack003.plugins_info.yaml create mode 100644 tests/publishers/fixtures/slack003.xml create mode 100644 tests/publishers/fixtures/slack003.yaml create mode 100644 tests/publishers/fixtures/slack004.plugins_info.yaml create mode 100644 tests/publishers/fixtures/slack004.xml create mode 100644 tests/publishers/fixtures/slack004.yaml diff --git a/jenkins_jobs/modules/properties.py b/jenkins_jobs/modules/properties.py index 005f59b21..ff9ed4950 100644 --- a/jenkins_jobs/modules/properties.py +++ b/jenkins_jobs/modules/properties.py @@ -32,6 +32,7 @@ Example:: """ import logging +import pkg_resources import xml.etree.ElementTree as XML from jenkins_jobs.errors import InvalidAttributeError @@ -639,9 +640,10 @@ def slack(parser, xml_parent, data): """yaml: slack Requires the Jenkins :jenkins-wiki:`Slack Plugin ` - As the Slack Plugin itself requires a publisher aswell as properties - please note that you have to add the publisher to your job configuration - aswell. + When using Slack Plugin version < 2.0, Slack Plugin itself requires a + publisher aswell as properties please note that you have to add the + publisher to your job configuration aswell. When using Slack Plugin + version >= 2.0, you should only configure the publisher. :arg bool notify-start: Send notification when the job starts (default: False) @@ -677,6 +679,16 @@ def slack(parser, xml_parent, data): value = str(value).lower() XML.SubElement(elem, name).text = value + logger = logging.getLogger(__name__) + + plugin_info = parser.registry.get_plugin_info('Slack Notification Plugin') + plugin_ver = pkg_resources.parse_version(plugin_info.get('version', "0")) + + if plugin_ver >= pkg_resources.parse_version("2.0"): + logger.warn( + "properties section is not used with plugin version >= 2.0", + ) + mapping = ( ('notify-start', 'startNotification', False), ('notify-success', 'notifySuccess', False), diff --git a/jenkins_jobs/modules/publishers.py b/jenkins_jobs/modules/publishers.py index d859688d2..726550389 100644 --- a/jenkins_jobs/modules/publishers.py +++ b/jenkins_jobs/modules/publishers.py @@ -5668,8 +5668,10 @@ def slack(parser, xml_parent, data): Requires the Jenkins :jenkins-wiki:`Slack Plugin ` - As the Slack Plugin itself requires a publisher aswell as properties - please note that you have to create those too. + When using Slack Plugin version < 2.0, Slack Plugin itself requires a + publisher aswell as properties please note that you have to create those + too. When using Slack Plugin version >= 2.0, you should only configure the + publisher. :arg str team-domain: Your team's domain at slack. (default: '') :arg str auth-token: The integration token to be used when sending @@ -5678,34 +5680,124 @@ def slack(parser, xml_parent, data): (default: '/') :arg str room: A comma seperated list of rooms / channels to post the notifications to. (default: '') + :arg bool notify-start: Send notification when the job starts (>=2.0). + (default: False) + :arg bool notify-success: Send notification on success (>=2.0). + (default: False) + :arg bool notify-aborted: Send notification when job is aborted (>=2.0). + (default: False) + :arg bool notify-not-built: Send notification when job set to NOT_BUILT + status (>=2.0). (default: False) + :arg bool notify-unstable: Send notification when job becomes unstable + (>=2.0). (default: False) + :arg bool notify-failure: Send notification when job fails for the first + time (previous build was a success) (>=2.0). (default: False) + :arg bool notifiy-back-to-normal: Send notification when job is succeeding + again after being unstable or failed (>=2.0). (default: False) + :arg bool notify-repeated-failure: Send notification when job fails + successively (previous build was also a failure) (>=2.0). + (default: False) + :arg bool include-test-summary: Include the test summary (>=2.0). + (default: False) + :arg str commit-info-choice: What commit information to include into + notification message, "NONE" includes nothing about commits, "AUTHORS" + includes commit list with authors only, and "AUTHORS_AND_TITLES" + includes commit list with authors and titles (>=2.0). (default: "NONE") + :arg bool include-custom-message: Include a custom message into the + notification (>=2.0). (default: False) + :arg str custom-message: Custom message to be included (>=2.0). + (default: '') - Example: + Example (version < 2.0): .. literalinclude:: /../../tests/publishers/fixtures/slack001.yaml :language: yaml + + Minimal example (version >= 2.0): + + .. literalinclude:: + /../../tests/publishers/fixtures/slack003.yaml + :language: yaml + + Full example (version >= 2.0): + + .. literalinclude:: + /../../tests/publishers/fixtures/slack004.yaml + :language: yaml + """ def _add_xml(elem, name, value=''): + if isinstance(value, bool): + value = str(value).lower() XML.SubElement(elem, name).text = value + logger = logging.getLogger(__name__) + + plugin_info = parser.registry.get_plugin_info('Slack Notification Plugin') + plugin_ver = pkg_resources.parse_version(plugin_info.get('version', "0")) + mapping = ( ('team-domain', 'teamDomain', ''), ('auth-token', 'authToken', ''), ('build-server-url', 'buildServerUrl', '/'), ('room', 'room', ''), ) + mapping_20 = ( + ('notify-start', 'startNotification', False), + ('notify-success', 'notifySuccess', False), + ('notify-aborted', 'notifyAborted', False), + ('notify-not-built', 'notifyNotBuilt', False), + ('notify-unstable', 'notifyUnstable', False), + ('notify-failure', 'notifyFailure', False), + ('notify-back-to-normal', 'notifyBackToNormal', False), + ('notify-repeated-failure', 'notifyRepeatedFailure', False), + ('include-test-summary', 'includeTestSummary', False), + ('commit-info-choice', 'commitInfoChoice', 'NONE'), + ('include-custom-message', 'includeCustomMessage', False), + ('custom-message', 'customMessage', ''), + ) + + commit_info_choices = ['NONE', 'AUTHORS', 'AUTHORS_AND_TITLES'] slack = XML.SubElement( xml_parent, 'jenkins.plugins.slack.SlackNotifier', ) + if plugin_ver >= pkg_resources.parse_version("2.0"): + mapping = mapping + mapping_20 + + if plugin_ver < pkg_resources.parse_version("2.0"): + for yaml_name, _, default_value in mapping: + # All arguments that don't have a default value are mandatory for + # the plugin to work as intended. + if not data.get(yaml_name, default_value): + raise MissingAttributeError(yaml_name) + + for yaml_name, _, _ in mapping_20: + if yaml_name in data: + logger.warn( + "'%s' is invalid with plugin version < 2.0, ignored", + yaml_name, + ) + for yaml_name, xml_name, default_value in mapping: value = data.get(yaml_name, default_value) - # All arguments that don't have a default value are mandatory for the - # plugin to work as intended. - if not value: - raise MissingAttributeError(yaml_name) + + # 'commit-info-choice' is enumerated type + if yaml_name == 'commit-info-choice': + if value not in commit_info_choices: + raise InvalidAttributeError( + yaml_name, value, commit_info_choices, + ) + + # Ensure that custom-message is set when include-custom-message is set + # to true. + if yaml_name == 'include-custom-message' and data is False: + if not data.get('custom-message', ''): + raise MissingAttributeError('custom-message') + _add_xml(slack, xml_name, value) diff --git a/tests/publishers/fixtures/slack003.plugins_info.yaml b/tests/publishers/fixtures/slack003.plugins_info.yaml new file mode 100644 index 000000000..8007c6cbd --- /dev/null +++ b/tests/publishers/fixtures/slack003.plugins_info.yaml @@ -0,0 +1,3 @@ +- longName: 'Slack Notification Plugin' + shortName: 'slack' + version: "2.0" diff --git a/tests/publishers/fixtures/slack003.xml b/tests/publishers/fixtures/slack003.xml new file mode 100644 index 000000000..a9045e751 --- /dev/null +++ b/tests/publishers/fixtures/slack003.xml @@ -0,0 +1,23 @@ + + + + + + + / + + false + false + false + false + false + false + false + false + false + NONE + false + + + + diff --git a/tests/publishers/fixtures/slack003.yaml b/tests/publishers/fixtures/slack003.yaml new file mode 100644 index 000000000..fccaf9e8d --- /dev/null +++ b/tests/publishers/fixtures/slack003.yaml @@ -0,0 +1,2 @@ +publishers: + - slack diff --git a/tests/publishers/fixtures/slack004.plugins_info.yaml b/tests/publishers/fixtures/slack004.plugins_info.yaml new file mode 100644 index 000000000..8007c6cbd --- /dev/null +++ b/tests/publishers/fixtures/slack004.plugins_info.yaml @@ -0,0 +1,3 @@ +- longName: 'Slack Notification Plugin' + shortName: 'slack' + version: "2.0" diff --git a/tests/publishers/fixtures/slack004.xml b/tests/publishers/fixtures/slack004.xml new file mode 100644 index 000000000..1c6c6ca67 --- /dev/null +++ b/tests/publishers/fixtures/slack004.xml @@ -0,0 +1,23 @@ + + + + + teamname + yourauthtoken + http://localhost:8081 + #builds + true + true + true + true + true + true + true + true + true + AUTHORS_AND_TITLES + true + A custom message. + + + diff --git a/tests/publishers/fixtures/slack004.yaml b/tests/publishers/fixtures/slack004.yaml new file mode 100644 index 000000000..54cc90df2 --- /dev/null +++ b/tests/publishers/fixtures/slack004.yaml @@ -0,0 +1,18 @@ +publishers: + - slack: + team-domain: 'teamname' + auth-token: 'yourauthtoken' + build-server-url: 'http://localhost:8081' + room: '#builds' + notify-start: True + notify-success: True + notify-aborted: True + notify-not-built: True + notify-unstable: True + notify-failure: True + notify-back-to-normal: True + notify-repeated-failure: True + include-test-summary: True + commit-info-choice: 'AUTHORS_AND_TITLES' + include-custom-message: True + custom-message: 'A custom message.'