diff options
-rw-r--r-- | app/controllers/projects/pipelines_controller.rb | 33 | ||||
-rw-r--r-- | app/views/projects/pipelines/_with_tabs.html.haml | 2 | ||||
-rw-r--r-- | changelogs/unreleased/add_links_to_latest_pipelines.yml | 5 | ||||
-rw-r--r-- | config/routes/project.rb | 3 | ||||
-rw-r--r-- | doc/ci/pipelines.md | 4 | ||||
-rw-r--r-- | spec/controllers/projects/pipelines_controller_spec.rb | 65 |
6 files changed, 106 insertions, 6 deletions
diff --git a/app/controllers/projects/pipelines_controller.rb b/app/controllers/projects/pipelines_controller.rb index db3b7c8b177..e6e3a440925 100644 --- a/app/controllers/projects/pipelines_controller.rb +++ b/app/controllers/projects/pipelines_controller.rb @@ -3,6 +3,7 @@ class Projects::PipelinesController < Projects::ApplicationController before_action :whitelist_query_limiting, only: [:create, :retry] before_action :pipeline, except: [:index, :new, :create, :charts] + before_action :set_pipeline_path, only: [:show] before_action :authorize_read_pipeline! before_action :authorize_read_build!, only: [:index] before_action :authorize_create_pipeline!, only: [:new, :create] @@ -174,14 +175,36 @@ class Projects::PipelinesController < Projects::ApplicationController # rubocop: disable CodeReuse/ActiveRecord def pipeline - @pipeline ||= project - .all_pipelines - .includes(user: :status) - .find_by!(id: params[:id]) - .present(current_user: current_user) + @pipeline ||= if params[:id].blank? && params[:latest] + latest_pipeline + else + project + .all_pipelines + .includes(user: :status) + .find_by!(id: params[:id]) + .present(current_user: current_user) + end end # rubocop: enable CodeReuse/ActiveRecord + def set_pipeline_path + @pipeline_path ||= if params[:id].blank? && params[:latest] + latest_project_pipelines_path(@project, params['ref']) + else + project_pipeline_path(@project, @pipeline) + end + end + + def latest_pipeline + ref = params['ref'].presence || @project.default_branch + sha = @project.commit(ref)&.sha + + @project.ci_pipelines + .newest_first(ref: ref, sha: sha) + .first + &.present(current_user: current_user) + end + 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') diff --git a/app/views/projects/pipelines/_with_tabs.html.haml b/app/views/projects/pipelines/_with_tabs.html.haml index c04f076a3ab..56995ffbcee 100644 --- a/app/views/projects/pipelines/_with_tabs.html.haml +++ b/app/views/projects/pipelines/_with_tabs.html.haml @@ -1,7 +1,7 @@ .tabs-holder %ul.pipelines-tabs.nav-links.no-top.no-bottom.mobile-separator.nav.nav-tabs %li.js-pipeline-tab-link - = link_to project_pipeline_path(@project, @pipeline), data: { target: '#js-tab-pipeline', action: 'pipelines', toggle: 'tab' }, class: 'pipeline-tab' do + = link_to @pipeline_path, data: { target: '#js-tab-pipeline', action: 'pipelines', toggle: 'tab' }, class: 'pipeline-tab' do = _('Pipeline') %li.js-builds-tab-link = link_to builds_project_pipeline_path(@project, @pipeline), data: { target: '#js-tab-builds', action: 'builds', toggle: 'tab' }, class: 'builds-tab' do diff --git a/changelogs/unreleased/add_links_to_latest_pipelines.yml b/changelogs/unreleased/add_links_to_latest_pipelines.yml new file mode 100644 index 00000000000..333cd6c92b4 --- /dev/null +++ b/changelogs/unreleased/add_links_to_latest_pipelines.yml @@ -0,0 +1,5 @@ +--- +title: 'Add links for latest pipelines' +merge_request: 20865 +author: Alex Ives +type: added diff --git a/config/routes/project.rb b/config/routes/project.rb index 9a453d101a1..29e462f904d 100644 --- a/config/routes/project.rb +++ b/config/routes/project.rb @@ -359,6 +359,9 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do collection do resource :pipelines_settings, path: 'settings', only: [:show, :update] get :charts + scope '(*ref)', constraints: { ref: Gitlab::PathRegex.git_reference_regex } do + get :latest, action: :show, defaults: { latest: true } + end end member do diff --git a/doc/ci/pipelines.md b/doc/ci/pipelines.md index ed8d0e3bc35..eaa6efc526d 100644 --- a/doc/ci/pipelines.md +++ b/doc/ci/pipelines.md @@ -377,6 +377,10 @@ This functionality is only available: - For users with at least Developer access. - If the the stage contains [manual actions](#manual-actions-from-pipeline-graphs). +## Most Recent Pipeline + +There's a link to the latest pipeline for the last commit of a given branch at `/project/pipelines/[branch]/latest`. Also, `/project/pipelines/latest` will redirect you to the latest pipeline for the last commit on the project's default branch. + ## Security on protected branches A strict security model is enforced when pipelines are executed on diff --git a/spec/controllers/projects/pipelines_controller_spec.rb b/spec/controllers/projects/pipelines_controller_spec.rb index 089d06e11eb..212d8b15252 100644 --- a/spec/controllers/projects/pipelines_controller_spec.rb +++ b/spec/controllers/projects/pipelines_controller_spec.rb @@ -397,4 +397,69 @@ describe Projects::PipelinesController do end end end + + describe 'GET latest' do + let(:branch_main) { project.repository.branches[0] } + let(:branch_secondary) { project.repository.branches[1] } + + let!(:pipeline_master) do + create(:ci_pipeline, + ref: branch_main.name, + sha: branch_main.target, + project: project) + end + + let!(:pipeline_secondary) do + create(:ci_pipeline, + ref: branch_secondary.name, + sha: branch_secondary.target, + project: project) + end + + before do + project.change_head(branch_main.name) + project.reload_default_branch + end + + context 'no ref provided' do + it 'shows latest pipeline for the default project branch' do + get :show, params: { namespace_id: project.namespace, project_id: project, latest: true, ref: nil } + + expect(response).to have_gitlab_http_status(200) + expect(assigns(:pipeline)).to have_attributes(id: pipeline_master.id) + end + end + + context 'ref provided' do + before do + create(:ci_pipeline, ref: 'master', project: project) + end + + it 'shows the latest pipeline for the provided ref' do + get :show, params: { namespace_id: project.namespace, project_id: project, latest: true, ref: branch_secondary.name } + + expect(response).to have_gitlab_http_status(200) + expect(assigns(:pipeline)).to have_attributes(id: pipeline_secondary.id) + end + + context 'newer pipeline exists for older sha' do + before do + create(:ci_pipeline, ref: branch_secondary.name, sha: project.commit(branch_secondary.name).parent, project: project) + end + + it 'shows the provided ref with the last sha/pipeline combo' do + get :show, params: { namespace_id: project.namespace, project_id: project, latest: true, ref: branch_secondary.name } + + expect(response).to have_gitlab_http_status(200) + expect(assigns(:pipeline)).to have_attributes(id: pipeline_secondary.id) + end + end + end + + it 'renders a 404 if no pipeline is found for the ref' do + get :show, params: { namespace_id: project.namespace, project_id: project, ref: 'no-branch' } + + expect(response).to have_gitlab_http_status(404) + end + end end |