Skip to content

fix(composer): record dist archives per commit so locked versions install - #179

Merged
maartenbode merged 1 commit into
mainfrom
fix/dist-archive-tracking
Aug 29, 2026
Merged

fix(composer): record dist archives per commit so locked versions install#179
maartenbode merged 1 commit into
mainfrom
fix/dist-archive-tracking

Conversation

@maartenbode

Copy link
Copy Markdown
Member

Branches move, but Pricore kept one package_versions row per version string and mutated it in place on every sync. Archive files are one-per-commit, so each sync wrote a new file and repointed the row, leaving the old archive on disk with nothing referencing it. composer install from a lock pinning an older commit then 404'd.

Archives are now recorded individually in a new dist_archives table, keyed by commit, so a locked commit resolves by lookup. package_versions.dist_* stays as a write-through cache of the current archive, with RecordDistArchiveAction as the only writer.

This also fixes a second, quieter bug on both sync paths: the dist columns were left describing the previous commit after source_reference moved, so metadata advertised the old archive — and its matching shasum — under the new reference, and Composer installed stale bytes without complaint. The pointer is now invalidated in the same transaction that moves the reference.

Fixes #178

Notes for review

  • DIST_KEEP_DETACHED_DAYS bounds how long superseded archives are kept, measured from when an archive stopped being current rather than when it was built. Unset by default, so upgrades keep every archive and nothing becomes prunable.
  • The backfill runs as its own idempotent migration and reads no files.
  • Resolution keeps the deterministic-path probe as a fallback for archives predating the backfill, which have no row. Commented with the migration name so it can be dropped later.
  • Deleting stale versions, packages and repositories now removes archive files; those paths previously bypassed model events and stranded them.
  • dist:cleanup remains unscheduled, as it was before.

Known trade-off

Between the reference moving and the new archive being recorded, a version advertises no dist and Composer falls back to cloning. The window lasts as long as the archive download. Building the archive before the transaction would close it and is worth doing as a follow-up.

Deliberately left out

  • A dist:reconcile sweep for files whose version row was already destroyed. Those are recoverable by neither lookup nor path, so they are garbage collection rather than part of this fix.
  • Storage accounting. The table makes SUM(size) possible; no UI here.
  • dist_url still bakes in APP_URL. Now that DistArchiveData::urlFor() exists, computing it at read time is a contained change.

@maartenbode
maartenbode merged commit 6963231 into main Aug 29, 2026
3 checks passed
@maartenbode
maartenbode deleted the fix/dist-archive-tracking branch August 29, 2026 16:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

composer install fails with 404 for branch versions when the lock pins an older commit

1 participant