Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
6531109
chore(build): upgrade to Debian Trixie + Python 3.13, drop Balena bas…
vpetersson Apr 29, 2026
cecf106
fix(ci): replace distutils.strtobool (3.12+ removal); satisfy SC2129
vpetersson Apr 29, 2026
dd22fa2
fix(security): HTTPS + SHA256-pin Pi keyring fetch; nuke libcec-dev typo
vpetersson Apr 29, 2026
67b9ae3
fix(sonar): declare USER root explicitly in webview/Dockerfile builder
vpetersson Apr 29, 2026
5e28919
docs: fix two Copilot-flagged comment inaccuracies
vpetersson Apr 30, 2026
eadd83d
ci(webview): adopt registry-cache backend, mirror docker-build.yaml
vpetersson Apr 30, 2026
a9b9522
fix(webview): trixie apt rename + adopt GHCR for Qt 5 builder image
vpetersson Apr 30, 2026
8d46890
docs: fix second `rpi` vs `firmware` comment in image_builder
vpetersson Apr 30, 2026
3dc0a04
ci(webview): build Qt 5 builder inline, drop the publish job
vpetersson Apr 30, 2026
1284a5e
ci(webview): drop registry cache plumbing, simpler is fine
vpetersson Apr 30, 2026
854bc49
Revert "ci(webview): drop registry cache plumbing, simpler is fine"
vpetersson Apr 30, 2026
dda69d2
chore(webview): add bin/rebuild_qt5_toolchain.sh helper
vpetersson Apr 30, 2026
8ca8ee5
Merge branch 'master' into trixie-upgrade
vpetersson Apr 30, 2026
6520965
fix(webview): make Qt 5 cross-build Dockerfile produce working tarbal…
vpetersson Apr 30, 2026
d8e8e01
chore(webview): bump QT5_TOOLCHAIN_TAG to WebView-v2026.04.1
vpetersson Apr 30, 2026
1d8c3be
docs(webview): refresh stale tag reference in rebuild_qt5_toolchain.s…
vpetersson Apr 30, 2026
fcb94f9
fix(ci): pass full SHA for GIT_HASH; keep short SHA only in GIT_SHORT…
vpetersson Apr 30, 2026
8b4e490
fix(docker): exclude Qt 5 toolchain build dir + caches from COPY
vpetersson Apr 30, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ansible-lint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ jobs:
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6

- name: Set up Python 3.11
- name: Set up Python 3.13
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6
with:
python-version: '3.11'
python-version: '3.13'

- name: Install uv
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
Expand Down
8 changes: 3 additions & 5 deletions .github/workflows/build-balena-disk-image.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ jobs:
balena-build-images:
strategy:
matrix:
board: ['pi1', 'pi2', 'pi3', 'pi4', 'pi5']
board: ['pi2', 'pi3', 'pi4-64', 'pi5']
runs-on: ubuntu-24.04
permissions:
contents: write
Expand Down Expand Up @@ -67,13 +67,11 @@ jobs:

- name: Get base board
run: |
if [ "${{ matrix.board }}" == 'pi1' ]; then
echo "BALENA_IMAGE=raspberry-pi" >> "$GITHUB_ENV"
elif [ "${{ matrix.board }}" == 'pi2' ]; then
if [ "${{ matrix.board }}" == 'pi2' ]; then
echo "BALENA_IMAGE=raspberry-pi2" >> "$GITHUB_ENV"
elif [ "${{ matrix.board }}" == 'pi3' ]; then
echo "BALENA_IMAGE=raspberrypi3" >> "$GITHUB_ENV"
elif [ "${{ matrix.board }}" == 'pi4' ]; then
elif [ "${{ matrix.board }}" == 'pi4-64' ]; then
echo "BALENA_IMAGE=raspberrypi4-64" >> "$GITHUB_ENV"
elif [ "${{ matrix.board }}" == 'pi5' ]; then
echo "BALENA_IMAGE=raspberrypi5" >> "$GITHUB_ENV"
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/build-webview.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,11 @@ jobs:
-t screenly/ose-qt-builder:latest .

