jenkins_pipeline_builder 0.4.2 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +65 -0
- data/LICENSE +1 -1
- data/README.md +64 -2
- data/Rakefile +13 -11
- data/bin/generate +2 -4
- data/jenkins_pipeline_builder.gemspec +14 -11
- data/lib/jenkins_pipeline_builder.rb +2 -1
- data/lib/jenkins_pipeline_builder/builders.rb +89 -33
- data/lib/jenkins_pipeline_builder/cli/base.rb +21 -29
- data/lib/jenkins_pipeline_builder/cli/helper.rb +12 -15
- data/lib/jenkins_pipeline_builder/cli/pipeline.rb +6 -1
- data/lib/jenkins_pipeline_builder/cli/view.rb +2 -2
- data/lib/jenkins_pipeline_builder/compiler.rb +58 -56
- data/lib/jenkins_pipeline_builder/generator.rb +362 -172
- data/lib/jenkins_pipeline_builder/job_builder.rb +48 -45
- data/lib/jenkins_pipeline_builder/module_registry.rb +4 -6
- data/lib/jenkins_pipeline_builder/publishers.rb +53 -38
- data/lib/jenkins_pipeline_builder/pull_request.rb +156 -0
- data/lib/jenkins_pipeline_builder/triggers.rb +24 -25
- data/lib/jenkins_pipeline_builder/utils.rb +13 -7
- data/lib/jenkins_pipeline_builder/version.rb +2 -2
- data/lib/jenkins_pipeline_builder/view.rb +120 -98
- data/lib/jenkins_pipeline_builder/wrappers.rb +44 -44
- data/lib/jenkins_pipeline_builder/xml_helper.rb +4 -4
- data/spec/func_tests/spec_helper.rb +2 -2
- data/spec/func_tests/view_spec.rb +6 -6
- data/spec/unit_tests/compiler_spec.rb +7 -7
- data/spec/unit_tests/fixtures/files/Job-Gem-Build.xml +2 -2
- data/spec/unit_tests/fixtures/files/Job-Gem-Build.yaml +1 -0
- data/spec/unit_tests/fixtures/files/concurrent_build.xml +17 -0
- data/spec/unit_tests/fixtures/files/concurrent_build.yaml +4 -0
- data/spec/unit_tests/fixtures/files/downstream_blocking.xml +19 -0
- data/spec/unit_tests/fixtures/files/downstream_blocking.yaml +15 -0
- data/spec/unit_tests/fixtures/files/groovy_postbuild.xml +29 -0
- data/spec/unit_tests/fixtures/files/groovy_postbuild.yaml +9 -0
- data/spec/unit_tests/generator_spec.rb +30 -25
- data/spec/unit_tests/module_registry_spec.rb +9 -9
- data/spec/unit_tests/resolve_dependencies_spec.rb +108 -89
- data/spec/unit_tests/spec_helper.rb +1 -1
- metadata +62 -4
@@ -1,5 +1,5 @@
|
|
1
1
|
#
|
2
|
-
# Copyright (c) 2014
|
2
|
+
# Copyright (c) 2014 Constant Contact
|
3
3
|
#
|
4
4
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
5
|
# of this software and associated documentation files (the "Software"), to deal
|
@@ -23,7 +23,7 @@
|
|
23
23
|
module JenkinsPipelineBuilder
|
24
24
|
class JobBuilder
|
25
25
|
def self.change_description(description, n_xml)
|
26
|
-
desc = n_xml.xpath(
|
26
|
+
desc = n_xml.xpath('//description').first
|
27
27
|
desc.content = "#{description}"
|
28
28
|
end
|
29
29
|
|
@@ -34,118 +34,121 @@ module JenkinsPipelineBuilder
|
|
34
34
|
XmlHelper.update_node_text(n_xml, '//scm/excludedUsers', params[:excluded_users]) if params[:excluded_users]
|
35
35
|
XmlHelper.update_node_text(n_xml, '//scm/userRemoteConfigs/hudson.plugins.git.UserRemoteConfig/name', params[:remote_name]) if params[:remote_name]
|
36
36
|
XmlHelper.update_node_text(n_xml, '//scm/skipTag', params[:skip_tag]) if params[:skip_tag]
|
37
|
+
XmlHelper.update_node_text(n_xml, '//scm/userRemoteConfigs/hudson.plugins.git.UserRemoteConfig/refspec', params[:refspec]) if params[:refspec]
|
37
38
|
end
|
38
39
|
|
39
40
|
def self.hipchat_notifier(params, n_xml)
|
40
|
-
|
41
|
+
fail 'No HipChat room specified' unless params[:room]
|
41
42
|
|
42
|
-
properties = n_xml.xpath(
|
43
|
+
properties = n_xml.xpath('//properties').first
|
43
44
|
Nokogiri::XML::Builder.with(properties) do |xml|
|
44
|
-
xml.send('jenkins.plugins.hipchat.HipChatNotifier_-HipChatJobProperty')
|
45
|
+
xml.send('jenkins.plugins.hipchat.HipChatNotifier_-HipChatJobProperty') do
|
45
46
|
xml.room params[:room]
|
46
47
|
xml.startNotification params[:'start-notify'] || false
|
47
|
-
|
48
|
+
end
|
48
49
|
end
|
49
50
|
end
|
50
51
|
|
51
52
|
def self.use_specific_priority(params, n_xml)
|
52
53
|
n_builders = n_xml.xpath('//properties').first
|
53
54
|
Nokogiri::XML::Builder.with(n_builders) do |xml|
|
54
|
-
xml.send('jenkins.advancedqueue.AdvancedQueueSorterJobProperty', 'plugin' => 'PrioritySorter')
|
55
|
+
xml.send('jenkins.advancedqueue.AdvancedQueueSorterJobProperty', 'plugin' => 'PrioritySorter') do
|
55
56
|
xml.useJobPriority params[:use_priority]
|
56
57
|
xml.priority params[:job_priority] || -1
|
57
|
-
|
58
|
+
end
|
58
59
|
end
|
59
60
|
end
|
60
61
|
|
61
62
|
def self.build_parameters(params, n_xml)
|
62
63
|
n_builders = n_xml.xpath('//properties').first
|
63
64
|
Nokogiri::XML::Builder.with(n_builders) do |xml|
|
64
|
-
xml.send('hudson.model.ParametersDefinitionProperty')
|
65
|
-
xml.parameterDefinitions
|
65
|
+
xml.send('hudson.model.ParametersDefinitionProperty') do
|
66
|
+
xml.parameterDefinitions do
|
66
67
|
param_proc = lambda do |xml, params, type|
|
67
|
-
xml.send(type)
|
68
|
+
xml.send(type) do
|
68
69
|
xml.name params[:name]
|
69
70
|
xml.description params[:description]
|
70
71
|
xml.defaultValue params[:default]
|
71
72
|
if params[:type] == 'choice'
|
72
|
-
|
73
|
-
|
74
|
-
xml.choices('class' => 'java.util.Arrays$ArrayList') {
|
75
|
-
xml.a('class' => 'string-array') {
|
73
|
+
xml.choices('class' => 'java.util.Arrays$ArrayList') do
|
74
|
+
xml.a('class' => 'string-array') do
|
76
75
|
params[:values].each do |value|
|
77
76
|
xml.string value
|
78
77
|
end
|
79
|
-
|
80
|
-
|
78
|
+
end
|
79
|
+
end
|
81
80
|
end
|
82
|
-
|
81
|
+
end
|
83
82
|
end
|
84
83
|
params.each do |param|
|
85
84
|
case param[:type]
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
85
|
+
when 'string'
|
86
|
+
paramType = 'hudson.model.StringParameterDefinition'
|
87
|
+
when 'bool'
|
88
|
+
paramType = 'hudson.model.BooleanParameterDefinition'
|
89
|
+
when 'text'
|
90
|
+
paramType = 'hudson.model.TextParameterDefinition'
|
91
|
+
when 'password'
|
92
|
+
paramType = 'hudson.model.PasswordParameterDefinition'
|
93
|
+
when 'choice'
|
94
|
+
paramType = 'hudson.model.ChoiceParameterDefinition'
|
95
|
+
else
|
96
|
+
paramType = 'hudson.model.StringParameterDefinition'
|
97
|
+
end
|
99
98
|
|
100
99
|
param_proc.call xml, param, paramType
|
101
100
|
end
|
102
|
-
|
103
|
-
|
101
|
+
end
|
102
|
+
end
|
104
103
|
end
|
105
104
|
end
|
106
105
|
|
107
106
|
def self.discard_old_param(params, n_xml)
|
108
107
|
properties = n_xml.child
|
109
108
|
Nokogiri::XML::Builder.with(properties) do |xml|
|
110
|
-
xml.send('logRotator', 'class' => 'hudson.tasks.LogRotator')
|
109
|
+
xml.send('logRotator', 'class' => 'hudson.tasks.LogRotator') do
|
111
110
|
xml.daysToKeep params[:days] if params[:days]
|
112
111
|
xml.numToKeep params[:number] || -1
|
113
112
|
xml.artifactDaysToKeep params[:artifact_days] || -1
|
114
113
|
xml.artifactNumToKeep params[:artifact_number] || -1
|
115
|
-
|
114
|
+
end
|
116
115
|
end
|
117
116
|
end
|
118
117
|
|
119
118
|
def self.throttle_job(params, n_xml)
|
120
119
|
properties = n_xml.xpath('//properties').first
|
121
|
-
cat_set = params[:option]==
|
120
|
+
cat_set = params[:option] == 'category'
|
122
121
|
Nokogiri::XML::Builder.with(properties) do |xml|
|
123
|
-
xml.send('hudson.plugins.throttleconcurrents.ThrottleJobProperty', 'plugin' => 'throttle-concurrents')
|
122
|
+
xml.send('hudson.plugins.throttleconcurrents.ThrottleJobProperty', 'plugin' => 'throttle-concurrents') do
|
124
123
|
xml.maxConcurrentPerNode params[:max_per_node] || 0
|
125
124
|
xml.maxConcurrentTotal params[:max_total] || 0
|
126
125
|
xml.throttleEnabled true
|
127
|
-
xml.throttleOption params[:option] ||
|
128
|
-
xml.categories
|
126
|
+
xml.throttleOption params[:option] || 'alone'
|
127
|
+
xml.categories do
|
129
128
|
xml.string params[:category] if cat_set
|
130
|
-
|
131
|
-
|
129
|
+
end
|
130
|
+
end
|
132
131
|
end
|
133
132
|
end
|
134
133
|
|
135
134
|
def self.prepare_environment(params, n_xml)
|
136
135
|
properties = n_xml.xpath('//properties').first
|
137
136
|
Nokogiri::XML::Builder.with(properties) do |xml|
|
138
|
-
xml.send('EnvInjectJobProperty')
|
139
|
-
xml.info
|
137
|
+
xml.send('EnvInjectJobProperty') do
|
138
|
+
xml.info do
|
140
139
|
xml.propertiesContent params[:properties_content] if params[:properties_content]
|
141
140
|
xml.loadFilesFromMaster params[:load_from_master] if params[:load_from_master]
|
142
|
-
|
141
|
+
end
|
143
142
|
xml.on true
|
144
143
|
xml.keepJenkinsSystemVariables params[:keep_environment] if params[:keep_environment]
|
145
144
|
xml.keepBuildVariables params[:keep_build] if params[:keep_build]
|
146
|
-
|
145
|
+
end
|
147
146
|
end
|
148
147
|
end
|
149
148
|
|
149
|
+
def self.concurrent_build(params, n_xml)
|
150
|
+
concurrentBuild = n_xml.xpath('//concurrentBuild').first
|
151
|
+
concurrentBuild.content = (params == true) ? 'true' : 'false'
|
152
|
+
end
|
150
153
|
end
|
151
154
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
#
|
2
|
-
# Copyright (c) 2014
|
2
|
+
# Copyright (c) 2014 Constant Contact
|
3
3
|
#
|
4
4
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
5
|
# of this software and associated documentation files (the "Software"), to deal
|
@@ -30,14 +30,12 @@ module JenkinsPipelineBuilder
|
|
30
30
|
|
31
31
|
def get(path)
|
32
32
|
parts = path.split('/')
|
33
|
-
|
33
|
+
get_by_path_collection(parts, @registry)
|
34
34
|
end
|
35
35
|
|
36
36
|
def get_by_path_collection(path, registry)
|
37
37
|
item = registry[path.shift.to_sym]
|
38
|
-
if path.count == 0
|
39
|
-
return item
|
40
|
-
end
|
38
|
+
return item if path.count == 0
|
41
39
|
|
42
40
|
get_by_path_collection(path, item)
|
43
41
|
end
|
@@ -67,7 +65,7 @@ module JenkinsPipelineBuilder
|
|
67
65
|
sub_registry = registry_item[:registry]
|
68
66
|
method = registry_item[:method]
|
69
67
|
method.call(sub_registry, value, n_xml)
|
70
|
-
elsif registry_item.kind_of?(Method)
|
68
|
+
elsif registry_item.kind_of?(Method) || registry_item.kind_of?(Proc)
|
71
69
|
registry_item.call(value, n_xml) unless registry_item.nil?
|
72
70
|
end
|
73
71
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
#
|
2
|
-
# Copyright (c) 2014
|
2
|
+
# Copyright (c) 2014 Constant Contact
|
3
3
|
#
|
4
4
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
5
|
# of this software and associated documentation files (the "Software"), to deal
|
@@ -23,106 +23,121 @@
|
|
23
23
|
module JenkinsPipelineBuilder
|
24
24
|
class Publishers
|
25
25
|
def self.description_setter(params, xml)
|
26
|
-
xml.send('hudson.plugins.descriptionsetter.DescriptionSetterPublisher')
|
26
|
+
xml.send('hudson.plugins.descriptionsetter.DescriptionSetterPublisher') do
|
27
27
|
xml.regexp params[:regexp]
|
28
28
|
xml.regexpForFailed params[:regexp]
|
29
29
|
xml.description params[:description]
|
30
30
|
xml.descriptionForFailed params[:description]
|
31
31
|
xml.setForMatrix false
|
32
|
-
|
32
|
+
end
|
33
33
|
end
|
34
34
|
|
35
35
|
def self.push_to_projects(params, xml)
|
36
|
-
xml.send('hudson.plugins.parameterizedtrigger.BuildTrigger')
|
37
|
-
xml.configs
|
38
|
-
xml.send('hudson.plugins.parameterizedtrigger.BuildTriggerConfig')
|
39
|
-
xml.configs
|
40
|
-
params[:data] = [
|
36
|
+
xml.send('hudson.plugins.parameterizedtrigger.BuildTrigger') do
|
37
|
+
xml.configs do
|
38
|
+
xml.send('hudson.plugins.parameterizedtrigger.BuildTriggerConfig') do
|
39
|
+
xml.configs do
|
40
|
+
params[:data] = [{ params: '' }] unless params[:data]
|
41
41
|
params[:data].each do |config|
|
42
42
|
if config[:params]
|
43
|
-
xml.send('hudson.plugins.parameterizedtrigger.PredefinedBuildParameters')
|
43
|
+
xml.send('hudson.plugins.parameterizedtrigger.PredefinedBuildParameters') do
|
44
44
|
xml.properties config[:params]
|
45
|
-
|
45
|
+
end
|
46
46
|
end
|
47
47
|
if config[:file]
|
48
|
-
xml.send('hudson.plugins.parameterizedtrigger.FileBuildParameters')
|
48
|
+
xml.send('hudson.plugins.parameterizedtrigger.FileBuildParameters') do
|
49
49
|
xml.propertiesFile config[:file]
|
50
50
|
xml.failTriggerOnMissing false
|
51
|
-
|
51
|
+
end
|
52
52
|
end
|
53
53
|
end
|
54
|
-
|
54
|
+
end
|
55
55
|
xml.projects params[:project]
|
56
56
|
xml.condition params[:condition] || 'SUCCESS'
|
57
57
|
xml.triggerWithNoParameters params[:trigger_with_no_parameters] || false
|
58
|
-
|
59
|
-
|
60
|
-
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
61
|
end
|
62
62
|
|
63
63
|
def self.push_to_hipchat(params, xml)
|
64
64
|
params = {} if params == true
|
65
|
-
xml.send('jenkins.plugins.hipchat.HipChatNotifier')
|
65
|
+
xml.send('jenkins.plugins.hipchat.HipChatNotifier') do
|
66
66
|
xml.jenkinsUrl params[:jenkinsUrl] || ''
|
67
67
|
xml.authToken params[:authToken] || ''
|
68
68
|
xml.room params[:room] || ''
|
69
|
-
|
69
|
+
end
|
70
70
|
end
|
71
71
|
|
72
72
|
def self.push_to_git(params, xml)
|
73
|
-
xml.send('hudson.plugins.git.GitPublisher')
|
73
|
+
xml.send('hudson.plugins.git.GitPublisher') do
|
74
74
|
xml.configVersion params[:configVersion] || 2
|
75
75
|
xml.pushMerge params[:'push-merge'] || false
|
76
76
|
xml.pushOnlyIfSuccess params[:'push-only-if-success'] || false
|
77
|
-
xml.branchesToPush
|
78
|
-
xml.send('hudson.plugins.git.GitPublisher_-BranchToPush')
|
77
|
+
xml.branchesToPush do
|
78
|
+
xml.send('hudson.plugins.git.GitPublisher_-BranchToPush') do
|
79
79
|
xml.targetRepoName params[:targetRepoName] || 'origin'
|
80
80
|
xml.branchName params[:branchName] || 'master'
|
81
|
-
|
82
|
-
|
83
|
-
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
84
|
end
|
85
85
|
|
86
86
|
def self.publish_junit(params, xml)
|
87
|
-
xml.send('hudson.tasks.junit.JUnitResultArchiver')
|
87
|
+
xml.send('hudson.tasks.junit.JUnitResultArchiver') do
|
88
88
|
xml.testResults params[:test_results] || ''
|
89
89
|
xml.keepLongStdio false
|
90
90
|
xml.testDataPublishers
|
91
|
-
|
91
|
+
end
|
92
92
|
end
|
93
93
|
|
94
94
|
def self.coverage_metric(name, params, xml)
|
95
|
-
xml.send('hudson.plugins.rubyMetrics.rcov.model.MetricTarget')
|
95
|
+
xml.send('hudson.plugins.rubyMetrics.rcov.model.MetricTarget') do
|
96
96
|
xml.metric name
|
97
97
|
xml.healthy params[:healthy]
|
98
98
|
xml.unhealthy params[:unhealthy]
|
99
99
|
xml.unstable params[:unstable]
|
100
|
-
|
100
|
+
end
|
101
101
|
end
|
102
102
|
|
103
103
|
def self.publish_rcov(params, xml)
|
104
|
-
xml.send('hudson.plugins.rubyMetrics.rcov.RcovPublisher')
|
104
|
+
xml.send('hudson.plugins.rubyMetrics.rcov.RcovPublisher') do
|
105
105
|
xml.reportDir params[:report_dir]
|
106
|
-
xml.targets
|
106
|
+
xml.targets do
|
107
107
|
coverage_metric('TOTAL_COVERAGE', params[:total], xml)
|
108
108
|
coverage_metric('CODE_COVERAGE', params[:code], xml)
|
109
|
-
|
110
|
-
|
109
|
+
end
|
110
|
+
end
|
111
111
|
end
|
112
112
|
|
113
113
|
def self.post_build_script(params, xml)
|
114
|
-
xml.send('org.jenkinsci.plugins.postbuildscript.PostBuildScript')
|
115
|
-
xml.buildSteps
|
114
|
+
xml.send('org.jenkinsci.plugins.postbuildscript.PostBuildScript') do
|
115
|
+
xml.buildSteps do
|
116
116
|
if params[:shell_command]
|
117
|
-
xml.send('hudson.tasks.Shell')
|
117
|
+
xml.send('hudson.tasks.Shell') do
|
118
118
|
xml.command params[:shell_command]
|
119
|
-
|
119
|
+
end
|
120
120
|
end
|
121
|
-
|
121
|
+
end
|
122
122
|
xml.scriptOnlyIfSuccess params[:on_success]
|
123
123
|
xml.scriptOnlyIfFailure params[:on_failure]
|
124
124
|
xml.executeOn params[:execute_on] || 'BOTH'
|
125
|
-
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def self.groovy_postbuild(params, xml)
|
129
|
+
xml.send('org.jvnet.hudson.plugins.groovypostbuild.GroovyPostbuildRecorder', 'plugin' => 'groovy-postbuild') do
|
130
|
+
xml.groovyScript params[:groovy_script]
|
131
|
+
xml.behavior params[:behavior] || '0'
|
132
|
+
xml.runFormMatrixParent 'false'
|
133
|
+
if params[:additional_classpaths]
|
134
|
+
params[:additional_classpaths].each do |path|
|
135
|
+
xml.send('org.jvnet.hudson.plugins.groovypostbuild.GroovyScriptPath') do
|
136
|
+
xml.path path[:path] || '/'
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
126
141
|
end
|
127
142
|
end
|
128
143
|
end
|
@@ -0,0 +1,156 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2014 Constant Contact
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
|
+
# of this software and associated documentation files (the "Software"), to deal
|
6
|
+
# in the Software without restriction, including without limitation the rights
|
7
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
8
|
+
# copies of the Software, and to permit persons to whom the Software is
|
9
|
+
# furnished to do so, subject to the following conditions:
|
10
|
+
#
|
11
|
+
# The above copyright notice and this permission notice shall be included in
|
12
|
+
# all copies or substantial portions of the Software.
|
13
|
+
#
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
15
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
16
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
17
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
18
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
19
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
20
|
+
# THE SOFTWARE.
|
21
|
+
#
|
22
|
+
|
23
|
+
module JenkinsPipelineBuilder
|
24
|
+
class PullRequestGenerator
|
25
|
+
# Initializes a new View object.
|
26
|
+
#
|
27
|
+
# @param generator [Generator] the client object
|
28
|
+
#
|
29
|
+
# @return [View] the view object
|
30
|
+
#
|
31
|
+
def initialize(generator)
|
32
|
+
@generator = generator
|
33
|
+
@client = generator.client
|
34
|
+
@logger = @client.logger
|
35
|
+
end
|
36
|
+
|
37
|
+
# Check for Github Pull Requests
|
38
|
+
#
|
39
|
+
# args[:git_url] URL to the github main page ex. https://www.github.com/
|
40
|
+
# args[:git_repo] Name of repo only, not url ex. jenkins_pipeline_builder
|
41
|
+
# args[:git_org] The Orig user ex. igorshare
|
42
|
+
# @return = array of pull request numbers
|
43
|
+
def check_for_pull(args)
|
44
|
+
fail 'Please specify all arguments' unless args[:git_url] && args[:git_org] && args[:git_repo]
|
45
|
+
# Build the Git URL
|
46
|
+
git_url = "#{args[:git_url]}api/v3/repos/#{args[:git_org]}/#{args[:git_repo]}/pulls"
|
47
|
+
|
48
|
+
# Download the JSON Data from the API
|
49
|
+
resp = Net::HTTP.get_response(URI.parse(git_url))
|
50
|
+
pulls = JSON.parse(resp.body)
|
51
|
+
pulls.map { |p| p['number'] }
|
52
|
+
end
|
53
|
+
|
54
|
+
# Purge old builds
|
55
|
+
def purge_old(pull_requests, project)
|
56
|
+
reqs = pull_requests.clone.map { |req| "#{project[:name]}-PR#{req}" }
|
57
|
+
@logger.info "Current pull requests: #{reqs}"
|
58
|
+
# Read File
|
59
|
+
old_requests = File.new('pull_requests.csv', 'a+').read.split(',')
|
60
|
+
|
61
|
+
# Pop off current pull requests
|
62
|
+
old_requests.delete_if { |req| reqs.include?("#{req}") }
|
63
|
+
|
64
|
+
# Delete the old requests from jenkins
|
65
|
+
@logger.info "Purging old requests: #{old_requests}"
|
66
|
+
old_requests.each do |req|
|
67
|
+
jobs = @client.job.list "#{req}.*"
|
68
|
+
jobs.each do |job|
|
69
|
+
@client.job.delete job
|
70
|
+
end
|
71
|
+
end
|
72
|
+
# Write File
|
73
|
+
File.open('pull_requests.csv', 'w+') { |file| file.write reqs.join(',') }
|
74
|
+
end
|
75
|
+
|
76
|
+
def run(project, job_collection, generator_job)
|
77
|
+
@logger.info 'Begin running Pull Request Generator'
|
78
|
+
pull_requests = check_for_pull generator_job[:value]
|
79
|
+
purge_old(pull_requests, project)
|
80
|
+
main_collection = job_collection
|
81
|
+
@logger.info pull_requests
|
82
|
+
pull_requests.each do |number|
|
83
|
+
# Manipulate the YAML
|
84
|
+
req = JenkinsPipelineBuilder::PullRequest.new(project, number, main_collection, generator_job)
|
85
|
+
@generator.job_collection.merge req.jobs
|
86
|
+
project = req.project
|
87
|
+
|
88
|
+
# Overwrite the jobs from the generator to the project
|
89
|
+
project[:value][:jobs] = generator_job[:value][:jobs]
|
90
|
+
|
91
|
+
# Build the jobs
|
92
|
+
success, compiled_project = @generator.resolve_project(project)
|
93
|
+
compiled_project[:value][:jobs].each do |i|
|
94
|
+
job = i[:result]
|
95
|
+
success, payload = @generator.compile_job_to_xml(job)
|
96
|
+
@generator.create_or_update(job, payload) if success
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
class PullRequest
|
103
|
+
attr_reader :project # The root project YAML as a hash
|
104
|
+
attr_reader :number # The pull request number
|
105
|
+
attr_reader :jobs # The jobs in the pull request as an array of hashes
|
106
|
+
attr_reader :generator # The generator job YAML as a hash
|
107
|
+
|
108
|
+
# Initialize
|
109
|
+
def initialize(project, number, jobs, generator)
|
110
|
+
@project = project.clone
|
111
|
+
@number = number
|
112
|
+
@jobs = jobs.clone
|
113
|
+
@generator = generator.clone
|
114
|
+
|
115
|
+
run!
|
116
|
+
end
|
117
|
+
|
118
|
+
private
|
119
|
+
|
120
|
+
# Apply all changes
|
121
|
+
def run!
|
122
|
+
update_jobs!
|
123
|
+
change_git!
|
124
|
+
change_name!
|
125
|
+
end
|
126
|
+
|
127
|
+
# Change the git branch for each job
|
128
|
+
def change_git!
|
129
|
+
@jobs.each_value do |job|
|
130
|
+
job[:value][:scm_branch] = "origin/pr/#{@number}/head"
|
131
|
+
job[:value][:scm_params] = {} unless job[:value][:scm_params]
|
132
|
+
job[:value][:scm_params][:refspec] = 'refs/pull/*:refs/remotes/origin/pr/*'
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
# Change the name of the pull request project
|
137
|
+
def change_name!
|
138
|
+
@project[:name] = "#{@project[:name]}-PR#{@number}" if @project[:name]
|
139
|
+
@project[:value][:name] = "#{@project[:value][:name]}-PR#{@number}" if @project[:value][:name]
|
140
|
+
end
|
141
|
+
|
142
|
+
# Apply any specified changes to each job
|
143
|
+
def update_jobs!
|
144
|
+
@jobs.each_value do |job|
|
145
|
+
name = job[:name]
|
146
|
+
changes = nil
|
147
|
+
# Search the generator for changes
|
148
|
+
@generator[:value][:jobs].each do |gen|
|
149
|
+
changes = gen[name.to_sym] if gen.is_a?(Hash) && gen.keys[0] == name.to_sym
|
150
|
+
end
|
151
|
+
# Apply changes
|
152
|
+
Utils.hash_merge!(job[:value], changes) unless changes.nil?
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|