jenkins_pipeline_builder 0.12.4 → 0.13.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- NmMyYTNiNzc4YjYyZGM1ZDM3OGFlMzQ5ZjdhNDA2NTM3NzA4YjFjYg==
4
+ ZGMzZGY0Yzk1MzZiMGYzNzc1ZGZlODIwNmQ3NDRjMWZkYWEzZWVkMw==
5
5
  data.tar.gz: !binary |-
6
- YTY5ZjBjMTk0NGY5OWYzMjE5MzViMDlkZmE5ZWQ5NWFkZDhjNTUyOQ==
6
+ OWNkMTcwZDE1NTgxYTU1MWU0MTlhZGNmOTZjNGEwYjE5NTIwNTIzMA==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- ZThiYmVmYmM1MmUxMTYxYTJhMjc2YTI2MDhiMTI2MDg4NDM5NDIzNDZhMDA4
10
- MzdkMmI3ZTIyYWI0NzE0N2ZjNWFjZGViMWUzMjhjMWRlZTc2MzFjZGU1ZTBm
11
- YTg4ZDMwZjNlNzFlZDQwZjQ4YzkzMzY2NDRjZjlmOGQ5ODg2MjY=
9
+ NmE2YTA2MGI3NmU1MjkxMzI0YjkzNjY1NmE2ZGYwOTMwMzY2NDU5Yzg5ZWM3
10
+ YjJmMjcyY2NhNjkwOWJhZTY0ZTgyODcxNjY0NWExZGU3MmY3ZmU0MDFhMTY3
11
+ NDUyMjA5MTBlOTg4YTc5YzA2NjM5NjFiNGZhY2ViODgxMzBlODQ=
12
12
  data.tar.gz: !binary |-
13
- MGNjOGYxYjUxMDRlMGIzMDFhYTY4NTViNzFiOTEyMGUwYTdiOGI0YzY1ZmRj
14
- MWM3ODU3YThjZmU3ZDI2NDBjNDRmMjEzZjE3OWMxNWQ3N2NkYzZhODM2YTNl
15
- ZmU5YWM4YmMyYmRhZjI3ODY3YWFlMzk5Y2Y4Y2U0YWQyNjYyNmM=
13
+ NmJiYjMyOGU5MDgyN2Y3MjI4MDEyZDVhNGZkOGEzZjE1YjNlMTE2YzRmNDZl
14
+ N2M5ZWIyYmFhNzZlZDg3ZjFmOTRkODRmOTFkYmVjYTNmYWEzY2ViMTYxNDVk
15
+ YzU2ZWJjYzM5N2VmMWY1NDAzYTUyY2ExMTg1ZTQ5OGNmMDI5Mzk=
@@ -28,7 +28,6 @@ require 'jenkins_pipeline_builder/utils'
28
28
  require 'jenkins_pipeline_builder/compiler'
29
29
  require 'jenkins_pipeline_builder/module_registry'
30
30
  require 'jenkins_pipeline_builder/pull_request_generator'
31
- require 'jenkins_pipeline_builder/pull_request'
32
31
  require 'jenkins_pipeline_builder/view'
33
32
  require 'jenkins_pipeline_builder/job_collection'
34
33
  require 'jenkins_pipeline_builder/job'
@@ -1,6 +1,5 @@
1
1
  #
2
2
  # Copyright (c) 2014 Constant Contact
3
- #
4
3
  # Permission is hereby granted, free of charge, to any person obtaining a copy
5
4
  # of this software and associated documentation files (the "Software"), to deal
6
5
  # in the Software without restriction, including without limitation the rights
@@ -48,29 +47,22 @@ module JenkinsPipelineBuilder
48
47
 
49
48
  def bootstrap(path, project_name = nil)
50
49
  logger.info "Bootstrapping pipeline from path #{path}"
51
- job_collection.load_from_path(path)
52
- job_collection.remote_dependencies.cleanup
53
-
54
- if job_collection.projects.any?
55
- errors = publish_project(project_name)
56
- else
57
- errors = publish_jobs(job_collection.standalone_jobs)
58
- end
59
- print_compile_errors errors
60
- errors
50
+ load_job_collection path
51
+ publish(project_name || job_collection.projects.first[:name])
61
52
  end
62
53
 
63
54
  def pull_request(path, project_name)
64
55
  logger.info "Pull Request Generator Running from path #{path}"
65
- job_collection.load_from_path(path)
66
- job_collection.remote_dependencies.cleanup
67
- logger.info "Project: #{job_collection.projects}"
68
- errors = {}
69
- job_collection.projects.each do |project|
70
- next unless project[:name] == project_name || project_name.nil?
71
- errors.merge! process_pull_request_project project
56
+ load_job_collection path
57
+ defaults = job_collection.defaults[:value]
58
+ pr_generator = PullRequestGenerator.new defaults
59
+ pr_generator.delete_closed_prs
60
+ errors = []
61
+ pr_generator.open_prs.each do |pr|
62
+ pr_generator.convert! job_collection, pr
63
+ error = publish(project_name)
64
+ errors << error unless error.empty?
72
65
  end
