Commit 8a3879f3 authored by Stan Hu's avatar Stan Hu

Fix 404s downloading latest build artifacts

Previously `ArtifactsController#latest_succeeded` might return 404s even
though `ArtifactsController#download` would successfully return an
artifact. For example, this could happen when:

1. A new commit was merged to `master`.
2. A user attempts to download the artifact for `master` before the
pipeline for `master` finishes, or the pipeline fails altogether.

To fix this problem, we fallback to looking up a successful pipelines by
ref name if one doesn't exist for the SHA.

Closes https://gitlab.com/gitlab-org/gitlab/-/issues/216055
parent 1e0d5ffb
......@@ -113,7 +113,7 @@ class Projects::ArtifactsController < Projects::ApplicationController
def build
@build ||= begin
build = build_from_id || build_from_ref
build = build_from_id || build_from_sha || build_from_ref
build&.present(current_user: current_user)
end
end
......@@ -127,7 +127,8 @@ class Projects::ArtifactsController < Projects::ApplicationController
project.builds.find_by_id(params[:job_id]) if params[:job_id]
end
def build_from_ref
def build_from_sha
return if params[:job].blank?
return unless @ref_name
commit = project.commit(@ref_name)
......@@ -136,6 +137,13 @@ class Projects::ArtifactsController < Projects::ApplicationController
project.latest_successful_build_for_sha(params[:job], commit.id)
end
def build_from_ref
return if params[:job].blank?
return unless @ref_name
project.latest_successful_build_for_ref(params[:job], @ref_name)
end
def artifacts_file
@artifacts_file ||= build&.artifacts_file_for_type(params[:file_type] || :archive)
end
......
---
title: Fix 404s downloading build artifacts
merge_request: 32741
author:
type: fixed
......@@ -3,6 +3,8 @@
require 'spec_helper'
describe Projects::ArtifactsController do
include RepoHelpers
let(:user) { project.owner }
let_it_be(:project) { create(:project, :repository, :public) }
......@@ -481,6 +483,22 @@ describe Projects::ArtifactsController do
expect(response).to redirect_to(path)
end
end
context 'with a failed pipeline on an updated master' do
before do
create_file_in_repo(project, 'master', 'master', 'test.txt', 'This is test')
create(:ci_pipeline,
project: project,
sha: project.commit.sha,
ref: project.default_branch,
status: 'failed')
get :latest_succeeded, params: params_from_ref(project.default_branch)
end
it_behaves_like 'redirect to the job'
end
end
end
end
......@@ -32,5 +32,11 @@ describe "User downloads artifacts" do
it_behaves_like "downloading"
end
context "via SHA" do
let(:url) { latest_succeeded_project_artifacts_path(project, "#{pipeline.sha}/download", job: job.name) }
it_behaves_like "downloading"
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment