5 Commits

Author SHA1 Message Date
pc-heini 44d64262e2 CI: install cmake/python3 for O3DE's get_python.sh
get_python.sh runs on the host shell and shells out to cmake to fetch the
engine's Python runtime, but the bare ubuntu container had neither cmake
nor python3. Add them (and tar) to the dependency install.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 10:11:14 +02:00
pc-heini 5ae57f3bbf 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 <noreply@anthropic.com>
2026-06-15 10:04:32 +02:00
pc-heini ff03166642 CI: replace actions/checkout with a shell git clone
The bare ubuntu:24.04 container has no Node.js, so the JS-based
actions/checkout@v4 fails with exit 127. Clone via plain git instead.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 09:46:22 +02:00
pc-heini 81b5856cbd Fix manifest for O3DE runtime reality found via .deb inspection
Inspecting o3de_2605_0.deb (control.tar md5sums) showed:
- everything installs under /opt/O3DE/<ver>/; no /usr glue, no app icon
- ~270 .so files sit beside the o3de launcher (LD_LIBRARY_PATH is required)
- the package depends on a build toolchain (clang/ninja/cmake/pkg-config)
- no Python runtime is bundled; O3DE fetches it into its install tree on
  first use, which is read-only in a Flatpak

Changes:
- run against org.freedesktop.Sdk so the build toolchain is present at runtime
- bake O3DE's Python in at build time via get_python.sh (network build-arg)
- drop the icon auto-grab (it would have installed a random asset SVG)
- document the remaining open risk: runtime writes into the read-only /app

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 09:37:18 +02:00
pc-heini 5421db2960 Initial O3DE Flatpak packaging + Gitea CI
Repackage the official O3DE Linux .deb as a Flatpak and publish it as a
static OSTree repo on the 'pages' branch for install via flatpak remote.