73
- print_compile_errors errors
74
66
  errors.empty?
75
67
  end
76
68
 
@@ -112,6 +104,21 @@ module JenkinsPipelineBuilder
112
104
 
113
105
  private
114
106
 
107
+ def load_job_collection(path)
108
+ job_collection.load_from_path(path)
109
+ job_collection.remote_dependencies.cleanup
110
+ end
111
+
112
+ def publish(project_name)
113
+ if job_collection.projects.any?
114
+ errors = publish_project(project_name)
115
+ else
116
+ errors = publish_jobs(job_collection.standalone_jobs)
117
+ end
118
+ print_compile_errors errors
119
+ errors
120
+ end
121
+
115
122
  def process_project(project)
116
123
  project_body = project[:value]
117
124
  jobs = prepare_jobs(project_body[:jobs]) if project_body[:jobs]
@@ -139,15 +146,6 @@ module JenkinsPipelineBuilder
139
146
  end
140
147
  end
141
148
 
142
- def process_pull_request_project(project)
143
- logger.info "Using Project #{project}"
144
-
145
- pull_request_generator = JenkinsPipelineBuilder::PullRequestGenerator.new project, self
146
-
147
- return {} if pull_request_generator.valid?
148
- { pull_request_generator.pull_generator[:name] => pull_request_generator.errors }
149
- end
150
-
151
149
  def prepare_jobs(jobs)
152
150
  jobs.map! do |job|
153
151
  job.is_a?(String) ? { job.to_sym => {} } : job
@@ -221,15 +219,8 @@ module JenkinsPipelineBuilder
221
219
  end
222
220
 
223
221
  def publish_project(project_name)
224
- errors = {}
225
- found = false
226
- job_collection.projects.each do |project|
227
- next if project[:name] != project_name && !project_name.nil?
228
- found = true
229
- errors = create_jobs_and_views(project)
230
- end
231
- fail "Project #{project_name} not found!" unless found
232
- errors
222
+ project = job_collection.projects.find { |p| p[:name] == project_name }
223
+ create_jobs_and_views(project || fail("Project #{project_name} not found!"))
233
224
  end
234
225
 
235
226
  def publish_jobs(jobs, errors = {})
@@ -19,149 +19,54 @@
19
19
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
20
  # THE SOFTWARE.
21
21
  #
22
-
23
22
  module JenkinsPipelineBuilder
24
23
  class PullRequestGenerator
25
24
  class NotFound < StandardError; end
25
+ attr_accessor :open_prs, :application_name
26
26
 
27
- attr_reader :purge, :create, :jobs, :project, :generator, :pull_generator, :errors, :pull_requests
28
-
29
- def initialize(project, generator)
30
- @project = project
31
- @generator = generator
32
- @purge = []
33
- @create = []
34
- @errors = {}
35
-
36
- @pull_generator = find
37
- payload = compile_generator
38
- return unless payload
39
- @jobs = filter_jobs
40
-
41
- # old init
42
- @pull_requests = check_for_pull payload
43
- find_old_pull_requests
44
- generate_pull_requests
45
-
46
- collection.merge! @jobs
47
- @errors.merge! create_jobs
48
-
49
- purge_jobs
50
- end
51
-
52
- def valid?
53
- errors.empty?
27
+ def initialize(defaults = {})
28
+ @application_name = defaults[:application_name]
29
+ @open_prs = active_prs defaults[:github_site], defaults[:git_org], defaults[:git_repo_name]
54
30
  end
55
31
 
56
- private
57
-
58
- def generate_pull_requests
59
- @pull_requests.each do |number|
60
- req = JenkinsPipelineBuilder::PullRequest.new(project, number, jobs, @pull_generator)
61
- @jobs.merge! req.jobs
62
- project_new = req.project
63
-
64
- # Overwrite the jobs from the generator to the project
65
- project_new[:value][:jobs] = req.jobs.keys
66
- @create << project_new
67
- end
32
+ def convert!(job_collection, pr)
33
+ job_collection.defaults[:value][:application_name] = "#{application_name}-PR#{pr}"
34
+ job_collection.jobs.each { |j| override j[:value], pr }
68
35
  end
69
36
 
70
- def purge_jobs
71
- purge.each do |purge_job|
72
- jobs = JenkinsPipelineBuilder.client.job.list "#{purge_job}.*"
73
- jobs.each do |job|
74
- JenkinsPipelineBuilder.client.job.delete job
75
- end
37
+ def delete_closed_prs
38
+ return if JenkinsPipelineBuilder.debug
39
+ jobs_to_delete = JenkinsPipelineBuilder.client.job.list "#{application_name}-PR.*"
40
+ open_prs.each do |n|
41
+ jobs_to_delete.reject! { |j| j.start_with? "#{application_name}-PR#{n}" }
76
42
  end
43
+ jobs_to_delete.each { |j| JenkinsPipelineBuilder.client.job.delete j }
77
44
  end
78
45
 