compile-webview-part-1:
name: Compile Webview (Pi 1-4 / Qt 5)
name: Compile Webview (Pi 2-3 / Qt 5)
needs: build-docker-image
strategy:
matrix:
board: ['pi1', 'pi2', 'pi3', 'pi4']
board: ['pi2', 'pi3']
runs-on: ubuntu-24.04
steps:
- name: Checkout
Expand Down Expand Up @@ -214,7 +214,7 @@ jobs:
- compile-webview-part-2
strategy:
matrix:
board: ['pi1', 'pi2', 'pi3', 'pi4', 'pi4-64', 'pi5', 'x86']
board: ['pi2', 'pi3', 'pi4-64', 'pi5', 'x86']
runs-on: ubuntu-24.04
permissions:
contents: write
Expand Down
16 changes: 5 additions & 11 deletions .github/workflows/docker-build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ jobs:
# dedup at the registry level. See refactor: drop celery image.
fail-fast: false
matrix:
board: ['pi1', 'pi2', 'pi3', 'pi4', 'pi4-64', 'pi5', 'x86']
python-version: ["3.11"]
board: ['pi2', 'pi3', 'pi4-64', 'pi5', 'x86']
python-version: ["3.13"]
runs-on: ubuntu-24.04

steps:
Expand Down Expand Up @@ -208,7 +208,7 @@ jobs:
run: |
set -euo pipefail
GIT_SHORT_HASH=$(git rev-parse --short=7 HEAD)
BOARDS=(pi1 pi2 pi3 pi4 pi4-64 pi5 x86)
BOARDS=(pi2 pi3 pi4-64 pi5 x86)
SERVICES=(server redis viewer)
# GHCR first so the canonical primary is current even if the
# Docker Hub mirror later in the loop flakes.
Expand Down Expand Up @@ -266,7 +266,7 @@ jobs:
needs: buildx
strategy:
matrix:
board: ['pi1', 'pi2', 'pi3', 'pi4', 'pi5']
board: ['pi2', 'pi3', 'pi4-64', 'pi5']
runs-on: ubuntu-24.04
steps:
- name: Checkout
Expand All @@ -275,13 +275,7 @@ jobs:
- name: Set Docker tag
run: |
echo "GIT_SHORT_HASH=$(git rev-parse --short HEAD)" >> "$GITHUB_ENV"

if [ "${{ matrix.board }}" == "pi4" ]; then
echo "BOARD=${{ matrix.board }}-64" >> "$GITHUB_ENV"
else
echo "BOARD=${{ matrix.board }}" >> "$GITHUB_ENV"
fi

echo "BOARD=${{ matrix.board }}" >> "$GITHUB_ENV"
echo "SHM_SIZE=256mb" >> "$GITHUB_ENV"

- name: Prepare Balena file
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/docker-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,10 @@ jobs:
uses: ./.github/workflows/test-runner.yml
with:
test-type: 'typescript'
python-version: '3.11'
python-version: '3.13'

run-python-tests:
uses: ./.github/workflows/test-runner.yml
with:
test-type: 'python'
python-version: '3.11'
python-version: '3.13'
4 changes: 2 additions & 2 deletions .github/workflows/generate-openapi-schema.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,10 @@ jobs:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6

- name: Set up Python 3.11
- name: Set up Python 3.13
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6
with:
python-version: "3.11"
python-version: "3.13"

- name: Install uv
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/python-lint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
runs-on: ubuntu-24.04
strategy:
matrix:
python-version: ["3.11"]
python-version: ["3.13"]
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/python-mypy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
runs-on: ubuntu-24.04
strategy:
matrix:
python-version: ["3.11"]
python-version: ["3.13"]
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test-runner.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ on:
python-version:
description: 'Python version to use'
required: false
default: '3.11'
default: '3.13'
type: string

