jenkins_pipeline_builder 0.10.16 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +8 -8
  2. data/.rubocop.yml +4 -4
  3. data/lib/jenkins_pipeline_builder.rb +5 -0
  4. data/lib/jenkins_pipeline_builder/compiler.rb +27 -24
  5. data/lib/jenkins_pipeline_builder/extension_dsl.rb +1 -0
  6. data/lib/jenkins_pipeline_builder/extension_set.rb +8 -8
  7. data/lib/jenkins_pipeline_builder/extensions.rb +12 -24
  8. data/lib/jenkins_pipeline_builder/extensions/builders.rb +36 -27
  9. data/lib/jenkins_pipeline_builder/extensions/helpers/builders/blocking_downstream_helper.rb +18 -0
  10. data/lib/jenkins_pipeline_builder/extensions/helpers/builders/maven3_helper.rb +11 -0
  11. data/lib/jenkins_pipeline_builder/extensions/helpers/extension_helper.rb +26 -0
  12. data/lib/jenkins_pipeline_builder/extensions/helpers/job_attributes/parameters_helper.rb +18 -0
  13. data/lib/jenkins_pipeline_builder/extensions/helpers/publishers/cobertura_report_helper.rb +40 -0
  14. data/lib/jenkins_pipeline_builder/extensions/helpers/publishers/email_ext_helper.rb +148 -0
  15. data/lib/jenkins_pipeline_builder/extensions/helpers/triggers/upstream_helper.rb +21 -0
  16. data/lib/jenkins_pipeline_builder/extensions/job_attributes.rb +1 -15
  17. data/lib/jenkins_pipeline_builder/extensions/publishers.rb +263 -6
  18. data/lib/jenkins_pipeline_builder/extensions/triggers.rb +3 -17
  19. data/lib/jenkins_pipeline_builder/extensions/wrappers.rb +3 -3
  20. data/lib/jenkins_pipeline_builder/generator.rb +10 -11
  21. data/lib/jenkins_pipeline_builder/job.rb +29 -25
  22. data/lib/jenkins_pipeline_builder/job_collection.rb +31 -21
  23. data/lib/jenkins_pipeline_builder/module_registry.rb +5 -1
  24. data/lib/jenkins_pipeline_builder/project.rb +28 -0
  25. data/lib/jenkins_pipeline_builder/pull_request_generator.rb +8 -8
  26. data/lib/jenkins_pipeline_builder/version.rb +1 -1
  27. data/spec/lib/jenkins_pipeline_builder/extension_dsl_spec.rb +43 -0
  28. data/spec/lib/jenkins_pipeline_builder/extension_set_spec.rb +110 -0
  29. data/spec/lib/jenkins_pipeline_builder/extensions/builders_spec.rb +56 -0
  30. data/spec/lib/jenkins_pipeline_builder/extensions/job_attributes_spec.rb +85 -0
  31. data/spec/lib/jenkins_pipeline_builder/extensions/publishers_spec.rb +81 -9
  32. data/spec/lib/jenkins_pipeline_builder/extensions/registered_spec.rb +134 -0
  33. data/spec/lib/jenkins_pipeline_builder/extensions/triggers_spec.rb +88 -0
  34. data/spec/lib/jenkins_pipeline_builder/extensions_spec.rb +0 -97
  35. data/spec/lib/jenkins_pipeline_builder/fixtures/job_collection/extensions/extension.rb +11 -0
  36. data/spec/lib/jenkins_pipeline_builder/fixtures/job_collection/extensions/helpers/my_test_thing_helper.rb +5 -0
  37. data/spec/lib/jenkins_pipeline_builder/job_collection_spec.rb +46 -0
  38. data/spec/lib/jenkins_pipeline_builder/module_registry_spec.rb +1 -110
  39. data/spec/lib/jenkins_pipeline_builder/spec_helper.rb +12 -0
  40. metadata +24 -2
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- MGExN2ExOTMzNjdkYzNlMTE2NzQ3Y2QyNjA1ODQ1MjEzNDllZjhmNw==
4
+ MWM3M2NlYzkyODVkOTJiMDcxNjgyY2U4MDFhZWRkNDkyMDViNGFmZg==
5
5
  data.tar.gz: !binary |-
