BigW Consortium Gitlab

commit_statuses.rb 3.55 KB
Newer Older
1 2 3 4
require 'mime/types'

module API
  # Project commit statuses API
5
  class CommitStatuses < Grape::API
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
    resource :projects do
      before { authenticate! }

      # Get a commit's statuses
      #
      # Parameters:
      #   id (required) - The ID of a project
      #   sha (required) - The commit hash
      #   ref (optional) - The ref
      #   stage (optional) - The stage
      #   name (optional) - The name
      #   all (optional) - Show all statuses, default: false
      # Examples:
      #   GET /projects/:id/repository/commits/:sha/statuses
      get ':id/repository/commits/:sha/statuses' do
21 22 23 24
        authorize!(:read_commit_status, user_project)

        not_found!('Commit') unless user_project.commit(params[:sha])

25 26
        pipelines = user_project.pipelines.where(sha: params[:sha])
        statuses = ::CommitStatus.where(pipeline: pipelines)
27
        statuses = statuses.latest unless to_boolean(params[:all])
28
        statuses = statuses.where(ref: params[:ref]) if params[:ref].present?
Kamil Trzcinski committed
29
        statuses = statuses.where(stage: params[:stage]) if params[:stage].present?
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
        statuses = statuses.where(name: params[:name]) if params[:name].present?
        present paginate(statuses), with: Entities::CommitStatus
      end

      # Post status to commit
      #
      # Parameters:
      #   id (required) - The ID of a project
      #   sha (required) - The commit hash
      #   ref (optional) - The ref
      #   state (required) - The state of the status. Can be: pending, running, success, error or failure
      #   target_url (optional) - The target URL to associate with this status
      #   description (optional) - A short description of the status
      #   name or context (optional) - A string label to differentiate this status from the status of other systems. Default: "default"
      # Examples:
45
      #   POST /projects/:id/statuses/:sha
46
      post ':id/statuses/:sha' do
Kamil Trzcinski committed
47
        authorize! :create_commit_status, user_project
48 49 50 51 52
        required_attributes! [:state]
        attrs = attributes_for_keys [:ref, :target_url, :description, :context, :name]
        commit = @project.commit(params[:sha])
        not_found! 'Commit' unless commit

53
        # Since the CommitStatus is attached to Ci::Pipeline (in the future Pipeline)
54 55 56 57 58 59 60 61 62 63 64 65
        # 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]
        unless ref
          branches = @project.repository.branch_names_contains(commit.sha)
          not_found! 'References for commit' if branches.none?
          ref = branches.first
        end
Kamil Trzcinski committed
66

67
        pipeline = @project.ensure_pipeline(commit.sha, ref, current_user)
68 69

        name = params[:name] || params[:context]
70 71
        status = GenericCommitStatus.running_or_pending.find_by(pipeline: pipeline, name: name, ref: params[:ref])
        status ||= GenericCommitStatus.new(project: @project, pipeline: pipeline, user: current_user)
72 73 74
        status.update(attrs)

        case params[:state].to_s
75 76 77 78 79 80 81 82 83 84
        when 'running'
          status.run
        when 'success'
          status.success
        when 'failed'
          status.drop
        when 'canceled'
          status.cancel
        else
          status.status = params[:state].to_s
85 86 87 88 89 90 91 92 93 94 95
        end

        if status.save
          present status, with: Entities::CommitStatus
        else
          render_validation_error!(status)
        end
      end
    end
  end
end