79
- def create_jobs
80
- errors = {}
81
- create.each do |pull_project|
82
- success, compiled_project = generator.resolve_project(pull_project)
83
- compiled_project[:value][:jobs].each do |i|
84
- job = i[:result]
85
- job = Job.new job
86
- success, payload = job.create_or_update
87
- errors[job.name] = payload unless success
88
- end
89
- end
90
- errors
91
- end
92
-
93
- def collection
94
- generator.job_collection.collection
95
- end
96
-
97
- def filter_jobs
98
- jobs = {}
99
- pull_jobs = pull_generator[:value][:jobs] || []
100
- pull_jobs.each do |job|
101
- if job.is_a? String
102
- jobs[job.to_s] = collection[job.to_s]
103
- else
104
- jobs[job.keys.first.to_s] = collection[job.keys.first.to_s]
105
- end
106
- end
107
- fail 'No jobs found for pull request' if jobs.empty?
108
- jobs
109
- end
110
-
111
- def compile_generator
112
- defaults = generator.job_collection.defaults
113
- settings = defaults.nil? ? {} : defaults[:value] || {}
114
- compiler = Compiler.new generator
115
- settings = compiler.get_settings_bag(project, settings)
116
- success, payload = generator.resolve_job_by_name(pull_generator[:name], settings)
117
- return payload if success
46
+ private
118
47
 
119
- @errors[@pull_generator[:name]] = payload
120
- false
48
+ def override(job, pr)
49
+ git_version = JenkinsPipelineBuilder.registry.registry[:job][:scm_params].installed_version
50
+ job[:scm_branch] = "origin/pr/#{pr}/head"
51
+ job[:scm_params] ||= {}
52
+ job[:scm_params][:refspec] = "refs/pull/#{pr}/head:refs/remotes/origin/pr/#{pr}/head"
53
+ job[:scm_params][:changelog_to_branch] ||= {}
54
+ job[:scm_params][:changelog_to_branch]
55
+ .merge!(remote: 'origin', branch: "pr/#{pr}/head") if Gem::Version.new(2.0) < git_version
121
56
  end
122
57
 
123
- def find
124
- project_jobs = project[:value][:jobs] || []
125
- pull_job = nil
126
- project_jobs.each do |job|
127
- job = job.keys.first if job.is_a? Hash
128
- job = collection[job.to_s]
129
-
130
- pull_job = job if job[:value][:job_type] == 'pull_request_generator'
131
- end
132
- fail NotFound, 'No jobs of type pull_request_generator found' unless pull_job
133
- pull_job
134
- end
135
-
136
- # Check for Github Pull Requests
137
- #
138
- # args[:git_url] URL to the github main page ex. https://www.github.com/
139
- # args[:git_repo] Name of repo only, not url ex. jenkins_pipeline_builder
140
- # args[:git_org] The Orig user ex. constantcontact
141
- # @return = array of pull request numbers
142
- def check_for_pull(args)
143
- fail 'Please specify all arguments' unless args[:git_url] && args[:git_org] && args[:git_repo]
58
+ def active_prs(git_url, git_org, git_repo)
59
+ (git_url && git_org && git_repo) || fail('Please set github_site, git_org and git_repo_name in your project.')
144
60
  # Build the Git URL
145
- git_url = "#{args[:git_url]}api/v3/repos/#{args[:git_org]}/#{args[:git_repo]}/pulls"
146
-
61
+ url = "#{git_url}/api/v3/repos/#{git_org}/#{git_repo}/pulls"
147
62
  # Download the JSON Data from the API
148
- resp = Net::HTTP.get_response(URI.parse(git_url))
149
- pulls = JSON.parse(resp.body)
150
- pulls.map { |p| p['number'] }
151
- end
152
-
153
- def find_old_pull_requests
154
- reqs = pull_requests.clone.map { |req| "#{project[:name]}-PR#{req}" }
155
- # Read File
156
- # FIXME: Shouldn't this be opening just with read permissions?
157
- old_requests = File.new('pull_requests.csv', 'a+').read.split(',')
158
-
159
- # Pop off current pull requests
160
- old_requests.delete_if { |req| reqs.include?("#{req}") }
161
- @purge = old_requests
162
-
163
- # Write File
164
- File.open('pull_requests.csv', 'w+') { |file| file.write reqs.join(',') }
63
+ begin
64
+ resp = Net::HTTP.get_response(URI.parse(url))
65
+ pulls = JSON.parse(resp.body)
66
+ pulls.map { |p| p['number'] }
67
+ rescue StandardError
68
+ raise 'Failed connecting to github!'
69
+ end
165
70
  end
166
71
  end
167
72
  end
@@ -21,5 +21,5 @@
21
21
  #
22
22
 
23
23
  module JenkinsPipelineBuilder
24
- VERSION = '0.12.4'
24
+ VERSION = '0.13.0'
25
25
  end
@@ -1,11 +1,5 @@
1
1
  - job:
2
2
  name: '{{name}}-40-PullRequestGenerator'
