summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/controllers/projects/pipeline_schedules_controller.rb16
-rw-r--r--app/helpers/gitlab_routing_helper.rb5
-rw-r--r--app/views/projects/pipeline_schedules/_pipeline_schedule.html.haml4
-rw-r--r--app/workers/run_pipeline_schedule_worker.rb20
-rw-r--r--changelogs/unreleased/sh-add-schedule-pipeline-run-now.yml5
-rw-r--r--config/routes/project.rb1
-rw-r--r--spec/controllers/projects/pipeline_schedules_controller_spec.rb26
-rw-r--r--spec/workers/run_pipeline_schedule_worker_spec.rb36
8 files changed, 110 insertions, 3 deletions
diff --git a/app/controllers/projects/pipeline_schedules_controller.rb b/app/controllers/projects/pipeline_schedules_controller.rb
index ec7c645df5a..9fc7935950d 100644
--- a/app/controllers/projects/pipeline_schedules_controller.rb
+++ b/app/controllers/projects/pipeline_schedules_controller.rb
@@ -1,9 +1,10 @@
class Projects::PipelineSchedulesController < Projects::ApplicationController
before_action :schedule, except: [:index, :new, :create]
+ before_action :authorize_create_pipeline!, only: [:run]
before_action :authorize_read_pipeline_schedule!
before_action :authorize_create_pipeline_schedule!, only: [:new, :create]
- before_action :authorize_update_pipeline_schedule!, except: [:index, :new, :create]
+ before_action :authorize_update_pipeline_schedule!, except: [:index, :new, :create, :run]
before_action :authorize_admin_pipeline_schedule!, only: [:destroy]
def index
@@ -40,6 +41,19 @@ class Projects::PipelineSchedulesController < Projects::ApplicationController
end
end
+ def run
+ job_id = RunPipelineScheduleWorker.perform_async(schedule.id, current_user.id)
+
+ flash[:notice] =
+ if job_id
+ 'Successfully scheduled pipeline to run immediately'
+ else
+ 'Unable to schedule a pipeline to run immediately'
+ end
+
+ redirect_to pipeline_schedules_path(@project)
+ end
+
def take_ownership
if schedule.update(owner: current_user)
redirect_to pipeline_schedules_path(@project)
diff --git a/app/helpers/gitlab_routing_helper.rb b/app/helpers/gitlab_routing_helper.rb
index a77aa0ad2cc..5f72c6e64b6 100644
--- a/app/helpers/gitlab_routing_helper.rb
+++ b/app/helpers/gitlab_routing_helper.rb
@@ -182,6 +182,11 @@ module GitlabRoutingHelper
edit_project_pipeline_schedule_path(project, schedule)
end
+ def run_pipeline_schedule_path(schedule, *args)
+ project = schedule.project
+ run_project_pipeline_schedule_path(project, schedule, *args)
+ end
+
def take_ownership_pipeline_schedule_path(schedule, *args)
project = schedule.project
take_ownership_project_pipeline_schedule_path(project, schedule, *args)
diff --git a/app/views/projects/pipeline_schedules/_pipeline_schedule.html.haml b/app/views/projects/pipeline_schedules/_pipeline_schedule.html.haml
index bd8c38292d6..57f0ffba9ff 100644
--- a/app/views/projects/pipeline_schedules/_pipeline_schedule.html.haml
+++ b/app/views/projects/pipeline_schedules/_pipeline_schedule.html.haml
@@ -26,10 +26,12 @@
= pipeline_schedule.owner&.name
%td
.pull-right.btn-group
+ - if can?(current_user, :create_pipeline, @project)
+ = link_to run_pipeline_schedule_path(pipeline_schedule), method: :post, title: s_('Play'), class: 'btn' do
+ = icon('play')
- if can?(current_user, :update_pipeline_schedule, pipeline_schedule)
= link_to take_ownership_pipeline_schedule_path(pipeline_schedule), method: :post, title: s_('PipelineSchedules|Take ownership'), class: 'btn' do
= s_('PipelineSchedules|Take ownership')
- - if can?(current_user, :update_pipeline_schedule, pipeline_schedule)
= link_to edit_pipeline_schedule_path(pipeline_schedule), title: _('Edit'), class: 'btn' do
= icon('pencil')
- if can?(current_user, :admin_pipeline_schedule, pipeline_schedule)
diff --git a/app/workers/run_pipeline_schedule_worker.rb b/app/workers/run_pipeline_schedule_worker.rb
new file mode 100644
index 00000000000..ac6371f0871
--- /dev/null
+++ b/app/workers/run_pipeline_schedule_worker.rb
@@ -0,0 +1,20 @@
+class RunPipelineScheduleWorker
+ include Sidekiq::Worker
+ include PipelineQueue
+
+ enqueue_in group: :creation
+
+ def perform(schedule_id, user_id)
+ schedule = Ci::PipelineSchedule.find(schedule_id)
+ user = User.find(user_id)
+
+ run_pipeline_schedule(schedule, user)
+ end
+
+ def run_pipeline_schedule(schedule, user)
+ Ci::CreatePipelineService.new(schedule.project,
+ user,
+ ref: schedule.ref)
+ .execute(:schedule, ignore_skip_ci: true, save_on_errors: false, schedule: schedule)
+ end
+end
diff --git a/changelogs/unreleased/sh-add-schedule-pipeline-run-now.yml b/changelogs/unreleased/sh-add-schedule-pipeline-run-now.yml
new file mode 100644
index 00000000000..6d06f695f10
--- /dev/null
+++ b/changelogs/unreleased/sh-add-schedule-pipeline-run-now.yml
@@ -0,0 +1,5 @@
+---
+title: Add button to run scheduled pipeline immediately
+merge_request:
+author:
+type: added
diff --git a/config/routes/project.rb b/config/routes/project.rb
index 093da10f57f..3dcb21e45c5 100644
--- a/config/routes/project.rb
+++ b/config/routes/project.rb
@@ -179,6 +179,7 @@ constraints(ProjectUrlConstrainer.new) do
resources :pipeline_schedules, except: [:show] do
member do
+ post :run
post :take_ownership
end
end
diff --git a/spec/controllers/projects/pipeline_schedules_controller_spec.rb b/spec/controllers/projects/pipeline_schedules_controller_spec.rb
index 4e52e261920..384a407a100 100644
--- a/spec/controllers/projects/pipeline_schedules_controller_spec.rb
+++ b/spec/controllers/projects/pipeline_schedules_controller_spec.rb
@@ -96,7 +96,7 @@ describe Projects::PipelineSchedulesController do
end
end
- context 'when variables_attributes has two variables and duplicted' do
+ context 'when variables_attributes has two variables and duplicated' do
let(:schedule) do
basic_param.merge({
variables_attributes: [{ key: 'AAA', value: 'AAA123' }, { key: 'AAA', value: 'BBB123' }]
@@ -364,6 +364,30 @@ describe Projects::PipelineSchedulesController do
end
end
+ describe 'POST #run' do
+ set(:user) { create(:user) }
+
+ context 'when a developer makes the request' do
+ before do
+ project.add_developer(user)
+ sign_in(user)
+ end
+
+ it 'executes a new pipeline' do
+ expect(RunPipelineScheduleWorker).to receive(:perform_async).with(pipeline_schedule.id, user.id).and_return('job-123')
+
+ go
+
+ expect(flash[:notice]).to eq 'Successfully scheduled pipeline to run immediately'
+ expect(response).to have_gitlab_http_status(302)
+ end
+ end
+
+ def go
+ post :run, namespace_id: project.namespace.to_param, project_id: project, id: pipeline_schedule.id
+ end
+ end
+
describe 'DELETE #destroy' do
set(:user) { create(:user) }
diff --git a/spec/workers/run_pipeline_schedule_worker_spec.rb b/spec/workers/run_pipeline_schedule_worker_spec.rb
new file mode 100644
index 00000000000..4a88ac51f62
--- /dev/null
+++ b/spec/workers/run_pipeline_schedule_worker_spec.rb
@@ -0,0 +1,36 @@
+require 'spec_helper'
+
+describe RunPipelineScheduleWorker do
+ describe '#perform' do
+ let(:project) { create(:project) }
+ let(:worker) { described_class.new }
+ let(:user) { create(:user) }
+ let(:pipeline_schedule) { create(:ci_pipeline_schedule, :nightly, project: project ) }
+
+ context 'when a project not found' do
+ it 'does not call the Service' do
+ expect(Ci::CreatePipelineService).not_to receive(:new)
+ expect { worker.perform(100000, user.id) }.to raise_error(ActiveRecord::RecordNotFound)
+ end
+ end
+
+ context 'when a user not found' do
+ it 'does not call the Service' do
+ expect(Ci::CreatePipelineService).not_to receive(:new)
+ expect { worker.perform(pipeline_schedule.id, 10000) }.to raise_error(ActiveRecord::RecordNotFound)
+ end
+ end
+
+ context 'when everything is ok' do
+ let(:project) { create(:project) }
+ let(:create_pipeline_service) { instance_double(Ci::CreatePipelineService) }
+
+ it 'calls the Service' do
+ expect(Ci::CreatePipelineService).to receive(:new).with(project, user, ref: pipeline_schedule.ref).and_return(create_pipeline_service)
+ expect(create_pipeline_service).to receive(:execute).with(:schedule, ignore_skip_ci: true, save_on_errors: false, schedule: pipeline_schedule)
+
+ worker.perform(pipeline_schedule.id, user.id)
+ end
+ end
+ end
+end