repro POC

this commit takes the relevant repro steps from the wsl image, and wraps
breaking changes to only affect the :repro image

testing reproducability is not yet included, so we can discuss the
approach first
This commit is contained in:
Mark Hegreberg 2026-03-27 19:27:56 -07:00
parent a4bf94ea08
commit 20bbc94b91
No known key found for this signature in database
GPG Key ID: 55E528B0958E8F16
3 changed files with 45 additions and 9 deletions

View File

@ -61,7 +61,7 @@ get_version:
stage: rootfs
parallel:
matrix:
- GROUP: [base, base-devel, multilib-devel]
- GROUP: [repro, base, base-devel, multilib-devel]
before_script:
- pacman -Syu --noconfirm git make fakechroot fakeroot
- pacman -Sdd --noconfirm devtools
@ -98,7 +98,7 @@ rootfs:secure:
stage: image
parallel:
matrix:
- GROUP: [base, base-devel, multilib-devel]
- GROUP: [repro, base, base-devel, multilib-devel]
tags:
- vm
id_tokens:
@ -192,6 +192,12 @@ image:publish:secure:
- id -u http
- locale | grep -q UTF-8
test:repro:
extends: .test
image: $CI_REGISTRY_IMAGE:repro-$CI_COMMIT_REF_SLUG
script:
- *test-script
test:base:
extends: .test
image: $CI_REGISTRY_IMAGE:base-$CI_COMMIT_REF_SLUG
@ -234,7 +240,7 @@ pre-release:
-d "{\"full_description\": $(cat README.md | jq -sR .)}"
# Upload rootfs to the Generic Packages Repository
for group in base base-devel multilib-devel; do
for group in repro base base-devel multilib-devel; do
rootfs_file="${group}-${BUILD_VERSION}.tar.zst"
mv "output/${group}.tar.zst" "output/${rootfs_file}"
mv "output/${group}.tar.zst.SHA256" "output/${rootfs_file}.SHA256"
@ -246,7 +252,7 @@ pre-release:
done
# Create the Dockerfiles, commit to the release branch
for group in base base-devel multilib-devel; do
for group in repro base base-devel multilib-devel; do
rootfs_file="${group}-${BUILD_VERSION}.tar.zst"
./scripts/make-dockerfile.sh "${rootfs_file}" "${group}" "output" "curl -sOJL \"${PACKAGE_REGISTRY_URL}/${rootfs_file}\"" "${group}"
sed -i "/^COPY ${rootfs_file} \/$/d" output/Dockerfile.${group}
@ -258,6 +264,9 @@ pre-release:
--form "branch=releases"
--form "commit_message=Release ${BUILD_VERSION}"
--form "actions[][action]=update"
--form "actions[][file_path]=Dockerfile.repro"
--form "actions[][content]=<output/Dockerfile.repro"
--form "actions[][action]=update"
--form "actions[][file_path]=Dockerfile.base"
--form "actions[][content]=<output/Dockerfile.base"
--form "actions[][action]=update"
@ -301,7 +310,11 @@ release:
ref: 'releases'
assets:
links:
- name: 'base-${BUILD_VERSION}.tar.zst'
- name: 'repro-${BUILD_VERSION}.tar.zst
url: '${PACKAGE_REGISTRY_URL}/repro-${BUILD_VERSION}.tar.zst'
- name: 'repro-${BUILD_VERSION}.tar.zst.SHA256'
url: '${PACKAGE_REGISTRY_URL}/repro-${BUILD_VERSION}.tar.zst.SHA256'
- name: 'base-${BUILD_VERSION}.tar.zst
url: '${PACKAGE_REGISTRY_URL}/base-${BUILD_VERSION}.tar.zst'
- name: 'base-${BUILD_VERSION}.tar.zst.SHA256'
url: '${PACKAGE_REGISTRY_URL}/base-${BUILD_VERSION}.tar.zst.SHA256'
@ -347,7 +360,7 @@ publish-dockerhub:
- git checkout -b "$head"
- cp ../docker-library.template library/archlinux
- |
for group in base base-devel multilib-devel; do
for group in repro base base-devel multilib-devel; do
test "${group}" = "base" && extra="latest, " || extra=""
echo "Tags: ${extra}${group}, ${group}-${BUILD_VERSION}" >> library/archlinux
echo "GitCommit: ${BUILD_COMMIT}" >> library/archlinux

View File

