jenkins_pipeline_builder 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +3 -11
- data/README.md +19 -29
- data/commit_build.sh +1 -4
- data/lib/jenkins_pipeline_builder.rb +9 -13
- data/lib/jenkins_pipeline_builder/cli/describe.rb +14 -5
- data/lib/jenkins_pipeline_builder/cli/helper.rb +2 -0
- data/lib/jenkins_pipeline_builder/cli/list.rb +11 -4
- data/lib/jenkins_pipeline_builder/extensions.rb +151 -40
- data/lib/jenkins_pipeline_builder/{builders.rb → extensions/builders.rb} +22 -15
- data/lib/jenkins_pipeline_builder/{job_builder.rb → extensions/job_attributes.rb} +37 -27
- data/lib/jenkins_pipeline_builder/{publishers.rb → extensions/publishers.rb} +55 -20
- data/lib/jenkins_pipeline_builder/{triggers.rb → extensions/triggers.rb} +18 -8
- data/lib/jenkins_pipeline_builder/{wrappers.rb → extensions/wrappers.rb} +23 -36
- data/lib/jenkins_pipeline_builder/generator.rb +29 -62
- data/lib/jenkins_pipeline_builder/module_registry.rb +21 -9
- data/lib/jenkins_pipeline_builder/pull_request.rb +1 -1
- data/lib/jenkins_pipeline_builder/version.rb +1 -1
- data/pipeline/Jenkins-Pipeline-Builder.yaml +3 -7
- data/pipeline/project.yaml +10 -0
- data/spec/lib/jenkins_pipeline_builder/compiler_spec.rb +9 -1
- data/spec/lib/jenkins_pipeline_builder/extensions/builders_spec.rb +53 -0
- data/spec/lib/jenkins_pipeline_builder/extensions/publishers_spec.rb +140 -0
- data/spec/lib/jenkins_pipeline_builder/extensions_spec.rb +113 -31
- data/spec/lib/jenkins_pipeline_builder/generator_spec.rb +12 -4
- data/spec/lib/jenkins_pipeline_builder/module_registry_spec.rb +202 -44
- data/spec/lib/jenkins_pipeline_builder/spec_helper.rb +5 -5
- data/spec/requests/pipeline_spec.rb +20 -0
- metadata +16 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1b24c99f73cecb047e1f58cd328000f81ee3b31c
|
4
|
+
data.tar.gz: 43f6ce844efe1ed19940d3e8d0dfaab50b243d79
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 82bce578c0a059d5cbee047fcd984bbe765174ed58e96601c721b41eb806583e4301959822a6bbe1e729dbdce2636b99d30d9ae00ec877171b1b9b490ecd59c0
|
7
|
+
data.tar.gz: 60bc6c5d94f07227b5750813455267f80c05f2dc7a677bfb972829acd6f32d17e7673eb1b211a3ac849bc085b8d8f6d0682e023a4081e5b74bc2f8fd32848ef5
|
data/.rubocop.yml
CHANGED
@@ -26,6 +26,7 @@ Style/LineLength:
|
|
26
26
|
- 'spec/lib/jenkins_pipeline_builder/compiler_spec.rb'
|
27
27
|
- 'spec/lib/jenkins_pipeline_builder/view_spec.rb'
|
28
28
|
- 'spec/lib/jenkins_pipeline_builder/pull_request_spec.rb'
|
29
|
+
- 'lib/jenkins_pipeline_builder/extensions/*'
|
29
30
|
|
30
31
|
# Configuration parameters: CountComments.
|
31
32
|
Style/MethodLength:
|
@@ -37,18 +38,9 @@ Style/Documentation:
|
|
37
38
|
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
38
39
|
Style/Next:
|
39
40
|
Exclude:
|
40
|
-
- 'lib/jenkins_pipeline_builder/
|
41
|
-
- 'lib/jenkins_pipeline_builder/triggers.rb'
|
42
|
-
- 'lib/jenkins_pipeline_builder/wrappers.rb'
|
43
|
-
- 'lib/jenkins_pipeline_builder/builders.rb'
|
44
|
-
- 'lib/jenkins_pipeline_builder/job_builder.rb'
|
41
|
+
- 'lib/jenkins_pipeline_builder/extensions/*'
|
45
42
|
|
46
43
|
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
47
44
|
Style/VariableName:
|
48
45
|
Exclude:
|
49
|
-
- 'lib/jenkins_pipeline_builder/
|
50
|
-
- 'lib/jenkins_pipeline_builder/triggers.rb'
|
51
|
-
- 'lib/jenkins_pipeline_builder/wrappers.rb'
|
52
|
-
- 'lib/jenkins_pipeline_builder/builders.rb'
|
53
|
-
- 'lib/jenkins_pipeline_builder/job_builder.rb'
|
54
|
-
#######
|
46
|
+
- 'lib/jenkins_pipeline_builder/extensions/*'
|
data/README.md
CHANGED
@@ -15,7 +15,7 @@ amazing progress done by the Open Stack community with their [jenkins-job-builde
|
|
15
15
|
The YAML structure very closely resembles the OpenStack Job Builder, but, in comparison to Python version, is 100%
|
16
16
|
pure Ruby and uses Jenkins API Client and has additional functionlity of building different types of Jenkins views.
|
17
17
|
|
18
|
-
#
|
18
|
+
# JenkinsPipelineBuilder
|
19
19
|
|
20
20
|
USAGE:
|
21
21
|
------
|
@@ -76,6 +76,8 @@ NOTE: you can run the pipeline in NOOP (debug-only) mode by addind -d parameter,
|
|
76
76
|
|
77
77
|
generate pipeline -d -c config/login.yml bootstrap ./pipeline
|
78
78
|
|
79
|
+
The command comes with fairly extensive help. For example you can list all of the registered extension types with `generate list` and a list of all extensions of a type with `generate list type`
|
80
|
+
|
79
81
|
DSL:
|
80
82
|
----
|
81
83
|
|
@@ -282,7 +284,7 @@ When running a project through this module, the project {{name}} is appended wit
|
|
282
284
|
job_type: pull_request_generator
|
283
285
|
git_url: 'https://www.github.com/'
|
284
286
|
git_repo: 'jenkins_pipeline_builder'
|
285
|
-
git_org: '
|
287
|
+
git_org: 'constantcontact'
|
286
288
|
jobs:
|
287
289
|
- '{{name}}-Job1':
|
288
290
|
publishers:
|
@@ -338,39 +340,27 @@ Extending the Pipeline Builder
|
|
338
340
|
|
339
341
|
Have a feature you want to test out before adding it to the source? Now you can create a quick "extension" to the pipeline builder to add new or overwrite existing functionality.
|
340
342
|
|
341
|
-
To add an extension, create an "extensions" directiroy inside of "pipeline" and create a file named "
|
342
|
-
|
343
|
-
When registering, you must use one of the following register methods, depending on what category your change falls into:
|
344
|
-
* register_job_attribute
|
345
|
-
* register_builder
|
346
|
-
* register_publisher
|
347
|
-
* register_wrapper
|
348
|
-
* register_trigger
|
343
|
+
To add an extension, create an "extensions" directiroy inside of "pipeline" and create a file named "my_extension.rb" (or any name). Then just `require 'jenkins_pipeline_builder/extensions'` and you can begin using the extension DSL. All of the plugins use this DSL and provide an excellent source of examples. You can find them in lib/jenkins_pipeline_builder/extensions.
|
349
344
|
|
350
345
|
For help figuring out what category your change is, examine the config.xml for a job that uses your feature. If it is a first child of the root "project" node, your change is a job_attribute. Otherwise it should be either a builder, publisher, wrapper, or trigger, depending what child node it is found in the XML tree.
|
351
346
|
|
352
347
|
Here is an example of extending the pipeline builder with a new publisher:
|
353
348
|
|
354
349
|
```ruby
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
JenkinsPipelineBuilder.extend do |registry|
|
370
|
-
registry.register_publisher :yaml_name, "Jenkins UI Name", "Description of this feature" do |params, xml|
|
371
|
-
xml.send("new_element") {
|
372
|
-
xml.property params[:value]
|
373
|
-
}
|
350
|
+
publisher do
|
351
|
+
name :yaml_name
|
352
|
+
plugin_id 123
|
353
|
+
min_version '0.4'
|
354
|
+
jenkins_name "Jenkins UI Name"
|
355
|
+
description "Description of this feature"
|
356
|
+
|
357
|
+
xml do |params, xml|
|
358
|
+
send("new_element") do
|
359
|
+
property params[:value]
|
360
|
+
if params[:thing]
|
361
|
+
thing 'true'
|
362
|
+
end
|
363
|
+
end
|
374
364
|
end
|
375
365
|
end
|
376
366
|
```
|
data/commit_build.sh
CHANGED
@@ -40,32 +40,28 @@ module JenkinsPipelineBuilder
|
|
40
40
|
|
41
41
|
def credentials=(creds)
|
42
42
|
@credentials = creds
|
43
|
-
@client =
|
44
|
-
|
45
|
-
generator.logger = @_client.logger
|
43
|
+
@client = JenkinsApi::Client.new(credentials)
|
44
|
+
generator.logger = @client.logger
|
46
45
|
@credentials
|
47
46
|
end
|
48
47
|
|
49
48
|
def logger
|
50
|
-
|
49
|
+
client.logger
|
51
50
|
end
|
52
51
|
|
53
52
|
def registry
|
54
53
|
generator.module_registry
|
55
54
|
end
|
56
|
-
|
57
|
-
def load_registry
|
58
|
-
load 'jenkins_pipeline_builder/builders.rb'
|
59
|
-
load 'jenkins_pipeline_builder/job_builder.rb'
|
60
|
-
load 'jenkins_pipeline_builder/wrappers.rb'
|
61
|
-
load 'jenkins_pipeline_builder/publishers.rb'
|
62
|
-
load 'jenkins_pipeline_builder/triggers.rb'
|
63
|
-
end
|
64
55
|
end
|
65
56
|
end
|
66
57
|
JenkinsPipelineBuilder.generator
|
67
58
|
require 'jenkins_pipeline_builder/extensions'
|
68
|
-
|
59
|
+
require 'jenkins_pipeline_builder/extensions/builders'
|
60
|
+
require 'jenkins_pipeline_builder/extensions/job_attributes'
|
61
|
+
require 'jenkins_pipeline_builder/extensions/wrappers'
|
62
|
+
require 'jenkins_pipeline_builder/extensions/publishers'
|
63
|
+
require 'jenkins_pipeline_builder/extensions/triggers'
|
64
|
+
|
69
65
|
require 'jenkins_pipeline_builder/cli/helper'
|
70
66
|
require 'jenkins_pipeline_builder/cli/view'
|
71
67
|
require 'jenkins_pipeline_builder/cli/pipeline'
|
@@ -22,15 +22,22 @@
|
|
22
22
|
|
23
23
|
module JenkinsPipelineBuilder
|
24
24
|
module CLI
|
25
|
-
JenkinsPipelineBuilder.registry.entries.keys
|
25
|
+
entries = JenkinsPipelineBuilder.registry.entries.keys
|
26
|
+
entries << :job_attributes
|
27
|
+
entries.each do |entry|
|
26
28
|
klass_name = entry.to_s.classify
|
27
29
|
# rubocop:disable Style/AccessModifierIndentation
|
28
30
|
klass = Class.new(Thor) do
|
29
31
|
|
30
|
-
|
31
|
-
|
32
|
+
if entry == :job_attributes
|
33
|
+
extensions = JenkinsPipelineBuilder.registry.registry[:job].select { |_, x| x.is_a? ExtensionSet }
|
34
|
+
else
|
35
|
+
extensions = JenkinsPipelineBuilder.registry.registry[:job][entry]
|
36
|
+
end
|
37
|
+
|
38
|
+
extensions.each do |key, extset|
|
32
39
|
# TODO: don't just take the first
|
33
|
-
ext =
|
40
|
+
ext = extset.extensions.first
|
34
41
|
desc key, "Details for #{ext.name}"
|
35
42
|
define_method(ext.name) do
|
36
43
|
display_module(ext)
|
@@ -47,7 +54,9 @@ module JenkinsPipelineBuilder
|
|
47
54
|
Module.const_set(klass_name, klass)
|
48
55
|
end
|
49
56
|
class Describe < Thor
|
50
|
-
JenkinsPipelineBuilder.registry.entries.
|
57
|
+
entries = JenkinsPipelineBuilder.registry.entries.keys
|
58
|
+
entries << :job_attributes
|
59
|
+
entries.each do |entry, _path|
|
51
60
|
klass_name = entry.to_s.classify
|
52
61
|
singular_model = entry.to_s.singularize
|
53
62
|
|
@@ -49,6 +49,8 @@ module JenkinsPipelineBuilder
|
|
49
49
|
creds = YAML.load_file(
|
50
50
|
File.expand_path("#{ENV['HOME']}/.jenkins_api_client/login.yml", __FILE__)
|
51
51
|
)
|
52
|
+
elsif options[:debug]
|
53
|
+
creds = { username: :foo, password: :bar, server_ip: :baz }
|
52
54
|
else
|
53
55
|
msg = 'Credentials are not set. Please pass them as parameters or'
|
54
56
|
msg << ' set them in the default credentials file'
|
@@ -26,15 +26,22 @@ module JenkinsPipelineBuilder
|
|
26
26
|
JenkinsPipelineBuilder.registry.entries.keys.each do |entry|
|
27
27
|
desc entry, "List all #{entry}"
|
28
28
|
define_method(entry) do
|
29
|
-
|
30
|
-
|
29
|
+
entries = JenkinsPipelineBuilder.registry.registry[:job][entry]
|
30
|
+
entries.each do |name, set|
|
31
|
+
ext = set.extensions.first
|
32
|
+
display_module(name, ext)
|
33
|
+
end
|
31
34
|
end
|
32
35
|
end
|
33
36
|
|
34
37
|
desc 'job_attributes', 'List all job attributes'
|
35
38
|
def job_attributes
|
36
|
-
|
37
|
-
|
39
|
+
entries = JenkinsPipelineBuilder.registry.registry[:job]
|
40
|
+
entries.each do |name, set|
|
41
|
+
next unless set.is_a? ExtensionSet
|
42
|
+
ext = set.extensions.first
|
43
|
+
display_module(name, ext)
|
44
|
+
end
|
38
45
|
end
|
39
46
|
|
40
47
|
private
|
@@ -23,74 +23,185 @@ require 'jenkins_pipeline_builder'
|
|
23
23
|
JenkinsPipelineBuilder.registry.entries.each do |type, path|
|
24
24
|
singular_type = type.to_s.singularize
|
25
25
|
define_method singular_type do |&block|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
26
|
+
set = JenkinsPipelineBuilder::ExtensionSet.new
|
27
|
+
set.instance_eval(&block)
|
28
|
+
set.blocks.each do |version, settings|
|
29
|
+
ext = JenkinsPipelineBuilder::Extension.new
|
30
|
+
ext.min_version version
|
31
|
+
ext.type singular_type
|
32
|
+
set.settings.merge(settings).each do |key, value|
|
33
|
+
ext.send key, value
|
34
|
+
end
|
35
|
+
ext.path path unless ext.path
|
36
|
+
set.extensions << ext
|
37
|
+
end
|
38
|
+
unless set.valid?
|
39
|
+
name = set.name || 'A plugin with no name provided'
|
32
40
|
puts "Encountered errors while registering #{name}"
|
33
|
-
puts
|
41
|
+
puts set.errors.map { |k, v| "#{k}: #{v}" }.join(', ')
|
34
42
|
return false
|
35
43
|
end
|
36
|
-
JenkinsPipelineBuilder.registry.register([:job, type],
|
37
|
-
|
44
|
+
JenkinsPipelineBuilder.registry.register([:job, type], set)
|
45
|
+
versions = set.extensions.map { |ext| ext.min_version }
|
46
|
+
puts "Successfully registered #{set.name} for versions #{versions}" if set.announced
|
38
47
|
end
|
39
48
|
end
|
40
49
|
|
41
50
|
def job_attribute(&block)
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
51
|
+
set = JenkinsPipelineBuilder::ExtensionSet.new
|
52
|
+
set.instance_eval(&block)
|
53
|
+
set.blocks.each do |version, settings|
|
54
|
+
ext = JenkinsPipelineBuilder::Extension.new
|
55
|
+
ext.min_version version
|
56
|
+
ext.type :job_attribute
|
57
|
+
set.settings.merge(settings).each do |key, value|
|
58
|
+
ext.send key, value
|
59
|
+
end
|
60
|
+
set.extensions << ext
|
61
|
+
end
|
62
|
+
unless set.valid?
|
63
|
+
name = set.name || 'A plugin with no name provided'
|
47
64
|
puts "Encountered errors while registering #{name}"
|
48
|
-
puts
|
65
|
+
puts set.errors.map { |k, v| "#{k}: #{v}" }.join(', ')
|
49
66
|
return false
|
50
67
|
end
|
51
|
-
JenkinsPipelineBuilder.registry.register([:job],
|
52
|
-
puts "Successfully registered #{
|
68
|
+
JenkinsPipelineBuilder.registry.register([:job], set)
|
69
|
+
puts "Successfully registered #{set.name} for versions #{set.min_version} and higher" if set.announced
|
70
|
+
end
|
71
|
+
|
72
|
+
module JenkinsPipelineBuilder
|
73
|
+
class ExtensionSet
|
74
|
+
SET_METHODS = [
|
75
|
+
:name,
|
76
|
+
:plugin_id,
|
77
|
+
:jenkins_name,
|
78
|
+
:description,
|
79
|
+
:announced,
|
80
|
+
:type
|
81
|
+
]
|
82
|
+
SET_METHODS.each do |method_name|
|
83
|
+
define_method method_name do |value = nil|
|
84
|
+
return settings[method_name] if value.nil?
|
85
|
+
settings[method_name] = value
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
attr_accessor :blocks, :extensions, :settings
|
90
|
+
|
91
|
+
def initialize
|
92
|
+
@blocks = {}
|
93
|
+
@settings = {}
|
94
|
+
@extensions = []
|
95
|
+
end
|
96
|
+
|
97
|
+
def installed_version=(version)
|
98
|
+
version = version.match(/\d+\.\d+/)
|
99
|
+
@version = Gem::Version.new version
|
100
|
+
end
|
101
|
+
|
102
|
+
def installed_version
|
103
|
+
return @version if @version
|
104
|
+
reg = JenkinsPipelineBuilder.registry
|
105
|
+
version = reg.versions[settings[:plugin_id]]
|
106
|
+
puts reg.versions.inspect if version.nil?
|
107
|
+
fail "Plugin #{settings[:name]} is not installed (plugin_id: #{settings[:plugin_id]})" if version.nil?
|
108
|
+
self.installed_version = version
|
109
|
+
@version
|
110
|
+
end
|
111
|
+
|
112
|
+
def extension
|
113
|
+
# TODO: Support multiple xml sections for the native to jenkins plugins
|
114
|
+
return extensions.first if settings[:plugin_id] == 'builtin'
|
115
|
+
|
116
|
+
versions = extensions.each_with_object({}) do |ext, hash|
|
117
|
+
hash[Gem::Version.new(ext.min_version)] = ext
|
118
|
+
end
|
119
|
+
versions.keys.sort!.reverse!.each do |version|
|
120
|
+
return versions[version] if version <= installed_version
|
121
|
+
end
|
122
|
+
|
123
|
+
fail "Can't find version of #{name} lte #{installed_version}, versions available are #{versions.keys.map(&:to_s)}"
|
124
|
+
end
|
125
|
+
|
126
|
+
def merge(other_set)
|
127
|
+
mismatch = []
|
128
|
+
SET_METHODS.each do |method_name|
|
129
|
+
val1 = settings[method_name]
|
130
|
+
val2 = other_set.settings[method_name]
|
131
|
+
mismatch << "The values for #{method_name} do not match '#{val1}' : '#{val2}'" unless val1 == val2
|
132
|
+
end
|
133
|
+
mismatch.each do |error|
|
134
|
+
puts error
|
135
|
+
end
|
136
|
+
fail 'Values did not match, cannot merge exception sets' if mismatch.any?
|
137
|
+
|
138
|
+
blocks.merge other_set.blocks
|
139
|
+
end
|
140
|
+
|
141
|
+
def xml(path: false, version: '0', &block)
|
142
|
+
unless block
|
143
|
+
fail "no block found for version #{version}" unless blocks.key version
|
144
|
+
return blocks[version][:block]
|
145
|
+
end
|
146
|
+
if blocks[version]
|
147
|
+
blocks[version].merge!(xml: block, path: path)
|
148
|
+
else
|
149
|
+
blocks[version] = { xml: block, path: path }
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
[:after, :before].each do |method_name|
|
154
|
+
define_method method_name do |version: '0', &block|
|
155
|
+
return instance_variable_get(method_name) unless block
|
156
|
+
blocks[version] = {} unless blocks[version]
|
157
|
+
blocks[version][method_name] = block
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
def valid?
|
162
|
+
errors.empty?
|
163
|
+
end
|
164
|
+
|
165
|
+
def errors
|
166
|
+
errors = {}
|
167
|
+
errors['ExtensionSet'] = 'no extensions successfully registered' if extensions.empty?
|
168
|
+
extensions.each do |ext|
|
169
|
+
ver = ext.min_version || 'unknown'
|
170
|
+
errors["#{ext.name} version #{ver}"] = ext.errors unless ext.valid?
|
171
|
+
end
|
172
|
+
errors
|
173
|
+
end
|
174
|
+
end
|
53
175
|
end
|
54
176
|
|
55
177
|
module JenkinsPipelineBuilder
|
56
178
|
class Extension
|
57
|
-
|
179
|
+
EXT_METHODS = {
|
58
180
|
name: false,
|
59
181
|
plugin_id: false,
|
60
|
-
min_version: false,
|
61
182
|
jenkins_name: 'No jenkins display name set',
|
62
183
|
description: 'No description set',
|
63
|
-
path: false,
|
64
184
|
announced: true,
|
65
|
-
|
185
|
+
min_version: false,
|
186
|
+
path: false,
|
187
|
+
type: false,
|
188
|
+
before: false,
|
189
|
+
after: false,
|
190
|
+
xml: false
|
66
191
|
}
|
67
|
-
|
192
|
+
EXT_METHODS.keys.each do |method_name|
|
68
193
|
define_method method_name do |value = nil|
|
69
194
|
return instance_variable_get("@#{method_name}") if value.nil?
|
70
195
|
instance_variable_set("@#{method_name}", value)
|
71
196
|
end
|
72
197
|
end
|
73
198
|
|
74
|
-
def xml(path = false, &block)
|
75
|
-
@path = path if path
|
76
|
-
return @xml unless block
|
77
|
-
@xml = block
|
78
|
-
end
|
79
|
-
|
80
|
-
def after(&block)
|
81
|
-
return @after unless block
|
82
|
-
@after = block
|
83
|
-
end
|
84
|
-
|
85
|
-
def before(&block)
|
86
|
-
return @before unless block
|
87
|
-
@before = block
|
88
|
-
end
|
89
|
-
|
90
199
|
def initialize
|
91
|
-
|
200
|
+
EXT_METHODS.each do |key, value|
|
92
201
|
instance_variable_set("@#{key}", value) if value
|
93
202
|
end
|
203
|
+
before false
|
204
|
+
after false
|
94
205
|
end
|
95
206
|
|
96
207
|
def valid?
|
@@ -99,7 +210,7 @@ module JenkinsPipelineBuilder
|
|
99
210
|
|
100
211
|
def errors
|
101
212
|
errors = {}
|
102
|
-
|
213
|
+
EXT_METHODS.keys.each do |name|
|
103
214
|
errors[name] = 'Must be set' if send(name).nil?
|
104
215
|
end
|
105
216
|
errors
|