The publish step uploads one apk at a time, in glob order, and stops at the first failed upload. With the kernel apk before soc-fairphone-fp6-audio in that order, a failure in between would leave the registry serving a kernel without the package that carries its card name's topology and UCM (the combined-stable tip CI builds names the card MILOS-Fairphone-Gen6 since 7.3; only soc-fairphone-fp6-audio >= 5 has those files, and without them that kernel boots with no sound card). Upload everything else first, the kernel last.
131 lines
5.6 KiB
YAML
131 lines
5.6 KiB
YAML
name: image
|
|
|
|
# Builds the flashable Nura images for the Fairphone 6 (kernel from
|
|
# milos-linux combined-stable + imsd) — Plasma Mobile (fp6-img-plasma.tar.xz) and
|
|
# Phosh (fp6-img-phosh.tar.xz) — and publishes both as the rolling 'latest'
|
|
# release.
|
|
#
|
|
# Runs on the dedicated privileged runner label "pmos" (loop devices for
|
|
# pmbootstrap install, qemu-user binfmt on the host for the aarch64 chroots).
|
|
# Until that runner is registered, dispatched runs will sit queued.
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
# push trigger is temporary, for pipeline bring-up; narrow to
|
|
# workflow_dispatch + a nightly schedule once the pipeline is green:
|
|
push:
|
|
branches: [main]
|
|
# schedule:
|
|
# - cron: '30 3 * * *'
|
|
|
|
jobs:
|
|
image:
|
|
runs-on: pmos
|
|
timeout-minutes: 420
|
|
steps:
|
|
# actions/checkout & friends are Node actions; bare alpine has no node.
|
|
# bash, curl, jq: required by the forgejo-release composite action —
|
|
# its setup_api falls back to apt-get when jq/curl are missing, which
|
|
# exits 127 on alpine.
|
|
- name: Provision job container
|
|
run: apk add -q nodejs git bash curl jq
|
|
|
|
- name: Checkout
|
|
uses: actions/checkout@v4
|
|
with:
|
|
persist-credentials: true
|
|
|
|
- name: Build image (Plasma Mobile)
|
|
run: ./build.sh
|
|
|
|
# Second UI from the same package builds (the kernel and the aports
|
|
# above are already current in pmbootstrap's work dir, so this is the
|
|
# install + export only): fp6-img-phosh.tar.xz next to fp6-img-plasma.tar.xz
|
|
# in the same release.
|
|
- name: Build image (Phosh)
|
|
run: FP6IMG_UI=phosh FP6IMG_KEEP_DIST=1 ./build.sh
|
|
|
|
- name: Upload artifacts
|
|
uses: actions/upload-artifact@v3
|
|
with:
|
|
name: fp6-image-${{ github.sha }}
|
|
path: dist/*
|
|
if-no-files-found: error
|
|
|
|
# Ship every locally built apk (kernel, modemmanager, callaudioshim,
|
|
# audio files, ...) to the Forgejo Alpine registry, so
|
|
# installed systems get updates via 'apk upgrade' instead of losing
|
|
# the FP6 patches to the next upstream version bump. Requires the
|
|
# PACKAGE_TOKEN repo secret (catbot account, package:write scope);
|
|
# skips quietly until it exists. 409 = same version already published.
|
|
# imsd and fingerprintd are skipped: build.sh 3b took them FROM the
|
|
# registry (re-signed for the chroot), so they are not ours to publish.
|
|
# libqmi is skipped too: its fork was retired and deleted from the
|
|
# registry (2026-10-12); should a leftover apk ever sit in the runner's
|
|
# package dir, it must not bring the fork back.
|
|
- name: Publish packages to the apk registry
|
|
env:
|
|
PACKAGE_TOKEN: ${{ secrets.PACKAGE_TOKEN }}
|
|
run: |
|
|
if [ -z "$PACKAGE_TOKEN" ]; then
|
|
echo "no PACKAGE_TOKEN secret configured; skipping package publish"
|
|
exit 0
|
|
fi
|
|
apk add -q curl
|
|
found=0
|
|
publish() {
|
|
case "$(basename "$1")" in
|
|
imsd-*|fingerprintd-*) echo "registry-sourced, not republished: $(basename "$1")"; return 0 ;;
|
|
libqmi-*|qmi-utils-*) echo "retired fork, not republished: $(basename "$1")"; return 0 ;;
|
|
esac
|
|
found=1
|
|
code=$(curl -s -o /dev/null -w '%{http_code}' \
|
|
--user "catbot:$PACKAGE_TOKEN" --upload-file "$1" \
|
|
"https://forgejo.catcrafts.net/api/packages/Catcrafts/alpine/edge/fp6")
|
|
case "$code" in
|
|
201) echo "published: $(basename "$1")" ;;
|
|
409) echo "already published: $(basename "$1")" ;;
|
|
*) echo "FAILED ($code): $(basename "$1")"; exit 1 ;;
|
|
esac
|
|
}
|
|
# The kernel goes last: a publish that fails part-way (the first
|
|
# failed upload ends this step) must never leave the registry serving
|
|
# a kernel without the userspace its card name needs - the 7.3 kernel
|
|
# has its topology and UCM only in soc-fairphone-fp6-audio >= 5.
|
|
for f in /home/build/.local/var/pmbootstrap/packages/*/aarch64/*.apk; do
|
|
[ -e "$f" ] || continue
|
|
case "$(basename "$f")" in linux-postmarketos-qcom-milos-*) continue ;; esac
|
|
publish "$f"
|
|
done
|
|
for f in /home/build/.local/var/pmbootstrap/packages/*/aarch64/linux-postmarketos-qcom-milos-*.apk; do
|
|
[ -e "$f" ] || continue
|
|
publish "$f"
|
|
done
|
|
[ "$found" = 1 ] || { echo "no packages found to publish"; exit 1; }
|
|
|
|
- name: Update rolling 'latest' tag
|
|
run: |
|
|
git config --global --add safe.directory "$PWD"
|
|
git config user.email "ci@catcrafts.net"
|
|
git config user.name "fp6-img CI"
|
|
git tag -f latest
|
|
git push origin latest --force
|
|
|
|
- name: Publish rolling 'latest' release
|
|
uses: https://code.forgejo.org/actions/forgejo-release@v2
|
|
with:
|
|
direction: upload
|
|
url: ${{ github.server_url }}
|
|
repo: ${{ github.repository }}
|
|
tag: latest
|
|
title: Latest FP6 Nura image
|
|
prerelease: true
|
|
override: true
|
|
release-dir: dist
|
|
token: ${{ secrets.GITHUB_TOKEN }}
|
|
# Empty, NOT 'false': the action guards its release-notes-assistant
|
|
# cache step with `if: ${{ inputs.release-notes-assistant }}`, where
|
|
# the default string 'false' is truthy. That step then can't reach the
|
|
# runner's cache server (it advertises the host's public IP) and burns
|
|
# ~4m40s per run on a connect timeout before reporting a miss.
|
|
release-notes-assistant: ''
|