3
- job_type: pull_request_generator
4
- git_url: '{{git_url}}'
5
- git_repo: '{{git_repo}}'
6
- git_org: '{{git_org}}'
7
- jobs:
8
- - '{{name}}-10-SampleJob'
9
3
  builders:
10
4
  - shell_command: |
11
5
  generate -v || gem install jenkins_pipeline_builder
@@ -1,11 +1,12 @@
1
1
  - defaults:
2
2
  name: global
3
+ application_name: 'testapp'
3
4
  description: 'Test pipeline for generator_spec.rb'
4
- git_url: 'https://github.com'
5
- git_org: 'bencentra'
6
- git_repo: 'generator_tests'
5
+ github_site: 'https://github.com'
6
+ git_org: 'testorg'
7
+ git_repo_name: 'generator_tests'
7
8
 
8
- - project:
9
+ - project:
9
10
  name: PullRequest
10
11
  jobs:
11
12
  - '{{name}}-10-SampleJob'
@@ -135,31 +135,32 @@ describe JenkinsPipelineBuilder::Generator do
135
135
  let(:path) { File.expand_path('../fixtures/generator_tests/pullrequest_pipeline', __FILE__) }
136
136
  it 'produces no errors while creating pipeline PullRequest' do
137
137
  job_name = 'PullRequest'
138
- allow_any_instance_of(JenkinsPipelineBuilder::PullRequestGenerator).to receive(:check_for_pull).and_return([1])
139
- allow_any_instance_of(JenkinsPipelineBuilder::PullRequestGenerator).to receive(:purge_jobs).and_return(true)
138
+ pr_generator = double('pr_generator')
139
+ expect(JenkinsPipelineBuilder::PullRequestGenerator).to receive(:new)
140
+ .with(hash_including(application_name: 'testapp',
141
+ github_site: 'https://github.com',
142
+ git_org: 'testorg',
143
+ git_repo_name: 'generator_tests'))
144
+ .and_return(pr_generator)
145
+ expect(pr_generator).to receive(:delete_closed_prs)
146
+ expect(pr_generator).to receive(:convert!)
147
+ expect(pr_generator).to receive(:open_prs).and_return [1]
140
148
  success = @generator.pull_request(path, job_name)
141
149
  expect(success).to be_truthy
142
150
  end
143
151
 
144
152
  it 'correctly creates jobs when there are multiple pulls open' do
145
153
  job_name = 'PullRequest'
146
- allow_any_instance_of(JenkinsPipelineBuilder::PullRequestGenerator).to receive(:check_for_pull).and_return([1, 2])
147
- job1 = double name: 'job name'
148
- job2 = double name: 'job name'
149
- expect(JenkinsPipelineBuilder::Job).to receive(:new).once.with(
150
- name: 'PullRequest-PR1-10-SampleJob', scm_branch: 'origin/pr/1/head', scm_params: {
151
- refspec: 'refs/pull/1/head:refs/remotes/origin/pr/1/head',
152
- changelog_to_branch: { remote: 'origin', branch: 'pr/1/head' }
153
- }
154
- ).and_return job1
155
- expect(JenkinsPipelineBuilder::Job).to receive(:new).once.with(
156
- name: 'PullRequest-PR2-10-SampleJob', scm_branch: 'origin/pr/2/head', scm_params: {
157
- refspec: 'refs/pull/2/head:refs/remotes/origin/pr/2/head',
158
- changelog_to_branch: { remote: 'origin', branch: 'pr/2/head' }
159
- }
160
- ).and_return job2
161
- expect(job1).to receive(:create_or_update).and_return true
162
- expect(job2).to receive(:create_or_update).and_return true
154
+ pr_generator = double('pr_generator')
155
+ expect(JenkinsPipelineBuilder::PullRequestGenerator).to receive(:new)
156
+ .with(hash_including(application_name: 'testapp',
157
+ github_site: 'https://github.com',
158
+ git_org: 'testorg',
159
+ git_repo_name: 'generator_tests'))
160
+ .and_return(pr_generator)
161
+ expect(pr_generator).to receive(:delete_closed_prs)
162
+ expect(pr_generator).to receive(:convert!).twice
163
+ expect(pr_generator).to receive(:open_prs).and_return [1, 2]
163
164
  expect(@generator.pull_request(path, job_name)).to be_truthy
164
165
  end
165
166
  # Things to check for
@@ -1,99 +1,132 @@
1
1
  require File.expand_path('../spec_helper', __FILE__)
2
- require 'webmock/rspec'
2
+ require 'json'
3
3
 
4
4
  describe JenkinsPipelineBuilder::PullRequestGenerator do
