jenkins_pipeline_builder 0.4.2 → 0.5.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 +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
|