diff --git a/CHANGELOG-EE b/CHANGELOG-EE index 281714e2512ee3f57fef95425f1c74ea79e52eaa..2c496536683636304f632899f8851177ba5d65f6 100644 --- a/CHANGELOG-EE +++ b/CHANGELOG-EE @@ -18,6 +18,7 @@ v 8.1.3 v 8.1.2 - Prevent a 500 error related to the JIRA external issue tracker service + - Add support for the Multi-Branch Project Plugin to Jenkins CI v 8.1.1 - Removed, see 8.1.2 diff --git a/app/controllers/projects/services_controller.rb b/app/controllers/projects/services_controller.rb index 404b5a5c43e60622526cc4db8aec76d37766974b..91c10ae9041623e128e455b43da8b1add3df4a89 100644 --- a/app/controllers/projects/services_controller.rb +++ b/app/controllers/projects/services_controller.rb @@ -10,7 +10,7 @@ class Projects::ServicesController < Projects::ApplicationController :jira_issue_transition_id, :notify, :color, :server_host, :server_port, :default_irc_uri, :enable_ssl_verification, - :multiproject_enabled, :pass_unstable] + :job_configuration, :pass_unstable] # Parameters to ignore if no value is specified FILTER_BLANK_PARAMS = [:password] diff --git a/app/models/project_services/jenkins_service.rb b/app/models/project_services/jenkins_service.rb index 6b589d6b54dca6138a842d69249f292715952697..be4ed815d6be0ccbafa54c36df27c294a8edb70c 100644 --- a/app/models/project_services/jenkins_service.rb +++ b/app/models/project_services/jenkins_service.rb @@ -15,7 +15,7 @@ class JenkinsService < CiService prop_accessor :project_url - prop_accessor :multiproject_enabled + prop_accessor :job_configuration prop_accessor :pass_unstable validates :project_url, presence: true, if: :activated? @@ -50,24 +50,31 @@ def to_param def fields [ { type: 'text', name: 'project_url', placeholder: 'Jenkins project URL like http://jenkins.example.com/job/my-project/' }, - { type: 'checkbox', name: 'multiproject_enabled', title: "Multi-project setup enabled?", - help: "Multi-project mode is configured in Jenkins Gitlab Hook plugin." }, + { type: 'radio_group', name: 'job_configuration', title: 'Job configuration', model_method: :job_configuration, + choices: [ + { value: 'simple', title: 'Simple', help: 'There is 1 job configured in Jenkins that build all branches' }, + { value: 'multi_project', title: 'Gitlab Hook plugin project per branch', help: 'Multi-project mode is configured in Jenkins Gitlab Hook plugin.' }, + { value: 'multi_branch_project', title: 'Multi branch project', help: 'The job is configured in Jenkins as Multi-Branch project (Multi-Branch Project Plugin)' } + ], + default_choice: 'simple' + }, { type: 'checkbox', name: 'pass_unstable', title: 'Should unstable builds be treated as passing?', help: 'Unstable builds will be treated as passing.' } ] end - def multiproject_enabled? - self.multiproject_enabled == '1' - end - def pass_unstable? self.pass_unstable == '1' end def build_page(sha, ref = nil) - if multiproject_enabled? && ref.present? + case self.job_configuration + when 'multi_project' URI.encode("#{base_project_url}/#{project.name}_#{ref.gsub('/', '_')}/scm/bySHA1/#{sha}").to_s + + when 'multi_branch_project' + "#{project_url}/branch/#{ref.gsub('/', '%2F')}/scm/bySHA1/#{sha}" + else "#{project_url}/scm/bySHA1/#{sha}" end diff --git a/app/views/shared/_field.html.haml b/app/views/shared/_field.html.haml index 8d6e16f74c3aa0357568c50925c4c89c6e9f410c..2f9a880f9b1e3b165ae503c1f24b1f1ec55bd3c4 100644 --- a/app/views/shared/_field.html.haml +++ b/app/views/shared/_field.html.haml @@ -6,6 +6,7 @@ - choices = field[:choices] - default_choice = field[:default_choice] - help = field[:help] +- model_method = field[:model_method] .form-group - if type == "password" && value.present? @@ -20,8 +21,10 @@ - elsif type == 'checkbox' = form.check_box name - elsif type == 'select' - = form.select name, options_for_select(choices, value ? value : default_choice), {}, { class: "form-control" } + = form.select name, options_for_select(choices, value || default_choice), {}, { class: "form-control" } - elsif type == 'password' = form.password_field name, autocomplete: "new-password", class: 'form-control' + - elsif type == 'radio_group' + = render('shared/radio_group', model_method: model_method, choices: choices, form: form, selected_choice: value || default_choice) - if help %span.help-block= help diff --git a/app/views/shared/_radio_group.html.haml b/app/views/shared/_radio_group.html.haml new file mode 100644 index 0000000000000000000000000000000000000000..15b09be1296ecf9b50d6f7a959166f5714b093b8 --- /dev/null +++ b/app/views/shared/_radio_group.html.haml @@ -0,0 +1,9 @@ +- choices.each do |choice| + .radio + = form.label "#{model_method}_#{choice[:value]}" do + = form.radio_button model_method, choice[:value], checked: (selected_choice == choice[:value]) + %span + = choice[:title] + - if choice[:help] + %span.help-block + = choice[:help] \ No newline at end of file diff --git a/db/migrate/20151023133800_migrate_jenkins_ci_job_configuration.rb b/db/migrate/20151023133800_migrate_jenkins_ci_job_configuration.rb new file mode 100644 index 0000000000000000000000000000000000000000..1300cca8c3c8c616f619c32a84d821b4fad6ef10 --- /dev/null +++ b/db/migrate/20151023133800_migrate_jenkins_ci_job_configuration.rb @@ -0,0 +1,32 @@ +class MigrateJenkinsCiJobConfiguration < ActiveRecord::Migration + # This migration can be done online without errors, but the build status of merge request that have the + # multiproject_enabled activated won't be available during the migration + + def change + reversible do |dir| + select_all("SELECT id, properties FROM services WHERE services.type = 'JenkinsService'").each do |jenkins_service| + id = jenkins_service['id'] + properties = JSON.parse(jenkins_service['properties']) + properties_was = properties.clone + + dir.up do + if properties.delete('multiproject_enabled') == '1' + properties['job_configuration'] = 'multi_project' + else + properties['job_configuration'] = 'simple' + end + end + + dir.down do + if properties.delete('job_configuration') == 'multi_project' + properties['multiproject_enabled'] = '1' + end + end + + if properties != properties_was + execute("UPDATE services SET properties = '#{quote_string(properties.to_json)}' WHERE id = #{id}") + end + end + end + end +end diff --git a/spec/models/project_services/jenkins_service_spec.rb b/spec/models/project_services/jenkins_service_spec.rb index 756dbfda7df3fe179a7ed383acfcbe5ff4340e3b..b969c003922043f176d0bf6fb6d751713118a882 100644 --- a/spec/models/project_services/jenkins_service_spec.rb +++ b/spec/models/project_services/jenkins_service_spec.rb @@ -41,7 +41,7 @@ def status_body_for_icon(state) allow(@service).to receive_messages( service_hook: true, project_url: 'http://jenkins.gitlab.org/job/2', - multiproject_enabled: '0', + job_configuration: 'simple', pass_unstable: '0', token: 'verySecret' ) @@ -62,7 +62,7 @@ def status_body_for_icon(state) allow(@service).to receive_messages( service_hook: true, project_url: 'http://jenkins.gitlab.org/job/2', - multiproject_enabled: '0', + job_configuration: 'simple', pass_unstable: '1', token: 'verySecret' ) @@ -74,14 +74,14 @@ def status_body_for_icon(state) end end - describe 'multiproject enabled' do + describe 'multi_project job configuration' do let!(:project) { create(:project) } before do @service = JenkinsService.new allow(@service).to receive_messages( service_hook: true, project_url: 'http://jenkins.gitlab.org/job/2', - multiproject_enabled: '1', + job_configuration: 'multi_project', token: 'verySecret', project: project ) @@ -96,13 +96,33 @@ def status_body_for_icon(state) end end - describe 'multiproject disabled' do + describe 'multi_branch_project job configuration' do before do @service = JenkinsService.new allow(@service).to receive_messages( service_hook: true, project_url: 'http://jenkins.gitlab.org/job/2', - multiproject_enabled: '0', + job_configuration: 'multi_branch_project', + token: 'verySecret' + ) + end + + describe :build_page do + it { expect(@service.build_page('2ab7834c', 'master')).to eq('http://jenkins.gitlab.org/job/2/branch/master/scm/bySHA1/2ab7834c') } + end + + describe :build_page_with_branch do + it { expect(@service.build_page('2ab7834c', 'test/branch')).to eq('http://jenkins.gitlab.org/job/2/branch/test%2Fbranch/scm/bySHA1/2ab7834c') } + end + end + + describe 'simple job configuration' do + before do + @service = JenkinsService.new + allow(@service).to receive_messages( + service_hook: true, + project_url: 'http://jenkins.gitlab.org/job/2', + job_configuration: 'simple', token: 'verySecret' ) end