Run 18 (schedule) checked out e06d965f, where its schedule was registered,
because the pushes after it said [skip ci]; its merge of upstream was then
behind main and the push was rejected.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
161 lines
7.9 KiB
YAML
161 lines
7.9 KiB
YAML
name: Build Aurora
|
|
|
|
# Builds Aurora from this tree (`just build`, the same command upstream's
|
|
# GitHub workflows run) and pushes it to this forge's registry as
|
|
# forge.quinefoundation.com/quine-global-labs/aurora: `stable`, plus
|
|
# `stable-<date>` and the commit. quine-global-labs/quine-linux builds FROM it.
|
|
#
|
|
# This directory existing is also what keeps Forgejo from running upstream's
|
|
# .github/workflows, which it falls back to when there's no .forgejo/workflows.
|
|
#
|
|
# Runs on runner-x86-linux (host mode, root podman; petersweb-infra,
|
|
# hosts/runner-x86-linux), which has just, buildah, skopeo, cosign, yq and jq.
|
|
#
|
|
# Upstream images (Kinoite, akmods, and image-versions.yml's) are vendored
|
|
# into forge.quinefoundation.com/quine-global-labs/mirror/ first, and the
|
|
# build pulls them from there (.forgejo/vendor-images.sh). After the push,
|
|
# the RPMs the build downloaded go to the forge's RPM registry, a group per
|
|
# upstream repository (.forgejo/upload-rpms.sh).
|
|
#
|
|
# Secret: REGISTRY_TOKEN, a Forgejo token with package write access.
|
|
# Variable (optional): REGISTRY_USER, the token's owner (default: the actor).
|
|
|
|
# Daily (and on "Run workflow"), it first merges upstream's main
|
|
# (github.com/ublue-os/aurora) into ours and pushes the merge, then builds:
|
|
# upstream's changes, plus the day's Fedora package updates, which Aurora's
|
|
# build resolves at build time. quine-global-labs/quine-linux builds on the
|
|
# result two hours later. A push made with the job's own token doesn't start
|
|
# another run, so the merge and the build happen in this one. A conflict
|
|
# fails the run before anything is pushed.
|
|
on:
|
|
push:
|
|
branches: [main]
|
|
schedule:
|
|
- cron: '0 5 * * *'
|
|
workflow_dispatch:
|
|
|
|
concurrency:
|
|
group: aurora-${{ github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
env:
|
|
REGISTRY: forge.quinefoundation.com
|
|
MIRRORS: https://forge.quinefoundation.com/quine-global-labs
|
|
IMAGE: forge.quinefoundation.com/quine-global-labs/aurora
|
|
TAG: stable
|
|
|
|
jobs:
|
|
build:
|
|
runs-on: runner-x86-linux
|
|
timeout-minutes: 300
|
|
steps:
|
|
# Our pull mirror of code.forgejo.org/actions/checkout.
|
|
- uses: https://forge.quinefoundation.com/quine-global-labs/mirror-actions-checkout@v4
|
|
with:
|
|
fetch-depth: 0
|
|
|
|
- name: Merge upstream
|
|
if: github.event_name != 'push'
|
|
run: |
|
|
git config user.name "forgejo-actions"
|
|
git config user.email "actions@forge.quinefoundation.com"
|
|
# A scheduled run checks out the commit its schedule was registered
|
|
# at, the last push without [skip ci], which can be behind main:
|
|
# merge onto main as it is now, or the push below is rejected.
|
|
git fetch --no-tags origin main
|
|
git checkout -B main FETCH_HEAD
|
|
# Our pull mirror of github.com/ublue-os/aurora, synced hourly.
|
|
git fetch --no-tags "$MIRRORS/mirror-ublue-os-aurora.git" main
|
|
before=$(git rev-parse HEAD)
|
|
git merge --no-edit -m "Merge upstream ublue-os/aurora main" FETCH_HEAD
|
|
if [ "$(git rev-parse HEAD)" != "$before" ]; then
|
|
git push origin HEAD:main
|
|
else
|
|
echo "Already up to date with upstream."
|
|
fi
|
|
|
|
- name: Point downloads at our mirrors
|
|
# Rewrites the GitHub files Aurora's build scripts fetch to our pull
|
|
# mirrors (public repos in this org, so the build needs no login).
|
|
# In the checkout only, not committed: committing would conflict
|
|
# with upstream's edits to these scripts at every merge. A URL that
|
|
# upstream changes no longer matches and is fetched from GitHub as
|
|
# before. skip-worktree keeps `git status` clean, which the Justfile
|
|
# reads to label the image with the commit rather than "deadbeef".
|
|
run: |
|
|
files=$(grep -rlE 'github(usercontent)?\.com/(ublue-os/(akmods|countme)|rcaloras/bash-preexec|coreos/fedora-coreos-config)/' build_scripts)
|
|
sed -i -E \
|
|
-e "s#https://github\.com/ublue-os/akmods/raw/refs/heads/([^/]+)/#$MIRRORS/mirror-ublue-os-akmods/raw/branch/\1/#g" \
|
|
-e "s#https://raw\.githubusercontent\.com/ublue-os/countme/([^/]+)/#$MIRRORS/mirror-ublue-os-countme/raw/branch/\1/#g" \
|
|
-e "s#https://raw\.githubusercontent\.com/rcaloras/bash-preexec/([0-9a-f]{40})/#$MIRRORS/mirror-rcaloras-bash-preexec/raw/commit/\1/#g" \
|
|
-e "s#https://raw\.githubusercontent\.com/coreos/fedora-coreos-config/refs/heads/([^/]+)/#$MIRRORS/mirror-coreos-fedora-coreos-config/raw/branch/\1/#g" \
|
|
$files
|
|
git update-index --skip-worktree $files
|
|
git diff -U0 --no-ext-diff HEAD -- $files | grep '^[-+][^-+]' || true
|
|
grep -rn "$MIRRORS" build_scripts
|
|
|
|
- name: Log in to the registry
|
|
env:
|
|
REGISTRY_USER: ${{ vars.REGISTRY_USER || github.actor }}
|
|
REGISTRY_TOKEN: ${{ secrets.REGISTRY_TOKEN }}
|
|
run: printf %s "$REGISTRY_TOKEN" | podman login "$REGISTRY" -u "$REGISTRY_USER" --password-stdin
|
|
|
|
- name: Vendor upstream images
|
|
# What `just build` pulls, worked out the way it does: the base
|
|
# (Kinoite at the tag's Fedora version), akmods for its kernel, and
|
|
# the digest-pinned images in image-versions.yml. Both akmods tags:
|
|
# `just build` reads the kernel off the short one.
|
|
run: |
|
|
org=$(just --evaluate base_image_org)
|
|
name=$(just --evaluate base_image_name)
|
|
ver=$(just fedora_version --image aurora --tag "$TAG" --flavor main)
|
|
akmods=ghcr.io/ublue-os/akmods:$(just akmods_flavor --tag "$TAG")-$ver
|
|
refs=("$org/$name:$ver" "$akmods")
|
|
if kernel=$(skopeo --registries-conf /dev/null inspect --no-tags --retry-times 3 "docker://$akmods" | jq -er '.Labels["ostree.linux"]'); then
|
|
refs+=("$akmods-$kernel")
|
|
fi
|
|
mapfile -t pinned < <(yq -r '.images[] | select(.name != "kinoite") | "\(.image):\(.tag)@\(.digest)"' image-versions.yml)
|
|
.forgejo/vendor-images.sh "${refs[@]}" "${pinned[@]}"
|
|
|
|
- name: Build
|
|
# Aurora reads its own past tags from ghcr.io/$GITHUB_REPOSITORY_OWNER
|
|
# and hands $GITHUB_TOKEN to GitHub's API. On Forgejo Actions those
|
|
# are this org and a Forgejo token, so: ublue-os, and no token.
|
|
run: >-
|
|
env -u GITHUB_TOKEN
|
|
GITHUB_REPOSITORY_OWNER=ublue-os
|
|
GIT_CONFIG_COUNT=1 GIT_CONFIG_KEY_0=safe.directory GIT_CONFIG_VALUE_0='*'
|
|
just build --image aurora --tag "$TAG" --flavor main
|
|
|
|
- name: Push
|
|
run: |
|
|
# The commit built, not $GITHUB_SHA: after "Merge upstream" that's
|
|
# the merge, not the commit the run started from.
|
|
built=$(git rev-parse HEAD)
|
|
for t in "$TAG" "$TAG-$(date -u +%Y%m%d)" "${built::12}"; do
|
|
podman tag "localhost/aurora:$TAG" "$IMAGE:$t"
|
|
podman push --retry 5 "$IMAGE:$t"
|
|
done
|
|
|
|
- name: Upload the build's RPMs
|
|
# From the dnf cache Containerfile.in's cache mounts keep (buildah
|
|
# keeps it on the runner, under /var/tmp/buildah-cache-0), to
|
|
# https://forge.quinefoundation.com/api/packages/quine-global-labs/rpm/<group>.
|
|
# Packages already there are skipped. Never fails the build.
|
|
continue-on-error: true
|
|
env:
|
|
REGISTRY_USER: ${{ vars.REGISTRY_USER || github.actor }}
|
|
REGISTRY_TOKEN: ${{ secrets.REGISTRY_TOKEN }}
|
|
run: |
|
|
fedora=$(ls -d /var/tmp/buildah-cache-0/*/fedora-*/ 2>/dev/null | head -1)
|
|
[ -n "$fedora" ] || { echo "::warning::no dnf cache under /var/tmp/buildah-cache-0"; exit 0; }
|
|
.forgejo/upload-rpms.sh "$(dirname "$fedora")"
|
|
|
|
- name: Clean up
|
|
if: always()
|
|
# The runner's hourly sweep keeps a day of images; this build's are
|
|
# done with now (quine-linux pulls the pushed image from the forge).
|
|
# `image prune` leaves the dnf cache the RPM upload reads.
|
|
run: |
|
|
podman logout "$REGISTRY" || true
|
|
podman image prune -af >/dev/null || true
|