Skip to content
This repository has been archived by the owner on May 10, 2021. It is now read-only.

Commit

Permalink
Merge pull request #85 from sinangedik/master
Browse files Browse the repository at this point in the history
New PR implementation
  • Loading branch information
crimsonknave committed Nov 4, 2015
2 parents 44e4d5a + 605479e commit f4ba8a8
Show file tree
Hide file tree
Showing 10 changed files with 203 additions and 532 deletions.
1 change: 0 additions & 1 deletion lib/jenkins_pipeline_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
require 'jenkins_pipeline_builder/compiler'
require 'jenkins_pipeline_builder/module_registry'
require 'jenkins_pipeline_builder/pull_request_generator'
require 'jenkins_pipeline_builder/pull_request'
require 'jenkins_pipeline_builder/view'
require 'jenkins_pipeline_builder/job_collection'
require 'jenkins_pipeline_builder/job'
Expand Down
65 changes: 28 additions & 37 deletions lib/jenkins_pipeline_builder/generator.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#
# Copyright (c) 2014 Constant Contact
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
Expand Down Expand Up @@ -48,29 +47,22 @@ def view

def bootstrap(path, project_name = nil)
logger.info "Bootstrapping pipeline from path #{path}"
job_collection.load_from_path(path)
job_collection.remote_dependencies.cleanup

if job_collection.projects.any?
errors = publish_project(project_name)
else
errors = publish_jobs(job_collection.standalone_jobs)
end
print_compile_errors errors
errors
load_job_collection path
publish(project_name || job_collection.projects.first[:name])
end

def pull_request(path, project_name)
logger.info "Pull Request Generator Running from path #{path}"
job_collection.load_from_path(path)
job_collection.remote_dependencies.cleanup
logger.info "Project: #{job_collection.projects}"
errors = {}
job_collection.projects.each do |project|
next unless project[:name] == project_name || project_name.nil?
errors.merge! process_pull_request_project project
load_job_collection path
defaults = job_collection.defaults[:value]
pr_generator = PullRequestGenerator.new defaults
pr_generator.delete_closed_prs
errors = []
pr_generator.open_prs.each do |pr|
pr_generator.convert! job_collection, pr
error = publish(project_name)
errors << error unless error.empty?
end
print_compile_errors errors
errors.empty?
end

Expand Down Expand Up @@ -112,6 +104,21 @@ def resolve_project(project)

private

def load_job_collection(path)
job_collection.load_from_path(path)
job_collection.remote_dependencies.cleanup
end

def publish(project_name)
if job_collection.projects.any?
errors = publish_project(project_name)
else
errors = publish_jobs(job_collection.standalone_jobs)
end
print_compile_errors errors
errors
end

def process_project(project)
project_body = project[:value]
jobs = prepare_jobs(project_body[:jobs]) if project_body[:jobs]
Expand Down Expand Up @@ -139,15 +146,6 @@ def print_project_errors(errors)
end
end

def process_pull_request_project(project)
logger.info "Using Project #{project}"

pull_request_generator = JenkinsPipelineBuilder::PullRequestGenerator.new project, self

return {} if pull_request_generator.valid?
{ pull_request_generator.pull_generator[:name] => pull_request_generator.errors }
end

def prepare_jobs(jobs)
jobs.map! do |job|
job.is_a?(String) ? { job.to_sym => {} } : job
Expand Down Expand Up @@ -221,15 +219,8 @@ def create_jobs_and_views(project)
end

def publish_project(project_name)
errors = {}
found = false
job_collection.projects.each do |project|
next if project[:name] != project_name && !project_name.nil?
found = true
errors = create_jobs_and_views(project)
end
fail "Project #{project_name} not found!" unless found
errors
project = job_collection.projects.find { |p| p[:name] == project_name }
create_jobs_and_views(project || fail("Project #{project_name} not found!"))
end

def publish_jobs(jobs, errors = {})
Expand Down
92 changes: 0 additions & 92 deletions lib/jenkins_pipeline_builder/pull_request.rb

This file was deleted.

159 changes: 32 additions & 127 deletions lib/jenkins_pipeline_builder/pull_request_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,149 +19,54 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#

module JenkinsPipelineBuilder
class PullRequestGenerator
class NotFound < StandardError; end
attr_accessor :open_prs, :application_name

attr_reader :purge, :create, :jobs, :project, :generator, :pull_generator, :errors, :pull_requests

def initialize(project, generator)
@project = project
@generator = generator
@purge = []
@create = []
@errors = {}

@pull_generator = find
payload = compile_generator
return unless payload
@jobs = filter_jobs

# old init
@pull_requests = check_for_pull payload
find_old_pull_requests
generate_pull_requests

collection.merge! @jobs
@errors.merge! create_jobs

purge_jobs
end

def valid?
errors.empty?
def initialize(defaults = {})
@application_name = defaults[:application_name]
@open_prs = active_prs defaults[:github_site], defaults[:git_org], defaults[:git_repo_name]
end

private

