Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2019-10-21 18:05:58 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2019-10-21 18:05:58 +0300
commitad1e4b8fb8104b642fa79ed34fd144bc2bed8a19 (patch)
tree78f95d63d4ea5ed0b1a8b3c83c38d9cbd682f884 /app/services/ci
parent664c4c7b49c6056136299817eb79e9f1de83e567 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/services/ci')
-rw-r--r--app/services/ci/compare_reports_base_service.rb5
-rw-r--r--app/services/ci/find_exposed_artifacts_service.rb70
-rw-r--r--app/services/ci/generate_exposed_artifacts_report_service.rb30
3 files changed, 105 insertions, 0 deletions
diff --git a/app/services/ci/compare_reports_base_service.rb b/app/services/ci/compare_reports_base_service.rb
index 5b76e1824e4..83ba70e8437 100644
--- a/app/services/ci/compare_reports_base_service.rb
+++ b/app/services/ci/compare_reports_base_service.rb
@@ -1,6 +1,11 @@
# frozen_string_literal: true
module Ci
+ # TODO: when using this class with exposed artifacts we see that there are
+ # 2 responsibilities:
+ # 1. reactive caching interface (same in all cases)
+ # 2. data generator (report comparison in most of the case but not always)
+ # issue: https://gitlab.com/gitlab-org/gitlab/issues/34224
class CompareReportsBaseService < ::BaseService
def execute(base_pipeline, head_pipeline)
comparer = comparer_class.new(get_report(base_pipeline), get_report(head_pipeline))
diff --git a/app/services/ci/find_exposed_artifacts_service.rb b/app/services/ci/find_exposed_artifacts_service.rb
new file mode 100644
index 00000000000..5c75af294bf
--- /dev/null
+++ b/app/services/ci/find_exposed_artifacts_service.rb
@@ -0,0 +1,70 @@
+# frozen_string_literal: true
+
+module Ci
+ # This class loops through all builds with exposed artifacts and returns
+ # basic information about exposed artifacts for given jobs for the frontend
+ # to display them as custom links in the merge request.
+ #
+ # This service must be used with care.
+ # Looking for exposed artifacts is very slow and should be done asynchronously.
+ class FindExposedArtifactsService < ::BaseService
+ include Gitlab::Routing
+
+ MAX_EXPOSED_ARTIFACTS = 10
+
+ def for_pipeline(pipeline, limit: MAX_EXPOSED_ARTIFACTS)
+ results = []
+
+ pipeline.builds.latest.with_exposed_artifacts.find_each do |job|
+ if job_exposed_artifacts = for_job(job)
+ results << job_exposed_artifacts
+ end
+
+ break if results.size >= limit
+ end
+
+ results
+ end
+
+ def for_job(job)
+ return unless job.has_exposed_artifacts?
+
+ metadata_entries = first_2_metadata_entries_for_artifacts_paths(job)
+ return if metadata_entries.empty?
+
+ {
+ text: job.artifacts_expose_as,
+ url: path_for_entries(metadata_entries, job),
+ job_path: project_job_path(project, job),
+ job_name: job.name
+ }
+ end
+
+ private
+
+ # we don't need to fetch all artifacts entries for a job because
+ # it could contain many. We only need to know whether it has 1 or more
+ # artifacts, so fetching the first 2 would be sufficient.
+ def first_2_metadata_entries_for_artifacts_paths(job)
+ job.artifacts_paths
+ .lazy
+ .map { |path| job.artifacts_metadata_entry(path, recursive: true) }
+ .select { |entry| entry.exists? }
+ .first(2)
+ end
+
+ def path_for_entries(entries, job)
+ return if entries.empty?
+
+ if single_artifact?(entries)
+ file_project_job_artifacts_path(project, job, entries.first.path)
+ else
+ browse_project_job_artifacts_path(project, job)
+ end
+ end
+
+ def single_artifact?(entries)
+ entries.size == 1 && entries.first.file?
+ end
+ end
+end
diff --git a/app/services/ci/generate_exposed_artifacts_report_service.rb b/app/services/ci/generate_exposed_artifacts_report_service.rb
new file mode 100644
index 00000000000..b9bf580bcbc
--- /dev/null
+++ b/app/services/ci/generate_exposed_artifacts_report_service.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+module Ci
+ # TODO: a couple of points with this approach:
+ # + reuses existing architecture and reactive caching
+ # - it's not a report comparison and some comparing features must be turned off.
+ # see CompareReportsBaseService for more notes.
+ # issue: https://gitlab.com/gitlab-org/gitlab/issues/34224
+ class GenerateExposedArtifactsReportService < CompareReportsBaseService
+ def execute(base_pipeline, head_pipeline)
+ data = FindExposedArtifactsService.new(project, current_user).for_pipeline(head_pipeline)
+ {
+ status: :parsed,
+ key: key(base_pipeline, head_pipeline),
+ data: data
+ }
+ rescue => e
+ Gitlab::Sentry.track_acceptable_exception(e, extra: { project_id: project.id })
+ {
+ status: :error,
+ key: key(base_pipeline, head_pipeline),
+ status_reason: _('An error occurred while fetching exposed artifacts.')
+ }
+ end
+
+ def latest?(base_pipeline, head_pipeline, data)
+ data&.fetch(:key, nil) == key(base_pipeline, head_pipeline)
+ end
+ end
+end