- org.o3de.O3DE.yaml: flatpak-builder manifest (extracts the .deb into /app)
- o3de-wrapper.sh: launcher that locates the versioned o3de binary at runtime
- desktop + AppStream metadata under the app-id
- scripts/: live version resolver and local build helper
- .gitea/workflows/build-flatpak.yml: daily check -> build -> publish -> tag

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 09:29:55 +02:00
19047 changed files with 626 additions and 11 deletions
+148
View File
@@ -0,0 +1,148 @@
name: Build and Publish O3DE Flatpak
on:
schedule:
- cron: '0 2 * * *' # daily at 02:00 - checks for a new O3DE release
workflow_dispatch:
inputs:
force:
description: 'Rebuild even if this version was already published'
type: boolean
default: false
permissions:
contents: write
jobs:
build:
# Adjust the label to match your registered act_runner. The runner needs a
# lot of free disk (O3DE is ~15-18 GB installed; the build needs ~2-3x that)
# and the container must be privileged so Flatpak's sandbox (bubblewrap) works.
runs-on: ubuntu-latest
container:
image: ubuntu:24.04
options: --privileged
steps:
- name: Install build dependencies
run: |
apt-get update
# cmake + python3: O3DE's get_python.sh (run on the host, not in the
# sandbox) uses cmake to fetch its Python runtime.
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
ca-certificates curl git jq xz-utils zstd binutils tar \
flatpak cmake python3
# 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.
- name: Checkout
env:
TOKEN: ${{ secrets.PUBLISH_TOKEN != '' && secrets.PUBLISH_TOKEN || secrets.GITHUB_TOKEN }}
run: |
AUTH_URL="$(echo "${GITHUB_SERVER_URL}" | sed "s#://#://${GITHUB_ACTOR}:${TOKEN}@#")/${GITHUB_REPOSITORY}.git"
git init -q
git config --global --add safe.directory "$GITHUB_WORKSPACE"
git remote add origin "$AUTH_URL"
git fetch -q --depth 1 origin "${GITHUB_SHA:-$GITHUB_REF_NAME}"
git checkout -q FETCH_HEAD
- name: Resolve latest O3DE version
id: ver
run: |
chmod +x scripts/*.sh
eval "$(scripts/get-latest-version.sh)"
{
echo "version=$version"
echo "deb_url=$deb_url"
echo "deb_file=$deb_file"
echo "sha256=$sha256"
} >> "$GITHUB_OUTPUT"
echo "Latest O3DE: $version ($deb_file)"
- name: Decide whether to build
id: check
run: |
git config --global --add safe.directory "$GITHUB_WORKSPACE"
if [ "${{ inputs.force }}" = "true" ]; then
echo "build=true" >> "$GITHUB_OUTPUT"
echo "Force build requested."
elif git ls-remote --tags origin "refs/tags/v${{ steps.ver.outputs.version }}" | grep -q .; then
echo "build=false" >> "$GITHUB_OUTPUT"
echo "v${{ steps.ver.outputs.version }} already published - nothing to do."
else
echo "build=true" >> "$GITHUB_OUTPUT"
echo "New version v${{ steps.ver.outputs.version }} - building."
fi
- name: Install Flatpak runtime and SDK
if: steps.check.outputs.build == 'true'
run: |
flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
flatpak install -y flathub org.freedesktop.Platform//24.08 org.freedesktop.Sdk//24.08
- name: Download O3DE .deb
if: steps.check.outputs.build == 'true'
run: |
curl -fL --retry 3 -o o3de.deb "${{ steps.ver.outputs.deb_url }}"
if [ -n "${{ steps.ver.outputs.sha256 }}" ]; then
echo "${{ steps.ver.outputs.sha256 }} o3de.deb" | sha256sum -c -
else
echo "::warning::No published checksum; skipping verification."
fi
- name: Stamp version into AppStream metadata
if: steps.check.outputs.build == 'true'
run: |
sed -i -E \
"s#<release version=\"[^\"]*\" date=\"[^\"]*\">#<release version=\"${{ steps.ver.outputs.version }}\" date=\"$(date +%F)\">#" \
org.o3de.O3DE.metainfo.xml
- name: Build Flatpak into OSTree repo
if: steps.check.outputs.build == 'true'
run: |
# 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 o3de.deb data
- name: Generate .flatpakrepo
if: steps.check.outputs.build == 'true'
run: |
BASE="${{ github.server_url }}/${{ github.repository }}/raw/branch/pages"
cat > repo/o3de.flatpakrepo <<EOF
[Flatpak Repo]
Title=O3DE (unofficial Flatpak)
Url=$BASE
Homepage=https://o3de.org/
Comment=Unofficial O3DE engine repackaged as a Flatpak
Description=Install the Open 3D Engine on any Linux distribution via Flatpak.
EOF
- name: Publish OSTree repo to the 'pages' branch
if: steps.check.outputs.build == 'true'
env:
# Prefer a personal access token (PUBLISH_TOKEN secret) with repo write
# access; fall back to the auto-provided Actions token.
TOKEN: ${{ secrets.PUBLISH_TOKEN != '' && secrets.PUBLISH_TOKEN || secrets.GITHUB_TOKEN }}
run: |
AUTH_URL="$(echo "${{ github.server_url }}" | sed "s#://#://${{ github.actor }}:${TOKEN}@#")/${{ github.repository }}.git"
rm -rf publish && mkdir publish && cd publish
git init -q -b pages
git config user.name "Gitea Actions"
git config user.email "actions@pc-heini.de"
cp -a ../repo/. .
touch .nojekyll
git add -A
git commit -q -m "O3DE Flatpak v${{ steps.ver.outputs.version }}"
# Force-push a single snapshot so the pages branch never accumulates history.
git push -f "$AUTH_URL" pages
cd ..
- name: Tag the published version
if: steps.check.outputs.build == 'true'
env:
TOKEN: ${{ secrets.PUBLISH_TOKEN != '' && secrets.PUBLISH_TOKEN || secrets.GITHUB_TOKEN }}
run: |
AUTH_URL="$(echo "${{ github.server_url }}" | sed "s#://#://${{ github.actor }}:${TOKEN}@#")/${{ github.repository }}.git"
git tag "v${{ steps.ver.outputs.version }}"
git push "$AUTH_URL" "v${{ steps.ver.outputs.version }}"
+14
View File
@@ -0,0 +1,14 @@
# flatpak-builder build artifacts
build-dir/
.flatpak-builder/
repo/
# downloaded payload
*.deb
*.deb.sha256
*.flatpak
o3de.deb
# misc
.DS_Store
*.log
View File
View File
+155
View File
@@ -0,0 +1,155 @@
# O3DE Flatpak
Repackage the official [Open 3D Engine](https://o3de.org/) Linux release as a
**Flatpak** so it can be installed on any distribution — not only Debian/Ubuntu.
A Gitea Actions workflow checks daily for a new O3DE release, builds the Flatpak,
and publishes it as a static [OSTree](https://ostreedev.github.io/ostree/) Flatpak
repository on the `pages` branch of this repo. You add that as a Flatpak remote and
`install` / `update` like any other app.
> **Status:** community / unofficial. O3DE is a large application (~1518 GB
> installed); building and hosting it is heavy. Treat this as best-effort.
---
## Installing (end users)
```sh
# Flathub provides the runtime O3DE needs
flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
# Add this repo (replace <owner> with the Gitea account that owns the repo)
flatpak remote-add --if-not-exists o3de \
https://gitea.pc-heini.de/<owner>/o3de-flatpak/raw/branch/pages/o3de.flatpakrepo
flatpak install o3de org.o3de.O3DE
flatpak run org.o3de.O3DE
```
Later updates:
```sh
flatpak update org.o3de.O3DE
```
> The repo is currently **unsigned** (no GPG). Flatpak will add it with GPG
> verification disabled. See *Signing* below to harden this.
---
## How it works
| File | Purpose |
| --- | --- |
| `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` | 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
(`https://o3debinaries.org/main/Latest/Linux/o3de_<ver>.deb`). The build extracts
it (`ar` + `tar`) and copies the payload into the Flatpak's `/app`. The version
directory inside the `.deb` changes every release, so the wrapper discovers the
executable at runtime rather than hard-coding a path.
---
## CI requirements (Gitea Actions)
The workflow targets a **self-hosted `act_runner`**. Because O3DE is large:
- **Disk:** budget **60 GB+** free. The build needs roughly 23× the installed
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.
- **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`
tag. The auto-provided `GITHUB_TOKEN` (with `contents: write`) usually suffices.
If your instance restricts it, create a Personal Access Token with repo write
access and add it as a secret named **`PUBLISH_TOKEN`** — the workflow prefers
it automatically.
Trigger it manually from the Gitea Actions UI (`workflow_dispatch`, with an
optional **force** rebuild), or let the daily `cron` run it. It only rebuilds when
the upstream version has no matching `vX.Y.Z` tag yet, so reruns are cheap no-ops.
---
## Building locally
```sh
# flatpak + cmake (cmake is used by O3DE's get_python.sh) + curl
sudo apt install flatpak cmake # or your distro's equivalent
./scripts/build.sh
```
Then install from the local `repo/` and run:
```sh
flatpak remote-add --user --no-gpg-verify o3de-local repo
flatpak install --user o3de-local org.o3de.O3DE
flatpak run org.o3de.O3DE
```
---
## Signing (recommended hardening)
The first iteration publishes an unsigned repo for simplicity. To sign:
1. Generate a key: `gpg --quick-gen-key "O3DE Flatpak" default default never`
2. Export the public key and add `GPGKey=<base64>` to the generated `.flatpakrepo`.
3. Pass `--gpg-sign=<KEYID>` to both `flatpak-builder` and `build-update-repo`,
and provide the private key to CI via a secret. Until then, users add the
remote with GPG verification disabled.
---
## Caveats & things to verify
These were confirmed by inspecting the v26.05 package (`opt/O3DE/26.05/…`):
- **Layout is confirmed for now**: the package installs everything under
`/opt/O3DE/<ver>/`, with the launcher at `bin/Linux/profile/Default/o3de` and
~270 `.so` files beside it (hence the wrapper's `LD_LIBRARY_PATH`). If a future
release moves things, adjust `o3de-wrapper.sh` and the manifest.
- **Runs against `org.freedesktop.Sdk`, not `Platform`.** O3DE's package
dependencies are a *build toolchain* (clang/ninja/cmake/pkg-config) because the
engine compiles project code at runtime. Those live in the SDK. Users therefore
pull the SDK runtime (larger than Platform) on install — Flatpak does this
automatically from Flathub.
- **Python is baked in at build time.** O3DE normally downloads its Python runtime
into its own install tree on first use, but that tree is read-only inside a
Flatpak. The manifest runs `python/get_python.sh` during the build (with network
access) so Python is part of the immutable image. **This is the most likely step
to need tweaking** — verify it on the first real CI build.
- **Runtime writes into the install tree may still fail.** Anything O3DE tries to
`pip install` or generate *inside* `/opt/O3DE/...` at runtime (e.g. per-gem
Python deps when building certain projects) will hit the read-only `/app`. Base
project building should work; exotic gems may not. This is the main open risk.
- **No launcher icon yet.** The `.deb` ships only in-editor asset icons, so the
desktop entry uses a generic icon. Drop a real O3DE logo into the repo and
install it in the manifest to fix this.
- **GPU / drivers:** the renderer needs working GPU access. The manifest grants
`--device=dri`/`--device=all`; on some setups you may also want the matching
GPU driver extension from Flathub.
- **Sandbox filesystem:** `--filesystem=home` lets the Project Manager create and
open projects under your home directory. Tighten or widen to taste.
- **Hosting via raw branch URLs** works because Flatpak fetches individual files
(`summary`, `config`, `objects/…`). Gitea serves these from the `pages` branch.
If you later put a real static web host in front of it, just change `Url=` in
the `.flatpakrepo`.
---
*Not affiliated with or endorsed by the Open 3D Foundation. O3DE is licensed under
Apache-2.0 / MIT.*
-7
View File
@@ -1,7 +0,0 @@
[core]
repo_version=1
mode=archive-z2
indexed-deltas=true
[flatpak]
title=O3DE (unofficial Flatpak)
+30
View File
@@ -0,0 +1,30 @@
#!/bin/sh
# Launcher for the O3DE Project Manager inside the Flatpak sandbox.
#
# The Debian package installs O3DE under /opt/O3DE/<version>/, which becomes
# /app/opt/O3DE/<version>/ inside the Flatpak. The version directory name
# changes with every release, so we discover the executable at runtime instead
# of hard-coding a path.
set -eu
O3DE_ROOT=/app/opt/O3DE
# Bundled shared libraries that ship inside the .deb.
export LD_LIBRARY_PATH="/app/lib:${O3DE_ROOT}/lib:${LD_LIBRARY_PATH:-}"
# Locate the Project Manager executable ("o3de").
O3DE_BIN=$(find "$O3DE_ROOT" -type f -name o3de -path '*bin/Linux*' 2>/dev/null | head -n 1)
if [ -z "$O3DE_BIN" ]; then
O3DE_BIN=$(find "$O3DE_ROOT" -type f -executable -name o3de 2>/dev/null | head -n 1)
fi
if [ -z "$O3DE_BIN" ]; then
echo "error: O3DE executable not found under $O3DE_ROOT" >&2
echo " (the .deb layout may have changed)" >&2
exit 1
fi
# Make libraries that sit next to the binary discoverable too.
export LD_LIBRARY_PATH="$(dirname "$O3DE_BIN"):${LD_LIBRARY_PATH}"
exec "$O3DE_BIN" "$@"
+5 -1
View File
@@ -1,6 +1,10 @@
[Flatpak Repo]
Title=O3DE (unofficial Flatpak)
Url=https://git.pc-heini.de/pc-heini/o3de-flatpak/raw/branch/pages
# Replace <owner> with the Gitea account/org that owns this repo.
# The CI job regenerates this file on the 'pages' branch with the correct URL,
# so the canonical copy to use is:
# https://gitea.pc-heini.de/<owner>/o3de-flatpak/raw/branch/pages/o3de.flatpakrepo
Url=https://gitea.pc-heini.de/<owner>/o3de-flatpak/raw/branch/pages
Homepage=https://o3de.org/
Comment=Unofficial O3DE engine repackaged as a Flatpak
Description=Install the Open 3D Engine on any Linux distribution via Flatpak.

Some files were not shown because too many files have changed in this diff Show More