gitlab-org--gitlab-foss/lib/api/commit_statuses.rb

130 lines
4.9 KiB
Ruby
Raw Normal View History

# frozen_string_literal: true
2015-10-06 10:01:16 +00:00
require 'mime/types'
module API
class CommitStatuses < Grape::API
params do
requires :id, type: String, desc: 'The ID of a project'
end
2017-08-31 11:44:49 +00:00
resource :projects, requirements: API::PROJECT_ENDPOINT_REQUIREMENTS do
2016-12-04 17:11:19 +00:00
include PaginationParams
2015-10-06 10:01:16 +00:00
before { authenticate! }
2016-10-14 08:45:23 +00:00
desc "Get a commit's statuses" do
success Entities::CommitStatus
end
params do
requires :sha, type: String, desc: 'The commit hash'
optional :ref, type: String, desc: 'The ref'
optional :stage, type: String, desc: 'The stage'
optional :name, type: String, desc: 'The name'
optional :all, type: String, desc: 'Show all statuses, default: false'
2016-12-04 17:11:19 +00:00
use :pagination
2016-10-14 08:45:23 +00:00
end
# rubocop: disable CodeReuse/ActiveRecord
2015-10-06 10:01:16 +00:00
get ':id/repository/commits/:sha/statuses' do
authorize!(:read_commit_status, user_project)
not_found!('Commit') unless user_project.commit(params[:sha])
pipelines = user_project.pipelines.where(sha: params[:sha])
statuses = ::CommitStatus.where(pipeline: pipelines)
2016-07-20 06:55:44 +00:00
statuses = statuses.latest unless to_boolean(params[:all])
2015-10-06 10:01:16 +00:00
statuses = statuses.where(ref: params[:ref]) if params[:ref].present?
2015-10-12 13:45:46 +00:00
statuses = statuses.where(stage: params[:stage]) if params[:stage].present?
2015-10-06 10:01:16 +00:00
statuses = statuses.where(name: params[:name]) if params[:name].present?
present paginate(statuses), with: Entities::CommitStatus
end
# rubocop: enable CodeReuse/ActiveRecord
2015-10-06 10:01:16 +00:00
2016-10-14 08:45:23 +00:00
desc 'Post status to a commit' do
success Entities::CommitStatus
end
params do
requires :sha, type: String, desc: 'The commit hash'
requires :state, type: String, desc: 'The state of the status',
2017-02-22 17:46:57 +00:00
values: %w(pending running success failed canceled)
2016-10-14 08:45:23 +00:00
optional :ref, type: String, desc: 'The ref'
optional :target_url, type: String, desc: 'The target URL to associate with this status'
optional :description, type: String, desc: 'A short description of the status'
optional :name, type: String, desc: 'A string label to differentiate this status from the status of other systems. Default: "default"'
optional :context, type: String, desc: 'A string label to differentiate this status from the status of other systems. Default: "default"'
optional :coverage, type: Float, desc: 'The total code coverage'
2016-10-14 08:45:23 +00:00
end
# rubocop: disable CodeReuse/ActiveRecord
2015-10-06 10:01:16 +00:00
post ':id/statuses/:sha' do
2015-10-12 19:35:52 +00:00
authorize! :create_commit_status, user_project
2016-10-14 08:45:23 +00:00
2015-10-06 10:01:16 +00:00
commit = @project.commit(params[:sha])
not_found! 'Commit' unless commit
# Since the CommitStatus is attached to Ci::Pipeline (in the future Pipeline)
2016-04-16 20:43:40 +00:00
# We need to always have the pipeline object
# To have a valid pipeline object that can be attached to specific MR
# Other CI service needs to send `ref`
# If we don't receive it, we will attach the CommitStatus to
# the first found branch on that commit
ref = params[:ref]
ref ||= @project.repository.branch_names_contains(commit.sha).first
not_found! 'References for commit' unless ref
name = params[:name] || params[:context] || 'default'
2016-04-11 14:55:40 +00:00
2017-05-24 13:13:51 +00:00
pipeline = @project.pipeline_for(ref, commit.sha)
unless pipeline
pipeline = @project.pipelines.create!(
source: :external,
sha: commit.sha,
ref: ref,
2017-09-01 08:54:07 +00:00
user: current_user,
protected: @project.protected_for?(ref))
2017-05-24 13:13:51 +00:00
end
2015-10-06 10:01:16 +00:00
status = GenericCommitStatus.running_or_pending.find_or_initialize_by(
project: @project,
pipeline: pipeline,
name: name,
ref: ref,
2017-09-01 08:54:07 +00:00
user: current_user,
protected: @project.protected_for?(ref)
)
2015-10-06 10:01:16 +00:00
optional_attributes =
attributes_for_keys(%w[target_url description coverage])
status.update(optional_attributes) if optional_attributes.any?
render_validation_error!(status) if status.invalid?
begin
case params[:state]
when 'pending'
status.enqueue!
when 'running'
status.enqueue
status.run!
when 'success'
status.success!
when 'failed'
2017-08-31 13:03:41 +00:00
status.drop!(:api_failure)
when 'canceled'
status.cancel!
else
render_api_error!('invalid state', 400)
end
2015-10-06 10:01:16 +00:00
MergeRequest.where(source_project: @project, source_branch: ref)
.update_all(head_pipeline_id: pipeline) if pipeline.latest?
2015-10-06 10:01:16 +00:00
present status, with: Entities::CommitStatus
rescue StateMachines::InvalidTransition => e
render_api_error!(e.message, 400)
2015-10-06 10:01:16 +00:00
end
end
# rubocop: enable CodeReuse/ActiveRecord
2015-10-06 10:01:16 +00:00
end
end
end