def generate_pull_requests
@pull_requests.each do |number|
req = JenkinsPipelineBuilder::PullRequest.new(project, number, jobs, @pull_generator)
@jobs.merge! req.jobs
project_new = req.project

# Overwrite the jobs from the generator to the project
project_new[:value][:jobs] = req.jobs.keys
@create << project_new
end
def convert!(job_collection, pr)
job_collection.defaults[:value][:application_name] = "#{application_name}-PR#{pr}"
job_collection.jobs.each { |j| override j[:value], pr }
end

def purge_jobs
purge.each do |purge_job|
jobs = JenkinsPipelineBuilder.client.job.list "#{purge_job}.*"
jobs.each do |job|
JenkinsPipelineBuilder.client.job.delete job
end
def delete_closed_prs
return if JenkinsPipelineBuilder.debug
jobs_to_delete = JenkinsPipelineBuilder.client.job.list "#{application_name}-PR.*"
open_prs.each do |n|
jobs_to_delete.reject! { |j| j.start_with? "#{application_name}-PR#{n}" }
end
jobs_to_delete.each { |j| JenkinsPipelineBuilder.client.job.delete j }
end

def create_jobs
errors = {}
create.each do |pull_project|
success, compiled_project = generator.resolve_project(pull_project)
compiled_project[:value][:jobs].each do |i|
job = i[:result]
job = Job.new job
success, payload = job.create_or_update
errors[job.name] = payload unless success
end
end
errors
end

def collection
generator.job_collection.collection
end

def filter_jobs
jobs = {}
pull_jobs = pull_generator[:value][:jobs] || []
pull_jobs.each do |job|
if job.is_a? String
jobs[job.to_s] = collection[job.to_s]
else
jobs[job.keys.first.to_s] = collection[job.keys.first.to_s]
end
end
fail 'No jobs found for pull request' if jobs.empty?
jobs
end

def compile_generator
defaults = generator.job_collection.defaults
settings = defaults.nil? ? {} : defaults[:value] || {}
compiler = Compiler.new generator
settings = compiler.get_settings_bag(project, settings)
success, payload = generator.resolve_job_by_name(pull_generator[:name], settings)
return payload if success
private

@errors[@pull_generator[:name]] = payload
false
def override(job, pr)
git_version = JenkinsPipelineBuilder.registry.registry[:job][:scm_params].installed_version
job[:scm_branch] = "origin/pr/#{pr}/head"
job[:scm_params] ||= {}
job[:scm_params][:refspec] = "refs/pull/#{pr}/head:refs/remotes/origin/pr/#{pr}/head"
job[:scm_params][:changelog_to_branch] ||= {}
job[:scm_params][:changelog_to_branch]
.merge!(remote: 'origin', branch: "pr/#{pr}/head") if Gem::Version.new(2.0) < git_version
end

def find
project_jobs = project[:value][:jobs] || []
pull_job = nil
project_jobs.each do |job|
job = job.keys.first if job.is_a? Hash
job = collection[job.to_s]

pull_job = job if job[:value][:job_type] == 'pull_request_generator'
end
fail NotFound, 'No jobs of type pull_request_generator found' unless pull_job
pull_job
end

# Check for Github Pull Requests
#
# args[:git_url] URL to the github main page ex. https://www.github.com/
# args[:git_repo] Name of repo only, not url ex. jenkins_pipeline_builder
# args[:git_org] The Orig user ex. constantcontact
# @return = array of pull request numbers
def check_for_pull(args)
fail 'Please specify all arguments' unless args[:git_url] && args[:git_org] && args[:git_repo]
def active_prs(git_url, git_org, git_repo)
(git_url && git_org && git_repo) || fail('Please set github_site, git_org and git_repo_name in your project.')
# Build the Git URL
git_url = "#{args[:git_url]}api/v3/repos/#{args[:git_org]}/#{args[:git_repo]}/pulls"

url = "#{git_url}/api/v3/repos/#{git_org}/#{git_repo}/pulls"
# Download the JSON Data from the API
resp = Net::HTTP.get_response(URI.parse(git_url))
pulls = JSON.parse(resp.body)
pulls.map { |p| p['number'] }
end

def find_old_pull_requests
reqs = pull_requests.clone.map { |req| "#{project[:name]}-PR#{req}" }
# Read File
# FIXME: Shouldn't this be opening just with read permissions?
old_requests = File.new('pull_requests.csv', 'a+').read.split(',')

# Pop off current pull requests
old_requests.delete_if { |req| reqs.include?("#{req}") }
@purge = old_requests

# Write File
File.open('pull_requests.csv', 'w+') { |file| file.write reqs.join(',') }
begin
resp = Net::HTTP.get_response(URI.parse(url))
pulls = JSON.parse(resp.body)
pulls.map { |p| p['number'] }
rescue StandardError
raise 'Failed connecting to github!'
end
end
end
end
2 changes: 1 addition & 1 deletion lib/jenkins_pipeline_builder/version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,5 @@
#

module JenkinsPipelineBuilder
VERSION = '0.12.4'
VERSION = '0.13.0'
end
Loading

0 comments on commit f4ba8a8

Please sign in to comment.