Commit 8ba7b602 authored by Kamil Trzciński's avatar Kamil Trzciński

Merge branch '10244-ux-improvements-for-group-runners' into 'master'

Improve UX For Group Runners

See merge request gitlab-org/gitlab-ce!18649
parents d0cbef7e d100396d
import initSettingsPanels from '~/settings_panels';
import AjaxVariableList from '~/ci_variable_list/ajax_variable_list'; import AjaxVariableList from '~/ci_variable_list/ajax_variable_list';
document.addEventListener('DOMContentLoaded', () => { document.addEventListener('DOMContentLoaded', () => {
// Initialize expandable settings panels
initSettingsPanels();
const variableListEl = document.querySelector('.js-ci-variable-list-section'); const variableListEl = document.querySelector('.js-ci-variable-list-section');
// eslint-disable-next-line no-new // eslint-disable-next-line no-new
new AjaxVariableList({ new AjaxVariableList({
......
class Groups::RunnersController < Groups::ApplicationController
# Proper policies should be implemented per
# https://gitlab.com/gitlab-org/gitlab-ce/issues/45894
before_action :authorize_admin_pipeline!
before_action :runner, only: [:edit, :update, :destroy, :pause, :resume, :show]
def show
render 'shared/runners/show'
end
def edit
end
def update
if Ci::UpdateRunnerService.new(@runner).update(runner_params)
redirect_to group_runner_path(@group, @runner), notice: 'Runner was successfully updated.'
else
render 'edit'
end
end
def destroy
@runner.destroy
redirect_to group_settings_ci_cd_path(@group, anchor: 'runners-settings'), status: 302
end
def resume
if Ci::UpdateRunnerService.new(@runner).update(active: true)
redirect_to group_settings_ci_cd_path(@group, anchor: 'runners-settings'), notice: 'Runner was successfully updated.'
else
redirect_to group_settings_ci_cd_path(@group, anchor: 'runners-settings'), alert: 'Runner was not updated.'
end
end
def pause
if Ci::UpdateRunnerService.new(@runner).update(active: false)
redirect_to group_settings_ci_cd_path(@group, anchor: 'runners-settings'), notice: 'Runner was successfully updated.'
else
redirect_to group_settings_ci_cd_path(@group, anchor: 'runners-settings'), alert: 'Runner was not updated.'
end
end
private
def runner
@runner ||= @group.runners.find(params[:id])
end
def authorize_admin_pipeline!
return render_404 unless can?(current_user, :admin_pipeline, group)
end
def runner_params
params.require(:runner).permit(Ci::Runner::FORM_EDITABLE)
end
end
...@@ -8,7 +8,7 @@ class Projects::RunnerProjectsController < Projects::ApplicationController ...@@ -8,7 +8,7 @@ class Projects::RunnerProjectsController < Projects::ApplicationController
return head(403) unless can?(current_user, :assign_runner, @runner) return head(403) unless can?(current_user, :assign_runner, @runner)
path = runners_path(project) path = project_runners_path(project)
runner_project = @runner.assign_to(project, current_user) runner_project = @runner.assign_to(project, current_user)
if runner_project.persisted? if runner_project.persisted?
...@@ -22,6 +22,6 @@ class Projects::RunnerProjectsController < Projects::ApplicationController ...@@ -22,6 +22,6 @@ class Projects::RunnerProjectsController < Projects::ApplicationController
runner_project = project.runner_projects.find(params[:id]) runner_project = project.runner_projects.find(params[:id])
runner_project.destroy runner_project.destroy
redirect_to runners_path(project), status: 302 redirect_to project_runners_path(project), status: 302
end end
end end
class Projects::RunnersController < Projects::ApplicationController class Projects::RunnersController < Projects::ApplicationController
before_action :authorize_admin_build! before_action :authorize_admin_build!
before_action :set_runner, only: [:edit, :update, :destroy, :pause, :resume, :show] before_action :runner, only: [:edit, :update, :destroy, :pause, :resume, :show]
layout 'project_settings' layout 'project_settings'
...@@ -13,7 +13,7 @@ class Projects::RunnersController < Projects::ApplicationController ...@@ -13,7 +13,7 @@ class Projects::RunnersController < Projects::ApplicationController
def update def update
if Ci::UpdateRunnerService.new(@runner).update(runner_params) if Ci::UpdateRunnerService.new(@runner).update(runner_params)
redirect_to runner_path(@runner), notice: 'Runner was successfully updated.' redirect_to project_runner_path(@project, @runner), notice: 'Runner was successfully updated.'
else else
render 'edit' render 'edit'
end end
...@@ -24,26 +24,27 @@ class Projects::RunnersController < Projects::ApplicationController ...@@ -24,26 +24,27 @@ class Projects::RunnersController < Projects::ApplicationController
@runner.destroy @runner.destroy
end end
redirect_to runners_path(@project), status: 302 redirect_to project_runners_path(@project), status: 302
end end
def resume def resume
if Ci::UpdateRunnerService.new(@runner).update(active: true) if Ci::UpdateRunnerService.new(@runner).update(active: true)
redirect_to runners_path(@project), notice: 'Runner was successfully updated.' redirect_to project_runners_path(@project), notice: 'Runner was successfully updated.'
else else
redirect_to runners_path(@project), alert: 'Runner was not updated.' redirect_to project_runners_path(@project), alert: 'Runner was not updated.'
end end
end end
def pause def pause
if Ci::UpdateRunnerService.new(@runner).update(active: false) if Ci::UpdateRunnerService.new(@runner).update(active: false)
redirect_to runners_path(@project), notice: 'Runner was successfully updated.' redirect_to project_runners_path(@project), notice: 'Runner was successfully updated.'
else else
redirect_to runners_path(@project), alert: 'Runner was not updated.' redirect_to project_runners_path(@project), alert: 'Runner was not updated.'
end end
end end
def show def show
render 'shared/runners/show'
end end
def toggle_shared_runners def toggle_shared_runners
...@@ -60,7 +61,7 @@ class Projects::RunnersController < Projects::ApplicationController ...@@ -60,7 +61,7 @@ class Projects::RunnersController < Projects::ApplicationController
protected protected
def set_runner def runner
@runner ||= project.runners.find(params[:id]) @runner ||= project.runners.find(params[:id])
end end
......
...@@ -19,14 +19,6 @@ module GitlabRoutingHelper ...@@ -19,14 +19,6 @@ module GitlabRoutingHelper
project_commits_path(project, ref_name, *args) project_commits_path(project, ref_name, *args)
end end
def runners_path(project, *args)
project_runners_path(project, *args)
end
def runner_path(runner, *args)
project_runner_path(@project, runner, *args)
end
def environment_path(environment, *args) def environment_path(environment, *args)
project_environment_path(environment.project, environment, *args) project_environment_path(environment.project, environment, *args)
end end
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
%hr %hr
.append-bottom-20 .append-bottom-20
= render '/projects/runners/form', runner: @runner, runner_form_url: admin_runner_path(@runner) = render 'shared/runners/form', runner: @runner, runner_form_url: admin_runner_path(@runner)
.row .row
.col-md-6 .col-md-6
......
- link = link_to 'Runners API', help_page_path('api/runners.md')
%h3
= _('Group Runners')
.bs-callout.bs-callout-warning
= _('GitLab Group Runners can execute code for all the projects in this group.')
= _('They can be managed using the %{link}.').html_safe % { link: link }
-# Proper policies should be implemented per
-# https://gitlab.com/gitlab-org/gitlab-ce/issues/45894
- if can?(current_user, :admin_pipeline, @group)
= render partial: 'ci/runner/how_to_setup_runner',
locals: { registration_token: @group.runners_token, type: 'group' }
- if @group.runners.empty?
%h4.underlined-title
= _('This group does not provide any group Runners yet.')
- else
%h4.underlined-title
= _('Available group Runners : %{runners}.').html_safe % { runners: @group.runners.count }
%ul.bordered-list
= render partial: 'groups/runners/runner', collection: @group.runners, as: :runner
= render 'shared/runners/runner_description'
%hr
%p.lead
= _('To start serving your jobs you can add Runners to your group')
.row
.col-sm-6
= render 'groups/runners/group_runners'
%li.runner{ id: dom_id(runner) }
%h4
= runner_status_icon(runner)
= link_to runner.short_sha, group_runner_path(@group, runner), class: 'commit-sha'
%small.edit-runner
= link_to edit_group_runner_path(@group, runner) do
= icon('edit')
.pull-right
- if runner.active?
= link_to _('Pause'), pause_group_runner_path(@group, runner), method: :post, class: 'btn btn-sm btn-danger', data: { confirm: _("Are you sure?") }
- else
= link_to _('Resume'), resume_group_runner_path(@group, runner), method: :post, class: 'btn btn-success btn-sm'
= link_to _('Remove Runner'), group_runner_path(@group, runner), data: { confirm: _("Are you sure?") }, method: :delete, class: 'btn btn-danger btn-sm'
.pull-right
%small.light
\##{runner.id}
- if runner.description.present?
%p.runner-description
= runner.description
- if runner.tag_list.present?
%p
- runner.tag_list.sort.each do |tag|
%span.label.label-primary
= tag
- page_title "Edit", "#{@runner.description} ##{@runner.id}", "Runners"
%h4 Runner ##{@runner.id}
%hr
= render 'shared/runners/form', runner: @runner, runner_form_url: group_runner_path(@group, @runner)
- breadcrumb_title "CI / CD Settings" - breadcrumb_title "CI / CD Settings"
- page_title "CI / CD" - page_title "CI / CD"
%h4 - expanded = Rails.env.test?
= _('Secret variables')
= link_to icon('question-circle'), help_page_path('ci/variables/README', anchor: 'secret-variables'), target: '_blank', rel: 'noopener noreferrer'
%p %section.settings#secret-variables.no-animate{ class: ('expanded' if expanded) }
= render "ci/variables/content" .settings-header
%h4
= _('Secret variables')
= link_to icon('question-circle'), help_page_path('ci/variables/README', anchor: 'secret-variables'), target: '_blank', rel: 'noopener noreferrer'
%button.btn.btn-default.js-settings-toggle{ type: "button" }
= expanded ? _('Collapse') : _('Expand')
%p.append-bottom-0
= render "ci/variables/content"
.settings-content
= render 'ci/variables/index', save_endpoint: group_variables_path
= render 'ci/variables/index', save_endpoint: group_variables_path %section.settings#runners-settings.no-animate{ class: ('expanded' if expanded) }
.settings-header
%h4
= _('Runners settings')
%button.btn.btn-default.js-settings-toggle{ type: "button" }
= expanded ? _('Collapse') : _('Expand')
%p
= _('Register and see your runners for this group.')
.settings-content
= render 'groups/runners/index'
%h3 Group Runners - link = link_to 'Runners API', help_page_path('api/runners.md')
%h3
= _('Group Runners')
.bs-callout.bs-callout-warning .bs-callout.bs-callout-warning
GitLab Group Runners can execute code for all the projects in this group. = _('GitLab Group Runners can execute code for all the projects in this group.')
They can be managed using the #{link_to 'Runners API', help_page_path('api/runners.md')}. = _('They can be managed using the %{link}.').html_safe % { link: link }
- if @project.group - if @project.group
%hr %hr
- if @project.group_runners_enabled? - if @project.group_runners_enabled?
= link_to toggle_group_runners_project_runners_path(@project), class: 'btn btn-warning', method: :post do = link_to toggle_group_runners_project_runners_path(@project), class: 'btn btn-close', method: :post do
Disable group Runners = _('Disable group Runners')
- else - else
= link_to toggle_group_runners_project_runners_path(@project), class: 'btn btn-success', method: :post do = link_to toggle_group_runners_project_runners_path(@project), class: 'btn btn-success btn-inverted', method: :post do
Enable group Runners = _('Enable group Runners')
&nbsp; for this project &nbsp;
= _('for this project')
- if !@project.group - if !@project.group
This project does not belong to a group and can therefore not make use of group Runners. = _('This project does not belong to a group and can therefore not make use of group Runners.')
- elsif @group_runners.empty? - elsif @group_runners.empty?
This group does not provide any group Runners yet. = _('This group does not provide any group Runners yet.')
- if can?(current_user, :admin_pipeline, @project.group) - if can?(current_user, :admin_pipeline, @project.group)
= render partial: 'ci/runner/how_to_setup_runner', - group_link = link_to 'Group CI/CD settings', group_settings_ci_cd_path(@project.group)
locals: { registration_token: @project.group.runners_token, type: 'group' } = _('Group masters can register group runners in the %{link}').html_safe % { link: group_link }
- else - else
Ask your group master to setup a group Runner. = _('Ask your group master to setup a group Runner.')
- else - else
%h4.underlined-title Available group Runners : #{@group_runners.count} %h4.underlined-title
= _('Available group Runners : %{runners}').html_safe % { runners: @group_runners.count }
%ul.bordered-list %ul.bordered-list
= render partial: 'projects/runners/runner', collection: @group_runners, as: :runner = render partial: 'projects/runners/runner', collection: @group_runners, as: :runner
.light.prepend-top-default = render 'shared/runners/runner_description'
%p
A 'Runner' is a process which runs a job.
You can setup as many Runners as you need.
%br
Runners can be placed on separate users, servers, and even on your local machine.
%p Each Runner can be in one of the following states:
%div
%ul
%li
%span.label.label-success active
\- Runner is active and can process any new jobs
%li
%span.label.label-danger paused
\- Runner is paused and will not receive any new jobs
%hr %hr
...@@ -23,7 +8,4 @@ ...@@ -23,7 +8,4 @@
= render 'projects/runners/specific_runners' = render 'projects/runners/specific_runners'
.col-sm-6 .col-sm-6
= render 'projects/runners/shared_runners' = render 'projects/runners/shared_runners'
.row
.col-sm-6
.col-sm-6
= render 'projects/runners/group_runners' = render 'projects/runners/group_runners'
...@@ -3,10 +3,10 @@ ...@@ -3,10 +3,10 @@
= runner_status_icon(runner) = runner_status_icon(runner)
- if @project_runners.include?(runner) - if @project_runners.include?(runner)
= link_to runner.short_sha, runner_path(runner), class: 'commit-sha' = link_to runner.short_sha, project_runner_path(@project, runner), class: 'commit-sha'
- if runner.locked? - if runner.locked?
= icon('lock', class: 'has-tooltip', title: 'Locked to current projects') = icon('lock', class: 'has-tooltip', title: _('Locked to current projects'))
%small.edit-runner %small.edit-runner
= link_to edit_project_runner_path(@project, runner) do = link_to edit_project_runner_path(@project, runner) do
...@@ -18,18 +18,18 @@ ...@@ -18,18 +18,18 @@
.pull-right .pull-right
- if @project_runners.include?(runner) - if @project_runners.include?(runner)
- if runner.active? - if runner.active?
= link_to 'Pause', pause_project_runner_path(@project, runner), method: :post, class: 'btn btn-sm btn-danger', data: { confirm: "Are you sure?" } = link_to _('Pause'), pause_project_runner_path(@project, runner), method: :post, class: 'btn btn-sm btn-danger', data: { confirm: _("Are you sure?") }
- else - else
= link_to 'Resume', resume_project_runner_path(@project, runner), method: :post, class: 'btn btn-success btn-sm' = link_to _('Resume'), resume_project_runner_path(@project, runner), method: :post, class: 'btn btn-success btn-sm'
- if runner.belongs_to_one_project? - if runner.belongs_to_one_project?
= link_to 'Remove Runner', runner_path(runner), data: { confirm: "Are you sure?" }, method: :delete, class: 'btn btn-danger btn-sm' = link_to _('Remove Runner'), project_runner_path(@project, runner), data: { confirm: _("Are you sure?") }, method: :delete, class: 'btn btn-danger btn-sm'
- else - else
- runner_project = @project.runner_projects.find_by(runner_id: runner) - runner_project = @project.runner_projects.find_by(runner_id: runner)
= link_to 'Disable for this project', project_runner_project_path(@project, runner_project), data: { confirm: "Are you sure?" }, method: :delete, class: 'btn btn-danger btn-sm' = link_to _('Disable for this project'), project_runner_project_path(@project, runner_project), data: { confirm: _("Are you sure?") }, method: :delete, class: 'btn btn-danger btn-sm'
- elsif !(runner.is_shared? || runner.group_type?) # We can simplify this to `runner.project_type?` when migrating #runner_type is complete - elsif !(runner.is_shared? || runner.group_type?) # We can simplify this to `runner.project_type?` when migrating #runner_type is complete
= form_for [@project.namespace.becomes(Namespace), @project, @project.runner_projects.new] do |f| = form_for [@project.namespace.becomes(Namespace), @project, @project.runner_projects.new] do |f|
= f.hidden_field :runner_id, value: runner.id = f.hidden_field :runner_id, value: runner.id
= f.submit 'Enable for this project', class: 'btn btn-sm' = f.submit _('Enable for this project'), class: 'btn btn-sm'
.pull-right .pull-right
%small.light %small.light
\##{runner.id} \##{runner.id}
......
...@@ -17,8 +17,8 @@ ...@@ -17,8 +17,8 @@
&nbsp; for this project &nbsp; for this project
- if @shared_runners_count.zero? - if @shared_runners_count.zero?
This GitLab server does not provide any shared Runners yet. This GitLab instance does not provide any shared Runners yet. Instance
Please use the specific Runners or ask your administrator to create one. administrators can register shared Runners in the admin area.
- else - else
%h4.underlined-title Available shared Runners : #{@shared_runners_count} %h4.underlined-title Available shared Runners : #{@shared_runners_count}
%ul.bordered-list.available-shared-runners %ul.bordered-list.available-shared-runners
......
...@@ -3,4 +3,4 @@ ...@@ -3,4 +3,4 @@
%h4 Runner ##{@runner.id} %h4 Runner ##{@runner.id}
%hr %hr
= render 'form', runner: @runner, runner_form_url: runner_path(@runner) = render 'shared/runners/form', runner: @runner, runner_form_url: project_runner_path(@project, @runner)
...@@ -18,12 +18,13 @@ ...@@ -18,12 +18,13 @@
.checkbox .checkbox
= f.check_box :run_untagged = f.check_box :run_untagged
%span.light Indicates whether this runner can pick jobs without tags %span.light Indicates whether this runner can pick jobs without tags
.form-group - unless runner.group_type?
= label :locked, 'Lock to current projects', class: 'control-label' .form-group
.col-sm-10 = label :locked, 'Lock to current projects', class: 'control-label'
.checkbox .col-sm-10
= f.check_box :locked .checkbox
%span.light When a runner is locked, it cannot be assigned to other projects = f.check_box :locked
%span.light When a runner is locked, it cannot be assigned to other projects
.form-group .form-group
= label_tag :token, class: 'control-label' do = label_tag :token, class: 'control-label' do
Token Token
......
.light.prepend-top-default
%p
= _("A 'Runner' is a process which runs a job. You can setup as many Runners as you need.")
%br
= _('Runners can be placed on separate users, servers, and even on your local machine.')
%p
= _('Each Runner can be in one of the following states:')
%div
%ul
%li
%span.label.label-success active
= _('- Runner is active and can process any new jobs')
%li
%span.label.label-danger paused
= _('- Runner is paused and will not receive any new jobs')
...@@ -6,6 +6,9 @@ ...@@ -6,6 +6,9 @@
- if @runner.shared? - if @runner.shared?
%span.runner-state.runner-state-shared %span.runner-state.runner-state-shared
Shared Shared
- elsif @runner.group_type?
%span.runner-state.runner-state-shared
Group
- else - else
%span.runner-state.runner-state-specific %span.runner-state.runner-state-specific
Specific Specific
...@@ -25,9 +28,10 @@ ...@@ -25,9 +28,10 @@
%tr %tr
%td Can run untagged jobs %td Can run untagged jobs
%td= @runner.run_untagged? ? 'Yes' : 'No' %td= @runner.run_untagged? ? 'Yes' : 'No'
%tr - unless @runner.group_type?
%td Locked to this project %tr
%td= @runner.locked? ? 'Yes' : 'No' %td Locked to this project
%td= @runner.locked? ? 'Yes' : 'No'
%tr %tr
%td Tags %td Tags
%td %td
......
...@@ -58,6 +58,13 @@ constraints(::Constraints::GroupUrlConstrainer.new) do ...@@ -58,6 +58,13 @@ constraints(::Constraints::GroupUrlConstrainer.new) do
# On CE only index and show actions are needed # On CE only index and show actions are needed
resources :boards, only: [:index, :show] resources :boards, only: [:index, :show]
resources :runners, only: [:index, :edit, :update, :destroy, :show] do
member do
post :resume
post :pause
end
end
end end
scope(path: '*id', scope(path: '*id',
......
require 'spec_helper'
describe Groups::RunnersController do
let(:user) { create(:user) }
let(:group) { create(:group) }
let(:runner) { create(:ci_runner) }
let(:params) do
{
group_id: group,
id: runner
}
end
before do
sign_in(user)
group.add_master(user)
group.runners << runner
end
describe '#update' do
it 'updates the runner and ticks the queue' do
new_desc = runner.description.swapcase
expect do
post :update, params.merge(runner: { description: new_desc } )
end.to change { runner.ensure_runner_queue_value }
runner.reload
expect(response).to have_gitlab_http_status(302)
expect(runner.description).to eq(new_desc)
end
end
describe '#destroy' do
it 'destroys the runner' do
delete :destroy, params
expect(response).to have_gitlab_http_status(302)
expect(Ci::Runner.find_by(id: runner.id)).to be_nil
end
end
describe '#resume' do
it 'marks the runner as active and ticks the queue' do
runner.update(active: false)
expect do
post :resume, params
end.to change { runner.ensure_runner_queue_value }
runner.reload
expect(response).to have_gitlab_http_status(302)
expect(runner.active).to eq(true)
end
end
describe '#pause' do
it 'marks the runner as inactive and ticks the queue' do
runner.update(active: true)
expect do
post :pause, params
end.to change { runner.ensure_runner_queue_value }
runner.reload
expect(response).to have_gitlab_http_status(302)
expect(runner.active).to eq(false)
end
end
end
...@@ -15,7 +15,7 @@ feature 'Runners' do ...@@ -15,7 +15,7 @@ feature 'Runners' do
end end
scenario 'user can see a button to install runners on kubernetes clusters' do scenario 'user can see a button to install runners on kubernetes clusters' do
visit runners_path(project) visit project_runners_path(project)
expect(page).to have_link('Install Runner on Kubernetes', href: project_clusters_path(project)) expect(page).to have_link('Install Runner on Kubernetes', href: project_clusters_path(project))
end end
...@@ -36,7 +36,7 @@ feature 'Runners' do ...@@ -36,7 +36,7 @@ feature 'Runners' do
end end
scenario 'user sees the specific runner' do scenario 'user sees the specific runner' do
visit runners_path(project) visit project_runners_path(project)
within '.activated-specific-runners' do within '.activated-specific-runners' do
expect(page).to have_content(specific_runner.display_name) expect(page).to have_content(specific_runner.display_name)
...@@ -48,7 +48,7 @@ feature 'Runners' do ...@@ -48,7 +48,7 @@ feature 'Runners' do
end end
scenario 'user can pause and resume the specific runner' do scenario 'user can pause and resume the specific runner' do
visit runners_path(project) visit project_runners_path(project)
within '.activated-specific-runners' do within '.activated-specific-runners' do
expect(page).to have_content('Pause') expect(page).to have_content('Pause')
...@@ -68,7 +68,7 @@ feature 'Runners' do ...@@ -68,7 +68,7 @@ feature 'Runners' do
end end
scenario 'user removes an activated specific runner if this is last project for that runners' do scenario 'user removes an activated specific runner if this is last project for that runners' do
visit runners_path(project) visit project_runners_path(project)
within '.activated-specific-runners' do within '.activated-specific-runners' do
click_on 'Remove Runner' click_on 'Remove Runner'
...@@ -78,7 +78,7 @@ feature 'Runners' do ...@@ -78,7 +78,7 @@ feature 'Runners' do
end end
scenario 'user edits the runner to be protected' do scenario 'user edits the runner to be protected' do
visit runners_path(project) visit project_runners_path(project)
within '.activated-specific-runners' do within '.activated-specific-runners' do
first('.edit-runner > a').click first('.edit-runner > a').click
...@@ -98,7 +98,7 @@ feature 'Runners' do ...@@ -98,7 +98,7 @@ feature 'Runners' do
end end
scenario 'user edits runner not to run untagged jobs' do scenario 'user edits runner not to run untagged jobs' do
visit runners_path(project) visit project_runners_path(project)
within '.activated-specific-runners' do within '.activated-specific-runners' do
first('.edit-runner > a').click first('.edit-runner > a').click
...@@ -117,7 +117,7 @@ feature 'Runners' do ...@@ -117,7 +117,7 @@ feature 'Runners' do
given!(:shared_runner) { create(:ci_runner, :shared) } given!(:shared_runner) { create(:ci_runner, :shared) }
scenario 'user sees CI/CD setting page' do scenario 'user sees CI/CD setting page' do
visit runners_path(project) visit project_runners_path(project)
expect(page.find('.available-shared-runners')).to have_content(shared_runner.display_name) expect(page.find('.available-shared-runners')).to have_content(shared_runner.display_name)
end end
...@@ -134,7 +134,7 @@ feature 'Runners' do ...@@ -134,7 +134,7 @@ feature 'Runners' do
end end
scenario 'user enables and disables a specific runner' do scenario 'user enables and disables a specific runner' do
visit runners_path(project) visit project_runners_path(project)
within '.available-specific-runners' do within '.available-specific-runners' do
click_on 'Enable for this project' click_on 'Enable for this project'
...@@ -159,7 +159,7 @@ feature 'Runners' do ...@@ -159,7 +159,7 @@ feature 'Runners' do
end end
scenario 'user sees shared runners description' do scenario 'user sees shared runners description' do
visit runners_path(project) visit project_runners_path(project)
expect(page.find('.shared-runners-description')).to have_content(shared_runners_html) expect(page.find('.shared-runners-description')).to have_content(shared_runners_html)
end end
...@@ -174,7 +174,7 @@ feature 'Runners' do ...@@ -174,7 +174,7 @@ feature 'Runners' do
end end
scenario 'user enables shared runners' do scenario 'user enables shared runners' do
visit runners_path(project) visit project_runners_path(project)
click_on 'Enable shared Runners' click_on 'Enable shared Runners'
...@@ -182,7 +182,7 @@ feature 'Runners' do ...@@ -182,7 +182,7 @@ feature 'Runners' do
end end
end end
context 'group runners' do context 'group runners in project settings' do
background do background do
project.add_master(user) project.add_master(user)
end end
...@@ -198,12 +198,12 @@ feature 'Runners' do ...@@ -198,12 +198,12 @@ feature 'Runners' do
given(:project) { create :project, group: group } given(:project) { create :project, group: group }
scenario 'group runners are not available' do scenario 'group runners are not available' do
visit runners_path(project) visit project_runners_path(project)
expect(page).to have_content 'This group does not provide any group Runners yet.' expect(page).to have_content 'This group does not provide any group Runners yet'
expect(page).to have_content 'Setup a group Runner manually' expect(page).to have_content 'Group masters can register group runners in the Group CI/CD settings'
expect(page).not_to have_content 'Ask your group master to setup a group Runner.' expect(page).not_to have_content 'Ask your group master to setup a group Runner'
end end
end end
end end
...@@ -213,7 +213,7 @@ feature 'Runners' do ...@@ -213,7 +213,7 @@ feature 'Runners' do
given(:project) { create :project } given(:project) { create :project }
scenario 'group runners are not available' do scenario 'group runners are not available' do
visit runners_path(project) visit project_runners_path(project)
expect(page).to have_content 'This project does not belong to a group and can therefore not make use of group Runners.' expect(page).to have_content 'This project does not belong to a group and can therefore not make use of group Runners.'
end end
...@@ -224,11 +224,11 @@ feature 'Runners' do ...@@ -224,11 +224,11 @@ feature 'Runners' do
given(:project) { create :project, group: group } given(:project) { create :project, group: group }
scenario 'group runners are not available' do scenario 'group runners are not available' do
visit runners_path(project) visit project_runners_path(project)
expect(page).to have_content 'This group does not provide any group Runners yet.' expect(page).to have_content 'This group does not provide any group Runners yet.'
expect(page).not_to have_content 'Setup a group Runner manually' expect(page).not_to have_content 'Group masters can register group runners in the Group CI/CD settings'
expect(page).to have_content 'Ask your group master to setup a group Runner.' expect(page).to have_content 'Ask your group master to setup a group Runner.'
end end
end end
...@@ -239,14 +239,14 @@ feature 'Runners' do ...@@ -239,14 +239,14 @@ feature 'Runners' do
given!(:ci_runner) { create :ci_runner, groups: [group], description: 'group-runner' } given!(:ci_runner) { create :ci_runner, groups: [group], description: 'group-runner' }
scenario 'group runners are available' do scenario 'group runners are available' do
visit runners_path(project) visit project_runners_path(project)
expect(page).to have_content 'Available group Runners : 1' expect(page).to have_content 'Available group Runners : 1'
expect(page).to have_content 'group-runner' expect(page).to have_content 'group-runner'
end end
scenario 'group runners may be disabled for a project' do scenario 'group runners may be disabled for a project' do
visit runners_path(project) visit project_runners_path(project)
click_on 'Disable group Runners' click_on 'Disable group Runners'
...@@ -261,4 +261,98 @@ feature 'Runners' do ...@@ -261,4 +261,98 @@ feature 'Runners' do
end end
end end
end end
context 'group runners in group settings' do
given(:group) { create :group }
background do
group.add_master(user)
end
context 'group with no runners' do
scenario 'there are no runners displayed' do
visit group_settings_ci_cd_path(group)
expect(page).to have_content 'This group does not provide any group Runners yet'
end
end
context 'group with a runner' do
let!(:runner) { create :ci_runner, groups: [group], description: 'group-runner' }
scenario 'the runner is visible' do
visit group_settings_ci_cd_path(group)
expect(page).not_to have_content 'This group does not provide any group Runners yet'
expect(page).to have_content 'Available group Runners : 1'
expect(page).to have_content 'group-runner'
end
scenario 'user can pause and resume the group runner' do
visit group_settings_ci_cd_path(group)
expect(page).to have_content('Pause')
expect(page).not_to have_content('Resume')
click_on 'Pause'
expect(page).not_to have_content('Pause')
expect(page).to have_content('Resume')
click_on 'Resume'
expect(page).to have_content('Pause')
expect(page).not_to have_content('Resume')
end
scenario 'user can view runner details' do
visit group_settings_ci_cd_path(group)
expect(page).to have_content(runner.display_name)
click_on runner.short_sha
expect(page).to have_content(runner.platform)
end
scenario 'user can remove a group runner' do
visit group_settings_ci_cd_path(group)
click_on 'Remove Runner'
expect(page).not_to have_content(runner.display_name)
end
scenario 'user edits the runner to be protected' do
visit group_settings_ci_cd_path(group)
first('.edit-runner > a').click
expect(page.find_field('runner[access_level]')).not_to be_checked
check 'runner_access_level'
click_button 'Save changes'
expect(page).to have_content 'Protected Yes'
end
context 'when a runner has a tag' do
background do
runner.update(tag_list: ['tag'])
end
scenario 'user edits runner not to run untagged jobs' do
visit group_settings_ci_cd_path(group)
first('.edit-runner > a').click
expect(page.find_field('runner[run_untagged]')).to be_checked
uncheck 'runner_run_untagged'
click_button 'Save changes'
expect(page).to have_content 'Can run untagged jobs No'
end
end
end
end
end end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment