Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 44d64262e2 | |||
| 5ae57f3bbf | |||
| ff03166642 | |||
| 81b5856cbd | |||
| 5421db2960 |
@@ -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
@@ -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
|
||||
@@ -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 (~15–18 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 2–3× 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.*
|
||||
@@ -1,7 +0,0 @@
|
||||
[core]
|
||||
repo_version=1
|
||||
mode=archive-z2
|
||||
indexed-deltas=true
|
||||
|
||||
[flatpak]
|
||||
title=O3DE (unofficial Flatpak)
|
||||
Executable
+30
@@ -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
@@ -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.
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user