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:
Diffstat (limited to 'app/services/ci')
-rw-r--r--app/services/ci/after_requeue_job_service.rb36
-rw-r--r--app/services/ci/archive_trace_service.rb2
-rw-r--r--app/services/ci/build_erase_service.rb49
-rw-r--r--app/services/ci/build_report_result_service.rb3
-rw-r--r--app/services/ci/compare_reports_base_service.rb9
-rw-r--r--app/services/ci/create_downstream_pipeline_service.rb15
-rw-r--r--app/services/ci/create_pipeline_service.rb1
-rw-r--r--app/services/ci/delete_objects_service.rb4
-rw-r--r--app/services/ci/expire_pipeline_cache_service.rb2
-rw-r--r--app/services/ci/generate_coverage_reports_service.rb2
-rw-r--r--app/services/ci/job_artifacts/create_service.rb2
-rw-r--r--app/services/ci/job_artifacts/delete_service.rb32
-rw-r--r--app/services/ci/job_artifacts/track_artifact_report_service.rb23
-rw-r--r--app/services/ci/pipeline_artifacts/coverage_report_service.rb8
-rw-r--r--app/services/ci/pipeline_artifacts/create_code_quality_mr_diff_report_service.rb20
-rw-r--r--app/services/ci/pipelines/add_job_service.rb2
-rw-r--r--app/services/ci/queue/pending_builds_strategy.rb6
-rw-r--r--app/services/ci/register_job_service.rb2
-rw-r--r--app/services/ci/resource_groups/assign_resource_from_resource_group_service.rb6
-rw-r--r--app/services/ci/runners/set_runner_associated_projects_service.rb69
-rw-r--r--app/services/ci/runners/update_runner_service.rb9
-rw-r--r--app/services/ci/stuck_builds/drop_helpers.rb2
-rw-r--r--app/services/ci/test_failure_history_service.rb4
-rw-r--r--app/services/ci/unlock_artifacts_service.rb17
24 files changed, 292 insertions, 33 deletions
diff --git a/app/services/ci/after_requeue_job_service.rb b/app/services/ci/after_requeue_job_service.rb
index 1ae4639751b..634c547a623 100644
--- a/app/services/ci/after_requeue_job_service.rb
+++ b/app/services/ci/after_requeue_job_service.rb
@@ -21,9 +21,16 @@ module Ci
@processable.pipeline.reset_source_bridge!(current_user)
end
+ # rubocop: disable CodeReuse/ActiveRecord
def dependent_jobs
+ return legacy_dependent_jobs unless ::Feature.enabled?(:ci_requeue_with_dag_object_hierarchy, project)
+
ordered_by_dag(
- stage_dependent_jobs.or(needs_dependent_jobs).ordered_by_stage
+ ::Ci::Processable
+ .from_union(needs_dependent_jobs, stage_dependent_jobs)
+ .skipped
+ .ordered_by_stage
+ .preload(:needs)
)
end
@@ -34,22 +41,37 @@ module Ci
end
def stage_dependent_jobs
- skipped_jobs.after_stage(@processable.stage_idx)
+ @processable.pipeline.processables.after_stage(@processable.stage_idx)
end
def needs_dependent_jobs
- skipped_jobs.scheduling_type_dag.with_needs([@processable.name])
+ ::Gitlab::Ci::ProcessableObjectHierarchy.new(
+ ::Ci::Processable.where(id: @processable.id)
+ ).descendants
end
- def skipped_jobs
- @skipped_jobs ||= @processable.pipeline.processables.skipped
+ def legacy_skipped_jobs
+ @legacy_skipped_jobs ||= @processable.pipeline.processables.skipped
+ end
+
+ def legacy_dependent_jobs
+ ordered_by_dag(
+ legacy_stage_dependent_jobs.or(legacy_needs_dependent_jobs).ordered_by_stage.preload(:needs)
+ )
+ end
+
+ def legacy_stage_dependent_jobs
+ legacy_skipped_jobs.after_stage(@processable.stage_idx)
+ end
+
+ def legacy_needs_dependent_jobs
+ legacy_skipped_jobs.scheduling_type_dag.with_needs([@processable.name])
end
- # rubocop: disable CodeReuse/ActiveRecord
def ordered_by_dag(jobs)
sorted_job_names = sort_jobs(jobs).each_with_index.to_h
- jobs.preload(:needs).group_by(&:stage_idx).flat_map do |_, stage_jobs|
+ jobs.group_by(&:stage_idx).flat_map do |_, stage_jobs|
stage_jobs.sort_by { |job| sorted_job_names.fetch(job.name) }
end
end
diff --git a/app/services/ci/archive_trace_service.rb b/app/services/ci/archive_trace_service.rb
index 9705a236d98..566346a4b09 100644
--- a/app/services/ci/archive_trace_service.rb
+++ b/app/services/ci/archive_trace_service.rb
@@ -27,7 +27,7 @@ module Ci
job.trace.archive!
job.remove_pending_state!
- if Feature.enabled?(:datadog_integration_logs_collection, job.project) && job.job_artifacts_trace.present?
+ if job.job_artifacts_trace.present?
job.project.execute_integrations(Gitlab::DataBuilder::ArchiveTrace.build(job), :archive_trace_hooks)
end
diff --git a/app/services/ci/build_erase_service.rb b/app/services/ci/build_erase_service.rb
new file mode 100644
index 00000000000..8a468e094eb
--- /dev/null
+++ b/app/services/ci/build_erase_service.rb
@@ -0,0 +1,49 @@
+# frozen_string_literal: true
+
+module Ci
+ class BuildEraseService
+ include BaseServiceUtility
+
+ def initialize(build, current_user)
+ @build = build
+ @current_user = current_user
+ end
+
+ def execute
+ unless build.erasable?
+ return ServiceResponse.error(message: _('Build cannot be erased'), http_status: :unprocessable_entity)
+ end
+
+ if build.project.refreshing_build_artifacts_size?
+ Gitlab::ProjectStatsRefreshConflictsLogger.warn_artifact_deletion_during_stats_refresh(
+ method: 'Ci::BuildEraseService#execute',
+ project_id: build.project_id
+ )
+ end
+
+ destroy_artifacts
+ erase_trace!
+ update_erased!
+
+ ServiceResponse.success(payload: build)
+ end
+
+ private
+
+ attr_reader :build, :current_user
+
+ def destroy_artifacts
+ # fix_expire_at is false because in this case we want to explicitly delete the job artifacts
+ # this flag is a workaround that will be removed with https://gitlab.com/gitlab-org/gitlab/-/issues/355833
+ Ci::JobArtifacts::DestroyBatchService.new(build.job_artifacts, fix_expire_at: false).execute
+ end
+
+ def erase_trace!
+ build.trace.erase!
+ end
+
+ def update_erased!
+ build.update(erased_by: current_user, erased_at: Time.current, artifacts_expire_at: nil)
+ end
+ end
+end
diff --git a/app/services/ci/build_report_result_service.rb b/app/services/ci/build_report_result_service.rb
index f9146b3677a..20a31322919 100644
--- a/app/services/ci/build_report_result_service.rb
+++ b/app/services/ci/build_report_result_service.rb
@@ -22,7 +22,8 @@ module Ci
private
def generate_test_suite_report(build)
- build.collect_test_reports!(Gitlab::Ci::Reports::TestReport.new)
+ test_report = build.collect_test_reports!(Gitlab::Ci::Reports::TestReport.new)
+ test_report.get_suite(build.test_suite_name)
end
def tests_params(test_suite)
diff --git a/app/services/ci/compare_reports_base_service.rb b/app/services/ci/compare_reports_base_service.rb
index 9aba3a50ec1..ee687706b53 100644
--- a/app/services/ci/compare_reports_base_service.rb
+++ b/app/services/ci/compare_reports_base_service.rb
@@ -8,6 +8,8 @@ module Ci
# issue: https://gitlab.com/gitlab-org/gitlab/issues/34224
class CompareReportsBaseService < ::BaseService
def execute(base_pipeline, head_pipeline)
+ return parsing_payload(base_pipeline, head_pipeline) if base_pipeline&.running?
+
base_report = get_report(base_pipeline)
head_report = get_report(head_pipeline)
comparer = build_comparer(base_report, head_report)
@@ -33,6 +35,13 @@ module Ci
protected
+ def parsing_payload(base_pipeline, head_pipeline)
+ {
+ status: :parsing,
+ key: key(base_pipeline, head_pipeline)
+ }
+ end
+
def build_comparer(base_report, head_report)
comparer_class.new(base_report, head_report)
end
diff --git a/app/services/ci/create_downstream_pipeline_service.rb b/app/services/ci/create_downstream_pipeline_service.rb
index b38b3b93353..25cc9045052 100644
--- a/app/services/ci/create_downstream_pipeline_service.rb
+++ b/app/services/ci/create_downstream_pipeline_service.rb
@@ -11,6 +11,7 @@ module Ci
DuplicateDownstreamPipelineError = Class.new(StandardError)
MAX_NESTED_CHILDREN = 2
+ MAX_HIERARCHY_SIZE = 1000
def execute(bridge)
@bridge = bridge
@@ -86,6 +87,11 @@ module Ci
return false
end
+ if Feature.enabled?(:ci_limit_complete_hierarchy_size) && pipeline_tree_too_large?
+ @bridge.drop!(:reached_max_pipeline_hierarchy_size)
+ return false
+ end
+
unless can_create_downstream_pipeline?(target_ref)
@bridge.drop!(:insufficient_bridge_permissions)
return false
@@ -137,10 +143,17 @@ module Ci
return false unless @bridge.triggers_child_pipeline?
# only applies to parent-child pipelines not multi-project
- ancestors_of_new_child = @bridge.pipeline.self_and_ancestors
+ ancestors_of_new_child = @bridge.pipeline.self_and_project_ancestors
ancestors_of_new_child.count > MAX_NESTED_CHILDREN
end
+ def pipeline_tree_too_large?
+ return false unless @bridge.triggers_downstream_pipeline?
+
+ # Applies to the entire pipeline tree across all projects
+ @bridge.pipeline.complete_hierarchy_count >= MAX_HIERARCHY_SIZE
+ end
+
def config_checksum(pipeline)
[pipeline.project_id, pipeline.ref, pipeline.source].hash
end
diff --git a/app/services/ci/create_pipeline_service.rb b/app/services/ci/create_pipeline_service.rb
index 02f25a82307..af175b8da1c 100644
--- a/app/services/ci/create_pipeline_service.rb
+++ b/app/services/ci/create_pipeline_service.rb
@@ -23,6 +23,7 @@ module Ci
Gitlab::Ci::Pipeline::Chain::RemoveUnwantedChatJobs,
Gitlab::Ci::Pipeline::Chain::SeedBlock,
Gitlab::Ci::Pipeline::Chain::EvaluateWorkflowRules,
+ Gitlab::Ci::Pipeline::Chain::AssignPartition,
Gitlab::Ci::Pipeline::Chain::Seed,
Gitlab::Ci::Pipeline::Chain::Limit::Size,
Gitlab::Ci::Pipeline::Chain::Limit::Deployments,
diff --git a/app/services/ci/delete_objects_service.rb b/app/services/ci/delete_objects_service.rb
index bac99abadc9..7a93d0e9665 100644
--- a/app/services/ci/delete_objects_service.rb
+++ b/app/services/ci/delete_objects_service.rb
@@ -27,9 +27,7 @@ module Ci
# `find_by_sql` performs a write in this case and we need to wrap it in
# a transaction to stick to the primary database.
Ci::DeletedObject.transaction do
- Ci::DeletedObject.find_by_sql([
- next_batch_sql, new_pick_up_at: RETRY_IN.from_now
- ])
+ Ci::DeletedObject.find_by_sql([next_batch_sql, new_pick_up_at: RETRY_IN.from_now])
end
end
# rubocop: enable CodeReuse/ActiveRecord
diff --git a/app/services/ci/expire_pipeline_cache_service.rb b/app/services/ci/expire_pipeline_cache_service.rb
index bf2355c447a..15597eb7209 100644
--- a/app/services/ci/expire_pipeline_cache_service.rb
+++ b/app/services/ci/expire_pipeline_cache_service.rb
@@ -86,7 +86,7 @@ module Ci
etag_paths << path
end
- pipeline.all_pipelines_in_hierarchy.includes(project: [:route, { namespace: :route }]).each do |relative_pipeline| # rubocop: disable CodeReuse/ActiveRecord
+ pipeline.upstream_and_all_downstreams.includes(project: [:route, { namespace: :route }]).each do |relative_pipeline| # rubocop: disable CodeReuse/ActiveRecord
etag_paths << project_pipeline_path(relative_pipeline.project, relative_pipeline)
etag_paths << graphql_pipeline_path(relative_pipeline)
etag_paths << graphql_pipeline_sha_path(relative_pipeline.sha)
diff --git a/app/services/ci/generate_coverage_reports_service.rb b/app/services/ci/generate_coverage_reports_service.rb
index 81f26e84ef8..8beecb79fd9 100644
--- a/app/services/ci/generate_coverage_reports_service.rb
+++ b/app/services/ci/generate_coverage_reports_service.rb
@@ -43,7 +43,7 @@ module Ci
end
def last_update_timestamp(pipeline_hierarchy)
- pipeline_hierarchy&.self_and_descendants&.maximum(:updated_at)
+ pipeline_hierarchy&.self_and_project_descendants&.maximum(:updated_at)
end
end
end
diff --git a/app/services/ci/job_artifacts/create_service.rb b/app/services/ci/job_artifacts/create_service.rb
index af56eb221d5..3dc097a8603 100644
--- a/app/services/ci/job_artifacts/create_service.rb
+++ b/app/services/ci/job_artifacts/create_service.rb
@@ -80,7 +80,7 @@ module Ci
Gitlab::CurrentSettings.current_application_settings.default_artifacts_expire_in
artifact_attributes = {
- job_id: job.id,
+ job: job,
project: project,
expire_in: expire_in
}
diff --git a/app/services/ci/job_artifacts/delete_service.rb b/app/services/ci/job_artifacts/delete_service.rb
new file mode 100644
index 00000000000..65cae03312e
--- /dev/null
+++ b/app/services/ci/job_artifacts/delete_service.rb
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+module Ci
+ module JobArtifacts
+ class DeleteService
+ include BaseServiceUtility
+
+ def initialize(build)
+ @build = build
+ end
+
+ def execute
+ if build.project.refreshing_build_artifacts_size?
+ Gitlab::ProjectStatsRefreshConflictsLogger.warn_artifact_deletion_during_stats_refresh(
+ method: 'Ci::JobArtifacts::DeleteService#execute',
+ project_id: build.project_id
+ )
+ end
+
+ # fix_expire_at is false because in this case we want to explicitly delete the job artifacts
+ # this flag is a workaround that will be removed with https://gitlab.com/gitlab-org/gitlab/-/issues/355833
+ Ci::JobArtifacts::DestroyBatchService.new(build.job_artifacts.erasable, fix_expire_at: false).execute
+
+ ServiceResponse.success
+ end
+
+ private
+
+ attr_reader :build
+ end
+ end
+end
diff --git a/app/services/ci/job_artifacts/track_artifact_report_service.rb b/app/services/ci/job_artifacts/track_artifact_report_service.rb
new file mode 100644
index 00000000000..1be1d98394f
--- /dev/null
+++ b/app/services/ci/job_artifacts/track_artifact_report_service.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+module Ci
+ module JobArtifacts
+ class TrackArtifactReportService
+ include Gitlab::Utils::UsageData
+
+ REPORT_TRACKED = %i[test].freeze
+
+ def execute(pipeline)
+ REPORT_TRACKED.each do |report|
+ if pipeline.complete_and_has_reports?(Ci::JobArtifact.of_report_type(report))
+ track_usage_event(event_name(report), pipeline.user_id)
+ end
+ end
+ end
+
+ def event_name(report)
+ "i_testing_#{report}_report_uploaded"
+ end
+ end
+ end
+end
diff --git a/app/services/ci/pipeline_artifacts/coverage_report_service.rb b/app/services/ci/pipeline_artifacts/coverage_report_service.rb
index c11a8f7a0fd..99877603554 100644
--- a/app/services/ci/pipeline_artifacts/coverage_report_service.rb
+++ b/app/services/ci/pipeline_artifacts/coverage_report_service.rb
@@ -27,12 +27,18 @@ module Ci
end
def pipeline_artifact_params
- {
+ attributes = {
pipeline: pipeline,
file_type: :code_coverage,
file: carrierwave_file,
size: carrierwave_file['tempfile'].size
}
+
+ if ::Feature.enabled?(:ci_update_unlocked_pipeline_artifacts, pipeline.project)
+ attributes[:locked] = pipeline.locked
+ end
+
+ attributes
end
def carrierwave_file
diff --git a/app/services/ci/pipeline_artifacts/create_code_quality_mr_diff_report_service.rb b/app/services/ci/pipeline_artifacts/create_code_quality_mr_diff_report_service.rb
index d6865efac9f..aeb68a75f88 100644
--- a/app/services/ci/pipeline_artifacts/create_code_quality_mr_diff_report_service.rb
+++ b/app/services/ci/pipeline_artifacts/create_code_quality_mr_diff_report_service.rb
@@ -13,21 +13,31 @@ module Ci
return if pipeline.has_codequality_mr_diff_report?
return unless new_errors_introduced?
+ pipeline.pipeline_artifacts.create!(**artifact_attributes)
+ end
+
+ private
+
+ attr_reader :pipeline
+
+ def artifact_attributes
file = build_carrierwave_file!
- pipeline.pipeline_artifacts.create!(
+ attributes = {
project_id: pipeline.project_id,
file_type: :code_quality_mr_diff,
file_format: Ci::PipelineArtifact::REPORT_TYPES.fetch(:code_quality_mr_diff),
size: file["tempfile"].size,
file: file,
expire_at: Ci::PipelineArtifact::EXPIRATION_DATE.from_now
- )
- end
+ }
- private
+ if ::Feature.enabled?(:ci_update_unlocked_pipeline_artifacts, pipeline.project)
+ attributes[:locked] = pipeline.locked
+ end
- attr_reader :pipeline
+ attributes
+ end
def merge_requests
strong_memoize(:merge_requests) do
diff --git a/app/services/ci/pipelines/add_job_service.rb b/app/services/ci/pipelines/add_job_service.rb
index fc852bc3edd..dfbb37cf0dc 100644
--- a/app/services/ci/pipelines/add_job_service.rb
+++ b/app/services/ci/pipelines/add_job_service.rb
@@ -39,11 +39,13 @@ module Ci
job.pipeline = pipeline
job.project = pipeline.project
job.ref = pipeline.ref
+ job.partition_id = pipeline.partition_id
# update metadata since it might have been lazily initialised before this call
# metadata is present on `Ci::Processable`
if job.respond_to?(:metadata) && job.metadata
job.metadata.project = pipeline.project
+ job.metadata.partition_id = pipeline.partition_id
end
end
end
diff --git a/app/services/ci/queue/pending_builds_strategy.rb b/app/services/ci/queue/pending_builds_strategy.rb
index c8bdbba5e65..cfafe66d10b 100644
--- a/app/services/ci/queue/pending_builds_strategy.rb
+++ b/app/services/ci/queue/pending_builds_strategy.rb
@@ -19,7 +19,11 @@ module Ci
def builds_for_group_runner
return new_builds.none if runner.namespace_ids.empty?
- new_builds.where('ci_pending_builds.namespace_traversal_ids && ARRAY[?]::int[]', runner.namespace_ids)
+ new_builds_relation = new_builds.where('ci_pending_builds.namespace_traversal_ids && ARRAY[?]::int[]', runner.namespace_ids)
+
+ return order(new_builds_relation) if ::Feature.enabled?(:order_builds_for_group_runner)
+
+ new_builds_relation
end
def builds_matching_tag_ids(relation, ids)
diff --git a/app/services/ci/register_job_service.rb b/app/services/ci/register_job_service.rb
index b357855db12..0bd4bf8cc86 100644
--- a/app/services/ci/register_job_service.rb
+++ b/app/services/ci/register_job_service.rb
@@ -287,7 +287,7 @@ module Ci
Gitlab::ErrorTracking.track_exception(ex,
build_id: build.id,
build_name: build.name,
- build_stage: build.stage,
+ build_stage: build.stage_name,
pipeline_id: build.pipeline_id,
project_id: build.project_id
)
diff --git a/app/services/ci/resource_groups/assign_resource_from_resource_group_service.rb b/app/services/ci/resource_groups/assign_resource_from_resource_group_service.rb
index dfd97498fc8..d7078200c14 100644
--- a/app/services/ci/resource_groups/assign_resource_from_resource_group_service.rb
+++ b/app/services/ci/resource_groups/assign_resource_from_resource_group_service.rb
@@ -9,8 +9,10 @@ module Ci
free_resources = resource_group.resources.free.count
- resource_group.upcoming_processables.take(free_resources).each do |processable|
- processable.enqueue_waiting_for_resource
+ resource_group.upcoming_processables.take(free_resources).each do |upcoming|
+ Gitlab::OptimisticLocking.retry_lock(upcoming, name: 'enqueue_waiting_for_resource') do |processable|
+ processable.enqueue_waiting_for_resource
+ end
end
end
# rubocop: enable CodeReuse/ActiveRecord
diff --git a/app/services/ci/runners/set_runner_associated_projects_service.rb b/app/services/ci/runners/set_runner_associated_projects_service.rb
new file mode 100644
index 00000000000..7930776749d
--- /dev/null
+++ b/app/services/ci/runners/set_runner_associated_projects_service.rb
@@ -0,0 +1,69 @@
+# frozen_string_literal: true
+
+module Ci
+ module Runners
+ class SetRunnerAssociatedProjectsService
+ # @param [Ci::Runner] runner: the project runner to assign/unassign projects from
+ # @param [User] current_user: the user performing the operation
+ # @param [Array<Integer>] project_ids: the IDs of the associated projects to assign the runner to
+ def initialize(runner:, current_user:, project_ids:)
+ @runner = runner
+ @current_user = current_user
+ @project_ids = project_ids
+ end
+
+ def execute
+ unless current_user&.can?(:assign_runner, runner)
+ return ServiceResponse.error(message: 'user not allowed to assign runner', http_status: :forbidden)
+ end
+
+ return ServiceResponse.success if project_ids.blank?
+
+ set_associated_projects
+ end
+
+ private
+
+ def set_associated_projects
+ new_project_ids = [runner.owner_project.id] + project_ids
+
+ response = ServiceResponse.success
+ runner.transaction do
+ # rubocop:disable CodeReuse/ActiveRecord
+ current_project_ids = runner.projects.ids
+ # rubocop:enable CodeReuse/ActiveRecord
+
+ unless associate_new_projects(new_project_ids, current_project_ids)
+ response = ServiceResponse.error(message: 'failed to assign projects to runner')
+ raise ActiveRecord::Rollback, response.errors
+ end
+
+ unless disassociate_old_projects(new_project_ids, current_project_ids)
+ response = ServiceResponse.error(message: 'failed to destroy runner project')
+ raise ActiveRecord::Rollback, response.errors
+ end
+ end
+
+ response
+ end
+
+ def associate_new_projects(new_project_ids, current_project_ids)
+ missing_projects = Project.id_in(new_project_ids - current_project_ids)
+ missing_projects.all? { |project| runner.assign_to(project, current_user) }
+ end
+
+ def disassociate_old_projects(new_project_ids, current_project_ids)
+ projects_to_be_deleted = current_project_ids - new_project_ids
+ return true if projects_to_be_deleted.empty?
+
+ Ci::RunnerProject
+ .destroy_by(project_id: projects_to_be_deleted)
+ .all?(&:destroyed?)
+ end
+
+ attr_reader :runner, :current_user, :project_ids
+ end
+ end
+end
+
+Ci::Runners::SetRunnerAssociatedProjectsService.prepend_mod
diff --git a/app/services/ci/runners/update_runner_service.rb b/app/services/ci/runners/update_runner_service.rb
index 6cc080f81c2..bd01f52f396 100644
--- a/app/services/ci/runners/update_runner_service.rb
+++ b/app/services/ci/runners/update_runner_service.rb
@@ -9,11 +9,14 @@ module Ci
@runner = runner
end
- def update(params)
+ def execute(params)
params[:active] = !params.delete(:paused) if params.include?(:paused)
- runner.update(params).tap do |updated|
- runner.tick_runner_queue if updated
+ if runner.update(params)
+ runner.tick_runner_queue
+ ServiceResponse.success
+ else
+ ServiceResponse.error(message: runner.errors.full_messages)
end
end
end
diff --git a/app/services/ci/stuck_builds/drop_helpers.rb b/app/services/ci/stuck_builds/drop_helpers.rb
index dca50963883..f56c9aaeb55 100644
--- a/app/services/ci/stuck_builds/drop_helpers.rb
+++ b/app/services/ci/stuck_builds/drop_helpers.rb
@@ -48,7 +48,7 @@ module Ci
Gitlab::ErrorTracking.track_exception(ex,
build_id: build.id,
build_name: build.name,
- build_stage: build.stage,
+ build_stage: build.stage_name,
pipeline_id: build.pipeline_id,
project_id: build.project_id
)
diff --git a/app/services/ci/test_failure_history_service.rb b/app/services/ci/test_failure_history_service.rb
index 2214a6a2729..5a8072b2a0d 100644
--- a/app/services/ci/test_failure_history_service.rb
+++ b/app/services/ci/test_failure_history_service.rb
@@ -80,8 +80,8 @@ module Ci
end
def generate_test_suite!(build)
- # Returns an instance of Gitlab::Ci::Reports::TestSuite
- build.collect_test_reports!(Gitlab::Ci::Reports::TestReport.new)
+ test_report = build.collect_test_reports!(Gitlab::Ci::Reports::TestReport.new)
+ test_report.get_suite(build.test_suite_name)
end
def ci_unit_test_attrs(batch)
diff --git a/app/services/ci/unlock_artifacts_service.rb b/app/services/ci/unlock_artifacts_service.rb
index 30da31ba8ec..1fee31da4fc 100644
--- a/app/services/ci/unlock_artifacts_service.rb
+++ b/app/services/ci/unlock_artifacts_service.rb
@@ -7,9 +7,12 @@ module Ci
def execute(ci_ref, before_pipeline = nil)
results = {
unlocked_pipelines: 0,
- unlocked_job_artifacts: 0
+ unlocked_job_artifacts: 0,
+ unlocked_pipeline_artifacts: 0
}
+ unlock_pipeline_artifacts_enabled = ::Feature.enabled?(:ci_update_unlocked_pipeline_artifacts, ci_ref.project)
+
if ::Feature.enabled?(:ci_update_unlocked_job_artifacts, ci_ref.project)
loop do
unlocked_pipelines = []
@@ -18,6 +21,10 @@ module Ci
::Ci::Pipeline.transaction do
unlocked_pipelines = unlock_pipelines(ci_ref, before_pipeline)
unlocked_job_artifacts = unlock_job_artifacts(unlocked_pipelines)
+
+ if unlock_pipeline_artifacts_enabled
+ results[:unlocked_pipeline_artifacts] += unlock_pipeline_artifacts(unlocked_pipelines)
+ end
end
break if unlocked_pipelines.empty?
@@ -100,6 +107,14 @@ module Ci
)
end
+ # rubocop:disable CodeReuse/ActiveRecord
+ def unlock_pipeline_artifacts(pipelines)
+ return 0 if pipelines.empty?
+
+ ::Ci::PipelineArtifact.where(pipeline_id: pipelines.rows.flatten).update_all(locked: :unlocked)
+ end
+ # rubocop:enable CodeReuse/ActiveRecord
+
def unlock_pipelines(ci_ref, before_pipeline)
::Ci::Pipeline.connection.exec_query(unlock_pipelines_query(ci_ref, before_pipeline))
end