From 5ae57f3bbf56b64c5362d2ace99f4cd76f058bce Mon Sep 17 00:00:00 2001 From: pc-heini Date: Mon, 15 Jun 2026 10:04:32 +0200 Subject: [PATCH] CI: build without flatpak-builder to avoid bwrap/privileged requirement flatpak-builder sandboxes each build command in bubblewrap, which needs user namespaces / a privileged job container that Gitea act_runner does not grant by default (bwrap: Creating new namespace failed). Replace it with scripts/make-flatpak.sh, which uses flatpak build-init/build-finish/build-export plus plain-shell extraction and the get_python.sh bake. None of these use bwrap, so an unprivileged container works. The flatpak-builder manifest stays as a documented alternative. Co-Authored-By: Claude Opus 4.8 --- .gitea/workflows/build-flatpak.yml | 13 +++--- README.md | 20 +++++---- scripts/build.sh | 17 ++++---- scripts/make-flatpak.sh | 67 ++++++++++++++++++++++++++++++ 4 files changed, 90 insertions(+), 27 deletions(-) create mode 100755 scripts/make-flatpak.sh diff --git a/.gitea/workflows/build-flatpak.yml b/.gitea/workflows/build-flatpak.yml index 9c9a743a8..f581a53c4 100644 --- a/.gitea/workflows/build-flatpak.yml +++ b/.gitea/workflows/build-flatpak.yml @@ -28,7 +28,7 @@ jobs: apt-get update DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ ca-certificates curl git jq xz-utils zstd binutils \ - flatpak flatpak-builder + flatpak # Done as a plain git clone instead of actions/checkout@v4: the bare # ubuntu image has no Node.js, so JavaScript actions fail with exit 127. @@ -97,14 +97,11 @@ jobs: - name: Build Flatpak into OSTree repo if: steps.check.outputs.build == 'true' run: | - flatpak-builder --disable-rofiles-fuse --force-clean \ - --repo=repo --default-branch=stable \ - build-dir org.o3de.O3DE.yaml - flatpak build-update-repo repo \ - --title="O3DE (unofficial Flatpak)" \ - --prune --prune-depth=1 + # Bwrap-free build (no flatpak-builder) so no privileged container is needed. + chmod +x scripts/make-flatpak.sh + scripts/make-flatpak.sh # Free disk before publishing (the repo/ snapshot is all we still need). - rm -rf build-dir .flatpak-builder o3de.deb data + rm -rf build-dir o3de.deb data - name: Generate .flatpakrepo if: steps.check.outputs.build == 'true' diff --git a/README.md b/README.md index 1d32672fc..321aff64f 100644 --- a/README.md +++ b/README.md @@ -42,12 +42,13 @@ flatpak update org.o3de.O3DE | File | Purpose | | --- | --- | -| `org.o3de.O3DE.yaml` | `flatpak-builder` manifest. Unpacks the official `o3de_*.deb` into `/app` and wires up a launcher. | +| `scripts/make-flatpak.sh` | **The build.** Unpacks the official `o3de_*.deb` into `/app`, bakes in Python, and exports an OSTree repo using `flatpak build-init`/`build-finish`/`build-export` — no `flatpak-builder`, no bubblewrap, no privileged container. | | `o3de-wrapper.sh` | Entry point. Finds the versioned `o3de` Project Manager binary inside the sandbox and sets `LD_LIBRARY_PATH`. | | `org.o3de.O3DE.desktop` | Desktop entry under the Flatpak app-id. | | `org.o3de.O3DE.metainfo.xml` | AppStream metadata (version stamped at build time). | | `scripts/get-latest-version.sh` | Resolves the latest `.deb` URL, version, and SHA-256 from o3debinaries.org. | -| `scripts/build.sh` | Build + test the Flatpak locally. | +| `scripts/build.sh` | Download + build + test the Flatpak locally (wraps `make-flatpak.sh`). | +| `org.o3de.O3DE.yaml` | Equivalent `flatpak-builder` manifest — kept as an **alternative** for builders that have a privileged/bwrap-capable environment. Not used by CI. | | `.gitea/workflows/build-flatpak.yml` | CI: detect new version → build → publish to `pages` → tag `vX.Y.Z`. | The engine ships as a Debian package at a predictable URL @@ -66,10 +67,9 @@ The workflow targets a **self-hosted `act_runner`**. Because O3DE is large: size (extracted payload in `build-dir` + a copy committed into the OSTree `repo/`). The job deletes `build-dir` before publishing to cut peak usage, but it can still be tight. If builds fail on space, that's the first thing to check. -- **Privileged container:** Flatpak's sandbox (bubblewrap) needs it. The job sets - `options: --privileged`; your runner's `config.yaml` must allow privileged - containers (or run jobs in host mode with `flatpak`/`flatpak-builder` installed - on the host). +- **No privileged container required.** The build avoids `flatpak-builder`/bwrap + and uses `flatpak build-init`/`build-finish`/`build-export`, which only touch + files and the OSTree repo. A plain unprivileged job container works. - **Runner label:** the job uses `runs-on: ubuntu-latest`. Change it if your runner is registered with a different label. - **Token:** publishing force-pushes the `pages` branch and creates a `vX.Y.Z` @@ -87,14 +87,16 @@ the upstream version has no matching `vX.Y.Z` tag yet, so reruns are cheap no-op ## Building locally ```sh -sudo apt install flatpak flatpak-builder # or your distro's equivalent +sudo apt install flatpak # or your distro's equivalent ./scripts/build.sh ``` -Test without installing: +Then install from the local `repo/` and run: ```sh -flatpak-builder --run build-dir org.o3de.O3DE.yaml o3de-wrapper.sh +flatpak remote-add --user --no-gpg-verify o3de-local repo +flatpak install --user o3de-local org.o3de.O3DE +flatpak run org.o3de.O3DE ``` --- diff --git a/scripts/build.sh b/scripts/build.sh index 4785e0a69..ad8ab4bbe 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash -# Build the O3DE Flatpak locally (for testing the manifest before relying on CI). +# Build the O3DE Flatpak locally (same bwrap-free path CI uses). # -# Requires: flatpak, flatpak-builder, curl, and the Flathub remote. +# Requires: flatpak, curl, and the Flathub remote. (No flatpak-builder needed.) # Note: O3DE is large (~15-18 GB installed); expect a multi-GB download and a # build that needs a lot of free disk space. set -euo pipefail @@ -22,20 +22,17 @@ else echo ">> No checksum published; skipping verification" >&2 fi -# Make sure the runtime/SDK are available (no-op if already installed). +# Make sure the SDK runtime is available (no-op if already installed). flatpak remote-add --user --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo -flatpak install --user -y flathub org.freedesktop.Platform//24.08 org.freedesktop.Sdk//24.08 || true +flatpak install --user -y flathub org.freedesktop.Sdk//24.08 || true echo ">> Building" -flatpak-builder --user --force-clean --install-deps-from=flathub \ - --repo=repo build-dir org.o3de.O3DE.yaml +scripts/make-flatpak.sh cat <> Done. - Test run without installing: - flatpak-builder --run build-dir org.o3de.O3DE.yaml o3de-wrapper.sh - Or install from the local repo: +>> Done. Install from the local repo to test: flatpak remote-add --user --no-gpg-verify o3de-local repo flatpak install --user o3de-local org.o3de.O3DE + flatpak run org.o3de.O3DE EOF diff --git a/scripts/make-flatpak.sh b/scripts/make-flatpak.sh new file mode 100755 index 000000000..652eae2ef --- /dev/null +++ b/scripts/make-flatpak.sh @@ -0,0 +1,67 @@ +#!/usr/bin/env bash +# Build the O3DE Flatpak WITHOUT flatpak-builder. +# +# flatpak-builder runs every build command inside a bubblewrap sandbox, which +# needs user namespaces / a privileged container - awkward in CI. We don't need +# it: our "build" is just unpacking a .deb and running get_python.sh, both plain +# shell. flatpak build-init/build-finish/build-export only touch files and the +# OSTree repo (no bwrap), so this works in an unprivileged container. +# +# Expects ./o3de.deb to already be present. Produces ./repo (an OSTree repo). +set -euo pipefail +cd "$(dirname "$0")/.." + +APP_ID=org.o3de.O3DE +RUNTIME=org.freedesktop.Sdk +RUNTIME_VER=24.08 +BRANCH=stable + +rm -rf build-dir data repo + +echo ">> build-init" +flatpak build-init build-dir "$APP_ID" "$RUNTIME" "$RUNTIME" "$RUNTIME_VER" +DEST=build-dir/files + +echo ">> extracting .deb payload" +mkdir -p data +ar x o3de.deb +tar -C data -xf data.tar.* +mkdir -p "$DEST/opt" +cp -a data/opt/. "$DEST/opt/" + +echo ">> baking O3DE's Python runtime into the image" +# O3DE fetches Python into its install tree on first use, but that tree is +# read-only at runtime in a Flatpak, so populate it now while it is writable. +ENGINE_DIR=$(find "$DEST/opt/O3DE" -mindepth 1 -maxdepth 1 -type d | head -n1) +echo " engine dir: $ENGINE_DIR" +if [ -x "$ENGINE_DIR/python/get_python.sh" ]; then + ( cd "$ENGINE_DIR" && HOME="$PWD" ./python/get_python.sh ) +else + echo " WARNING: get_python.sh not found; Python may fail at runtime" >&2 +fi + +echo ">> installing launcher + metadata" +install -Dm755 o3de-wrapper.sh "$DEST/bin/o3de-wrapper.sh" +install -Dm644 org.o3de.O3DE.desktop "$DEST/share/applications/$APP_ID.desktop" +install -Dm644 org.o3de.O3DE.metainfo.xml "$DEST/share/metainfo/$APP_ID.metainfo.xml" + +echo ">> build-finish (command + sandbox permissions)" +flatpak build-finish build-dir \ + --command=o3de-wrapper.sh \ + --share=ipc \ + --share=network \ + --socket=x11 \ + --socket=fallback-x11 \ + --socket=wayland \ + --socket=pulseaudio \ + --device=dri \ + --device=all \ + --filesystem=home \ + --talk-name=org.freedesktop.Notifications \ + --env=QT_QPA_PLATFORM=xcb + +echo ">> export to OSTree repo" +flatpak build-export repo build-dir "$BRANCH" +flatpak build-update-repo repo --title="O3DE (unofficial Flatpak)" --prune --prune-depth=1 + +echo ">> done: ./repo"