5
- let(:pull_request_generator) { JenkinsPipelineBuilder::PullRequestGenerator }
6
- let(:project) do
5
+ let(:application_name) { 'testapp' }
6
+ let(:github_site) { 'https://github.com' }
7
+ let(:git_org) { 'git_org' }
8
+ let(:git_repo_name) { 'git_repo' }
9
+ let(:prs) { (1..10).map { |n| "#{application_name}-PR#{n}" } }
10
+ let(:closed_prs) { (1..6).map { |n| "#{application_name}-PR#{n}" } }
11
+ let(:open_prs_json) { (7..10).map { |n| { number: n } }.to_json }
12
+ let(:url) { "#{github_site}/api/v3/repos/#{git_org}/#{git_repo_name}/pulls" }
13
+ let(:params) do
7
14
  {
8
- name: 'pull_req_test',
9
- type: :project,
10
- value: {
11
- name: 'pull_req_test',
12
- jobs: [
13
- {
14
- name: '{{name}}-00',
15
- type: :job,
16
- job_type: 'pull_request_generator',
17
- git_url: 'https://www.github.com/',
18
- git_repo: 'jenkins_pipeline_builder',
19
- git_org: 'constantcontact',
20
- jobs: [
21
- '{{name}}-10',
22
- '{{name}}-11'
23
- ],
24
- builders: [{ shell_command: 'generate -v || gem install jenkins_pipeline_builder\ngenerate pipeline -c config/{{login_config}} pull_request pipeline/ {{name}}\n' }]
25
- },
26
- '{{name}}-10',
27
- '{{name}}-11']
28
- }
15
+ github_site: github_site,
16
+ git_org: git_org,
17
+ git_repo_name: git_repo_name,
18
+ application_name: application_name
29
19
  }
30
20
  end
31
- let(:jobs) do
32
- {
33
- '{{name}}-10' => {
34
- name: '{{name}}-10',
35
- type: :'job-template',
36
- value: {
37
- name: '{{name}}-10',
38
- description: '{{description}}',
39
- publishers: [{ downstream: { project: '{{job@{{name}}-11}}' } }]
40
- }
41
- },
42
- '{{name}}-11' => {
43
- name: '{{name}}-11',
44
- type: :'job-template',
45
- value: {
46
- name: '{{name}}-11',
47
- description: '{{description}}' }
48
- }
49
- }
21
+ let(:job_collection) do
22
+ double('job_collection',
23
+ defaults: { value: { application_name: application_name } },
24
+ jobs: [{ value: { scm_branch: 'master', scm_params: { random: 'foo' } } }])
50
25
  end
51
- let(:create_jobs) do
52
- [
53
- {
54
- name: 'pull_req_test-PR5',
55
- type: :project,
56
- value: {
57
- name: 'pull_req_test-PR5',
58
- jobs: ['{{name}}-10',
59
- '{{name}}-11'],
60
- pull_request_number: '5' }
61
- },
62
- {
63
- name: 'pull_req_test-PR6',
64
- type: :project,
65
- value: {
66
- name: 'pull_req_test-PR6',
67
- jobs: ['{{name}}-10',
68
- '{{name}}-11'],
69
- pull_request_number: '6'
70
- }
71
- }
72
- ]
26
+ subject { JenkinsPipelineBuilder::PullRequestGenerator.new params }
27
+
28
+ context '#initialize' do
29
+ it 'fails when one of the params is not set' do
30
+ expect do
31
+ JenkinsPipelineBuilder::PullRequestGenerator.new(application_name: 'name')
32
+ end.to raise_error('Please set github_site, git_org and git_repo_name in your project.')
33
+ end
34
+ it 'fails when github is not reponding properly' do
35
+ stub_request(:get, url)
36
+ .with(headers: { 'Accept' => '*/*',
37
+ 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
38
+ 'Host' => 'github.com',
39
+ 'User-Agent' => 'Ruby' })
40
+ .to_raise 'error'
41
+ expect { subject }.to raise_error('Failed connecting to github!')
42
+ end
73
43
  end
74
- let(:generator) { JenkinsPipelineBuilder::Generator.new }
75
- before do
76
- # Request to get current pull requests from github
77
- stub_request(:any, 'https://www.github.com/api/v3/repos/constantcontact/jenkins_pipeline_builder/pulls').to_return(body: '[{"number": 5,"state": "open","title": "Update README again" },{"number": 6,"state": "open", "title": "Update README again2"}]')
78
- stub_request(:any, 'http://username:password@127.0.0.1:8080/api/json').to_return(body: '{"assignedLabels":[{}],"mode":"NORMAL","nodeDescription":"the master Jenkins node","nodeName":"","numExecutors":2,"description":null,"jobs":[{"name":"PurgeTest-PR1","url":"http://localhost:8080/job/PurgeTest-PR1/","color":"notbuilt" },{"name":"PurgeTest-PR3","url":"http://localhost:8080/job/PurgeTest-PR3/","color":"notbuilt" },{"name":"PurgeTest-PR4","url":"http://localhost:8080/job/PurgeTest-PR4/","color":"notbuilt"}],"overallLoad":{},"primaryView":{"name":"All","url":"http://localhost:8080/" },"quietingDown":false,"slaveAgentPort":0,"unlabeledLoad":{},"useCrumbs":false,"useSecurity":true,"views":[{"name":"All","url":"http://localhost:8080/"}]}')
44
+
45
+ context '#delete_closed_prs' do
46
+ it 'deletes closed prs' do
47
+ stub_request(:get, url)
48
+ .with(headers: { 'Accept' => '*/*',
49
+ 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
50
+ 'Host' => 'github.com',
51
+ 'User-Agent' => 'Ruby' })
52
+ .to_return(status: 200, body: open_prs_json, headers: {})
53
+ job = double('job')
54
+ expect(job).to receive(:list).with("#{application_name}-PR.*").and_return prs
55
+ client = double('client', job: job)
56
+ expect(JenkinsPipelineBuilder).to receive(:debug).and_return false
57
+ allow(JenkinsPipelineBuilder).to receive(:client).and_return client
58
+ closed_prs.each { |pr| expect(job).to receive(:delete).with(pr) }
59
+ subject.delete_closed_prs
60
+ end
61
+
62
+ it 'does not fail when there are no closed prs' do
63
+ stub_request(:get, url)
64
+ .with(headers: { 'Accept' => '*/*',
65
+ 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
66
+ 'Host' => 'github.com',
67
+ 'User-Agent' => 'Ruby' })
68
+ .to_return(status: 200, body: open_prs_json, headers: {})
69
+ job = double('job')
70
+ expect(job).to receive(:list).with("#{application_name}-PR.*").and_return prs - closed_prs
71
+ client = double('client', job: job)
72
+ expect(JenkinsPipelineBuilder).to receive(:debug).and_return false
73
+ allow(JenkinsPipelineBuilder).to receive(:client).and_return client
74
+ expect(job).not_to receive(:delete)
75
+ subject.delete_closed_prs
76
+ end
79
77
  end
