Build Bazzite #5554
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Build Bazzite | |
on: | |
schedule: | |
- cron: "40 4 * * 1" # 4:40 utc monday | |
pull_request: | |
branches: | |
- testing | |
- unstable | |
paths-ignore: | |
- "**.md" | |
- "**.txt" | |
- "installer/**" | |
- "repo_content/**" | |
- "spec_files/**" | |
- "post_install_files/**" | |
- "press_kit/**" | |
- "docs/**" | |
- ".github/workflows/build_iso.yml" | |
push: | |
branches: | |
- testing | |
- unstable | |
paths-ignore: | |
- "**.md" | |
- "**.txt" | |
- "repo_content/**" | |
- "spec_files/**" | |
- "post_install_files/**" | |
- "press_kit/**" | |
- ".github/workflows/build_iso.yml" | |
merge_group: | |
workflow_dispatch: | |
inputs: | |
handwritten: | |
description: 'Small changelog:' | |
# Run with this periodically to analyze the image again | |
# As package drift will make the plan eventually non-ideal | |
# (existing users will have to redownload most of the image) | |
fresh-rechunk: | |
description: 'Clear rechunk history' | |
type: boolean | |
default: false | |
env: | |
IMAGE_REGISTRY: ghcr.io/${{ github.repository_owner }} | |
concurrency: | |
group: ${{ github.workflow }}-${{ github.ref || github.run_id }} | |
cancel-in-progress: true | |
jobs: | |
push-ghcr: | |
name: Make | |
runs-on: ubuntu-24.04 | |
continue-on-error: false | |
permissions: | |
contents: read | |
packages: write | |
id-token: write | |
strategy: | |
fail-fast: false | |
matrix: | |
base_image_flavor: [main] | |
base_name: [bazzite, bazzite-deck, bazzite-nvidia] | |
base_image_name: [kinoite, silverblue] | |
target_image_flavor: [main, asus] | |
target_nvidia_flavor: [nvidia, nvidia-open] | |
fedora_version: [41] | |
include: | |
- fedora_version: 41 | |
is_latest_version: true | |
is_stable_version: true | |
kernel_flavor: bazzite # must match a kernel_flavor from akmods repo | |
kernel_version: 6.11.9-301.bazzite.fc41.x86_64 # must match a cached version of the above flavor | |
exclude: | |
- base_name: bazzite | |
target_nvidia_flavor: nvidia | |
- base_name: bazzite-deck | |
target_nvidia_flavor: nvidia | |
steps: | |
- name: Define env.IMAGE_FLAVOR | |
run: | | |
if [[ "${{ matrix.base_name }}" == "bazzite-nvidia" ]]; then | |
if [[ "${{ matrix.target_image_flavor }}" == "main" ]]; then | |
echo "IMAGE_FLAVOR=${{ matrix.target_nvidia_flavor }}" >> $GITHUB_ENV | |
else | |
echo "IMAGE_FLAVOR=${{ format('{0}-{1}', matrix.target_image_flavor, matrix.target_nvidia_flavor) }}" >> $GITHUB_ENV | |
fi | |
else | |
echo "IMAGE_FLAVOR=${{ matrix.target_image_flavor }}" >> $GITHUB_ENV | |
fi | |
- name: Define env.IMAGE_NAME | |
run: | | |
DESKTOP="" | |
if [[ "${{ matrix.base_image_name }}" == "silverblue" ]]; then | |
DESKTOP="-gnome" | |
fi | |
if [[ "${{ matrix.base_name }}" == "bazzite-deck" ]]; then | |
if [[ "${{ matrix.target_image_flavor }}" == "asus" ]]; then | |
echo "IMAGE_NAME=${{ format('{0}{1}', 'bazzite-ally', '${DESKTOP}') }}" >> $GITHUB_ENV | |
else | |
echo "IMAGE_NAME=${{ format('{0}{1}', 'bazzite-deck', '${DESKTOP}') }}" >> $GITHUB_ENV | |
fi | |
else | |
if [[ "${{ env.IMAGE_FLAVOR }}" == "main" ]]; then | |
echo "IMAGE_NAME=${{ format('{0}{1}', 'bazzite', '${DESKTOP}') }}" >> $GITHUB_ENV | |
else | |
echo "IMAGE_NAME=${{ format('{0}{1}-{2}', 'bazzite', '${DESKTOP}', env.IMAGE_FLAVOR) }}" >> $GITHUB_ENV | |
fi | |
fi | |
- name: Define env.SHA_HEAD_SHORT | |
run: | | |
echo "SHA_HEAD_SHORT=${GITHUB_SHA::7}" >> $GITHUB_ENV | |
- name: Verify main image | |
uses: EyeCantCU/cosign-action/[email protected] | |
with: | |
containers: ${{ matrix.base_image_name }}-${{ matrix.base_image_flavor }}:${{ matrix.fedora_version }} | |
pubkey: https://raw.githubusercontent.com/ublue-os/${{ matrix.base_image_flavor }}/main/cosign.pub | |
registry: ${{ env.IMAGE_REGISTRY }} | |
- name: Verify akmods image | |
uses: EyeCantCU/cosign-action/[email protected] | |
with: | |
containers: akmods:${{ matrix.kernel_flavor}}-${{ matrix.fedora_version }}-${{ matrix.kernel_version }} | |
pubkey: https://raw.githubusercontent.com/ublue-os/akmods/main/cosign.pub | |
registry: ${{ env.IMAGE_REGISTRY }} | |
- name: Verify akmods-nvidia image | |
uses: EyeCantCU/cosign-action/[email protected] | |
with: | |
containers: akmods-${{ matrix.target_nvidia_flavor }}:${{ matrix.kernel_flavor}}-${{ matrix.fedora_version }}-${{ matrix.kernel_version }} | |
pubkey: https://raw.githubusercontent.com/ublue-os/akmods/main/cosign.pub | |
registry: ${{ env.IMAGE_REGISTRY }} | |
# Checkout push-to-registry action GitHub repository | |
- name: Checkout Push to Registry action | |
uses: actions/checkout@v4 | |
# Prepare offline documentation | |
- run: mkdir -p ${{ github.workspace }}/system_files/desktop/shared/usr/share/ublue-os/docs/html | |
continue-on-error: true | |
- name: Checkout docs repo | |
run: rm -r ${{ github.workspace }}/docs && git clone https://github.com/KyleGospo/docs.bazzite.gg.git ${{ github.workspace }}/docs | |
continue-on-error: true | |
- name: Build offline documentation | |
uses: ./.github/workflows/build_mkdocs | |
continue-on-error: true | |
with: | |
github_token: ${{ github.token }} | |
output_dir: ${{ github.workspace }}/system_files/desktop/shared/usr/share/ublue-os/docs/html | |
upload_github_page: "false" | |
- name: Check just syntax | |
uses: ublue-os/just-action@v2 | |
- name: Maximize build space | |
uses: ublue-os/remove-unwanted-software@v7 | |
- name: Pull main, akmods, rechunk images | |
uses: Wandalen/[email protected] | |
with: | |
attempt_limit: 3 | |
attempt_delay: 15000 | |
command: | | |
# pull the base images used for FROM in Containerfile so | |
# we can retry on that unfortunately common failure case | |
sudo podman pull ${{ env.IMAGE_REGISTRY }}/${{ matrix.base_image_name }}-${{ matrix.base_image_flavor }}:${{ matrix.fedora_version }} | |
sudo podman pull ${{ env.IMAGE_REGISTRY }}/akmods:${{ matrix.kernel_flavor}}-${{ matrix.fedora_version }}-${{ matrix.kernel_version }} | |
sudo podman pull ${{ env.IMAGE_REGISTRY }}/akmods-${{ matrix.target_nvidia_flavor }}:${{ matrix.kernel_flavor}}-${{ matrix.fedora_version }}-${{ matrix.kernel_version }} | |
# Add rechunk as well to remove this source of failure | |
sudo podman pull ghcr.io/hhd-dev/rechunk:v1.0.1 | |
- name: Get source versions | |
id: labels | |
uses: Wandalen/[email protected] | |
with: | |
attempt_limit: 3 | |
attempt_delay: 15000 | |
command: | | |
set -eo pipefail | |
skopeo inspect docker://${{ env.IMAGE_REGISTRY }}/${{ matrix.base_image_name }}-${{ matrix.base_image_flavor }}:${{ matrix.fedora_version }} > source.json | |
ver=$(jq -r '.Labels["org.opencontainers.image.version"]' source.json) | |
if [ -z "$ver" ] || [ "null" = "$ver" ]; then | |
echo "inspected image version must not be empty or null" | |
exit 1 | |
fi | |
echo "SOURCE_IMAGE_VERSION=$ver" >> $GITHUB_ENV | |
# Generate a primary version key that appears | |
# in KDE, rpm-ostree status, and github. | |
- name: Generate Version | |
id: generate-version | |
shell: bash | |
run: | | |
# Generate the primary version key that will be stored on os-release, | |
# shown on the bootloader, and used for the image tag. | |
UPSTREAM_TAG="${{ env.SOURCE_IMAGE_VERSION }}" | |
# Remove .0 suffix from upstream tag so we can add our own and | |
# the wrong one does not end up in the image. | |
UPSTREAM_TAG="${UPSTREAM_TAG%.*}" | |
FEDORA_VERSION="${{ matrix.fedora_version }}" | |
SHA_SHORT="${GITHUB_SHA::7}" | |
if [ -n "${{ github.event.pull_request.number }}" ]; then | |
VERSION="pr-${FEDORA_VERSION}-${{ github.event.pull_request.number }}" | |
PRETTY_VERSION="PR (${{ github.event.pull_request.number }}, ${UPSTREAM_TAG})" | |
elif [[ ${{ github.ref_name }} == "unstable" ]]; then | |
VERSION="unstable-${UPSTREAM_TAG}" | |
PRETTY_VERSION="Unstable (F${UPSTREAM_TAG}, #${SHA_SHORT})" | |
elif [[ ${{ github.ref_name }} == "testing" ]]; then | |
VERSION="testing-${UPSTREAM_TAG}" | |
PRETTY_VERSION="Testing (F${UPSTREAM_TAG}, #${SHA_SHORT})" | |
else | |
VERSION="${UPSTREAM_TAG}" | |
PRETTY_VERSION="Stable (F${UPSTREAM_TAG})" | |
fi | |
echo "tag=${VERSION}" >> $GITHUB_OUTPUT | |
echo "pretty=${PRETTY_VERSION}" >> $GITHUB_OUTPUT | |
echo "Generated the following:" | |
cat $GITHUB_OUTPUT | |
# Build image using buildah and save it to raw-img | |
- name: Build Image | |
id: build_image | |
run: | | |
sudo buildah build \ | |
--target ${{ matrix.base_name }} \ | |
--build-arg IMAGE_NAME=${{ env.IMAGE_NAME }} \ | |
--build-arg IMAGE_FLAVOR=${{ env.IMAGE_FLAVOR }} \ | |
--build-arg NVIDIA_FLAVOR=${{ matrix.target_nvidia_flavor }} \ | |
--build-arg IMAGE_VENDOR=${{ github.repository_owner }} \ | |
--build-arg BASE_IMAGE_NAME=${{ matrix.base_image_name }} \ | |
--build-arg BASE_IMAGE_FLAVOR=${{ matrix.base_image_flavor }} \ | |
--build-arg FEDORA_VERSION=${{ matrix.fedora_version }} \ | |
--build-arg KERNEL_FLAVOR=${{ matrix.kernel_flavor }} \ | |
--build-arg KERNEL_VERSION=${{ matrix.kernel_version }} \ | |
--build-arg IMAGE_BRANCH=${{ github.ref_name }} \ | |
--build-arg SHA_HEAD_SHORT=${{ env.SHA_HEAD_SHORT }} \ | |
--build-arg VERSION_TAG=${{ steps.generate-version.outputs.tag }} \ | |
--build-arg VERSION_PRETTY="${{ steps.generate-version.outputs.pretty }}" \ | |
--tag raw-img . | |
- name: Remove auxiliary images | |
# We are tight on space, need at least 2x for OSTree | |
run: | | |
sudo podman image rm ${{ env.IMAGE_REGISTRY }}/${{ matrix.base_image_name }}-${{ matrix.base_image_flavor }}:${{ matrix.fedora_version }} | |
sudo podman image rm ${{ env.IMAGE_REGISTRY }}/akmods:${{ matrix.kernel_flavor}}-${{ matrix.fedora_version }}-${{ matrix.kernel_version }} | |
sudo podman image rm ${{ env.IMAGE_REGISTRY }}/akmods-${{ matrix.target_nvidia_flavor }}:${{ matrix.kernel_flavor}}-${{ matrix.fedora_version }}-${{ matrix.kernel_version }} | |
# Generate the previous image reference used by the Rechunker | |
- name: Generate previous reference | |
id: generate-prev-ref | |
shell: bash | |
run: | | |
if [ "${{ github.event.inputs.fresh-rechunk }}" == "true" ]; then | |
IMAGEREF="" | |
else | |
IMAGEREF="${{ env.IMAGE_REGISTRY }}/${{ env.IMAGE_NAME }}:stable" | |
fi | |
echo "ref=${IMAGEREF}" >> $GITHUB_OUTPUT | |
echo "Generated the following:" | |
cat $GITHUB_OUTPUT | |
- name: Check Secureboot | |
shell: bash | |
run: | | |
set -x | |
if [[ ! $(command -v sbverify) || ! $(command -v curl) || ! $(command -v openssl) ]]; then | |
sudo apt update | |
sudo apt install sbsigntool curl openssl | |
fi | |
TMP=$(sudo podman create raw-img bash) | |
sudo podman cp $TMP:/usr/lib/modules/${{ matrix.kernel_version }}/vmlinuz . | |
sudo podman rm $TMP | |
sudo chmod 666 vmlinuz # might not be needed | |
sbverify --list vmlinuz | |
curl --retry 3 -Lo kernel-sign.der https://github.com/ublue-os/kernel-cache/raw/main/certs/public_key.der | |
curl --retry 3 -Lo akmods.der https://github.com/ublue-os/kernel-cache/raw/main/certs/public_key_2.der | |
openssl x509 -in kernel-sign.der -out kernel-sign.crt | |
openssl x509 -in akmods.der -out akmods.crt | |
sbverify --cert kernel-sign.crt vmlinuz || exit 1 | |
sbverify --cert akmods.crt vmlinuz || exit 1 | |
# Reprocess raw-img using rechunker which will delete it | |
- name: Run Rechunker | |
id: rechunk | |
uses: hhd-dev/[email protected] | |
with: | |
rechunk: 'ghcr.io/hhd-dev/rechunk:v1.0.1' | |
ref: 'raw-img' | |
prev-ref: '${{ steps.generate-prev-ref.outputs.ref }}' | |
version: '${{ steps.generate-version.outputs.tag }}' | |
labels: | | |
io.artifacthub.package.logo-url=https://raw.githubusercontent.com/ublue-os/bazzite/main/repo_content/logo.png | |
io.artifacthub.package.readme-url=https://docs.bazzite.gg | |
org.opencontainers.image.created=<timestamp> | |
org.opencontainers.image.description=Bazzite is a custom image built upon Fedora Atomic Desktops that brings the best of Linux gaming to all of your devices - including your favorite handheld. | |
org.opencontainers.image.licenses=Apache-2.0 | |
org.opencontainers.image.revision=${{ github.sha }} | |
org.opencontainers.image.source=https://github.com/ublue-os/bazzite | |
org.opencontainers.image.title=Bazzite | |
org.opencontainers.image.vendor=Universal Blue | |
org.opencontainers.image.url=https://bazzite.gg | |
org.universal-blue.pkg.kernel=<relver:kernel> | |
org.universal-blue.pkg.gamescope=<relver:gamescope> | |
# Generate tags after rechunker runs and checks the primary tag is not duplicated | |
# If it is, rechunk will suffix it by .1, .2, etc and put it in steps.rechunk.outputs.version | |
- name: Generate tags | |
id: generate-tags | |
shell: bash | |
run: | | |
# Common vars for generating tags | |
VERSION_TAG="${{ steps.rechunk.outputs.version }}" | |
UPSTREAM_TAG="${{ env.SOURCE_IMAGE_VERSION }}" | |
FEDORA_VERSION="${{ matrix.fedora_version }}" | |
SHA_SHORT="${GITHUB_SHA::7}" | |
BUILD_TAGS=( "${VERSION_TAG}" ) | |
# Use latest var to check if we should tag as latest | |
unset LATEST | |
if [[ "${{ matrix.is_latest_version }}" == "true" ]] && \ | |
[[ "${{ matrix.is_stable_version }}" == "true" ]]; then | |
LATEST="1" | |
fi | |
if [[ "${{ github.event_name }}" == "pull_request" ]]; then | |
# Track latest ver per PR | |
if [ -n "$LATEST" ]; then | |
BUILD_TAGS+=("pr-${{ github.event.pull_request.number }}") | |
fi | |
elif [[ ${{ github.ref_name }} == "unstable" ]]; then | |
# Per fedora version | |
BUILD_TAGS+=("${FEDORA_VERSION}-unstable") | |
BUILD_TAGS+=("unstable-${FEDORA_VERSION}") # flip ver to be last | |
if [ -n "$LATEST" ]; then | |
BUILD_TAGS+=("unstable") | |
fi | |
elif [[ ${{ github.ref_name }} == "testing" ]]; then | |
# Per fedora version | |
BUILD_TAGS+=("${FEDORA_VERSION}-testing") | |
BUILD_TAGS+=("testing-${FEDORA_VERSION}") # flip ver to be last | |
if [ -n "$LATEST" ]; then | |
BUILD_TAGS+=("testing") | |
fi | |
else | |
BUILD_TAGS+=("${FEDORA_VERSION}") | |
BUILD_TAGS+=("stable-${VERSION_TAG}") | |
# Per fedora version | |
BUILD_TAGS+=("${FEDORA_VERSION}-stable") | |
BUILD_TAGS+=("stable-${FEDORA_VERSION}") # flip ver to be last | |
if [ -n "$LATEST" ]; then | |
BUILD_TAGS+=("latest" "stable") | |
fi | |
fi | |
echo "Generated the following build tags: " | |
for TAG in "${BUILD_TAGS[@]}"; do | |
echo "${TAG}" | |
done | |
echo "alias_tags=${BUILD_TAGS[*]}" >> $GITHUB_OUTPUT | |
# Workaround bug where capital letters in your GitHub username make it impossible to push to GHCR. | |
# https://github.com/macbre/push-to-ghcr/issues/12 | |
- name: Lowercase Registry | |
id: registry_case | |
uses: ASzc/change-string-case-action@v6 | |
with: | |
string: ${{ env.IMAGE_REGISTRY }} | |
# Push the image to GHCR (Image Registry) | |
- name: Push To GHCR | |
uses: Wandalen/[email protected] | |
id: push | |
if: github.event_name != 'pull_request' | |
with: | |
attempt_limit: 3 | |
attempt_delay: 15000 | |
command: | | |
echo "${{ secrets.GITHUB_TOKEN }}" | sudo podman login ghcr.io -u ${{ github.actor }} --password-stdin | |
for tag in ${{ steps.generate-tags.outputs.alias_tags }}; do | |
sudo skopeo copy ${{ steps.rechunk.outputs.ref }} docker://${{ steps.registry_case.outputs.lowercase }}/${{ env.IMAGE_NAME }}:$tag | |
done | |
- name: Get Image Digest | |
id: digest | |
run: | | |
# Get digest for signing | |
DIGEST=$(sudo skopeo inspect --format '{{.Digest}}' ${{ steps.rechunk.outputs.ref }}) | |
echo "Digest is: $DIGEST" | |
echo "digest=${DIGEST}" >> $GITHUB_OUTPUT | |
- name: Sign container image | |
uses: EyeCantCU/cosign-action/[email protected] | |
if: github.event_name != 'pull_request' | |
with: | |
containers: ${{ env.IMAGE_NAME }} | |
registry-token: ${{ secrets.GITHUB_TOKEN }} | |
signing-secret: ${{ secrets.SIGNING_SECRET }} | |
tags: ${{ steps.digest.outputs.digest }} | |
generate_release: | |
name: Generate Release | |
needs: [push-ghcr] | |
if: github.event_name != 'pull_request' | |
secrets: inherit | |
uses: ./.github/workflows/generate_release.yml | |
build_iso: | |
name: Build ISO | |
needs: [push-ghcr] | |
if: github.ref_name == 'testing' | |
# Eventually would be nice for building images in PRs | |
#if: ${{ endsWith(github.event.pull_request.title, '[ISO]') }} | |
uses: ./.github/workflows/build_iso.yml | |
secrets: inherit |