@ -1,6 +1,8 @@
OCITOOL=podman # or docker
BUILDDIR=$(shell pwd)/build
OUTPUTDIR=$(shell pwd)/output
ARCHIVE_SNAPSHOT=$(shell date -d "$(awk -F. '{print $1"-"$2"-"$3}' <<< "$IMAGE_VERSION") -1 day" +"%Y/%m/%d")
SOURCE_DATE_EPOCH=$(shell date -u -d "$(echo "$ARCHIVE_SNAPSHOT")" +"%s")
.PHONY: clean
clean:
@ -8,7 +10,7 @@ clean:
.PRECIOUS: $(OUTPUTDIR)/%.tar.zst
$(OUTPUTDIR)/%.tar.zst:
scripts/make-rootfs.sh $(*) $(BUILDDIR) $(OUTPUTDIR)
scripts/make-rootfs.sh $(*) $(BUILDDIR) $(OUTPUTDIR) $(ARCHIVE_SNAPSHOT) $(SOURCE_DATE_EPOCH)
.PRECIOUS: $(OUTPUTDIR)/Dockerfile.%
$(OUTPUTDIR)/Dockerfile.%: $(OUTPUTDIR)/%.tar.zst
@ -16,6 +18,6 @@ $(OUTPUTDIR)/Dockerfile.%: $(OUTPUTDIR)/%.tar.zst
# The following is for local builds only, it is not used by the CI/CD pipeline
all: image-base image-base-devel image-multilib-devel
all: image-repro image-base image-base-devel image-multilib-devel
image-%: $(OUTPUTDIR)/Dockerfile.%
${OCITOOL} build -f $(OUTPUTDIR)/Dockerfile.$(*) -t archlinux/archlinux:$(*) $(OUTPUTDIR)

View File

@ -7,6 +7,8 @@ declare -r WRAPPER="fakechroot -- fakeroot"
declare -r GROUP="$1"
declare -r BUILDDIR="$2"
declare -r OUTPUTDIR="$3"
declare -r ARCHIVE_SNAPSHOT="$4"
declare -rx SOURCE_DATE_EPOCH="$5"
mkdir -vp "$BUILDDIR/alpm-hooks/usr/share/libalpm/hooks"
find /usr/share/libalpm/hooks -exec ln -sf /dev/null "$BUILDDIR/alpm-hooks"{} \;
@ -33,18 +35,33 @@ fi
cp --recursive --preserve=timestamps rootfs/* "$BUILDDIR/"
ln -fs /usr/lib/os-release "$BUILDDIR/etc/os-release"
# Use archived repo snapshot from archive.archlinux.org for reproducible builds
sed -i "1iServer = https://archive.archlinux.org/repos/$ARCHIVE_SNAPSHOT/\\\$repo/os/\\\$arch" "$BUILDDIR/etc/pacman.d/mirrorlist"
$WRAPPER -- \
pacman -Sy -r "$BUILDDIR" \
--disable-sandbox-filesystem \
--noconfirm --dbpath "$BUILDDIR/var/lib/pacman" \
--config pacman.conf \
--noscriptlet \
--hookdir "$BUILDDIR/alpm-hooks/usr/share/libalpm/hooks/" base "$GROUP"
--hookdir "$BUILDDIR/alpm-hooks/usr/share/libalpm/hooks/" base ${GROUP:+${GROUP/repro/}}
# # repro is not a package, so excluded here ^
$WRAPPER -- chroot "$BUILDDIR" update-ca-trust
$WRAPPER -- chroot "$BUILDDIR" pacman-key --init
$WRAPPER -- chroot "$BUILDDIR" pacman-key --populate
# Remove archived repo snapshot from the mirrorlist
sed -i '1d' "$BUILDDIR/etc/pacman.d/mirrorlist"
if [[ "$GROUP" == "repro" ]];
# Clear pacman keyring for reproducible builds
rm -rf "$BUILDDIR"/etc/pacman.d/gnupg/*
fi
# Normalize mtimes
find "$BUILDDIR" -exec touch --no-dereference --date="@$SOURCE_DATE_EPOCH" {} +
# add system users
$WRAPPER -- chroot "$BUILDDIR" /usr/bin/systemd-sysusers --root "/"
@ -58,6 +75,10 @@ fakeroot -- \
--numeric-owner \
--xattrs \
--acls \
--mtime="@$SOURCE_DATE_EPOCH" \
--clamp-mtime \
--sort=name \
--pax-option=delete=atime,delete=ctime \
--exclude-from=exclude \
-C "$BUILDDIR" \
-c . \