80
- describe '#initialize' do
81
- after(:all) do
82
- FileUtils.rm_r 'pull_requests.csv'
78
+
79
+ context '#convert!' do
80
+ it 'converts the job application name' do
81
+ stub_request(:get, url)
82
+ .with(headers: { 'Accept' => '*/*',
83
+ 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
84
+ 'Host' => 'github.com',
85
+ 'User-Agent' => 'Ruby' })
86
+ .to_return(status: 200, body: open_prs_json, headers: {})
87
+ collection = job_collection.clone
88
+ subject.convert! collection, 8
89
+ expect(collection.defaults[:value][:application_name]).to eq "#{application_name}-PR8"
83
90
  end
84
91
 
85
- it 'can work without a csv' do
86
- pending 'rework this'
87
- pull = pull_request_generator.new(project, generator)
88
- generator.job_collection.collection = jobs
89
- expect(pull.purge.count).to eq(0)
90
- expect(pull.create).to eq(create_jobs)
92
+ it 'overrides the git params' do
93
+ stub_request(:get, url)
94
+ .with(headers: { 'Accept' => '*/*',
95
+ 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
96
+ 'Host' => 'github.com',
97
+ 'User-Agent' => 'Ruby' })
98
+ .to_return(status: 200, body: open_prs_json, headers: {})
99
+ pr = 8
100
+ collection = job_collection.clone
101
+ subject.convert! collection, pr
102
+ expect(collection.jobs.first[:value]).to eq(
103
+ scm_branch: "origin/pr/#{pr}/head",
104
+ scm_params: {
105
+ refspec: "refs/pull/#{pr}/head:refs/remotes/origin/pr/#{pr}/head",
106
+ changelog_to_branch: { remote: 'origin', branch: "pr/#{pr}/head" },
107
+ random: 'foo'
108
+ }
109
+ )
91
110
  end
92
- it 'can work with a csv' do
93
- pending 'rework this'
94
- pull = pull_request_generator.new(project, generator)
95
- expect(pull.purge.count).to eq(0)
96
- expect(pull.create).to eq(create_jobs)
111
+
112
+ it 'does not override extra params' do
113
+ stub_request(:get, url)
114
+ .with(headers: { 'Accept' => '*/*',
115
+ 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
116
+ 'Host' => 'github.com',
117
+ 'User-Agent' => 'Ruby' })
118
+ .to_return(status: 200, body: open_prs_json, headers: {})
119
+ pr = 8
120
+ collection = job_collection.clone
121
+ subject.convert! collection, pr
122
+ expect(collection.jobs.first[:value]).to eq(
123
+ scm_branch: "origin/pr/#{pr}/head",
124
+ scm_params: {
125
+ refspec: "refs/pull/#{pr}/head:refs/remotes/origin/pr/#{pr}/head",
126
+ changelog_to_branch: { remote: 'origin', branch: "pr/#{pr}/head" },
127
+ random: 'foo'
128
+ }
129
+ )
97
130
  end
98
131
  end
99
132
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jenkins_pipeline_builder
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.4
4
+ version: 0.13.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Igor Moochnick
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-09-18 00:00:00.000000000 Z
12
+ date: 2015-11-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: nokogiri
@@ -370,7 +370,6 @@ files:
370
370
  - lib/jenkins_pipeline_builder/job_collection.rb
371
371
  - lib/jenkins_pipeline_builder/module_registry.rb
372
372
  - lib/jenkins_pipeline_builder/project.rb
373
- - lib/jenkins_pipeline_builder/pull_request.rb
374
373
  - lib/jenkins_pipeline_builder/pull_request_generator.rb
