jenkins_pipeline_builder 0.12.4 → 0.13.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 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