6
- ZDUzNmFkYTUxNjViYTcwZDAxYzBlYTEzZTAyZDIyNTE1MjFjNmVmOQ==
6
+ MGQ1MDM2NDQ4OGJjMWExNzRiZGI1ZDEwMzAwODcxNDFkMjAyYTE0Yw==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- MmI3YzUzODJjYjIwZjkzNjI4ZjRmMzEwOGU2NDdhNjZjMGI4M2M4MzI3YmQ5
10
- OWExYWZlYjNlYTJiMTRhYTY4MjQyNzZlOTZkN2JiYjg1NjE5YzIzYjYxYTRi
11
- YTk1NzM2MTA0MzMwYzJiYzljYWFmNzU0ZjM3YjM1M2E1ZDViNTU=
9
+ YTQ2ZjU1YzkwOWNlN2RjNTJjNzhhZGEwNmZmNTI5ZWU5ZjE5MzgwN2YzNjAx
10
+ NDIyNzJhMTI2ODkwMDhhOGE2NGNlYTc4OTgxYmZiODZjZjk3NmRhYTNiMWJh
11
+ YTRjMTQxMGYyM2U4YTM0N2JmMTg3NGMzMWI4NzdmY2I3ZmVlNWQ=
12
12
  data.tar.gz: !binary |-
13
- MWQ2YzA5YjdmYmNkODgyOWMwZjRmZGY5NWU5MzEyMmU3ZjcwMTFjNjEzZjUy
14
- MWU1OWEzY2YzYTQ0MjlkYzUwMTMwNDA4YzEyYzAxOGIzMDQ5ZGU1MTA5N2Fl
15
- MTJjMGNhMTlkZDU0NzljZmRiY2ZlY2Q5ZjEwNzgyMzQxNmY2NGQ=
13
+ ZDE3OGY2ZDU3N2VjOTExN2MzNDYyZjEyYjU2MmZmM2I3ZmFkY2QxYzY4OGIw
14
+ YzY0NDZjZTczNWMzMGQ5NWFiYzY0N2Q4ZjUxYTMwYzY3ZTZjY2U4N2M2ZjNl
15
+ YmNiNjk2OTI4YmViODEyNWMxMzYxYTIzZjU3Y2I1YWQxMGU1MWE=
data/.rubocop.yml CHANGED
@@ -5,7 +5,7 @@ Metrics/CyclomaticComplexity:
5
5
  Metrics/PerceivedComplexity:
6
6
  Max: 11
7
7
  Metrics/MethodLength:
8
- Max: 30
8
+ Max: 20
9
9
  Metrics/ClassLength:
10
10
  Max: 175
11
11
 
@@ -19,7 +19,7 @@ Metrics/LineLength:
19
19
  - 'spec/lib/jenkins_pipeline_builder/view_spec.rb'
20
20
  - 'spec/lib/jenkins_pipeline_builder/pull_request_spec.rb'
21
21
  - 'spec/lib/jenkins_pipeline_builder/pull_request_generator_spec.rb'
22
- - 'lib/jenkins_pipeline_builder/extensions/*'
22
+ - 'lib/jenkins_pipeline_builder/extensions/**/*'
23
23
 
24
24
  Style/Documentation:
25
25
  Enabled: false
@@ -27,12 +27,12 @@ Style/Documentation:
27
27
  # Configuration parameters: EnforcedStyle, SupportedStyles.
28
28
  Style/Next:
29
29
  Exclude:
30
- - 'lib/jenkins_pipeline_builder/extensions/*'
30
+ - 'lib/jenkins_pipeline_builder/extensions/**/*'
31
31
 
32
32
  # Configuration parameters: EnforcedStyle, SupportedStyles.
33
33
  Style/VariableName:
34
34
  Exclude:
35
- - 'lib/jenkins_pipeline_builder/extensions/*'
35
+ - 'lib/jenkins_pipeline_builder/extensions/**/*'
36
36
 
37
37
  Style/SymbolProc:
38
38
  IgnoredMethods: new
@@ -80,6 +80,11 @@ JenkinsPipelineBuilder.generator
80
80
  require 'jenkins_pipeline_builder/extensions'
