Commit 8e7f19c6 authored by Stan Hu's avatar Stan Hu

Add button to run scheduled pipeline immediately

Closes #38741
parent ad1ce123
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)
......
......@@ -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)
......
......@@ -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)
......
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
---
title: Add button to run scheduled pipeline immediately
merge_request:
author:
type: added
......@@ -179,6 +179,7 @@ constraints(ProjectUrlConstrainer.new) do
resources :pipeline_schedules, except: [:show] do
member do
post :run
post :take_ownership
end
end
......
......@@ -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) }
......
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
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