From db7e6ccc18e75fbf9376becc03030ba15817685d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Martin?= Date: Tue, 6 Oct 2026 12:39:37 +0200 Subject: [PATCH] CI: jobs run in a container, PlatformIO directly in it, the toolchains in a volume The runner now gives each job a container. The workflow asks for python:3.12-slim, installs git, a compiler and PlatformIO, and mounts the roro9stack-pio volume as the cache; the scripts skip their own docker run when RORO_NO_DOCKER says they're in the build container already. A tag from before the framework was rebuilt gets the stock framework libraries back before it builds. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT --- .gitea/workflows/ci.yml | 33 ++++++++++++++++++++++++--------- scripts/_docker.sh | 8 +++++++- scripts/ci.sh | 2 +- scripts/release_build.sh | 7 ++++++- 4 files changed, 38 insertions(+), 12 deletions(-) diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index b2e41c6..70669fb 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -3,9 +3,9 @@ # A tag v*: the same, then a Gitea release with the signed Update File. # Run by hand: the release of a tag that exists already (the ones from before CI). # -# The runner executes jobs on its own host, where Docker is: the steps are plain shell and the build -# runs in the project's image, exactly as scripts/ci.sh does on a developer's machine. No JavaScript -# actions (the host has no Node), so the checkout is done with git. +# The job runs in a plain Python image, as scripts/ci.sh does on a developer's machine, with the +# toolchains in a Docker volume the runner allows (container.valid_volumes: roro9stack-pio): that +# volume is the cache. No JavaScript actions, so the image needs no Node: the checkout is git. name: CI on: push: @@ -19,11 +19,26 @@ on: jobs: build: - runs-on: "ubuntu://docker:ubuntu:resolute" + runs-on: ubuntu + container: + image: python:3.12-slim + volumes: + - roro9stack-pio:/pio + env: + PLATFORMIO_CORE_DIR: /pio + RORO_NO_DOCKER: 1 steps: + - name: Tools + run: | + apt-get update -qq + apt-get install -y -qq --no-install-recommends git build-essential openssl >/dev/null + pip install -q --no-cache-dir --root-user-action=ignore platformio + pio --version; df -h /pio | tail -1; ls /pio | head + - name: Check out run: | find . -mindepth 1 -maxdepth 1 -exec rm -rf {} + + git config --global --add safe.directory '*' git init -q . git remote add origin "${{ github.server_url }}/${{ github.repository }}.git" git fetch -q --tags origin '+refs/heads/*:refs/remotes/origin/*' @@ -49,16 +64,16 @@ jobs: OTA_SIGNING_KEY: ${{ secrets.OTA_SIGNING_KEY }} run: | # The sources of the tag in a clone of their own; the tools are this commit's. - rm -rf ../release-src dist - git clone -q . ../release-src - git -C ../release-src checkout -q --detach "refs/tags/${{ steps.release.outputs.tag }}" - # The key exists as a file only while this step runs. + rm -rf /tmp/release-src dist + git clone -q . /tmp/release-src + git -C /tmp/release-src checkout -q --detach "refs/tags/${{ steps.release.outputs.tag }}" + # The key exists as a file only while this step runs, in a container that goes with the job. umask 077 export RORO_OTA_KEY="$(mktemp)" trap 'rm -f "$RORO_OTA_KEY"' EXIT printf '%s\n' "$OTA_SIGNING_KEY" > "$RORO_OTA_KEY" umask 022 - scripts/release_build.sh ../release-src dist + scripts/release_build.sh /tmp/release-src dist - name: Publish the release if: steps.release.outputs.tag != '' diff --git a/scripts/_docker.sh b/scripts/_docker.sh index fefd935..cc38627 100755 --- a/scripts/_docker.sh +++ b/scripts/_docker.sh @@ -1,8 +1,10 @@ # Shared helper: run a command inside the roro9stack build container. +# With RORO_NO_DOCKER set, the caller is in such a container already (a CI job): the command runs +# right here, in the checkout. IMAGE=roro9stack-build ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" -docker build -q -t "$IMAGE" "$ROOT/docker" >/dev/null +[ -n "${RORO_NO_DOCKER:-}" ] || docker build -q -t "$IMAGE" "$ROOT/docker" >/dev/null # The Debug Console token (ADR 0004): made once, kept with the OTA key, never committed. DEBUG_TOKEN_FILE="$HOME/.config/roro9stack/debug-token" @@ -12,6 +14,10 @@ if [ ! -s "$DEBUG_TOKEN_FILE" ]; then fi run_in_container() { + if [ -n "${RORO_NO_DOCKER:-}" ]; then + (cd "$ROOT" && RORO_DEBUG_TOKEN="$(cat "$DEBUG_TOKEN_FILE")" "$@") + return + fi docker run --rm \ -u "$(id -u):$(id -g)" -e HOME=/tmp \ -e RORO_DEBUG_TOKEN="$(cat "$DEBUG_TOKEN_FILE")" \ diff --git a/scripts/ci.sh b/scripts/ci.sh index 8f018b4..4f289b7 100755 --- a/scripts/ci.sh +++ b/scripts/ci.sh @@ -4,4 +4,4 @@ set -euo pipefail source "$(dirname "$0")/_docker.sh" DOCKER_EXTRA=() -run_in_container bash -c 'git config --global --add safe.directory /work && pio test -e native && pio run -e cardputer-adv -e cardputer-adv-debug' +run_in_container bash -c 'git config --global --add safe.directory "$PWD" && pio test -e native && pio run -e cardputer-adv -e cardputer-adv-debug' diff --git a/scripts/release_build.sh b/scripts/release_build.sh index cc4c0ee..974c768 100755 --- a/scripts/release_build.sh +++ b/scripts/release_build.sh @@ -21,7 +21,12 @@ git -C "$SRC" describe --tags --exact-match >/dev/null 2>&1 || { echo "release: source "$TOOLS/_docker.sh" ROOT="$SRC" # _docker.sh mounts $ROOT as /work: the checkout to build, not necessarily this copy DOCKER_EXTRA=() -run_in_container bash -c 'git config --global --add safe.directory /work && pio run -e cardputer-adv' +# A tag from before the framework was rebuilt with our settings (ADR 0006) can't link against a +# rebuilt one left in the toolchain cache: it gets the framework's libraries as they come. +if ! grep -q custom_sdkconfig "$SRC/platformio.ini"; then + run_in_container bash -c 'rm -rf "${PLATFORMIO_CORE_DIR:-/pio}/packages/framework-arduinoespressif32-libs"' +fi +run_in_container bash -c 'git config --global --add safe.directory "$PWD" && pio run -e cardputer-adv' BUILD="$SRC/.pio/build/cardputer-adv" NAME="roro9stack-$VERSION"