defmodule GitGud.Repo.Migrations.AddPackageFormats do
use Ecto.Migration
@moduledoc """
Phase 0 of the private package registries plan: the substrate the
PyPI/Hex/Cargo/apt adapters all sit on.
Three changes:
* `packages.format` — which registry protocol serves this package.
Everything that exists today came from zot, so it backfills to
`oci`. Uniqueness moves from `(repository_id, kind, name)` to
`(repository_id, format, normalized_name)`, which is what every
adapter actually looks up by.
* `packages.normalized_name` — the form the ecosystem canonicalises
to (PEP 503 for PyPI, lowercase for Cargo, verbatim for Hex/OCI).
Stored rather than computed so lookups hit an index.
* `package_files` — one row per uploaded artifact. OCI keeps its
bytes in zot, but every other format hands us a file (a wheel, a
`.tar`, a `.crate`, a `.deb`) that lives in `GitGud.Storage`.
A version may have several (sdist + wheels, per-arch debs).
"""
def up do
alter table(:packages) do
add :format, :string, null: false, default: "oci", size: 20
add :normalized_name, :string, size: 200
end
execute "UPDATE packages SET format = 'oci', normalized_name = lower(name)"
alter table(:packages) do
modify :normalized_name, :string, null: false, size: 200
end
drop unique_index(:packages, [:repository_id, :kind, :name])
create unique_index(:packages, [:repository_id, :format, :normalized_name])
create index(:packages, [:format, :normalized_name])
# Non-OCI versions are identified by the artifact's own checksum,
# which lives on `package_files` — there is no single manifest
# digest to require here.
alter table(:package_versions) do
modify :digest, :string, null: true
add :metadata, :map
add :yanked, :boolean, null: false, default: false
add :yanked_reason, :string
end
create table(:package_files) do
add :package_version_id, references(:package_versions, on_delete: :delete_all), null: false
add :filename, :string, null: false, size: 300
add :content_type, :string
add :size, :bigint, null: false, default: 0
# Lowercase hex. SHA-256 is the floor for every format we serve —
# apt clients are required to reject MD5Sum/SHA1 for security.
add :sha256, :string, null: false, size: 64
# Only populated where a format's index demands it (apt's optional
# MD5Sum field, Hex's inner tarball checksum).
add :md5, :string, size: 32
add :storage_bucket, :string, null: false
add :storage_key, :string, null: false
# Per-format extras: requires-python and the PEP 592 yank reason,
# a crate's dependency table, a .deb's control stanza.
add :metadata, :map
add :uploader_id, references(:users, on_delete: :nilify_all)
timestamps(type: :utc_datetime)
end
create unique_index(:package_files, [:package_version_id, :filename])
create index(:package_files, [:sha256])
end
def down do
drop table(:package_files)
alter table(:package_versions) do
remove :yanked_reason
remove :yanked
remove :metadata
modify :digest, :string, null: false
end
drop index(:packages, [:format, :normalized_name])
drop unique_index(:packages, [:repository_id, :format, :normalized_name])
create unique_index(:packages, [:repository_id, :kind, :name])
alter table(:packages) do
remove :normalized_name
remove :format
end
end
end
neiam
/gitgud
Git Gud
public · Issues · Pulls · Labels · Forks · Compare · Actions success · Badges · Packages
⭐
1
Log in to mark this repository.
3.5 KiB · text
History
b868907