Alpine's community/libqmi is at upstream 1c972b8a (2026-10-05), 23 commits past the 30f3e998 this fork pinned "just past the !470 merge", with the qmi-glib 1.39.1 the GNSS patches in modemmanager need. No patch was left; the fork's one remaining addition, the FP6-tuned build (-march/-mtune, whose gain was never measured), goes with it. build.sh loses its tarball, checksum and build steps. The registry still serves the fork (1.39.1_git20260808-r100 and -r101), and that version outranks Alpine's 1.38.0_git* line, so with the aport alone installed phones keep the fork and a fresh image takes it back at its first 'apk upgrade': the fork's packages are deleted from the registry with this push. Fresh images then install Alpine's libqmi and keep it. Installed phones keep the fork until 'apk upgrade -a' downgrades them to Alpine's or Alpine's version passes 1.39.1; the new modemmanager works on either (verified on the FP6 with both). pmbootstrap keeps a local package repository in its work dir and consults it before every other repository. Whether that dir survives from one CI run to the next is not established (run 60 rebuilt libqmi, modemmanager and libcamera at the versions run 58 had built, which says it did not), but nothing guarantees it either way, so build.sh deletes any libqmi/qmi-utils apks found there before building, re-indexes the repository from the files present and fails the run if any are left; the publish step skips libqmi-*/qmi-utils-* as the backstop. pmbootstrap's 'zap --pkgs-local-mismatch' cannot do this: with systemd selected it looks at packages/systemd-edge, not at the packages/edge the builds land in.
119 lines
4.9 KiB
YAML
119 lines
4.9 KiB
YAML
name: image
|
|
|
|
# Builds the flashable postmarketOS images for the Fairphone 6 (kernel from
|
|
# milos-linux combined-stable + imsd) — Plasma Mobile (fp6-img.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.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
|
|
for f in /home/build/.local/var/pmbootstrap/packages/*/aarch64/*.apk; do
|
|
[ -e "$f" ] || continue
|
|
case "$(basename "$f")" in
|
|
imsd-*|fingerprintd-*) echo "registry-sourced, not republished: $(basename "$f")"; continue ;;
|
|
libqmi-*|qmi-utils-*) echo "retired fork, not republished: $(basename "$f")"; continue ;;
|
|
esac
|
|
found=1
|
|
code=$(curl -s -o /dev/null -w '%{http_code}' \
|
|
--user "catbot:$PACKAGE_TOKEN" --upload-file "$f" \
|
|
"https://forgejo.catcrafts.net/api/packages/Catcrafts/alpine/edge/fp6")
|
|
case "$code" in
|
|
201) echo "published: $(basename "$f")" ;;
|
|
409) echo "already published: $(basename "$f")" ;;
|
|
*) echo "FAILED ($code): $(basename "$f")"; exit 1 ;;
|
|
esac
|
|
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 postmarketOS 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: ''
|