375
374
  - lib/jenkins_pipeline_builder/remote_dependencies.rb
376
375
  - lib/jenkins_pipeline_builder/utils.rb
@@ -427,7 +426,6 @@ files:
427
426
  - spec/lib/jenkins_pipeline_builder/job_spec.rb
428
427
  - spec/lib/jenkins_pipeline_builder/module_registry_spec.rb
429
428
  - spec/lib/jenkins_pipeline_builder/pull_request_generator_spec.rb
430
- - spec/lib/jenkins_pipeline_builder/pull_request_spec.rb
431
429
  - spec/lib/jenkins_pipeline_builder/spec_helper.rb
432
430
  - spec/lib/jenkins_pipeline_builder/utils_spec.rb
433
431
  - spec/lib/jenkins_pipeline_builder/view_spec.rb
@@ -505,7 +503,6 @@ test_files:
505
503
  - spec/lib/jenkins_pipeline_builder/job_spec.rb
506
504
  - spec/lib/jenkins_pipeline_builder/module_registry_spec.rb
507
505
  - spec/lib/jenkins_pipeline_builder/pull_request_generator_spec.rb
508
- - spec/lib/jenkins_pipeline_builder/pull_request_spec.rb
509
506
  - spec/lib/jenkins_pipeline_builder/spec_helper.rb
510
507
  - spec/lib/jenkins_pipeline_builder/utils_spec.rb
511
508
  - spec/lib/jenkins_pipeline_builder/view_spec.rb
