diff --git a/app/assets/javascripts/dispatcher.js b/app/assets/javascripts/dispatcher.js index 34708977d20..9e84e441ae8 100644 --- a/app/assets/javascripts/dispatcher.js +++ b/app/assets/javascripts/dispatcher.js @@ -521,6 +521,13 @@ import ProjectVariables from './project_variables'; case 'projects:settings:ci_cd:show': // Initialize expandable settings panels initSettingsPanels(); + + import(/* webpackChunkName: "ci-cd-settings" */ './projects/ci_cd_settings_bundle') + .then(ciCdSettings => ciCdSettings.default()) + .catch((err) => { + Flash(s__('ProjectSettings|Problem setting up the CI/CD settings JavaScript')); + throw err; + }); case 'groups:settings:ci_cd:show': new ProjectVariables(); break; diff --git a/app/assets/javascripts/flash.js b/app/assets/javascripts/flash.js index 67261c1c9b4..44deab9288e 100644 --- a/app/assets/javascripts/flash.js +++ b/app/assets/javascripts/flash.js @@ -41,7 +41,7 @@ const createFlashEl = (message, type, isInContentWrapper = false) => ` `; const removeFlashClickListener = (flashEl, fadeTransition) => { - flashEl.parentNode.addEventListener('click', () => hideFlash(flashEl, fadeTransition)); + flashEl.addEventListener('click', () => hideFlash(flashEl, fadeTransition)); }; /* diff --git a/app/assets/javascripts/main.js b/app/assets/javascripts/main.js index 08e326cba9c..5e0edd823be 100644 --- a/app/assets/javascripts/main.js +++ b/app/assets/javascripts/main.js @@ -301,6 +301,8 @@ $(function () { const flashContainer = document.querySelector('.flash-container'); if (flashContainer && flashContainer.children.length) { - removeFlashClickListener(flashContainer.children[0]); + flashContainer.querySelectorAll('.flash-alert, .flash-notice, .flash-success').forEach((flashEl) => { + removeFlashClickListener(flashEl); + }); } }); diff --git a/app/assets/javascripts/projects/ci_cd_settings_bundle.js b/app/assets/javascripts/projects/ci_cd_settings_bundle.js new file mode 100644 index 00000000000..90e418f6771 --- /dev/null +++ b/app/assets/javascripts/projects/ci_cd_settings_bundle.js @@ -0,0 +1,19 @@ +function updateAutoDevopsRadios(radioWrappers) { + radioWrappers.forEach((radioWrapper) => { + const radio = radioWrapper.querySelector('.js-auto-devops-enable-radio'); + const runPipelineCheckboxWrapper = radioWrapper.querySelector('.js-run-auto-devops-pipeline-checkbox-wrapper'); + const runPipelineCheckbox = radioWrapper.querySelector('.js-run-auto-devops-pipeline-checkbox'); + + if (runPipelineCheckbox) { + runPipelineCheckbox.checked = radio.checked; + runPipelineCheckboxWrapper.classList.toggle('hide', !radio.checked); + } + }); +} + +export default function initCiCdSettings() { + const radioWrappers = document.querySelectorAll('.js-auto-devops-enable-radio-wrapper'); + radioWrappers.forEach(radioWrapper => + radioWrapper.addEventListener('change', () => updateAutoDevopsRadios(radioWrappers)), + ); +} diff --git a/app/assets/stylesheets/framework/flash.scss b/app/assets/stylesheets/framework/flash.scss index e1b086ebb2b..88ce119ee3a 100644 --- a/app/assets/stylesheets/framework/flash.scss +++ b/app/assets/stylesheets/framework/flash.scss @@ -34,8 +34,15 @@ } } + .flash-success { + @extend .alert; + @extend .alert-success; + margin: 0; + } + .flash-notice, - .flash-alert { + .flash-alert, + .flash-success { border-radius: $border-radius-default; .container-fluid, @@ -48,7 +55,8 @@ margin-bottom: 0; .flash-notice, - .flash-alert { + .flash-alert, + .flash-success { border-radius: 0; } } diff --git a/app/controllers/projects/pipelines_settings_controller.rb b/app/controllers/projects/pipelines_settings_controller.rb index e65495b420e..b890818c475 100644 --- a/app/controllers/projects/pipelines_settings_controller.rb +++ b/app/controllers/projects/pipelines_settings_controller.rb @@ -12,6 +12,7 @@ class Projects::PipelinesSettingsController < Projects::ApplicationController if service.run_auto_devops_pipeline? CreatePipelineWorker.perform_async(project.id, current_user.id, project.default_branch, :web, ignore_skip_ci: true, save_on_errors: false) + flash[:success] = "A new Auto DevOps pipeline has been created, go to Pipelines page for details".html_safe end redirect_to project_settings_ci_cd_path(@project) diff --git a/app/views/layouts/_flash.html.haml b/app/views/layouts/_flash.html.haml index baa8036de10..1db32379df3 100644 --- a/app/views/layouts/_flash.html.haml +++ b/app/views/layouts/_flash.html.haml @@ -1,10 +1,6 @@ .flash-container.flash-container-page - - if alert - .flash-alert + -# We currently only support `alert`, `notice`, `success` + - flash.each do |key, value| + %div{ class: "flash-#{key}" } %div{ class: (container_class) } - %span= alert - - - elsif notice - .flash-notice - %div{ class: (container_class) } - %span= notice + %span= value diff --git a/app/views/projects/pipelines_settings/_show.html.haml b/app/views/projects/pipelines_settings/_show.html.haml index 77211099830..ee4fa663b9f 100644 --- a/app/views/projects/pipelines_settings/_show.html.haml +++ b/app/views/projects/pipelines_settings/_show.html.haml @@ -13,29 +13,39 @@ %p.settings-message.text-center = message.html_safe = f.fields_for :auto_devops_attributes, @auto_devops do |form| - .radio + .radio.js-auto-devops-enable-radio-wrapper = form.label :enabled_true do - = form.radio_button :enabled, 'true' + = form.radio_button :enabled, 'true', class: 'js-auto-devops-enable-radio' %strong Enable Auto DevOps %br %span.descr The Auto DevOps pipeline configuration will be used when there is no .gitlab-ci.yml in the project. - .radio + - if show_run_auto_devops_pipeline_checkbox_for_explicit_setting?(@project) + .checkbox.hide.js-run-auto-devops-pipeline-checkbox-wrapper + = label_tag 'project[run_auto_devops_pipeline_explicit]' do + = check_box_tag 'project[run_auto_devops_pipeline_explicit]', true, false, class: 'js-run-auto-devops-pipeline-checkbox' + = s_('ProjectSettings|Immediately run a pipeline on the default branch') + + .radio.js-auto-devops-enable-radio-wrapper = form.label :enabled_false do - = form.radio_button :enabled, 'false' + = form.radio_button :enabled, 'false', class: 'js-auto-devops-enable-radio' %strong Disable Auto DevOps %br %span.descr An explicit .gitlab-ci.yml needs to be specified before you can begin using Continuous Integration and Delivery. - .radio - = form.label :enabled_nil do - = form.radio_button :enabled, '' + .radio.js-auto-devops-enable-radio-wrapper + = form.label :enabled_ do + = form.radio_button :enabled, '', class: 'js-auto-devops-enable-radio' %strong Instance default (#{current_application_settings.auto_devops_enabled? ? 'enabled' : 'disabled'}) %br %span.descr Follow the instance default to either have Auto DevOps enabled or disabled when there is no project specific .gitlab-ci.yml. - %br + - if show_run_auto_devops_pipeline_checkbox_for_instance_setting?(@project) + .checkbox.hide.js-run-auto-devops-pipeline-checkbox-wrapper + = label_tag 'project[run_auto_devops_pipeline_implicit]' do + = check_box_tag 'project[run_auto_devops_pipeline_implicit]', true, false, class: 'js-run-auto-devops-pipeline-checkbox' + = s_('ProjectSettings|Immediately run a pipeline on the default branch') %p You need to specify a domain if you want to use Auto Review Apps and Auto Deploy stages. = form.text_field :domain, class: 'form-control', placeholder: 'domain.com' diff --git a/doc/topics/autodevops/img/auto_devops_settings.png b/doc/topics/autodevops/img/auto_devops_settings.png new file mode 100644 index 00000000000..b572cc5b855 Binary files /dev/null and b/doc/topics/autodevops/img/auto_devops_settings.png differ diff --git a/doc/topics/autodevops/index.md b/doc/topics/autodevops/index.md index 28308fc905c..914217772b8 100644 --- a/doc/topics/autodevops/index.md +++ b/doc/topics/autodevops/index.md @@ -121,7 +121,7 @@ Google Cloud. ## Enabling Auto DevOps -NOTE: **Note:** +**Note:** If you haven't done already, read the [prerequisites](#prerequisites) to make full use of Auto DevOps. If this is your fist time, we recommend you follow the [quick start guide](#quick-start). @@ -129,10 +129,14 @@ full use of Auto DevOps. If this is your fist time, we recommend you follow the 1. Go to your project's **Settings > CI/CD > General pipelines settings** and find the Auto DevOps section 1. Select "Enable Auto DevOps" +1. After selecting an option to enable Auto DevOps, a checkbox will appear below + so you can immediately run a pipeline on the default branch 1. Optionally, but recommended, add in the [base domain](#auto-devops-base-domain) that will be used by Kubernetes to deploy your application 1. Hit **Save changes** for the changes to take effect +![Project AutoDevops settings section](img/auto_devops_settings.png) + Now that it's enabled, there are a few more steps depending on whether your project has a `.gitlab-ci.yml` or not: diff --git a/spec/features/projects/settings/pipelines_settings_spec.rb b/spec/features/projects/settings/pipelines_settings_spec.rb index ea8f997409d..eb8e7265dd3 100644 --- a/spec/features/projects/settings/pipelines_settings_spec.rb +++ b/spec/features/projects/settings/pipelines_settings_spec.rb @@ -8,13 +8,14 @@ feature "Pipelines settings" do background do sign_in(user) project.team << [user, role] - visit project_pipelines_settings_path(project) end context 'for developer' do given(:role) { :developer } scenario 'to be disallowed to view' do + visit project_settings_ci_cd_path(project) + expect(page.status_code).to eq(404) end end @@ -23,6 +24,8 @@ feature "Pipelines settings" do given(:role) { :master } scenario 'be allowed to change' do + visit project_settings_ci_cd_path(project) + fill_in('Test coverage parsing', with: 'coverage_regex') click_on 'Save changes' @@ -32,6 +35,8 @@ feature "Pipelines settings" do end scenario 'updates auto_cancel_pending_pipelines' do + visit project_settings_ci_cd_path(project) + page.check('Auto-cancel redundant, pending pipelines') click_on 'Save changes' @@ -42,14 +47,119 @@ feature "Pipelines settings" do expect(checkbox).to be_checked end - scenario 'update auto devops settings' do - fill_in('project_auto_devops_attributes_domain', with: 'test.com') - page.choose('project_auto_devops_attributes_enabled_false') - click_on 'Save changes' + describe 'Auto DevOps' do + it 'update auto devops settings' do + visit project_settings_ci_cd_path(project) - expect(page.status_code).to eq(200) - expect(project.auto_devops).to be_present - expect(project.auto_devops).not_to be_enabled + fill_in('project_auto_devops_attributes_domain', with: 'test.com') + page.choose('project_auto_devops_attributes_enabled_false') + click_on 'Save changes' + + expect(page.status_code).to eq(200) + expect(project.auto_devops).to be_present + expect(project.auto_devops).not_to be_enabled + end + + describe 'Immediately run pipeline checkbox option', :js do + context 'when auto devops is set to instance default (enabled)' do + before do + stub_application_setting(auto_devops_enabled: true) + project.create_auto_devops!(enabled: nil) + visit project_settings_ci_cd_path(project) + end + + it 'does not show checkboxes on page-load' do + expect(page).to have_selector('.js-run-auto-devops-pipeline-checkbox-wrapper.hide', count: 1, visible: false) + end + + it 'selecting explicit disabled hides all checkboxes' do + page.choose('project_auto_devops_attributes_enabled_false') + + expect(page).to have_selector('.js-run-auto-devops-pipeline-checkbox-wrapper.hide', count: 1, visible: false) + end + + it 'selecting explicit enabled hides all checkboxes because we are already enabled' do + page.choose('project_auto_devops_attributes_enabled_true') + + expect(page).to have_selector('.js-run-auto-devops-pipeline-checkbox-wrapper.hide', count: 1, visible: false) + end + end + + context 'when auto devops is set to instance default (disabled)' do + before do + stub_application_setting(auto_devops_enabled: false) + project.create_auto_devops!(enabled: nil) + visit project_settings_ci_cd_path(project) + end + + it 'does not show checkboxes on page-load' do + expect(page).to have_selector('.js-run-auto-devops-pipeline-checkbox-wrapper.hide', count: 1, visible: false) + end + + it 'selecting explicit disabled hides all checkboxes' do + page.choose('project_auto_devops_attributes_enabled_false') + + expect(page).to have_selector('.js-run-auto-devops-pipeline-checkbox-wrapper.hide', count: 1, visible: false) + end + + it 'selecting explicit enabled shows a checkbox' do + page.choose('project_auto_devops_attributes_enabled_true') + + expect(page).to have_selector('.js-run-auto-devops-pipeline-checkbox-wrapper:not(.hide)', count: 1) + end + end + + context 'when auto devops is set to explicit disabled' do + before do + stub_application_setting(auto_devops_enabled: true) + project.create_auto_devops!(enabled: false) + visit project_settings_ci_cd_path(project) + end + + it 'does not show checkboxes on page-load' do + expect(page).to have_selector('.js-run-auto-devops-pipeline-checkbox-wrapper.hide', count: 2, visible: false) + end + + it 'selecting explicit enabled shows a checkbox' do + page.choose('project_auto_devops_attributes_enabled_true') + + expect(page).to have_selector('.js-run-auto-devops-pipeline-checkbox-wrapper:not(.hide)', count: 1) + end + + it 'selecting instance default (enabled) shows a checkbox' do + page.choose('project_auto_devops_attributes_enabled_') + + expect(page).to have_selector('.js-run-auto-devops-pipeline-checkbox-wrapper:not(.hide)', count: 1) + end + end + + context 'when auto devops is set to explicit enabled' do + before do + stub_application_setting(auto_devops_enabled: false) + project.create_auto_devops!(enabled: true) + visit project_settings_ci_cd_path(project) + end + + it 'does not have any checkboxes' do + expect(page).not_to have_selector('.js-run-auto-devops-pipeline-checkbox-wrapper', visible: false) + end + end + + context 'when master contains a .gitlab-ci.yml file' do + let(:project) { create(:project, :repository) } + + before do + project.repository.create_file(user, '.gitlab-ci.yml', "script: ['test']", message: 'test', branch_name: project.default_branch) + stub_application_setting(auto_devops_enabled: true) + project.create_auto_devops!(enabled: false) + visit project_settings_ci_cd_path(project) + end + + it 'does not have any checkboxes' do + expect(page).not_to have_selector('.js-run-auto-devops-pipeline-checkbox-wrapper', visible: false) + end + end + end end end end diff --git a/spec/javascripts/flash_spec.js b/spec/javascripts/flash_spec.js index b669aabcee4..97e3ab682c5 100644 --- a/spec/javascripts/flash_spec.js +++ b/spec/javascripts/flash_spec.js @@ -278,7 +278,7 @@ describe('Flash', () => { removeFlashClickListener(flashEl, false); - flashEl.parentNode.click(); + flashEl.click(); setTimeout(() => { expect(document.querySelector('.flash')).toBeNull();