jobs:
Expand Down
2 changes: 1 addition & 1 deletion .python-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.11
3.13
4 changes: 2 additions & 2 deletions ansible/site.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@
- anthias_user | length > 0
- anthias_branch | length > 0
- device_type | length > 0
- device_type in ['pi1', 'pi2', 'pi3', 'pi4', 'pi5', 'x86']
- device_type in ['pi2', 'pi3', 'pi4-64', 'pi5', 'x86']
fail_msg: >-
Required environment variables missing or invalid.
USER must be set; DEVICE_TYPE must be one of
pi1, pi2, pi3, pi4, pi5, x86.
pi2, pi3, pi4-64, pi5, x86.

roles:
- system
Expand Down
8 changes: 2 additions & 6 deletions bin/deploy_to_balena.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ print_help() {
echo "Usage: deploy_to_balena.sh [options]"
echo "Options:"
echo " -h, --help show this help message and exit"
echo " -b, --board BOARD specify the board to build for (pi1, pi2, pi3, pi4, pi5)"
echo " -b, --board BOARD specify the board to build for (pi2, pi3, pi4-64, pi5)"
echo " -f, --fleet FLEET specify the fleet name to deploy to"
echo " -s, --short-hash HASH specify the short hash to use for the image tag"
echo " -d, --dev run in dev mode"
Expand All @@ -23,7 +23,7 @@ while [[ $# -gt 0 ]]; do
-b|--board)
export BOARD="$2"

if [[ $BOARD =~ ^(pi1|pi2|pi3|pi4|pi5)$ ]]; then
if [[ $BOARD =~ ^(pi2|pi3|pi4-64|pi5)$ ]]; then
echo "Building for $BOARD"
else
echo "Invalid board $BOARD"
Expand Down Expand Up @@ -82,10 +82,6 @@ if [[ -z "${SHM_SIZE+x}" ]]; then
fi

function prepare_balena_file() {
if [[ "$BOARD" == "pi4" ]]; then
export BOARD="pi4-64"
fi

mkdir -p balena-deploy
cp balena.yml balena-deploy/
cat docker-compose.balena.yml.tmpl | \
Expand Down
18 changes: 9 additions & 9 deletions bin/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ ARCHITECTURE=$(uname -m)
UV_PIN_VERSION="0.9.17"

INTRO_MESSAGE=(
"Anthias runs on a dedicated Raspberry Pi (1-5) or x86 device."
"Anthias runs on a dedicated Raspberry Pi (2/3/4-64-bit/5) or x86 device."
"The host will be repurposed for digital signage — on a Pi you lose the"
"regular desktop environment, and on x86 the machine should not be used"
"for anything else."
Expand Down Expand Up @@ -201,15 +201,14 @@ function install_ansible() {
fi

# Resolve and install the `host` dependency group from pyproject.toml.
# `--python ">=3.11"` overrides the repo's .python-version (3.11) so the
# installer accepts whatever interpreter the host already ships — Bookworm
# has 3.11, Trixie has 3.13. Without this, uv would insist on 3.11 and
# fail on Trixie/Pi 2 (armv7l), where there's no system 3.11 and uv has
# no managed download for that arch.
# `--python ">=3.13"` matches pyproject.toml's requires-python pin —
# Trixie ships 3.13 by default, so the installer just picks up the
# system interpreter on supported hosts. Older Debian releases
# (Bookworm = 3.11) are no longer supported on the host.
UV_PROJECT_ENVIRONMENT="${INSTALLER_VENV}" \
uv sync \
--project "${ANTHIAS_REPO_DIR}" \
--python ">=3.11" \
--python ">=3.13" \
--no-default-groups \
--group host \
--no-install-project
Expand All @@ -221,13 +220,14 @@ function set_device_type() {
elif grep -qF "Raspberry Pi 5" /proc/device-tree/model || grep -qF "Compute Module 5" /proc/device-tree/model; then
export DEVICE_TYPE="pi5"
elif grep -qF "Raspberry Pi 4" /proc/device-tree/model || grep -qF "Compute Module 4" /proc/device-tree/model; then
export DEVICE_TYPE="pi4"
export DEVICE_TYPE="pi4-64"
elif grep -qF "Raspberry Pi 3" /proc/device-tree/model || grep -qF "Compute Module 3" /proc/device-tree/model; then
export DEVICE_TYPE="pi3"
elif grep -qF "Raspberry Pi 2" /proc/device-tree/model; then
export DEVICE_TYPE="pi2"
else
export DEVICE_TYPE="pi1"
echo "Unsupported Raspberry Pi model. Anthias supports Pi 2/3/4 (64-bit)/5 and x86." >&2
exit 1
fi
}

Expand Down
25 changes: 7 additions & 18 deletions bin/upgrade_containers.sh
Original file line number Diff line number Diff line change
Expand Up @@ -34,34 +34,23 @@ if [ -z "$DOCKER_TAG" ]; then
export DOCKER_TAG="latest"
fi

# Detect Raspberry Pi version
# Detect Raspberry Pi version. Pi 4 is always treated as pi4-64 (the
# 32-bit pi4 image stream was retired with the Trixie upgrade); legacy
# 0.19.5-and-older 32-bit pi4 deployments stay on whatever DOCKER_TAG
# they were already running and don't reach this code path.
if [ ! -f /proc/device-tree/model ] && [ "$(uname -m)" = "x86_64" ]; then
export DEVICE_TYPE="x86"
elif grep -qF "Raspberry Pi 5" /proc/device-tree/model || grep -qF "Compute Module 5" /proc/device-tree/model; then
export DEVICE_TYPE="pi5"
elif grep -qF "Raspberry Pi 4" /proc/device-tree/model || grep -qF "Compute Module 4" /proc/device-tree/model; then
if [ "$(getconf LONG_BIT)" = "64" ]; then
if [ "$GIT_BRANCH" = "master" ]; then
export DEVICE_TYPE="pi4-64"
else
# Remove 'v' prefix if present for version comparison
VERSION_NUM=${GIT_BRANCH#v}
if printf '%s\n' "$VERSION_NUM" "0.19.5" | sort -V -C; then
export DEVICE_TYPE="pi4"
else
export DEVICE_TYPE="pi4-64"
fi
fi
else
export DEVICE_TYPE="pi4"
fi
export DEVICE_TYPE="pi4-64"
elif grep -qF "Raspberry Pi 3" /proc/device-tree/model || grep -qF "Compute Module 3" /proc/device-tree/model; then
export DEVICE_TYPE="pi3"
elif grep -qF "Raspberry Pi 2" /proc/device-tree/model; then
export DEVICE_TYPE="pi2"
else
# If all else fail, assume pi1
export DEVICE_TYPE="pi1"
echo "Unsupported Raspberry Pi model. Anthias supports Pi 2/3/4/5 and x86." >&2
exit 1
fi

if [[ -n $(docker ps | grep srly-ose) ]]; then
Expand Down
42 changes: 38 additions & 4 deletions docker/Dockerfile.base.j2
Original file line number Diff line number Diff line change
@@ -1,5 +1,43 @@
FROM {{ base_image }}:{{ base_image_tag }}

{% if is_legacy_pi_armhf %}
# 32-bit Pi boards (pi2, pi3) need libraspberrypi0 (legacy Broadcom
# userland: libbcm_host, libmmal, libvchiq_arm) for the Qt 5 webview.
# Trixie's archive.raspberrypi.org/main no longer ships it (replaced
# by raspi-utils, which doesn't cover Qt's link path), so we pull it
# from archive.raspbian.org's `rpi` component instead.
#
# Trixie's apt uses Sequoia (sqv) for signature verification and rejects
# the standalone .public.key / .gpg.key files because their User ID
# self-signatures are SHA-1, deprecated since 2026-02-01. The .deb
# keyring packages in each archive ship freshly-bound keys that pass
# the new policy — install those instead.
#
# Sources are written as Deb822 (.sources) entries — the format Trixie
# prefers (its own /etc/apt/sources.list.d/debian.sources uses it).
# Lets us pin Architectures: armhf so apt doesn't query the Pi mirrors
# for arches they don't ship.
{% if disable_cache_mounts %}
RUN \
{% else %}
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
{% endif %}
apt-get update && \
apt-get install -y --no-install-recommends ca-certificates curl && \
mkdir -p /tmp/keyrings && \
curl -fsSL -o /tmp/keyrings/raspberrypi-archive-keyring.deb \
http://archive.raspberrypi.org/debian/pool/main/r/raspberrypi-archive-keyring/raspberrypi-archive-keyring_2025.1+rpt1_all.deb && \
curl -fsSL -o /tmp/keyrings/raspbian-archive-keyring.deb \
http://archive.raspbian.org/raspbian/pool/main/r/raspbian-archive-keyring/raspbian-archive-keyring_20120528.4_all.deb && \
dpkg-deb -x /tmp/keyrings/raspberrypi-archive-keyring.deb / && \
dpkg-deb -x /tmp/keyrings/raspbian-archive-keyring.deb / && \
rm -rf /tmp/keyrings && \
printf 'Types: deb\nURIs: http://archive.raspberrypi.org/debian\nSuites: trixie\nComponents: main\nArchitectures: armhf\nSigned-By: /usr/share/keyrings/raspberrypi-archive-keyring.gpg\n' \
> /etc/apt/sources.list.d/raspi.sources && \
printf 'Types: deb\nURIs: http://archive.raspbian.org/raspbian\nSuites: trixie\nComponents: firmware\nArchitectures: armhf\nSigned-By: /usr/share/keyrings/raspbian-archive-keyring.gpg\n' \
Comment thread
vpetersson marked this conversation as resolved.
Outdated
> /etc/apt/sources.list.d/raspbian-firmware.sources
Comment thread
vpetersson marked this conversation as resolved.
{% endif %}

{% if disable_cache_mounts %}
RUN \
{% else %}
Expand All @@ -15,8 +53,4 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
{% endif %}
{% endfor %}

# Works around issue with `curl`
# https://github.com/balena-io-library/base-images/issues/562
RUN c_rehash

{% include 'labels.j2' %}
2 changes: 1 addition & 1 deletion docker/Dockerfile.dev
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM python:3.11-bookworm
FROM python:3.13-trixie

RUN apt-get update -y && \
pip install uv
Expand Down
12 changes: 6 additions & 6 deletions docker/uv-builder.j2
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
{% set uv_version = '0.9.17' %}
FROM {{ base_image }}:{{ base_image_tag }} AS uv-builder

{# ghcr.io/astral-sh/uv only publishes linux/amd64 and linux/arm64/v8
manifests, so 32-bit ARM targets (pi1/pi2/pi3/pi4-32) have to install
uv from PyPI instead of COPY-ing it from the prebuilt image. #}
{% if target_platform in ['linux/arm/v6', 'linux/arm/v7', 'linux/arm/v8'] %}
{# ghcr.io/astral-sh/uv only publishes linux/amd64 and linux/arm64
manifests, so 32-bit ARM targets (pi2, pi3 / armv7) install uv
from PyPI instead of COPY-ing it from the prebuilt image. #}
{% if target_platform == 'linux/arm/v7' %}
{% if disable_cache_mounts %}
RUN \
{% else %}
Expand Down Expand Up @@ -48,14 +48,14 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \

ENV UV_LINK_MODE=copy \
UV_COMPILE_BYTECODE=1 \
UV_PYTHON=/usr/bin/python3.11 \
UV_PYTHON=/usr/bin/python3 \
UV_PROJECT_ENVIRONMENT=/venv

WORKDIR /app
COPY pyproject.toml uv.lock /app/

{% if uv_system_site_packages %}
RUN uv venv --system-site-packages --python /usr/bin/python3.11 /venv
RUN uv venv --system-site-packages --python /usr/bin/python3 /venv
{% endif %}
{% if disable_cache_mounts %}
RUN \
Expand Down
Loading
Loading