From ff0ecac7c64d96797d01e1471982870aea2e499f Mon Sep 17 00:00:00 2001 From: Rotaru Sergey Date: Tue, 9 Jun 2020 15:21:07 +0300 Subject: Implement script-id for multibranch with default. Main feature to use multibranch with defaults project type is build configuration mode with default groovy script stored in global Jenkins store provided by config-file provider plugin. Options "script-id" and "sandbox" fully implements this feature. Besides both project type support "script-path" and "script-id" mode. It may be convenient to switch mode without changing project type in order to save project history. Change-Id: I4cd62e69c9abe7d8fc2e0dfdbe25d8b07ddf51c5 --- jenkins_jobs/modules/project_multibranch.py | 91 ++++++++++++++++++---- .../multibranch/fixtures/multibranch_defaults.xml | 63 --------------- .../multibranch/fixtures/multibranch_defaults.yaml | 7 -- .../fixtures/multibranch_defaults_id_mode.xml | 64 +++++++++++++++ .../fixtures/multibranch_defaults_id_mode.yaml | 9 +++ .../fixtures/multibranch_defaults_path_mode.xml | 63 +++++++++++++++ .../fixtures/multibranch_defaults_path_mode.yaml | 7 ++ 7 files changed, 219 insertions(+), 85 deletions(-) delete mode 100644 tests/multibranch/fixtures/multibranch_defaults.xml delete mode 100644 tests/multibranch/fixtures/multibranch_defaults.yaml create mode 100644 tests/multibranch/fixtures/multibranch_defaults_id_mode.xml create mode 100644 tests/multibranch/fixtures/multibranch_defaults_id_mode.yaml create mode 100644 tests/multibranch/fixtures/multibranch_defaults_path_mode.xml create mode 100644 tests/multibranch/fixtures/multibranch_defaults_path_mode.yaml diff --git a/jenkins_jobs/modules/project_multibranch.py b/jenkins_jobs/modules/project_multibranch.py index 93b5f380..1024e41e 100644 --- a/jenkins_jobs/modules/project_multibranch.py +++ b/jenkins_jobs/modules/project_multibranch.py @@ -60,10 +60,18 @@ Plugins required: (default '-1, forever') * **script-path** (`str`): Path to Jenkinsfile, relative to workspace. (default 'Jenkinsfile') + * **script-id** (`str`): Script id from the global Jenkins script store + provided by the config-file provider plugin. Mutually exclusive with + **script-path** option. + * **sandbox** (`bool`): This option is strongly recommended if the + Jenkinsfile is using load to evaluate a groovy source file from an + SCM repository. Usable only with **script-id** option. (default 'false') Job examples: -.. literalinclude:: /../../tests/multibranch/fixtures/multibranch_defaults.yaml +.. literalinclude:: /../../tests/multibranch/fixtures/multibranch_defaults_id_mode.yaml + +.. literalinclude:: /../../tests/multibranch/fixtures/multibranch_defaults_path_mode.yaml .. literalinclude:: /../../tests/multibranch/fixtures/multi_scm_full.yaml @@ -85,8 +93,39 @@ logger = logging.getLogger(str(__name__)) class WorkflowMultiBranch(jenkins_jobs.modules.base.Base): sequence = 0 multibranch_path = "org.jenkinsci.plugins.workflow.multibranch" + multibranch_defaults_path = "org.jenkinsci.pipeline.workflow.multibranch" jenkins_class = "".join([multibranch_path, ".WorkflowMultiBranchProject"]) - jenkins_factory_class = "".join([multibranch_path, ".WorkflowBranchProjectFactory"]) + jenkins_factory = { + "script_path": { + "class": "".join([multibranch_path, ".WorkflowBranchProjectFactory"]) + }, + "script_id": { + "class": "".join( + [ + multibranch_defaults_path, + ".defaults.PipelineBranchDefaultsProjectFactory", + ] + ), + "plugin": "pipeline-multibranch-defaults", + }, + } + + @staticmethod + def _factory_opts_check(data): + + sandbox = data.get("sandbox", None) + script_id = data.get("script-id", None) + script_path = data.get("script-path", None) + + if script_id and script_path: + error_msg = "script-id and script-path are mutually exclusive options" + raise JenkinsJobsException(error_msg) + elif not script_id and sandbox: + error_msg = ( + "Sandbox mode is applicable only for multibranch with defaults" + "project type used with script-id option" + ) + raise JenkinsJobsException(error_msg) def root_xml(self, data): xml_parent = XML.Element(self.jenkins_class) @@ -268,28 +307,50 @@ class WorkflowMultiBranch(jenkins_jobs.modules.base.Base): # Factory # ########### - factory = XML.SubElement( - xml_parent, "factory", {"class": self.jenkins_factory_class} - ) + self._factory_opts_check(data) + + if data.get("script-id"): + mode = "script_id" + fopts_map = ( + ("script-id", "scriptId", None), + ("sandbox", "useSandbox", None), + ) + else: + mode = "script_path" + fopts_map = (("script-path", "scriptPath", "Jenkinsfile"),) + + factory = XML.SubElement(xml_parent, "factory", self.jenkins_factory[mode]) XML.SubElement( factory, "owner", {"class": self.jenkins_class, "reference": "../.."} ) - XML.SubElement(factory, "scriptPath").text = data.get( - "script-path", "Jenkinsfile" - ) + + # multibranch default + + helpers.convert_mapping_to_xml(factory, data, fopts_map, fail_required=False) return xml_parent class WorkflowMultiBranchDefaults(WorkflowMultiBranch): - jenkins_class = ( - "org.jenkinsci.plugins.pipeline.multibranch" - ".defaults.PipelineMultiBranchDefaultsProject" - ) - jenkins_factory_class = ( - "org.jenkinsci.plugins.pipeline.multibranch" - ".defaults.PipelineBranchDefaultsProjectFactory" + multibranch_path = "org.jenkinsci.plugins.workflow.multibranch" + multibranch_defaults_path = "org.jenkinsci.plugins.pipeline.multibranch" + jenkins_class = "".join( + [multibranch_defaults_path, ".defaults.PipelineMultiBranchDefaultsProject"] ) + jenkins_factory = { + "script_path": { + "class": "".join([multibranch_path, ".WorkflowBranchProjectFactory"]), + "plugin": "workflow-multibranch", + }, + "script_id": { + "class": "".join( + [ + multibranch_defaults_path, + ".defaults.PipelineBranchDefaultsProjectFactory", + ] + ) + }, + } def bitbucket_scm(xml_parent, data): diff --git a/tests/multibranch/fixtures/multibranch_defaults.xml b/tests/multibranch/fixtures/multibranch_defaults.xml deleted file mode 100644 index 94859b22..00000000 --- a/tests/multibranch/fixtures/multibranch_defaults.xml +++ /dev/null @@ -1,63 +0,0 @@ - - - - - - All - false - false - - - - - - - - - - - false - - - - - - - true - -1 - -1 - - - - - - - gh-johndoe-foo - johndoe - foo - secret - - - 1 - - - 1 - - - - 1 - - - - - - - - - - - - - Jenkinsfile - - diff --git a/tests/multibranch/fixtures/multibranch_defaults.yaml b/tests/multibranch/fixtures/multibranch_defaults.yaml deleted file mode 100644 index 51e41beb..00000000 --- a/tests/multibranch/fixtures/multibranch_defaults.yaml +++ /dev/null @@ -1,7 +0,0 @@ -name: 'demo-multibranch-defaults' -project-type: multibranch-defaults -scm: - - github: - repo: 'foo' - repo-owner: 'johndoe' - credentials-id: 'secret' diff --git a/tests/multibranch/fixtures/multibranch_defaults_id_mode.xml b/tests/multibranch/fixtures/multibranch_defaults_id_mode.xml new file mode 100644 index 00000000..8136ab90 --- /dev/null +++ b/tests/multibranch/fixtures/multibranch_defaults_id_mode.xml @@ -0,0 +1,64 @@ + + + + + + All + false + false + + + + + + + + + + + false + + + + + + + true + -1 + -1 + + + + + + + gh-johndoe-foo + johndoe + foo + secret + + + 1 + + + 1 + + + + 1 + + + + + + + + + + + + + my-pipeline + true + + diff --git a/tests/multibranch/fixtures/multibranch_defaults_id_mode.yaml b/tests/multibranch/fixtures/multibranch_defaults_id_mode.yaml new file mode 100644 index 00000000..b7b52f1a --- /dev/null +++ b/tests/multibranch/fixtures/multibranch_defaults_id_mode.yaml @@ -0,0 +1,9 @@ +name: 'demo-multibranch-defaults' +project-type: multibranch-defaults +script-id: my-pipeline +sandbox: true +scm: + - github: + repo: 'foo' + repo-owner: 'johndoe' + credentials-id: 'secret' diff --git a/tests/multibranch/fixtures/multibranch_defaults_path_mode.xml b/tests/multibranch/fixtures/multibranch_defaults_path_mode.xml new file mode 100644 index 00000000..c8a0070e --- /dev/null +++ b/tests/multibranch/fixtures/multibranch_defaults_path_mode.xml @@ -0,0 +1,63 @@ + + + + + + All + false + false + + + + + + + + + + + false + + + + + + + true + -1 + -1 + + + + + + + gh-johndoe-foo + johndoe + foo + secret + + + 1 + + + 1 + + + + 1 + + + + + + + + + + + + + Jenkinsfile + + diff --git a/tests/multibranch/fixtures/multibranch_defaults_path_mode.yaml b/tests/multibranch/fixtures/multibranch_defaults_path_mode.yaml new file mode 100644 index 00000000..51e41beb --- /dev/null +++ b/tests/multibranch/fixtures/multibranch_defaults_path_mode.yaml @@ -0,0 +1,7 @@ +name: 'demo-multibranch-defaults' +project-type: multibranch-defaults +scm: + - github: + repo: 'foo' + repo-owner: 'johndoe' + credentials-id: 'secret' -- cgit