81
81
  require 'jenkins_pipeline_builder/extension_dsl'
82
82
  require 'jenkins_pipeline_builder/extension_set'
83
+ require 'jenkins_pipeline_builder/extensions/helpers/extension_helper'
84
+ Dir[File.join(File.dirname(__FILE__), 'jenkins_pipeline_builder/extensions/helpers/**/*.rb')].each do |file|
85
+ require file
86
+ end
87
+
83
88
  require 'jenkins_pipeline_builder/extensions/builders'
84
89
  require 'jenkins_pipeline_builder/extensions/job_attributes'
85
90
  require 'jenkins_pipeline_builder/extensions/wrappers'
@@ -88,29 +88,26 @@ module JenkinsPipelineBuilder
88
88
  [true, new_value]
89
89
  end
90
90
 
91
- def compile_array(item, settings)
91
+ def compile_array(array, settings)
92
92
  errors = {}
93
93
  result = []
94
- item.each do |value|
95
- if value.nil?
96
- errors[item] = "found a nil value when processing following array:\n #{item.inspect}"
97
- break
98
- end
99
- success, payload = compile(value, settings)
100
- unless success
101
- errors.merge!(payload)
102
- next
103
- end
104
- if payload.nil?
105
- errors[value] = "Failed to resolve:\n===>item #{value}\n\n===>of list: #{item}"
106
- next
107
- end
94
+ array.each do |value|
95
+ success, payload = compile_array_item value, settings, array
96
+ errors[value] = payload unless success
108
97
  result << payload
109
98
  end
110
99
  return false, errors unless errors.empty?
111
100
  [true, result]
112
101
  end
113
102
 
103
+ def compile_array_item(item, settings, array)
104
+ success, payload = compile(item, settings)
105
+ return false, "found a nil value when processing following array:\n #{array.inspect}" if item.nil?
106
+ return false, payload unless success
107
+ return false, "Failed to resolve:\n===>item #{item}\n\n===>of list: #{array.inspect}" if payload.nil?
108
+ [true, payload]
109
+ end
110
+
114
111
  def compile_item(key, value, errors, settings)
115
112
  if value.nil?
116
113
  errors[key] = "key: #{key} has a nil value, this is often a yaml syntax error. Skipping children and siblings"
@@ -155,16 +152,12 @@ module JenkinsPipelineBuilder
155
152
 
156
153
  settings = settings.with_indifferent_access
157
154
  value_s = value.to_s.clone
158
- # First we try to do job name correction
159
- vars = value_s.scan(/{{job@(.*)}}/).flatten
160
- if vars.count > 0
161
- vars.select! do |var|
162
- var_val = job_collection[var.to_s]
163
- value_s.gsub!("{{job@#{var}}}", var_val[:value][:name]) unless var_val.nil?
164
- var_val.nil?
165
- end
166
- end
155
+ correct_job_names! value_s
167
156
  # Then we look for normal values to replace
157
+ # TODO: This needs to be pulled out into a 'replace_values' method
158
+ # However, there is not testing around if we can't replace everything
159
+ # (the return nil line can be removed and we are still green)
160
+ # Also, this should *not* be calling gsub! inside a select
168
161
  vars = value_s.scan(/{{([^{}@]+)}}/).flatten
169
162
  vars.select! do |var|
170
163
  var_val = settings[var]
@@ -174,5 +167,15 @@ module JenkinsPipelineBuilder
174
167
  return nil if vars.count != 0
175
168
  value_s
176
169
  end
170
+
171
+ def correct_job_names!(value)
172
+ vars = value.scan(/{{job@(.*)}}/).flatten
173
+ return unless vars.count > 0
174
+ vars.select! do |var|
175
+ var_val = job_collection[var.to_s]
176
+ value.gsub!("{{job@#{var}}}", var_val[:value][:name]) unless var_val.nil?
177
+ var_val.nil?
178
+ end
179
+ end
177
180
  end
178
181
  end
@@ -18,4 +18,5 @@ def job_attribute(&block)
18
18
  JenkinsPipelineBuilder.registry.register([:job], set)
19
19
  versions = set.extensions.map(&:min_version)
