Build Fedora aarch64 images for the Lenovo Yoga C630
Assembles a ready-to-write disk image via Gitea Actions. Mainline has carried sdm850-lenovo-yoga-c630.dts since 5.5 and Fedora ships it in kernel-core, so unlike aarch64-laptops/build there is no kernel or GRUB to compile — what is left is producing an image that boots on firmware which hands Linux no device tree. The build runs in an aarch64 container under qemu-user and builds filesystems from directory trees with mke2fs -d and mcopy rather than mounting loop devices, so it works on runners that will not hand out /dev/loop-control. A kernel-install hook writes the devicetree line into each BLS entry; without it the first `dnf update kernel` would produce an unbootable system. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XWRjNJMistCy6ngXH5aJLS
This commit is contained in:
122
.gitea/workflows/build-image.yaml
Normal file
122
.gitea/workflows/build-image.yaml
Normal file
@@ -0,0 +1,122 @@
|
||||
name: build image
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
tags: ['v*']
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
variant:
|
||||
description: which variant to build
|
||||
type: choice
|
||||
default: minimal
|
||||
options: [minimal, workstation, both]
|
||||
|
||||
jobs:
|
||||
# Which variants to build. Pushes and PRs build minimal only — it is the fast
|
||||
# one and it exercises the entire pipeline. Tags build everything.
|
||||
prepare:
|
||||
runs-on: metal
|
||||
outputs:
|
||||
variants: ${{ steps.pick.outputs.variants }}
|
||||
steps:
|
||||
- id: pick
|
||||
run: |
|
||||
if [ "${{ startsWith(github.ref, 'refs/tags/') }}" = "true" ]; then
|
||||
variants='["minimal","workstation"]'
|
||||
else
|
||||
case "${{ inputs.variant }}" in
|
||||
both) variants='["minimal","workstation"]' ;;
|
||||
workstation) variants='["workstation"]' ;;
|
||||
*) variants='["minimal"]' ;;
|
||||
esac
|
||||
fi
|
||||
echo "variants=$variants" | tee -a "$GITHUB_OUTPUT"
|
||||
|
||||
build:
|
||||
needs: prepare
|
||||
runs-on: metal
|
||||
timeout-minutes: 600
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
variant: ${{ fromJSON(needs.prepare.outputs.variants) }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Report runner
|
||||
run: |
|
||||
echo "host arch : $(uname -m)"
|
||||
echo "kernel : $(uname -r)"
|
||||
echo "user : $(id -un) (uid $(id -u))"
|
||||
echo "podman : $(podman --version 2>/dev/null || echo MISSING)"
|
||||
df -h .
|
||||
|
||||
# Building an aarch64 root filesystem means executing aarch64 rpm
|
||||
# scriptlets, which needs a binfmt_misc handler in the host kernel. A
|
||||
# container cannot register one for itself.
|
||||
- name: Ensure aarch64 emulation
|
||||
run: |
|
||||
handler=/proc/sys/fs/binfmt_misc/qemu-aarch64
|
||||
if [ ! -e "$handler" ]; then
|
||||
echo "no aarch64 binfmt handler, attempting to install one"
|
||||
sudo dnf install -y qemu-user-static-aarch64
|
||||
sudo systemctl restart systemd-binfmt
|
||||
fi
|
||||
if [ ! -e "$handler" ]; then
|
||||
echo "::error::aarch64 emulation is unavailable on this runner." \
|
||||
"See docs/runner-setup.md for the one-time host setup."
|
||||
exit 1
|
||||
fi
|
||||
cat "$handler"
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
case "${{ matrix.variant }}" in
|
||||
workstation) size=16384 ;;
|
||||
*) size=8192 ;;
|
||||
esac
|
||||
./build/build-image.sh --variant "${{ matrix.variant }}" --size "$size"
|
||||
|
||||
- name: Checksums
|
||||
run: cat output/*.sha256
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: fedora-${{ matrix.variant }}-lenovo-yoga-c630
|
||||
path: |
|
||||
output/*.img.zst
|
||||
output/*.sha256
|
||||
retention-days: 14
|
||||
compression-level: 0 # already zstd
|
||||
|
||||
- name: Attach to release
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
env:
|
||||
TOKEN: ${{ github.token }}
|
||||
SERVER: ${{ github.server_url }}
|
||||
REPO: ${{ github.repository }}
|
||||
TAG: ${{ github.ref_name }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
api="$SERVER/api/v1/repos/$REPO"
|
||||
auth="Authorization: token $TOKEN"
|
||||
# python3 rather than jq — jq is not guaranteed on a Fedora Server runner.
|
||||
field() { python3 -c 'import json,sys; print(json.load(sys.stdin).get(sys.argv[1],""))' "$1"; }
|
||||
|
||||
id=$(curl -sf -H "$auth" "$api/releases/tags/$TAG" | field id || true)
|
||||
if [ -z "${id:-}" ]; then
|
||||
id=$(curl -sf -X POST -H "$auth" -H 'Content-Type: application/json' \
|
||||
-d "{\"tag_name\":\"$TAG\",\"name\":\"$TAG\"}" \
|
||||
"$api/releases" | field id)
|
||||
fi
|
||||
echo "release id: $id"
|
||||
|
||||
for f in output/*.img.zst output/*.sha256; do
|
||||
echo "uploading $(basename "$f")"
|
||||
curl -sf -X POST -H "$auth" \
|
||||
-F "attachment=@${f}" \
|
||||
"$api/releases/$id/assets?name=$(basename "$f")" >/dev/null
|
||||
done
|
||||
Reference in New Issue
Block a user