defmodule GitGud.Packages.BuildCacheTest do
@moduledoc """
A BuildKit registry cache (`--cache-to type=registry,ref=…:buildcache`)
is pushed after the real tags, and must not become a container
package's `latest_version` (`PackageVersion.build_cache?/1`).
"""
use GitGud.DataCase, async: true
import GitGud.ForgeFixtures
alias GitGud.Packages
alias GitGud.Packages.PackageVersion
@cache "application/vnd.buildkit.cacheconfig.v0"
describe "build_cache?/1" do
test "an index listing BuildKit's cache config" do
doc = %{
"mediaType" => "application/vnd.oci.image.index.v1+json",
"manifests" => [
%{"mediaType" => "application/vnd.oci.image.layer.v1.tar+gzip"},
%{"mediaType" => @cache}
]
}
assert PackageVersion.build_cache?(%{version: "whatever", manifest_doc: doc})
end
test "an image whose config is BuildKit's cache config" do
doc = %{"config" => %{"mediaType" => @cache}, "layers" => []}
assert PackageVersion.build_cache?(%{version: "x", manifest_doc: doc})
end
test "a real image isn't one, whatever its tag is called" do
doc = %{"config" => %{"mediaType" => "application/vnd.oci.image.config.v1+json"}}
refute PackageVersion.build_cache?(%{version: "cache", manifest_doc: doc})
end
test "with no manifest, the tag's name decides" do
for tag <- ~w(buildcache cli-buildcache cache build-cache app_cache) do
assert PackageVersion.build_cache?(%{version: tag, manifest_doc: %{}}), tag
end
for tag <- ~w(latest master v1.2.0 sha-cf87d70 cachet precache) do
refute PackageVersion.build_cache?(%{version: tag, manifest_doc: nil}), tag
end
end
end
describe "latest_version" do
setup do
{_user, repo} = repository_fixture()
{:ok, repo: repo}
end
defp push(repo, tag, at) do
{:ok, {package, _}} =
Packages.record_push(repo, "container", "app", %{
version: tag,
digest: "sha256:" <> String.duplicate("a", 64),
pushed_at: at
})
Repo.reload!(package)
end
test "a cache pushed after the real tags doesn't take it", %{repo: repo} do
push(repo, "v1.2.0", ~U[2026-11-05 16:09:41Z])
push(repo, "latest", ~U[2026-11-05 16:09:42Z])
package = push(repo, "buildcache", ~U[2026-11-05 16:10:09Z])
assert package.latest_version == "latest"
end
test "a cache is the latest when it's all there is", %{repo: repo} do
assert push(repo, "buildcache", ~U[2026-11-05 16:10:09Z]).latest_version == "buildcache"
assert push(repo, "v1", ~U[2026-11-05 16:11:00Z]).latest_version == "v1"
end
test "deleting the latest falls back past caches", %{repo: repo} do
push(repo, "v1", ~U[2026-11-05 16:00:00Z])
push(repo, "buildcache", ~U[2026-11-05 16:05:00Z])
push(repo, "v2", ~U[2026-11-05 16:10:00Z])
{:ok, :updated} = Packages.delete_version(repo, "container", "app", "v2")
assert Packages.get_package_by(repo.id, "container", "app").latest_version == "v1"
end
test "the migration repairs a package stuck on a cache", %{repo: repo} do
push(repo, "v1", ~U[2026-11-05 16:00:00Z])
push(repo, "latest", ~U[2026-11-05 16:09:41Z])
push(repo, "buildcache", ~U[2026-11-05 16:10:09Z])
# As the old rule left it: the newest push, the cache.
Packages.get_package_by(repo.id, "container", "app")
|> Ecto.Changeset.change(latest_version: "buildcache")
|> Repo.update!()
Code.require_file(
"priv/repo/migrations/20261110011023_skip_build_caches_as_latest_package_version.exs"
)
Repo.query!(GitGud.Repo.Migrations.SkipBuildCachesAsLatestPackageVersion.sql())
assert Packages.get_package_by(repo.id, "container", "app").latest_version == "latest"
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.8 KiB · text
History
308b64e