20
20
  puts "Successfully registered #{set.name} for versions #{versions}" if set.announced
21
+ true
21
22
  end
@@ -34,7 +34,7 @@ module JenkinsPipelineBuilder
34
34
  end
35
35
 
36
36
  def installed_version=(version)
37
- version = version.match(/\d+\.\d+/)
37
+ version = version.match(/\d+\.\d+(\.\d+)?/)
38
38
  @version = Gem::Version.new version
39
39
  end
40
40
 
@@ -83,7 +83,7 @@ module JenkinsPipelineBuilder
83
83
  end
84
84
  fail 'Values did not match, cannot merge extension sets' if mismatch.any?
85
85
 
86
- blocks.merge other_set.blocks
86
+ self.extensions = versions.merge(other_set.versions).values
87
87
  end
88
88
 
89
89
  def parameters(params)
@@ -145,6 +145,12 @@ module JenkinsPipelineBuilder
145
145
  errors
146
146
  end
147
147
 
148
+ def versions
149
+ @versions ||= extensions.each_with_object({}) do |ext, hash|
150
+ hash[Gem::Version.new(ext.min_version)] = ext
151
+ end
152
+ end
153
+
148
154
  private
149
155
 
150
156
  def highest_allowed_version
@@ -161,12 +167,6 @@ module JenkinsPipelineBuilder
161
167
  end
162
168
  end
163
169
 
164
- def versions
165
- @versions ||= extensions.each_with_object({}) do |ext, hash|
166
- hash[Gem::Version.new(ext.min_version)] = ext
167
- end
168
- end
169
-
170
170
  def ordered_version_list
171
171
  versions.keys.sort.reverse
172
172
  end
@@ -19,31 +19,9 @@
19
19
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
20
  # THE SOFTWARE.
21
21
 
22
- require 'jenkins_pipeline_builder'
23
- JenkinsPipelineBuilder.registry.entries.each do |type, path|
24
- singular_type = type.to_s.singularize
25
- define_method singular_type do |&block|
26
- set = JenkinsPipelineBuilder::ExtensionSet.new singular_type, path, &block
27
- return false unless set.valid?
28
-
29
- JenkinsPipelineBuilder.registry.register([:job, type], set)
30
- versions = set.extensions.map(&:min_version)
31
- puts "Successfully registered #{set.name} for versions #{versions}" if set.announced
32
- true
33
- end
34
- end
35
-
36
- def job_attribute(&block)
37
- set = JenkinsPipelineBuilder::ExtensionSet.new :job_attribute, &block
38
- return false unless set.valid?
39
-
40
- JenkinsPipelineBuilder.registry.register([:job], set)
41
- versions = set.extensions.map(&:min_version)
42
- puts "Successfully registered #{set.name} for versions #{versions}" if set.announced
43
- end
44
-
45
22
  module JenkinsPipelineBuilder
46
23
  class Extension
