Ingest v3 PMDB license data via new spdx_expression column
What does this MR do and why?
The v3 package metadata export can license a package with an SPDX expression such as
MIT OR Apache-2.0, where v2 only ever carried single identifiers. An expression is
not an identifier: policies evaluate the two differently, so each expression gets its
own row instead of being squeezed into the identifier column.
This MR adds the v3 write path. Expressions are stored as raw, unparsed strings, because deciding what an expression means belongs to policy evaluation when the data is read, not to ingestion. A package that declares both an identifier and an expression keeps both. And since the same string can legitimately be an identifier for one package and an expression for another, the two roles are looked up and written through separate maps, so neither can shadow the other.
PMDB exports are treated as untrusted input: the v3 data object filters out license
values it cannot store (blank, wrong type, beyond the column limits) and rejects
records without a usable shape, which the fabricator's existing error tracking
reports per registry. A package with no licenses at all is kept rather than dropped,
which relaxes license_ids minItems from 1 to 0 in the pm_package_licenses schema.
The v2 path behaves exactly as before.
Note
Danger applied the database label because this branch had to carry the schema changes
from !250673 (merged) while it targeted the v3 sync service branch; that content has since
merged and left this diff. Separate database review should not be needed:
pm_licenses is a tiny normalization table (~500 rows), and the expression upsert
mirrors the identifier upsert that has existed since v2, backed by the unique index
reviewed in !250673 (merged).
References
- Epic: &22880 (Sync V3 license expression ingestion)
- Closes #606523 (closed), #606524 (closed)
- Read path: !250978 (merged), cutover: #606527 (closed)
- Built on !250673 (merged) and !251978 (merged) (both merged)
How to set up and validate locally
Attachments: verify_samples.rb, sample_v2.ndjson, sample_v3.ndjson.
- Run migrations:
bundle exec rails db:migrate - Place the attached sample files under
findings/fixtures/ - Run:
bundle exec rails runner findings/fixtures/verify_samples.rb
The script ingests 1000 real v2 records and 1002 real v3 records, including packages that carry both an identifier and an expression and a pair declaring the same string in each role, and checks the resulting rows against the input, exiting non-zero on any mismatch.
MR acceptance checklist
Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.