Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot
2025-05-17 06:07:18 +00:00
parent 7e95538fea
commit 363278e322
4 changed files with 76 additions and 1 deletions

View File

@ -21,7 +21,6 @@ Layout/LineBreakAfterFinalMixin:
- 'app/workers/purge_dependency_proxy_cache_worker.rb'
- 'app/workers/remove_unreferenced_lfs_objects_worker.rb'
- 'app/workers/repository_archive_cache_worker.rb'
- 'app/workers/stuck_ci_jobs_worker.rb'
- 'app/workers/stuck_export_jobs_worker.rb'
- 'app/workers/user_status_cleanup/batch_worker.rb'
- 'app/workers/users/create_statistics_worker.rb'

View File

@ -270,6 +270,25 @@ module Projects
end
delete_commit_statuses
destroy_orphaned_ci_job_artifacts!
end
# This method will delete all orphaned CI Job artifacts for the project, which are job artifacts
# whose jobs do not exist anymore. The reason these artifacts might still exist is because of
# https://gitlab.com/gitlab-org/gitlab/-/issues/508672.
# TODO: remove this method after we have a working & valid FK.
def destroy_orphaned_ci_job_artifacts!
orphaned_job_artifacts = ::Ci::JobArtifact.for_project(project)
return if orphaned_job_artifacts.none?
service = orphaned_job_artifacts.begin_fast_destroy
orphaned_job_artifacts.finalize_fast_destroy(service)
Gitlab::AppLogger.info(
class: self.class.name,
project_id: project.id,
message: 'Orphaned CI job artifacts deleted'
)
end
def delete_commit_statuses

View File

@ -8,6 +8,7 @@ class StuckCiJobsWorker # rubocop:disable Scalability/IdempotentWorker
# This is an instance-wide cleanup query, so there's no meaningful
# scope to consider this in the context of.
include CronjobQueue
# rubocop:enable Scalability/CronWorkerContext
data_consistency :always

View File

@ -978,6 +978,62 @@ RSpec.describe Projects::DestroyService, :aggregate_failures, :event_store_publi
end
end
describe '#destroy_orphaned_ci_job_artifacts!' do
let(:service) { described_class.new(project, user) }
context 'when there are no orphaned job artifacts' do
let(:no_job_artifacts) { Ci::JobArtifact.none }
before do
allow(Ci::JobArtifact).to receive(:for_project).with(project).and_return(no_job_artifacts)
end
it 'returns early without performing any destroy operations' do
expect(no_job_artifacts).not_to receive(:begin_fast_destroy)
expect(no_job_artifacts).not_to receive(:finalize_fast_destroy)
service.send(:destroy_orphaned_ci_job_artifacts!)
end
end
context 'when there are orphaned job artifacts' do
let(:job) { create(:ci_build, project: project) }
let(:orphaned_job_artifact) { create(:ci_job_artifact, job: job, project: project) }
before do
orphaned_job_artifact.connection.transaction do
orphaned_job_artifact.connection.execute(<<~SQL)
ALTER TABLE p_ci_job_artifacts DISABLE TRIGGER ALL;
SQL
orphaned_job_artifact.update_column(:job_id, non_existing_record_id)
orphaned_job_artifact.connection.execute(<<~SQL)
ALTER TABLE p_ci_job_artifacts ENABLE TRIGGER ALL;
SQL
end
end
it 'destroys orphaned artifacts' do
expect { destroy_project(project, user) }.to change { Ci::JobArtifact.count }.by(-1)
expect(Ci::JobArtifact.exists?(orphaned_job_artifact.id)).to be_falsey
end
it 'logs that the artifacts have been destroyed' do
allow(Gitlab::AppLogger).to receive(:info) # Logged during artifact deletion
expect(Gitlab::AppLogger).to receive(:info).with(
class: described_class.name,
project_id: project.id,
message: 'Orphaned CI job artifacts deleted'
)
service.send(:destroy_orphaned_ci_job_artifacts!)
end
end
end
def destroy_project(project, user, params = {})
described_class.new(project, user, params).public_send(async ? :async_execute : :execute)
end