.ai/principles/distilled/import-direct-and-offline.md
Prerequisite: If you haven't already, also read .ai/principles/distilled/import-fundamentals.md - it contains foundational rules that apply to all import work.
lib/bulk_imports/projects/stage.rb or lib/bulk_imports/groups/stage.rb; a stage only starts once every pipeline in the previous stage finishes.BulkImports::Common::Pipelines; place project-only pipelines under BulkImports::Projects::Pipelines and group-only pipelines under BulkImports::Groups::Pipelines.import_export.yml (project or group variant) under tree.project or tree.group; add EE-only associations to the ee.tree.project tree at the end of the file.import_export.yml in dependency order (dependencies before the associations that require them).included_attributes entries for every attribute that must be exported; attributes not listed are filtered out on both export and import.excluded_attributes entries for attributes that must not be exported: anything ending in _id/_ids, containing attributes (except custom_attributes), ending in _html, or holding sensitive data such as tokens or encrypted values.methods entries for any relation method whose return value must be exported and used on import.minimum_source_version on a pipeline stage entry when the relation export was introduced in a specific GitLab version; specify maximum_source_version when a relation is deprecated and the pipeline should only run up to a certain version.BULK_IMPORT_STATIC_ITEMS in app/assets/javascripts/import/constants.js for every new relation so it displays in human-readable form in the UI.BulkImports::LfsObjectsExportService as an example), add the relation to the file_relations list in BulkImports::FileTransfer::ProjectConfig, and add it to BulkImports::FileExportService.BulkImports::FileDownloadService, BulkImports::FileDecompressionService, and BulkImports::ArchiveExtractionService as helpers in binary-relation pipeline extract steps.OVERRIDES hash in Gitlab::ImportExport::Project::RelationFactory (or the Group equivalent) so the importer can constantize them correctly.EXISTING_OBJECT_RELATIONS in RelationFactory and implement the corresponding ObjectBuilder lookup attributes to prevent duplicate records on import.BulkImports::Pipeline::Runner processes NDJSON entries one at a time and records failures as BulkImports::Failure without stopping the pipeline (unless the pipeline class is marked abort_on_failure!).RelationObjectSaver saves the top-level record first so that an invalid nested sub-relation does not fail the parent record; record each invalid sub-relation as its own BulkImports::Failure.BulkImports::Common::Pipelines::MembersPipeline (via SourceUserMemberAttributesTransformer and Import::SourceUserMapper) as the primary mechanism for creating source user and placeholder records.BulkImports::NdjsonPipeline::IGNORE_PLACEHOLDER_USER_CREATION (approvals, builds, ci_pipelines, events, and similar) because they may reference users that no longer exist on the source instance.spec/lib/gitlab/import_export/project/tree_saver_spec.rb (and the EE equivalent for EE-specific relations).spec/lib/bulk_imports/common/pipelines/milestones_pipeline_spec.rb.For the full picture, see: