Add implementation of manual actions
This commit is contained in:
parent
4e898b9b5e
commit
7d0fe1f04e
12 changed files with 96 additions and 17 deletions
|
@ -57,6 +57,15 @@ class Projects::BuildsController < Projects::ApplicationController
|
|||
redirect_to build_path(build)
|
||||
end
|
||||
|
||||
def play
|
||||
unless @build.playable?
|
||||
return render_404
|
||||
end
|
||||
|
||||
build = @build.play(current_user)
|
||||
redirect_to build_path(build)
|
||||
end
|
||||
|
||||
def cancel
|
||||
@build.cancel
|
||||
redirect_to build_path(@build)
|
||||
|
|
|
@ -15,6 +15,7 @@ module Ci
|
|||
scope :with_artifacts, ->() { where.not(artifacts_file: nil) }
|
||||
scope :with_expired_artifacts, ->() { with_artifacts.where('artifacts_expire_at < ?', Time.now) }
|
||||
scope :last_month, ->() { where('created_at > ?', Date.today - 1.month) }
|
||||
scope :manual_actions, ->() { where(when: :manual).without_created }
|
||||
|
||||
mount_uploader :artifacts_file, ArtifactUploader
|
||||
mount_uploader :artifacts_metadata, ArtifactUploader
|
||||
|
@ -91,6 +92,29 @@ module Ci
|
|||
end
|
||||
end
|
||||
|
||||
def manual?
|
||||
self.when == 'manual'
|
||||
end
|
||||
|
||||
def playable_actions
|
||||
pipeline.playable_actions
|
||||
end
|
||||
|
||||
def playable?
|
||||
project.builds_enabled? && commands.present? && manual?
|
||||
end
|
||||
|
||||
def play(current_user = nil)
|
||||
if skipped?
|
||||
# We can run skipped build
|
||||
new_build.user = current_user
|
||||
new_build.queue
|
||||
else
|
||||
# Otherwise we need to create a duplicate
|
||||
Ci::Build.retry(self, current_user)
|
||||
end
|
||||
end
|
||||
|
||||
def retryable?
|
||||
project.builds_enabled? && commands.present? && complete?
|
||||
end
|
||||
|
|
|
@ -65,6 +65,10 @@ module Ci
|
|||
!tag?
|
||||
end
|
||||
|
||||
def playable_actions
|
||||
builds.manual_actions.latest
|
||||
end
|
||||
|
||||
def retryable?
|
||||
builds.latest.any? do |build|
|
||||
build.failed? && build.retryable?
|
||||
|
|
|
@ -32,4 +32,8 @@ class Deployment < ActiveRecord::Base
|
|||
def keep_around_commit
|
||||
project.repository.keep_around(self.sha)
|
||||
end
|
||||
|
||||
def playable_actions
|
||||
deployable.try(:playable_actions)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -39,6 +39,8 @@
|
|||
%span.label.label-danger allowed to fail
|
||||
- if defined?(retried) && retried
|
||||
%span.label.label-warning retried
|
||||
- if build.manual?
|
||||
%span.label.label-info manual
|
||||
|
||||
|
||||
- if defined?(runner) && runner
|
||||
|
@ -79,6 +81,11 @@
|
|||
- if build.active?
|
||||
= link_to cancel_namespace_project_build_path(build.project.namespace, build.project, build, return_to: request.original_url), method: :post, title: 'Cancel', class: 'btn btn-build' do
|
||||
= icon('remove', class: 'cred')
|
||||
- elsif defined?(allow_retry) && allow_retry && build.retryable?
|
||||
= link_to retry_namespace_project_build_path(build.project.namespace, build.project, build, return_to: request.original_url), method: :post, title: 'Retry', class: 'btn btn-build' do
|
||||
= icon('repeat')
|
||||
- elsif defined?(allow_retry) && allow_retry
|
||||
- if build.retryable?
|
||||
= link_to retry_namespace_project_build_path(build.project.namespace, build.project, build, return_to: request.original_url), method: :post, title: 'Retry', class: 'btn btn-build' do
|
||||
= icon('repeat')
|
||||
- elsif build.playable?
|
||||
= link_to play_namespace_project_build_path(build.project.namespace, build.project, build, return_to: request.original_url), method: :post, title: 'Retry', class: 'btn btn-build' do
|
||||
= icon('play')
|
||||
|
||||
|
|
|
@ -57,18 +57,30 @@
|
|||
%td.pipeline-actions
|
||||
.controls.hidden-xs.pull-right
|
||||
- artifacts = pipeline.builds.latest.select { |b| b.artifacts? }
|
||||
- if artifacts.present?
|
||||
.inline
|
||||
.btn-group
|
||||
%a.dropdown-toggle.btn.btn-default.build-artifacts{type: 'button', 'data-toggle' => 'dropdown'}
|
||||
= icon("download")
|
||||
%b.caret
|
||||
%ul.dropdown-menu.dropdown-menu-align-right
|
||||
- artifacts.each do |build|
|
||||
- playable = pipeline.playable_actions
|
||||
- if artifacts.present? || playable.any?
|
||||
.btn-group.inline
|
||||
- if playable.any?
|
||||
.btn-group
|
||||
%a.dropdown-toggle.btn.btn-default{type: 'button', 'data-toggle' => 'dropdown'}
|
||||
= icon("play")
|
||||
%b.caret
|
||||
%ul.dropdown-menu.dropdown-menu-align-right
|
||||
%li
|
||||
= link_to download_namespace_project_build_artifacts_path(@project.namespace, @project, build), rel: 'nofollow' do
|
||||
= icon("download")
|
||||
%span Download '#{build.name}' artifacts
|
||||
= link_to play_namespace_project_build_path(@project.namespace, @project, build), rel: 'nofollow' do
|
||||
= icon("play")
|
||||
%span= playable.name.titleize
|
||||
- if artifacts.present?
|
||||
.btn-group
|
||||
%a.dropdown-toggle.btn.btn-default.build-artifacts{type: 'button', 'data-toggle' => 'dropdown'}
|
||||
= icon("download")
|
||||
%b.caret
|
||||
%ul.dropdown-menu.dropdown-menu-align-right
|
||||
- artifacts.each do |build|
|
||||
%li
|
||||
= link_to download_namespace_project_build_artifacts_path(@project.namespace, @project, build), rel: 'nofollow' do
|
||||
= icon("download")
|
||||
%span Download '#{build.name}' artifacts
|
||||
|
||||
- if can?(current_user, :update_pipeline, @project)
|
||||
.cancel-retry-btns.inline
|
||||
|
|
|
@ -21,3 +21,5 @@
|
|||
Retry
|
||||
- else
|
||||
Rollback
|
||||
|
||||
= render 'playable', deployment: deployment
|
||||
|
|
12
app/views/projects/deployments/_playable.html.haml
Normal file
12
app/views/projects/deployments/_playable.html.haml
Normal file
|
@ -0,0 +1,12 @@
|
|||
- playable = deployment.playable_actions
|
||||
- if playable.any?
|
||||
.btn-group.inline
|
||||
.btn-group
|
||||
%a.dropdown-toggle.btn.btn-default{type: 'button', 'data-toggle' => 'dropdown'}
|
||||
= icon("play")
|
||||
%b.caret
|
||||
%ul.dropdown-menu.dropdown-menu-align-right
|
||||
%li
|
||||
= link_to play_namespace_project_build_path(@project.namespace, @project, build), rel: 'nofollow' do
|
||||
= icon("play")
|
||||
%span= playable.name.titleize
|
|
@ -15,3 +15,7 @@
|
|||
%td
|
||||
- if last_deployment
|
||||
#{time_ago_with_tooltip(last_deployment.created_at)}
|
||||
|
||||
%td
|
||||
- if can?(current_user, :create_deployment, last_deployment) && last_deployment.deployable
|
||||
= render 'projects/deployments/playable', deployment: last_deployment
|
||||
|
|
|
@ -750,6 +750,7 @@ Rails.application.routes.draw do
|
|||
get :status
|
||||
post :cancel
|
||||
post :retry
|
||||
post :play
|
||||
post :erase
|
||||
get :trace
|
||||
get :raw
|
||||
|
|
|
@ -194,8 +194,8 @@ module Ci
|
|||
raise ValidationError, "#{name} job: allow_failure parameter should be an boolean"
|
||||
end
|
||||
|
||||
if job[:when] && !job[:when].in?(%w[on_success on_failure always])
|
||||
raise ValidationError, "#{name} job: when parameter should be on_success, on_failure or always"
|
||||
if job[:when] && !job[:when].in?(%w[on_success on_failure always manual])
|
||||
raise ValidationError, "#{name} job: when parameter should be on_success, on_failure, always or manual"
|
||||
end
|
||||
|
||||
if job[:environment] && !validate_environment(job[:environment])
|
||||
|
|
|
@ -1141,7 +1141,7 @@ EOT
|
|||
config = YAML.dump({ rspec: { script: "test", when: 1 } })
|
||||
expect do
|
||||
GitlabCiYamlProcessor.new(config, path)
|
||||
end.to raise_error(GitlabCiYamlProcessor::ValidationError, "rspec job: when parameter should be on_success, on_failure or always")
|
||||
end.to raise_error(GitlabCiYamlProcessor::ValidationError, "rspec job: when parameter should be on_success, on_failure, always or manual")
|
||||
end
|
||||
|
||||
it "returns errors if job artifacts:name is not an a string" do
|
||||
|
|
Loading…
Reference in a new issue