From cfeb8b05252529a001e8aa5f379a5eee258119da Mon Sep 17 00:00:00 2001 From: Alex Scott Date: Wed, 28 Oct 2026 14:33:34 +1100 Subject: [PATCH] Do not stage APKINDEX files into the apko_image cache apk_repository fetches the live, unpinned APKINDEX.tar.gz for every repository in the lockfile, and is deliberately not marked reproducible because the bytes depend on when it ran. apko_image then copied those indexes into the cache tree artifact that the apko build action consumes, so the action keys for both the cache staging step and `apko build` were a function of fetch time. Two machines that fetched the index even minutes apart could never share a remote cache entry for the image, and Wolfi rewrites its index several times an hour. `apko build --lockfile` never reads the index: it installs exactly the packages listed in the lockfile by URL and checksum (installablePackagesForArch -> InstallPackages) and only ResolveWorld, which is unreachable when a lockfile is given, loads repository indexes. Building with and without the indexes in the offline cache produces byte-identical OCI manifests on both amd64 and arm64. Stop staging the indexes. The `indexes` output group of apk_filegroup is left in place for any other consumers; with nothing depending on it the apk_repository repos are no longer fetched for image builds either. Signed-off-by: Alex Scott --- apko/private/apko_image.bzl | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/apko/private/apko_image.bzl b/apko/private/apko_image.bzl index c0d8dcf..a8eaa22 100644 --- a/apko/private/apko_image.bzl +++ b/apko/private/apko_image.bzl @@ -67,12 +67,16 @@ def _impl(ctx): lockfile = ctx.attr.contents[OutputGroupInfo].lockfile.to_list()[0] apks = ctx.attr.contents[OutputGroupInfo].apks - indexes = ctx.attr.contents[OutputGroupInfo].indexes keyrings = ctx.attr.contents[OutputGroupInfo].keyrings inputs = prepare_apko_config_in_workdir(workdir, ctx) - deps = [apks, keyrings, indexes] + # The APKINDEX files from the `indexes` output group are deliberately not + # staged. `apko build --lockfile` installs exactly the locked packages by + # URL and checksum and never reads an index, while the indexes themselves + # are live, unpinned downloads: including them made the action key depend + # on when the repository was fetched and defeated remote caching. + deps = [apks, keyrings] supports_lockfile = versions.is_at_least("0.13.0", apko_info.version) if supports_lockfile: