pipelines_controller.rb 4.94 KB
Newer Older
Kamil Trzcinski's avatar
Kamil Trzcinski committed
1
class Projects::PipelinesController < Projects::ApplicationController
2 3
  prepend ::EE::Projects::PipelinesController

4
  before_action :whitelist_query_limiting, only: [:create, :retry]
5
  before_action :pipeline, except: [:index, :new, :create, :charts]
6
  before_action :commit, only: [:show, :builds, :failures]
Kamil Trzcinski's avatar
WIP  
Kamil Trzcinski committed
7 8 9 10
  before_action :authorize_read_pipeline!
  before_action :authorize_create_pipeline!, only: [:new, :create]
  before_action :authorize_update_pipeline!, only: [:retry, :cancel]

11 12
  wrap_parameters Ci::Pipeline

13 14
  POLLING_INTERVAL = 10_000

Kamil Trzcinski's avatar
WIP  
Kamil Trzcinski committed
15 16
  def index
    @scope = params[:scope]
17
    @pipelines = PipelinesFinder
18 19
      .new(project, scope: @scope)
      .execute
20 21
      .page(params[:page])
      .per(30)
22

23 24 25 26
    @running_count = limited_pipelines_count(project, 'running')
    @pending_count = limited_pipelines_count(project, 'pending')
    @finished_count = limited_pipelines_count(project, 'finished')
    @pipelines_count = limited_pipelines_count(project)
27

Kamil Trzcinski's avatar
Kamil Trzcinski committed
28 29 30
    respond_to do |format|
      format.html
      format.json do
31
        Gitlab::PollingInterval.set_header(response, interval: POLLING_INTERVAL)
32

33 34
        render json: {
          pipelines: PipelineSerializer
Fatih Acet's avatar
Fatih Acet committed
35
            .new(project: @project, current_user: @current_user)
36
            .with_pagination(request, response)
37
            .represent(@pipelines, disable_coverage: true, preload: true),
38 39
          count: {
            all: @pipelines_count,
40 41
            running: @running_count,
            pending: @pending_count,
42
            finished: @finished_count
43 44
          }
        }
Kamil Trzcinski's avatar
Kamil Trzcinski committed
45 46
      end
    end
Kamil Trzcinski's avatar
WIP  
Kamil Trzcinski committed
47 48 49
  end

  def new
50
    @pipeline = project.pipelines.new(ref: @project.default_branch)
Kamil Trzcinski's avatar
WIP  
Kamil Trzcinski committed
51 52 53
  end

  def create
54 55
    @pipeline = Ci::CreatePipelineService
      .new(project, current_user, create_params)
56
      .execute(:web, ignore_skip_ci: true, save_on_errors: false)
57 58

    if @pipeline.persisted?
59
      redirect_to project_pipeline_path(project, @pipeline)
60
    else
Kamil Trzcinski's avatar
Kamil Trzcinski committed
61
      render 'new'
Kamil Trzcinski's avatar
WIP  
Kamil Trzcinski committed
62 63 64 65
    end
  end

  def show
66 67 68 69 70 71
    respond_to do |format|
      format.html
      format.json do
        Gitlab::PollingInterval.set_header(response, interval: POLLING_INTERVAL)

        render json: PipelineSerializer
Fatih Acet's avatar
Fatih Acet committed
72
          .new(project: @project, current_user: @current_user)
73 74 75
          .represent(@pipeline, grouped: true)
      end
    end
Kamil Trzcinski's avatar
WIP  
Kamil Trzcinski committed
76 77
  end

Filipa Lacerda's avatar
Filipa Lacerda committed
78
  def builds
79
    render_show
80 81 82
  end

  def failures
83
    if @pipeline.failed_builds.present?
84 85 86
      render_show
    else
      redirect_to pipeline_path(@pipeline)
87
    end
Filipa Lacerda's avatar
Filipa Lacerda committed
88 89
  end

90
  def status
91
    render json: PipelineSerializer
Fatih Acet's avatar
Fatih Acet committed
92
      .new(project: @project, current_user: @current_user)
Shinya Maeda's avatar
Shinya Maeda committed
93
      .represent_status(@pipeline)
