diff --git a/Gemfile b/Gemfile index 1aefe6e..d4d4386 100644 --- a/Gemfile +++ b/Gemfile @@ -1,10 +1,17 @@ source 'https://rubygems.org' -gem 'jenkins_api_client', '~> 1.3.0' +gem 'jenkins_api_client', '> 1.3.0' # HAML views gem 'haml-rails' +gem 'devise' +# , git: 'https://github.com/gogovan/devise.git', branch: 'rails-5.1' +gem 'erubis' + +# No: gem 'protected_attributes' +gem 'protected_attributes_continued' + group :development, :test do gem 'rspec', '~> 3.0.0' gem 'rspec-rails', '~> 3.0.1' @@ -19,7 +26,7 @@ group :development, :test do gem 'database_cleaner' # Code coverage - gem 'simplecov', '~> 0.9.1' + gem 'simplecov', '~> 0.14.1' gem 'simplecov-rcov' # Junit results diff --git a/app/controllers/jenkins_controller.rb b/app/controllers/jenkins_controller.rb index df8cabb..dc9cfa1 100644 --- a/app/controllers/jenkins_controller.rb +++ b/app/controllers/jenkins_controller.rb @@ -2,9 +2,9 @@ class JenkinsController < ApplicationController unloadable # Redmine ApplicationController method - before_filter :find_project_by_project_id - before_filter :can_view_jenkins_jobs - before_filter :find_jenkins_settings + before_action :find_project_by_project_id + before_action :can_view_jenkins_jobs + before_action :find_jenkins_settings require 'will_paginate/array' diff --git a/app/controllers/jenkins_jobs_controller.rb b/app/controllers/jenkins_jobs_controller.rb index 565252c..02319f9 100644 --- a/app/controllers/jenkins_jobs_controller.rb +++ b/app/controllers/jenkins_jobs_controller.rb @@ -2,10 +2,10 @@ class JenkinsJobsController < ApplicationController unloadable # Redmine ApplicationController method - before_filter :find_project_by_project_id + before_action :find_project_by_project_id - before_filter :can_build_jenkins_jobs, only: [:build] - before_filter :find_job, except: [:index, :new, :create] + before_action :can_build_jenkins_jobs, only: [:build] + before_action :find_job, except: [:index, :new, :create] layout Proc.new { |controller| controller.request.xhr? ? false : 'base' } diff --git a/app/controllers/jenkins_settings_controller.rb b/app/controllers/jenkins_settings_controller.rb index 9e7ad8b..99efbd7 100644 --- a/app/controllers/jenkins_settings_controller.rb +++ b/app/controllers/jenkins_settings_controller.rb @@ -2,8 +2,8 @@ class JenkinsSettingsController < ApplicationController unloadable # Redmine ApplicationController method - before_filter :find_project_by_project_id - before_filter :load_jenkins_settings + before_action :find_project_by_project_id + before_action :load_jenkins_settings def save diff --git a/app/models/jenkins_job.rb b/app/models/jenkins_job.rb index 795a959..8c5d8ac 100644 --- a/app/models/jenkins_job.rb +++ b/app/models/jenkins_job.rb @@ -32,9 +32,12 @@ def job_id def url - "#{jenkins_url}/job/#{name}" + "#{jenkins_url}/job/" + name2url end + def name2url + name.gsub('/', '/job/') + end def latest_build_url "#{url}/#{latest_build_number}" @@ -44,7 +47,7 @@ def latest_build_url def console console_output = begin - jenkins_connection.job.get_console_output(name, latest_build_number)['output'].gsub('\r\n', '
') + jenkins_connection.job.get_console_output(name2url, latest_build_number)['output'].gsub('\r\n', '
') rescue => e e.message end diff --git a/app/services/jenkins_client.rb b/app/services/jenkins_client.rb index 1b43d48..99496e5 100644 --- a/app/services/jenkins_client.rb +++ b/app/services/jenkins_client.rb @@ -1,4 +1,5 @@ require 'jenkins_api_client' +require 'logger' class JenkinsClient @@ -11,6 +12,12 @@ def initialize(url, opts = {}) @options[:http_read_timeout] = opts[:http_read_timeout] || 60 @options[:username] = opts[:username] if opts.has_key?(:username) @options[:password] = opts[:password] if opts.has_key?(:password) + + @log_location = STDOUT unless @log_location + @log_level = Logger::INFO unless @log_level + @logger = Logger.new(@log_location) + @logger.level = @log_level + end @@ -44,12 +51,51 @@ def test_connection def get_jobs_list - connection.job.list_all rescue [] + response_json_jobs = connection.job.list_all_with_details rescue [] + jobs = get_jobs_list_aux(response_json_jobs, '', []) + # connection.job.list_all rescue [] + jobs + end + + def get_jobs_list_aux(response_jobs_json, prefix, jobs_accumulator) + response_jobs_json.each do |job| + job_name = job["name"] + new_prefix = compute_new_prefix(prefix, job_name) + + @logger.info "get_jobs_list: If isFolder('#{job["name"]}') -> getSubfolders " + @logger.info "'#{job}'" + + + if job["_class"] == "com.cloudbees.hudson.plugins.folder.Folder" + job_suburl = name2url(new_prefix) + @logger.info "Job is a folder. Getting details of folder '#{new_prefix}' ('#{job_suburl}'): " + details_response_json = connection.job.list_details(job_suburl) + @logger.info "'#{details_response_json}'" + + jobs_accumulator = get_jobs_list_aux(details_response_json["jobs"], new_prefix, jobs_accumulator) rescue jobs_accumulator + else + jobs_accumulator << compute_new_prefix(prefix, job_name) + end + end + jobs_accumulator + end + + def compute_new_prefix(prefix, job_name) + if '' == prefix + new_prefix = job_name + else + new_prefix = prefix + '/' + job_name + end + new_prefix end + def name2url(job_name) + job_name.gsub('/', '/job/') + end def number_of_builds_for(job_name) - connection.job.list_details(job_name)['builds'].size rescue 0 + job_suburl = name2url(job_name) + connection.job.list_details(job_suburl)['builds'].size rescue 0 end end diff --git a/app/use_cases/jenkins_jobs/base.rb b/app/use_cases/jenkins_jobs/base.rb index 0db12fb..49baff0 100644 --- a/app/use_cases/jenkins_jobs/base.rb +++ b/app/use_cases/jenkins_jobs/base.rb @@ -1,3 +1,5 @@ +require 'logger' + module JenkinsJobs class Base @@ -14,6 +16,12 @@ def initialize(jenkins_job) @job_data = nil @errors = [] @use_case = self.class.name.split('::').last.underscore + + @log_location = STDOUT unless @log_location + @log_level = Logger::INFO unless @log_level + @logger = Logger.new(@log_location) + @logger.level = @log_level + end @@ -102,14 +110,18 @@ def create_build(build_number) build.save! ## Update changesets - create_changeset(build, build_details['changeSet']['items']) + create_changeset_if_possible(build, build_details) end def update_build(build, build_number) + @logger.info "update_build: Updating build information for build number '#{build_number}'" + ## Get BuildDetails from Jenkins build_details = get_jenkins_build_details(build_number) + @logger.info "update_build: build_details: '#{build_details}'" + ## Update the AR object with new data build.result = build_details['result'].nil? ? 'running' : build_details['result'] build.building = build_details['building'] @@ -117,10 +129,28 @@ def update_build(build, build_number) build.finished_at = Time.at(build_details['timestamp'].to_f / 1000) build.save! - ## Update changesets - create_changeset(build, build_details['changeSet']['items']) + ## Update changesets. + create_changeset_if_possible(build, build_details) end + def create_changeset_if_possible(build, build_details) + ## Update changesets. Be careful: sometimes the answer does not have them ... + if (build_details['changeSet'] == nil) + errorMsg = "Could not create changeSet: changeSet not available in Jenkins response." + @logger.warn errorMsg + @errors << errorMsg + else + changeSet = build_details['changeSet'] + if (changeSet['items'] == nil) + errorMsg = "Could not create changeSet: changeSetItems not available in Jenkins response." + @logger.warn errorMsg + @errors << errorMsg + else + changeSetItems = changeSet['items'] + create_changeset(build, changeSetItems) + end + end + end def clean_up_builds jenkins_job.builds.first(number_of_builds_to_delete).map(&:destroy) if too_much_builds? @@ -148,7 +178,7 @@ def create_changeset(build, changesets) def get_jenkins_job_details begin - data = jenkins_client.job.list_details(jenkins_job.name) + data = jenkins_client.job.list_details(jenkins_job.name2url) rescue => e @errors << e.message else @@ -159,7 +189,7 @@ def get_jenkins_job_details def get_jenkins_build_details(build_number) begin - data = jenkins_client.job.get_build_details(jenkins_job.name, build_number) + data = jenkins_client.job.get_build_details(jenkins_job.name2url, build_number) rescue => e @errors << e.message nil diff --git a/app/use_cases/jenkins_jobs/trigger_build.rb b/app/use_cases/jenkins_jobs/trigger_build.rb index ccc3358..01910ad 100644 --- a/app/use_cases/jenkins_jobs/trigger_build.rb +++ b/app/use_cases/jenkins_jobs/trigger_build.rb @@ -7,13 +7,21 @@ def execute opts['build_start_timeout'] = 30 if jenkins_job.wait_for_build_id begin - build_number = jenkins_client.job.build(jenkins_job.name, {}, opts) + jenkins_job_url = jenkins_job.name2url + @logger.info "Jenkins job suburl: '#{jenkins_job_url}' " + @logger.info "Jenkins job opts: '#{opts}' " + build_number = jenkins_client.job.build(jenkins_job_url, {}, opts) rescue => e - @errors << e.message + errorMsg = "Jenkins Response: " + e.message + @errors << errorMsg + @logger.error errorMsg + @logger.error e.backtrace.join("\n") else jenkins_job.latest_build_number = build_number if jenkins_job.wait_for_build_id jenkins_job.state = 'running' + @logger.error 'Jenkins job state is running' jenkins_job.save! + @logger.error 'Jenkins job saved! ' end end diff --git a/app/use_cases/jenkins_jobs/update_last_build.rb b/app/use_cases/jenkins_jobs/update_last_build.rb index 6963fde..2391efd 100644 --- a/app/use_cases/jenkins_jobs/update_last_build.rb +++ b/app/use_cases/jenkins_jobs/update_last_build.rb @@ -3,8 +3,16 @@ class UpdateLastBuild < Base def execute return if !job_status_updated? - last_build = job_data['builds'].any? ? [job_data['builds'].first] : [] - do_create_builds(last_build, true) + + begin + last_build = job_data['builds'].any? ? [job_data['builds'].first] : [] + do_create_builds(last_build, true) + rescue => e + @errors << e.message + @logger.error e.message + @logger.error e.backtrace.join("\n") + end + end end diff --git a/db/migrate/20150316023100_create_jenkins_settings.rb b/db/migrate/20150316023100_create_jenkins_settings.rb index feef466..d69afba 100644 --- a/db/migrate/20150316023100_create_jenkins_settings.rb +++ b/db/migrate/20150316023100_create_jenkins_settings.rb @@ -1,4 +1,4 @@ -class CreateJenkinsSettings < ActiveRecord::Migration +class CreateJenkinsSettings < ActiveRecord::Migration[5.0] def change create_table :jenkins_settings do |t| diff --git a/db/migrate/20150316023101_create_jenkins_jobs.rb b/db/migrate/20150316023101_create_jenkins_jobs.rb index 2449835..8b34457 100644 --- a/db/migrate/20150316023101_create_jenkins_jobs.rb +++ b/db/migrate/20150316023101_create_jenkins_jobs.rb @@ -1,4 +1,4 @@ -class CreateJenkinsJobs < ActiveRecord::Migration +class CreateJenkinsJobs < ActiveRecord::Migration[5.0] def change create_table :jenkins_jobs do |t| diff --git a/db/migrate/20150316023102_create_jenkins_builds.rb b/db/migrate/20150316023102_create_jenkins_builds.rb index 8709d88..d8113c9 100644 --- a/db/migrate/20150316023102_create_jenkins_builds.rb +++ b/db/migrate/20150316023102_create_jenkins_builds.rb @@ -1,4 +1,4 @@ -class CreateJenkinsBuilds < ActiveRecord::Migration +class CreateJenkinsBuilds < ActiveRecord::Migration[5.0] def change create_table :jenkins_builds do |t| diff --git a/db/migrate/20150316023103_create_jenkins_test_results.rb b/db/migrate/20150316023103_create_jenkins_test_results.rb index d2d41e3..ae270fe 100644 --- a/db/migrate/20150316023103_create_jenkins_test_results.rb +++ b/db/migrate/20150316023103_create_jenkins_test_results.rb @@ -1,4 +1,4 @@ -class CreateJenkinsTestResults < ActiveRecord::Migration +class CreateJenkinsTestResults < ActiveRecord::Migration[5.0] def change create_table :jenkins_test_results do |t| diff --git a/db/migrate/20150316023104_create_changesets_jenkins_builds.rb b/db/migrate/20150316023104_create_changesets_jenkins_builds.rb index afa5bb8..5763e29 100644 --- a/db/migrate/20150316023104_create_changesets_jenkins_builds.rb +++ b/db/migrate/20150316023104_create_changesets_jenkins_builds.rb @@ -1,4 +1,4 @@ -class CreateChangesetsJenkinsBuilds < ActiveRecord::Migration +class CreateChangesetsJenkinsBuilds < ActiveRecord::Migration[5.0] def change create_table :changesets_jenkins_builds do |t| diff --git a/install_and_test_plugin.sh b/install_and_test_plugin.sh new file mode 100755 index 0000000..a5ca5a9 --- /dev/null +++ b/install_and_test_plugin.sh @@ -0,0 +1,35 @@ +#!/bin/bash + +http_proxy=http://10.254.250.94:3128/ +https_proxy=http://10.254.250.94:3128/ + + +pushd /var/www/redmine-4.0/plugins/redmine_jenkins + +http_proxy=http://10.254.250.94:3128/ https_proxy=http://10.254.250.94:3128/ bundle update +http_proxy=http://10.254.250.94:3128/ https_proxy=http://10.254.250.94:3128/ bundle install + +popd + +pushd /var/www/redmine-4.0/ + +http_proxy=http://10.254.250.94:3128/ https_proxy=http://10.254.250.94:3128/ bundle update +http_proxy=http://10.254.250.94:3128/ https_proxy=http://10.254.250.94:3128/ bundle install + +popd + +echo "Restarting httpd..." + +systemctl stop httpd +systemctl start httpd + +systemctl status httpd + +echo " " +echo " " +echo "tail -f -n 100 /var/log/httpd/error_log /var/www/redmine-4.0/log/production.log" +echo " " +echo " " + +tail -f -n 100 /var/log/httpd/error_log /var/www/redmine-4.0/log/production.log + diff --git a/lib/redmine_jenkins/patches/projects_controller_patch.rb b/lib/redmine_jenkins/patches/projects_controller_patch.rb index c46da15..e3351ff 100644 --- a/lib/redmine_jenkins/patches/projects_controller_patch.rb +++ b/lib/redmine_jenkins/patches/projects_controller_patch.rb @@ -5,19 +5,22 @@ module Patches module ProjectsControllerPatch def self.included(base) - base.send(:include, InstanceMethods) +# base.send(:include, InstanceMethods) +# base.send(:include) base.class_eval do unloadable helper :jenkins helper :redmine_bootstrap_kit - alias_method_chain :settings, :redmine_jenkins + # alias_method_chain :settings, :redmine_jenkins + alias_method :settings_without_redmine_jenkins, :settings + alias_method :settings, :settings_with_redmine_jenkins end end - module InstanceMethods +# module InstanceMethods def settings_with_redmine_jenkins(&block) settings_without_redmine_jenkins(&block) @@ -30,7 +33,7 @@ def settings_with_redmine_jenkins(&block) end end - end +# end end end diff --git a/lib/redmine_jenkins/patches/projects_helper_patch.rb b/lib/redmine_jenkins/patches/projects_helper_patch.rb index 9f884f3..24634bf 100644 --- a/lib/redmine_jenkins/patches/projects_helper_patch.rb +++ b/lib/redmine_jenkins/patches/projects_helper_patch.rb @@ -5,16 +5,19 @@ module Patches module ProjectsHelperPatch def self.included(base) - base.send(:include, InstanceMethods) +# base.send(:include, InstanceMethods) base.class_eval do unloadable - alias_method_chain :project_settings_tabs, :redmine_jenkins + # alias_method_chain :project_settings_tabs, :redmine_jenkins + alias_method :project_settings_tabs_without_redmine_jenkins, :project_settings_tabs + alias_method :project_settings_tabs, :project_settings_tabs_with_redmine_jenkins + end end - module InstanceMethods +# module InstanceMethods def project_settings_tabs_with_redmine_jenkins(&block) tabs = project_settings_tabs_without_redmine_jenkins(&block) @@ -28,7 +31,7 @@ def project_settings_tabs_with_redmine_jenkins(&block) tabs end - end +# end end end diff --git a/lib/redmine_jenkins/patches/query_patch.rb b/lib/redmine_jenkins/patches/query_patch.rb index 14bf68c..cc20a59 100644 --- a/lib/redmine_jenkins/patches/query_patch.rb +++ b/lib/redmine_jenkins/patches/query_patch.rb @@ -5,18 +5,25 @@ module Patches module QueryPatch def self.included(base) - base.send(:include, InstanceMethods) +# base.send(:include, InstanceMethods) +# base.send(:include) base.class_eval do unloadable - alias_method_chain :available_filters, :redmine_jenkins - alias_method_chain :sql_for_field, :redmine_jenkins + # alias_method_chain :available_filters, :redmine_jenkins + alias_method :available_filters_without_redmine_jenkins, :available_filters + alias_method :available_filters, :available_filters_with_redmine_jenkins + + # alias_method_chain :sql_for_field, :redmine_jenkins + alias_method :sql_for_field_without_redmine_jenkins, :sql_for_field + alias_method :sql_for_field, :sql_for_field_with_redmine_jenkins + end end - module InstanceMethods +# module InstanceMethods def available_filters_with_redmine_jenkins return @available_filters if @available_filters @@ -204,7 +211,7 @@ def conditions_for(field, operator, value) return retval end - end +# end end end