24
+ attr_accessor :helper
47
25
  EXT_METHODS = {
48
26
  name: false,
49
27
  plugin_id: false,
@@ -88,7 +66,9 @@ module JenkinsPipelineBuilder
88
66
  n_builders = n_xml.xpath(path).first
89
67
  n_builders.instance_exec(value, &before) if before
90
68
  Nokogiri::XML::Builder.with(n_builders) do |builder|
91
- builder.instance_exec value, &xml
69
+ include_helper value, builder
70
+ helper.extension = self
71
+ builder.instance_exec helper, &xml
92
72
  end
93
73
  n_builders.instance_exec(value, &after) if after
94
74
  true
@@ -110,5 +90,13 @@ module JenkinsPipelineBuilder
110
90
  end
111
91
  errors
112
92
  end
93
+
94
+ private
95
+
96
+ def include_helper(params, builder)
97
+ klass = "#{name.to_s.camelize}Helper".safe_constantize
98
+ klass ||= ExtensionHelper
99
+ self.helper = klass.new params, builder
100
+ end
113
101
  end
114
102
  end
@@ -67,13 +67,19 @@ builder do
67
67
  description 'Jenkins plugin for building Maven 2/3 jobs via a special project type.'
68
68
  jenkins_name 'Invoke Maven 3'
69
69
  announced false
70
+ parameters [
71
+ :mavenName,
72
+ :rootPom,
73
+ :goals,
74
+ :options
75
+ ]
70
76
 
71
- xml do |params|
77
+ xml do |helper|
72
78
  send('org.jfrog.hudson.maven3.Maven3Builder') do
73
- mavenName params[:mavenName] || 'tools-maven-3.0.3'
74
- rootPom params[:rootPom]
75
- goals params[:goals]
76
- mavenOpts params[:options]
79
+ mavenName helper.mavenName
80
+ rootPom helper.rootPom
81
+ goals helper.goals
82
+ mavenOpts helper.options
77
83
  end
78
84
  end
79
85
  end
@@ -114,19 +120,22 @@ builder do
114
120
  description 'This plugin lets you trigger new builds when your build has completed, with various ways of specifying parameters for the new build.'
115
121
  jenkins_name 'Trigger/call builds on other projects'
116
122
  announced false
123
+ parameters [
124
+ :data,
125
+ :project,
126
+ :trigger_with_no_parameters,
127
+ :fail,
128
+ :mark_fail,
129
+ :mark_unstable
130
+ ]
117
131
 
118
- xml do |params|
119
- colors = {
120
- 'SUCCESS' => { ordinal: 0, color: 'BLUE' },
121
- 'FAILURE' => { ordinal: 2, color: 'RED' },
122
- 'UNSTABLE' => { ordinal: 1, color: 'YELLOW' }
123
- }
132
+ xml do |helper|
124
133
  send('hudson.plugins.parameterizedtrigger.TriggerBuilder', 'plugin' => 'parameterized-trigger') do
125
134
  configs do
126
135
  send('hudson.plugins.parameterizedtrigger.BlockableBuildTriggerConfig') do
127
136
  configs do
128
- params[:data] = [{ params: '' }] unless params[:data]
129
- params[:data].each do |config|
137
+ helper.data
138
+ helper.data.each do |config|
130
139
  if config[:params]
131
140
  send('hudson.plugins.parameterizedtrigger.PredefinedBuildParameters') do
132
141
  properties config[:params]
@@ -140,31 +149,31 @@ builder do
140
149
  end
141
150
  end
142
151
  end
143
- projects params[:project]
152
+ projects helper[:project]
144
153
  condition 'ALWAYS'
145
- triggerWithNoParameters params[:trigger_with_no_parameters] || false
154
+ triggerWithNoParameters helper.trigger_with_no_parameters
146
155
  block do
147
- if params[:fail] && colors.include?(params[:fail])
156
+ if helper.fail && helper.colors.include?(helper.fail)
148
157
  buildStepFailureThreshold do
149
- name params[:fail]
150
- ordinal colors[params[:fail]][:ordinal]
151
- color colors[params[:fail]][:color]
158
+ name helper.fail
159
+ ordinal helper.colors[helper.fail][:ordinal]
160
+ color helper.colors[helper.fail][:color]
152
161
  completeBuild 'true'
153
162
  end
154
163
  end
155
- if params[:mark_fail] && colors.include?(params[:mark_fail])
164
+ if helper.mark_fail && helper.colors.include?(helper.mark_fail)
156
165
  failureThreshold do
157
- name params[:mark_fail]
158
- ordinal colors[params[:mark_fail]][:ordinal]
159
- color colors[params[:mark_fail]][:color]
166
+ name helper.mark_fail
167
+ ordinal helper.colors[helper.mark_fail][:ordinal]
168
+ color helper.colors[helper.mark_fail][:color]
160
169
  completeBuild 'true'
161
170
  end
162
171
  end
163
- if params[:mark_unstable] && colors.include?(params[:mark_unstable])
172
+ if helper.mark_unstable && helper.colors.include?(helper.mark_unstable)
164
173
  unstableThreshold do
165
- name params[:mark_unstable]
166
- ordinal colors[params[:mark_unstable]][:ordinal]
167
- color colors[params[:mark_unstable]][:color]
174
+ name helper.mark_unstable
175
+ ordinal helper.colors[helper.mark_unstable][:ordinal]
176
+ color helper.colors[helper.mark_unstable][:color]
168
177
  completeBuild 'true'
169
178
  end
170
179
  end
@@ -0,0 +1,18 @@
1
+ class BlockingDownstreamHelper < ExtensionHelper
2
+ attr_reader :colors
3
+ def initialize(params, builder)
4
+ super params, builder, defaults
5
+ @colors = {
6
+ 'SUCCESS' => { ordinal: 0, color: 'BLUE' },
7
+ 'FAILURE' => { ordinal: 2, color: 'RED' },
8
+ 'UNSTABLE' => { ordinal: 1, color: 'YELLOW' }
9
+ }
10
+ end
11
+
12
+ def defaults
13
+ {
14
+ data: [{ params: '' }],
15
+ trigger_with_no_parameters: false
16
+ }
17
+ end
18
+ end
@@ -0,0 +1,11 @@
1
+ class Maven3Helper < ExtensionHelper
2
+ def initialize(params, builder)
3
+ super params, builder, defaults
4
+ end
5
+
6
+ def defaults
7
+ {
8
+ mavenName: 'tools-maven-3.0.3'
9
+ }
10
+ end
11
+ end
@@ -0,0 +1,26 @@
1
+ class ExtensionHelper < SimpleDelegator
2
+ attr_reader :params, :builder
3
+ attr_accessor :extension
4
+ def initialize(params, builder, defaults = {})
5
+ # TODO: We should allow for default values to be passed in here
6
+ # That will allow for defaults to be pulled out of the extension and it
7
+ # will also let better enable overriding of those values that do not have
8
+ # an option to do so currently.
9
+ if params.is_a? Hash
10
+ @params = defaults.merge params
11
+ else
12
+ @params = params
13
+ end
14
+ @builder = builder
15
+ super @params
16
+ end
17
+
18
+ def method_missing(name, *args, &block)
19
+ return super unless extension.parameters.include? name
20
+ self[name]
21
+ end
22
+
23
+ # TODO: Method missing that pulls out of params?
24
+ # That would allow everything to just call helper.foo
25
+ # and then the helper can do any fiddling it needs to (or not)
26
+ end
@@ -0,0 +1,18 @@
1
+ class ParametersHelper < ExtensionHelper
2
+ def param_type(param)
3
+ case param[:type]
4
+ when 'string'
5
+ 'hudson.model.StringParameterDefinition'
6
+ when 'bool'
7
+ 'hudson.model.BooleanParameterDefinition'
8
+ when 'text'
9
+ 'hudson.model.TextParameterDefinition'
10
+ when 'password'
11
+ 'hudson.model.PasswordParameterDefinition'
12
+ when 'choice'
13
+ 'hudson.model.ChoiceParameterDefinition'
14
+ else
15
+ 'hudson.model.StringParameterDefinition'
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,40 @@
1
+ class CoberturaReportHelper < ExtensionHelper
2
+ def thresholds
3
+ @thresholds ||= params[:metric_targets]
4
+ return @thresholds if @thresholds
5
+ @thresholds = {
6
+ failing: [
7
+ { type: 'type', value: 0 },
8
+ { type: 'line', value: 0 },
9
+ { type: 'conditional', value: 0 }
10
+ ],
11
+ unhealthy: [
12
+ { type: 'type', value: 0 },
13
+ { type: 'line', value: 0 },
14
+ { type: 'conditional', value: 0 }
15
+ ],
16
+ healthy: [
17
+ { type: 'type', value: 80 },
18
+ { type: 'line', value: 80 },
19
+ { type: 'conditional', value: 70 }
20
+ ]
21
+ }
22
+ end
23
+
24
+ def send_metric_targets(target)
25
+ name = "#{target}Target"
26
+
27
+ builder.instance_exec self do |helper|
28
+ send name do
29
+ targets 'class' => 'enum-map', 'enum-type' => 'hudson.plugins.cobertura.targets.CoverageMetric' do
30
+ helper.thresholds[target].each do |threshold|
31
+ entry do
32
+ send('hudson.plugins.cobertura.targets.CoverageMetric') { text threshold[:type].upcase }
33
+ send('int') { text(threshold[:value] * 100_000).to_i }
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end