summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/controllers/projects/pipelines_controller.rb33
-rw-r--r--app/views/projects/pipelines/_with_tabs.html.haml2
-rw-r--r--changelogs/unreleased/add_links_to_latest_pipelines.yml5
-rw-r--r--config/routes/project.rb3
-rw-r--r--doc/ci/pipelines.md4
-rw-r--r--spec/controllers/projects/pipelines_controller_spec.rb65
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