@@ -1,92 +0,0 @@
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
- module JenkinsPipelineBuilder
23
- class PullRequest
24
- attr_reader :project # The root project YAML as a hash
25
- attr_reader :number # The pull request number
26
- attr_reader :jobs # The jobs in the pull request as an array of hashes
27
- attr_reader :pull_generator # The generator job YAML as a hash
28
-
29
- def initialize(project, number, jobs, pull_generator)
30
- @project = Marshal.load(Marshal.dump(project))
31
- @number = number
32
- @jobs = Marshal.load(Marshal.dump(jobs))
33
- @pull_generator = Marshal.load(Marshal.dump(pull_generator))
34
- @project[:value][:pull_request_number] = "#{@number}"
35
-
36
- run!
37
- end
38
-
39
- private
40
-
41
- def run!
42
- git_version = JenkinsPipelineBuilder.registry.registry[:job][:scm_params].installed_version
43
- if git_version >= Gem::Version.new(2.0)
44
- @jobs.each_value do |j|
45
- override_git_2_params j
46
- end
47
- end
48
- update_jobs!
49
- change_git!
50
- change_name!
51
- end
52
-
53
- def override_git_2_params(job)
54
- job[:value][:scm_params] ||= {}
55
- job[:value][:scm_params][:changelog_to_branch] = { remote: 'origin', branch: 'pr/{{pull_request_number}}/head' }
56
- end
57
-
58
- # Change the git branch for each job
59
- def change_git!
60
- @jobs.each_value do |job|
61
- job[:value][:scm_branch] = 'origin/pr/{{pull_request_number}}/head'
62
- job[:value][:scm_params] = {} unless job[:value][:scm_params]
63
- refspec = 'refs/pull/{{pull_request_number}}/head:refs/remotes/origin/pr/{{pull_request_number}}/head'
64
- job[:value][:scm_params][:refspec] = refspec
65
- end
66
- end
67
-
68
- # Change the name of the pull request project
69
- def change_name!
70
- @project[:name] = "#{@project[:name]}-PR#{@number}" if @project[:name]
71
- @project[:value][:name] = "#{@project[:value][:name]}-PR#{@number}" if @project[:value][:name]
72
-
73
- return unless pull_generator[:value][:inject_pr_into]
74
-
75
- key = pull_generator[:value][:inject_pr_into].to_sym
76
- project[:value][key] = "{{#{key}}}-PR#{@number}" if project[:value]
77
- end
78
-
79
- # Apply any specified changes to each job
80
- def update_jobs!
81
- @jobs.each_value do |job|
82
- name = job[:name]
83
- changes = nil
84
- @pull_generator[:value][:jobs].each do |gen|
85
- changes = gen[name.to_sym] if gen.is_a?(Hash) && gen.keys[0] == name.to_sym
86
- end
87
- # Apply changes
88
- Utils.hash_merge!(job[:value], changes) unless changes.nil?
89
- end
90
- end
91
- end
92
- end
@@ -1,161 +0,0 @@
1
- require File.expand_path('../spec_helper', __FILE__)
2
- require 'webmock/rspec'
3
-
4
- describe JenkinsPipelineBuilder::PullRequest do
5
- before :each do
6
- JenkinsPipelineBuilder.registry.registry[:job][:scm_params].installed_version = '1000.0'
7
- end
8
- after :each do
9
- JenkinsPipelineBuilder.registry.registry[:job][:scm_params].clear_installed_version
10
- end
11
- let(:project) do
12
- {
13
- name: 'pull_req_test',
14
- type: :project,
15
- value: {
16
- name: 'pull_req_test',
17
- jobs: ['{{name}}-00', '{{name}}-10', '{{name}}-11']
18
- }
19
- }
20
- end
21
- let(:value) { { jobs: ['{{name}}-10', '{{name}}-11'] } }
22
- let(:pull_request) do
23
- {
24
- name: '{{name}}-00',
25
- type: :job,
26
- job_type: 'pull_request_generator',
27
- git_url: 'https://www.github.com/',
28
- git_repo: 'jenkins_pipeline_builder',
29
- git_org: 'constantcontact',
30
- value: value,
31
- builders: [
32
- { shell_command: 'echo "shell command"' }
33
- ]
34
- }
35
- end
36
- let(:job1) { '{{name}}-10' }
37
- let(:job2) { '{{name}}-11' }
38
- let(:jobs) do
39
- {
40
- job1 => {
41
- name: job1,
42
- type: :'job-template',
43
- value: {
44
- name: job1,
45
- description: '{{description}}',
46
- publishers: [{ downstream: { project: "{{job@#{job2}}}" } }]
47
- }
48
- },
49
- job2 => {
50
- name: job2,
51
- type: :'job-template',
52
- value: {
53
- name: job2,
54
- description: '{{description}}'
55
- }
56
- }
57
- }
58
- end
59
- let(:post_scm_params) do
60
- {
61
- changelog_to_branch: {
62
- remote: 'origin',
63
- branch: 'pr/{{pull_request_number}}/head'
64
- },
65
- refspec: 'refs/pull/{{pull_request_number}}/head:refs/remotes/origin/pr/{{pull_request_number}}/head'
66
- }
67
- end
68
- let(:post_jobs) do
69
- {
70
- '{{name}}-10' => {
71
- name: '{{name}}-10',
72
- type: :'job-template',
73
- value: {
74
- name: '{{name}}-10',
75
- description: '{{description}}',
76
- publishers: [{ downstream: { project: '{{job@{{name}}-11}}' } }],
77
- scm_branch: 'origin/pr/{{pull_request_number}}/head',
78
- scm_params: post_scm_params
79
- }
80
- },
81
- '{{name}}-11' => {
82
- name: '{{name}}-11',
83
- type: :'job-template',
84
- value: {
85
- name: '{{name}}-11',
86
- description: '{{description}}',
87
- scm_branch: 'origin/pr/{{pull_request_number}}/head',
88
- scm_params: post_scm_params
89
- }
90
- }
91
- }
92
- end
93
- describe '#initialize' do
94
- it 'process pull_request' do
95
- pull = described_class.new(project, 2, jobs, pull_request)
96
- post_project = {
97
- name: 'pull_req_test-PR2',
98
- type: :project,
99
- value: {
100
- name: 'pull_req_test-PR2',
101
- jobs: ['{{name}}-00', '{{name}}-10', '{{name}}-11'],
102
- pull_request_number: '2'
103
- }
104
- }
105
-
106
- expect(pull.project).to eq(post_project)
107
- expect(pull.jobs).to eq(post_jobs)
108
- end
109
- end
110
-
111
- describe '#git_version_0' do
112
- let(:post_scm_params) do
113
- { refspec: 'refs/pull/{{pull_request_number}}/head:refs/remotes/origin/pr/{{pull_request_number}}/head' }
114
- end
115
-
116
- before :each do
117
- JenkinsPipelineBuilder.registry.registry[:job][:scm_params].installed_version = '0'
118
- end
119
- it 'process pull_request' do
120
- pull = described_class.new(project, 2, jobs, pull_request)
121
- expect(pull.jobs).to eq(post_jobs)
122
- end
123
- end
124
-
125
- describe '#git_version_2' do
126
- before :each do
127
- JenkinsPipelineBuilder.registry.registry[:job][:scm_params].installed_version = '2.0'
128
- end
129
- it 'process pull_request' do
130
- pull = described_class.new(project, 2, jobs, pull_request)
131
- expect(pull.jobs).to eq(post_jobs)
132
- end
133
- end
134
-
135
- context 'when the job does not have {{name}} in it' do
136
- let(:project) do
137
- {
138
- name: 'pull_req_test',
139
- type: :project,
140
- app_name: 'my_app',
141
- value: {
142
- name: 'pull_req_test',
143
- app_name: 'my_app',
144
- jobs: ['{{app_name}}-00', '{{app_name}}-10', '{{app_name}}-11']
145
- }
146
- }
147
- end
148
- let(:value) do
149
- {
150
- inject_pr_into: :app_name,
151
- jobs: ['{{app_name}}-10', '{{app_name}}-11']
152
- }
153
- end
154
- let(:job1) { '{{app_name}}-10' }
155
- let(:job2) { '{{app_name}}-11' }
156
- it 'injects the pr number into the job name when told to' do
157
- pull = described_class.new project, 2, jobs, pull_request
158
- expect(pull.project[:value][:app_name]).to eq '{{app_name}}-PR2'
159
- end
160
- end
161
- end