Persist v3 licenses and expressions

Persist v3 license expressions into pm_licenses and reference them from package version tuples alongside existing identifier rows. SyncService#ingest mis-routes v3 to v1 today; LicenseIngestionTask keys the upsert on spdx_identifier, which is null on expression rows; PackageBuilder only packs identifier ids.

  • v3 branch in SyncService#ingest
  • Upsert expression rows into pm_licenses using a separate unique_by: :spdx_expression conflict key; identifier rows keep unique_by: :spdx_identifier. Postgres treats nulls as distinct in a unique index, so the two upsert paths must be separate.
  • PackageBuilder tuple references a mixed list of identifier and expression row ids
  • v2 path unchanged

When a package reports both an identifier and an expression, both are ingested and both ids appear in the tuple. Read-path precedence between the two is tracked in #606525 (closed).

Dependencies

#606521 (closed) (schema column), #606523 (closed) (parse), #611126 (closed) (v3 predicate)

Key files

  • ee/app/services/package_metadata/ingestion/compressed_package/license_ingestion_task.rb
  • ee/app/services/package_metadata/ingestion/compressed_package/package_ingestion_task.rb
  • ee/app/services/package_metadata/sync_service.rb
  • ee/app/models/package_metadata/license.rb
Edited by 🤖 GitLab Bot 🤖