94 95
  end

96
  def stage
97
    @stage = pipeline.legacy_stage(params[:stage])
98 99
    return not_found unless @stage

100 101
    render json: StageSerializer
      .new(project: @project, current_user: @current_user)
Kamil Trzciński's avatar
Kamil Trzciński committed
102
      .represent(@stage, details: true)
103 104
  end

105 106 107 108 109 110
  # TODO: This endpoint is used by mini-pipeline-graph
  # TODO: This endpoint should be migrated to `stage.json`
  def stage_ajax
    @stage = pipeline.legacy_stage(params[:stage])
    return not_found unless @stage

Kamil Trzciński's avatar
Kamil Trzciński committed
111
    render json: { html: view_to_html_string('projects/pipelines/_stage') }
112 113
  end

Kamil Trzcinski's avatar
WIP  
Kamil Trzcinski committed
114
  def retry
115
    pipeline.retry_failed(current_user)
Kamil Trzcinski's avatar
WIP  
Kamil Trzcinski committed
116

117 118
    respond_to do |format|
      format.html do
119
        redirect_back_or_default default: project_pipelines_path(project)
120 121
      end

122
      format.json { head :no_content }
123
    end
Kamil Trzcinski's avatar
WIP  
Kamil Trzcinski committed
124 125 126
  end

  def cancel
Kamil Trzcinski's avatar
Kamil Trzcinski committed
127
    pipeline.cancel_running
Kamil Trzcinski's avatar
WIP  
Kamil Trzcinski committed
128

129 130
    respond_to do |format|
      format.html do
131
        redirect_back_or_default default: project_pipelines_path(project)
132 133
      end

134
      format.json { head :no_content }
135
    end
Kamil Trzcinski's avatar
WIP  
Kamil Trzcinski committed
136 137
  end

138 139
  def charts
    @charts = {}
140 141 142 143
    @charts[:week] = Gitlab::Ci::Charts::WeekChart.new(project)
    @charts[:month] = Gitlab::Ci::Charts::MonthChart.new(project)
    @charts[:year] = Gitlab::Ci::Charts::YearChart.new(project)
    @charts[:pipeline_times] = Gitlab::Ci::Charts::PipelineTime.new(project)
144 145 146 147 148

    @counts = {}
    @counts[:total] = @project.pipelines.count(:all)
    @counts[:success] = @project.pipelines.success.count(:all)
    @counts[:failed] = @project.pipelines.failed.count(:all)
149 150
  end

Kamil Trzcinski's avatar
WIP  
Kamil Trzcinski committed
151 152
  private

153 154 155 156 157 158 159 160
  def render_show
    respond_to do |format|
      format.html do
        render 'show'
      end
    end
  end

Kamil Trzcinski's avatar
Kamil Trzcinski committed
161
  def create_params
162
    params.require(:pipeline).permit(:ref, variables_attributes: %i[key secret_value])
Kamil Trzcinski's avatar
Kamil Trzcinski committed
163 164
  end

Kamil Trzcinski's avatar
Kamil Trzcinski committed
165
  def pipeline
166
    @pipeline ||= project.pipelines.find_by!(id: params[:id]).present(current_user: current_user)
Kamil Trzcinski's avatar
WIP  
Kamil Trzcinski committed
167
  end
Kamil Trzcinski's avatar
Kamil Trzcinski committed
168 169

  def commit
170
    @commit ||= @pipeline.commit
Kamil Trzcinski's avatar
Kamil Trzcinski committed
171
  end
172 173 174 175 176

  def whitelist_query_limiting
    # Also see https://gitlab.com/gitlab-org/gitlab-ce/issues/42343
    Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab-ce/issues/42339')
  end
177 178 179 180

  def authorize_update_pipeline!
    return access_denied! unless can?(current_user, :update_pipeline, @pipeline)
  end
181 182 183 184 185 186

  def limited_pipelines_count(project, scope = nil)
    finder = PipelinesFinder.new(project, scope: scope)

    view_context.limited_counter_with_delimiter(finder.execute)
  end
Kamil Trzcinski's avatar
WIP  
Kamil Trzcinski committed
187
end