From e21a7f04ea5292b712d247d0d57edc790145eff1 Mon Sep 17 00:00:00 2001 From: drew Date: Thu, 10 Apr 2025 18:33:45 -0400 Subject: [PATCH] A sketch of what a BuildMetadataArchive service would look like --- .../build_metadata_archive_service.rb | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 app/services/ci/pipeline_artifacts/build_metadata_archive_service.rb diff --git a/app/services/ci/pipeline_artifacts/build_metadata_archive_service.rb b/app/services/ci/pipeline_artifacts/build_metadata_archive_service.rb new file mode 100644 index 00000000000000..b3157ebdc83ebd --- /dev/null +++ b/app/services/ci/pipeline_artifacts/build_metadata_archive_service.rb @@ -0,0 +1,68 @@ +# frozen_string_literal: true + +module Ci + module PipelineArtifacts + class BuildMetadataArchiveService + # Columns intentionally not kept: partition_id, id_tokens, exit_code, runner_runtime_features + EXPORTABLE_ATTRIBUTE_NAMES = + %w[project_id build_id timeout timeout_source interruptible config_options config_variables + has_exposed_artifacts environment_auto_stop_in expanded_environment_name secrets debug_trace_enabled].freeze + + def initialize(old_pipeline) + @pipeline = old_pipeline + end + + def export_artifact_from_database + Ci::PipelineArtifact.create_or_replace_for_pipeline!(**pipeline_artifact_params) + + Ci::BuildMetadata.for_pipeline(old_pipeline).delete_all + end + + def import_database_records_from_artifact + attributes_hashes = artifact_data[:metadata_attributes].map do |attributes_hash| + attributes_hash.merge(partition_id: @pipeline.partition_id) + end + + Ci::BuildMetadata.create!(attributes_hashes) + + @pipeline.builds_metadata_artifact.destroy! + end + + private + + def export_data + # .for_pipeline doesnt' really exist but you get it + attributes_hashes = Ci::BuildMetadata.for_pipeline(old_pipeline).map do |metadata| + metadata.attributes.slice(EXPORTABLE_ATTRIBUTE_NAMES) + end + + { metadata_attributes: attributes_hashes } + end + + def artifact_data + @artifact_data ||= Gitlab::Json.parse(@pipeline.builds_metadata_artifact.content) + end + + # Stolen directly out of CoverageReportService for illustrative purposes + def pipeline_artifact_params + { + pipeline: @pipeline, + file_type: :builds_metadata, + file: carrierwave_file, + size: carrierwave_file['tempfile'].size, + locked: @pipeline.locked + } + end + + # Stolen directly out of CoverageReportService for illustrative purposes + # We'll gzip this file at some point before it lands on ObjectStorage + def carrierwave_file + CarrierWaveStringFile.new_file( + file_content: Gitlab::Json.dump(export_data), + filename: Ci::PipelineArtifact::DEFAULT_FILE_NAMES.fetch(:build_metadata), + content_type: 'application/json' + ) + end + end + end +end -- GitLab