Files
punktfunk/.gitea/workflows/flatpak.yml
T
enricobuehlerandClaude Fable 5 d83eeedde4
audit / bun-audit (push) Successful in 11s
ci / web (push) Successful in 46s
ci / docs-site (push) Successful in 1m5s
apple / swift (push) Successful in 1m21s
audit / cargo-audit (push) Successful in 2m20s
decky / build-publish (push) Successful in 19s
ci / bench (push) Successful in 6m53s
apple / screenshots (push) Successful in 6m28s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 1m0s
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 12s
docker / build-push (ci, ci/rust-ci-noble.Dockerfile, punktfunk-rust-ci-noble) (push) Successful in 9s
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 9s
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 11s
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Successful in 6m27s
windows-drivers / probe-and-proto (push) Successful in 16s
windows-drivers / driver-build (push) Successful in 1m27s
deb / build-publish-host (push) Successful in 9m37s
android / android (push) Successful in 11m56s
docker / deploy-docs (push) Successful in 24s
deb / build-publish (push) Successful in 11m31s
arch / build-publish (push) Successful in 15m34s
windows-host / package (push) Successful in 11m29s
ci / rust (push) Successful in 24m30s
rpm / build-publish (43, bazzite, punktfunk-fedora-rpm) (push) Successful in 15m37s
rpm / build-publish (44, fedora-44, punktfunk-fedora44-rpm) (push) Successful in 15m28s
flatpak / build-publish (push) Failing after 8m18s
ci(flatpak): drop the use-vc TCP-DNS hack — the runner-side cache made it the failure
Every flatpak Tooling failure on 2026-07-22 (4 runs, incl. two AFTER the
runner fleet got its local dnsmasq cache) died in flatpak remote-add with an
instant 'Could not resolve hostname' ×10 while dnf in the SAME container
resolved fine. The one thing only this leg does is force glibc onto TCP DNS
(use-vc) — a 2026-07-11 mitigation for the embedded resolver dropping UDP
under fleet load. With job containers now resolving against the on-box
dnsmasq cache (daemon.json dns → docker0), UDP is reliable again and the TCP
path through the same chain is the flaky one under concurrency. Remove the
hack; keep the nss-resolve drop and retry.sh as the backstop.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 00:27:52 +02:00

369 lines
23 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Build the native punktfunk Linux CLIENT as a single-file Flatpak bundle and publish it to
# Gitea's GENERIC package registry, so the Steam Deck (and any flatpak distro) installs it
# the SteamOS-native, update-survivable way: `flatpak install --user <downloaded>.flatpak`.
# (The HOST stays an RPM/deb — it needs unsandboxed /dev/uinput + zero-copy NVENC; only the
# CLIENT is sandbox-friendly. See packaging/README.md and packaging/flatpak/README.md.)
#
# Gitea has NO flatpak/ostree registry, so the bundle lives in the generic registry:
# PUT https://git.unom.io/api/packages/unom/generic/punktfunk-client-flatpak/<version>/<file>
# GET https://git.unom.io/api/packages/unom/generic/punktfunk-client-flatpak/<version>/<file>
# On tags the bundle is ALSO attached to the Gitea release (mirrors release.yml's DMG).
#
# PRIVILEGED-BUILD CONSTRAINT: flatpak-builder runs bubblewrap, which needs user namespaces.
# In a Gitea/act_runner Docker executor that means the job container must be --privileged
# (the same runner already runs `docker build` in docker.yml, so its Docker daemon allows it).
# If your runner CANNOT grant --privileged, this job will fail at `flatpak-builder` with
# "Creating new namespace failed: Operation not permitted" — see the fallback in
# packaging/flatpak/README.md (build on the Deck via org.flatpak.Builder, or on a Linux box,
# then upload with the curl line below).
#
# REGISTRY_TOKEN: repo Actions secret, a PAT with write:package scope (shared with deb/rpm/docker).
name: flatpak
on:
push:
branches: [main]
# The flatpak is the CLIENT — only rebuild when the client/core/manifest change, not on every
# design/host push (this is a heavy flatpak-builder run). Tags (v*, the client release) build too.
# The bundle ships BOTH client binaries (shell + Vulkan session), so every crate in either
# binary's dependency closure must be listed here.
paths:
- 'clients/linux/**'
- 'clients/session/**'
- 'crates/punktfunk-core/**'
- 'crates/pf-client-core/**'
- 'crates/pf-presenter/**'
- 'crates/pf-console-ui/**'
- 'packaging/flatpak/**'
- 'Cargo.lock'
- '.gitea/workflows/flatpak.yml'
tags: ['v*']
workflow_dispatch:
env:
REGISTRY: git.unom.io
OWNER: unom
APP_ID: io.unom.Punktfunk
MANIFEST: packaging/flatpak/io.unom.Punktfunk.yml
PACKAGE: punktfunk-client-flatpak # generic-registry package name
REPO_URL: https://flatpak.unom.io # shared unom OSTree repo (reusable across unom apps)
DEPLOY_DIR: unom-flatpak # ~/<dir> on unom-1 (compose + ./site tree)
jobs:
build-publish:
runs-on: ubuntu-24.04
timeout-minutes: 120
container:
# Fedora ships a recent flatpak + flatpak-builder + the kernel userns support.
# --privileged is required for bubblewrap inside the Docker executor (see header).
image: fedora:43
options: --privileged
steps:
# DNS fix — MUST run before any network step. fedora:43's nsswitch.conf is
# `hosts: files myhostname resolve [!UNAVAIL=return] dns`: the `resolve`
# module is nss-resolve (systemd-resolved), which isn't running in a CI
# container. glibc getaddrinfo (git, curl, dnf) mostly falls through to the
# `dns` module -> Docker's embedded 127.0.0.11 -> works. flatpak/ostree's
# resolver does NOT fall through: the absent-daemon socket connect trips
# `[!UNAVAIL=return]` and it reports "[6] Could not resolve hostname". This
# was masked as an intermittent "busy runner drops DNS" and papered over
# with retry.sh — but it's deterministic on a runner where the resolve
# module tips that way (surfaced when jobs began landing on home-runner-2).
# Drop the `resolve` entry so host lookups use plain `dns`. NOTE: this alone is not
# sufficient — the Tooling step's dnf install pulls a systemd package upgrade whose RPM
# trigger re-runs authselect and regenerates this file, undoing the fix. It's reapplied
# there, right before the first `flatpak` network call.
- name: Fix container DNS (drop nss-resolve)
run: |
sed -i 's/resolve \[!UNAVAIL=return\] //' /etc/nsswitch.conf
# History: this step used to ALSO force glibc onto TCP DNS (`options use-vc`) because
# the runner fleet's Docker embedded resolver dropped UDP lookups under parallel-job
# load (investigated 2026-07-11; v0.15.0/v0.16.0 each burned retry.sh's whole budget).
# That root cause is now fixed at the infra level (2026-07-22): the runner host runs a
# local dnsmasq cache on the docker bridge and daemon.json points every job container
# at it, so lookups terminate on-box instead of crossing the saturated uplink — the
# UDP path is reliable again. The TCP path through the same chain proved FLAKY under
# fleet concurrency (flatpak remote-add failed 10/10 with instant NXDOMAIN while dnf
# in the same container resolved fine), so `use-vc` flipped from mitigation to sole
# cause of this leg's failures — removed. retry.sh (10×) stays as the backstop for
# genuine upstream blips.
cat /etc/resolv.conf || true
# fedora:43 has no node, but actions/checkout (a JS action) needs it. A plain `run:` step
# executes via the container shell (no node needed), so install node BEFORE checkout.
- name: node for the JS actions
run: dnf -y install nodejs
- uses: actions/checkout@v4
- name: Tooling
run: |
# flatpak-cargo-generator.py (master) needs aiohttp + tomlkit (NOT the old `toml`).
# gnupg2/rsync/openssh-clients: sign the OSTree repo + rsync it to unom-1 (see the deploy step).
dnf -y install flatpak flatpak-builder git python3 python3-aiohttp python3-tomlkit curl jq \
gnupg2 rsync openssh-clients
# Belt-and-suspenders: keep nsswitch on plain `dns` even if this dnf transaction pulled
# in a fresh systemd-resolved (it does — flatpak recommends xdg-desktop-portal ->
# pipewire/wireplumber -> systemd-networkd/-resolved). Verified on the real runner
# (2026-07-11) this dnf install does NOT actually rewrite /etc/nsswitch.conf — no
# authselect trigger fires — so this line alone was never the fix for the failures
# below. See the retry.sh bump for the real cause.
sed -i 's/resolve \[!UNAVAIL=return\] //' /etc/nsswitch.conf
# Flathub provides the GNOME runtime/SDK + the rust-stable + ffmpeg-full extensions.
#
# ROOT CAUSE (confirmed 2026-07-11 by watching a live run on home-runner-1): this is
# NOT a deterministic nsswitch/DNS-config bug. gitea-runner-fleet on home-runner-1 is
# a SHARED, resource-capped fleet (3 replicas, --cpus 5 --memory 7g each, on a 16c/24G
# box) serving punktfunk AND several other orgs' repos (chatwoot, website, cms, data,
# infra, tempblade, played...). A push to punktfunk's main fans out ~8 workflows at
# once, and this runner box's Docker embedded DNS resolver (127.0.0.11) genuinely
# drops UDP lookups under that concurrent load — exactly what retry.sh's own header
# comment already documented. Reproduced: manually dispatching this job when the box
# was idle (1 container running) succeeded immediately, with or without the sed above.
# 5 attempts (~100s total) isn't always enough to outlast a synchronized multi-org
# burst, so bump the bootstrap fetch's budget — never fail the job on a single-shot
# fetch. Same treatment for every network command below.
bash scripts/ci/retry.sh 10 flatpak remote-add --user --if-not-exists flathub \
https://dl.flathub.org/repo/flathub.flatpakrepo
git config --global --add safe.directory "$PWD"
- name: Version + channel
# Tag vX.Y.Z -> X.Y.Z on the OSTree `stable` branch (a real release); a main push ->
# <next-minor>-ciN.g<sha> on the `canary` branch (base one minor ahead of the latest stable
# tag via scripts/ci/pf-version.sh). The two branches live side-by-side in one repo
# (rsync runs without --delete), each tracked by its own .flatpakref, so `flatpak update`
# on a stable box never jumps to a canary build. The generic-registry version string allows
# letters/dots/hyphens.
run: |
eval "$(bash scripts/ci/pf-version.sh)" # -> PF_BASE (one minor ahead of the latest stable tag)
SHORT=$(echo "$GITHUB_SHA" | cut -c1-8)
case "$GITHUB_REF" in
refs/tags/v*) V="${GITHUB_REF_NAME#v}"; BRANCH=stable; ALIAS=latest ;;
*) V="${PF_BASE}-ci${GITHUB_RUN_NUMBER}.g${SHORT}"; BRANCH=canary; ALIAS=canary ;;
esac
echo "VERSION=$V" >> "$GITHUB_ENV"
echo "BUNDLE=punktfunk-client-${V}.flatpak" >> "$GITHUB_ENV"
echo "FLATPAK_BRANCH=$BRANCH" >> "$GITHUB_ENV"
echo "ALIAS=$ALIAS" >> "$GITHUB_ENV"
echo "flatpak version $V -> branch '$BRANCH' alias '$ALIAS'"
- name: Generate offline cargo sources
# flatpak builds with no network; vendor every crate from Cargo.lock into
# cargo-sources.json next to the manifest (referenced by the manifest's
# punktfunk-client module).
#
# Prune the microsoft/windows-rs git crates first: they belong to
# punktfunk-client-windows, which the flatpak never builds, and leaving them in makes
# flatpak-builder full-clone that multi-GB repo at build time → "No space left on
# device" (see packaging/flatpak/prune-windows-lock.py). The committed Cargo.lock is
# untouched; cargo --offline only needs sources for the crates it compiles.
run: |
curl -fsSL --retry 5 --retry-all-errors --retry-delay 5 -o /tmp/flatpak-cargo-generator.py \
https://raw.githubusercontent.com/flatpak/flatpak-builder-tools/master/cargo/flatpak-cargo-generator.py
python3 packaging/flatpak/prune-windows-lock.py Cargo.lock /tmp/Cargo.flatpak.lock
python3 /tmp/flatpak-cargo-generator.py /tmp/Cargo.flatpak.lock \
-o packaging/flatpak/cargo-sources.json
- name: Seed the local OSTree repo from the live server (keep BOTH channels in the summary)
# Each CI run builds only ONE branch (canary on main, stable on a tag). The deploy step's
# `flatpak build-update-repo` regenerates the repo SUMMARY from whatever refs are in the
# LOCAL repo, and the rsync publishes it (without --delete). A fresh single-branch local
# repo therefore produces a single-branch summary that CLOBBERS the other channel on the
# server — the exact bug that made `app/io.unom.Punktfunk/x86_64/stable` unresolvable
# ("No such ref") after a canary main-push overwrote the post-release summary, even though
# the stable commit's objects were still on disk. Fix: mirror the published repo DOWN first,
# so the local repo carries every existing branch; the build below then only ADDS this run's
# commit and the regenerated+signed summary keeps both channels. No-op on a fresh repo (first
# publish) or when the deploy secrets aren't set (the build still produces a valid bundle).
env:
DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
DEPLOY_USER: ${{ secrets.DEPLOY_USER }}
DEPLOY_PORT: ${{ secrets.DEPLOY_PORT }}
DEPLOY_SSH_KEY: ${{ secrets.DEPLOY_SSH_KEY }}
run: |
set -euo pipefail
if [ -z "${DEPLOY_HOST:-}" ] || [ -z "${DEPLOY_SSH_KEY:-}" ]; then
echo "::warning::DEPLOY_* not set — no seed; building a fresh single-branch repo."
exit 0
fi
install -d -m700 ~/.ssh
printf '%s\n' "$DEPLOY_SSH_KEY" > ~/.ssh/deploy; chmod 600 ~/.ssh/deploy
SSH="ssh -i $HOME/.ssh/deploy -p ${DEPLOY_PORT:-22} -o StrictHostKeyChecking=accept-new"
DEST="${DEPLOY_USER}@${DEPLOY_HOST}"
mkdir -p "$PWD/repo"
# Pull the currently-published repo (all channels' objects + refs) into the repo the build
# will extend. No --delete: the local repo starts empty, so this only ADDS.
# Probe first (retried) whether a published repo exists at all: ONLY that case may
# continue with a fresh repo. A transient network failure must FAIL the job instead —
# a blanket `rsync || continue` here is exactly how a flaky link produces the
# single-branch summary that clobbers the other channel (the bug described above).
PRESENT=$(bash scripts/ci/retry.sh 5 $SSH "$DEST" \
"[ -d $DEPLOY_DIR/site/repo/refs ] && echo present || echo absent")
if [ "$PRESENT" = present ]; then
bash scripts/ci/retry.sh 5 rsync -az --info=stats1 -e "$SSH" \
"$DEST:$DEPLOY_DIR/site/repo/" "$PWD/repo/"
else
echo "::warning::no published repo on the server (first publish) — continuing fresh"
fi
echo "seeded refs:"; ls "$PWD/repo/refs/heads/app/$APP_ID/x86_64/" 2>/dev/null || echo " (none)"
- name: Prefetch deps + sources (retried — the network phase, split off the build)
run: |
# All of the job's heavy network I/O happens HERE, retried, so a dropped DNS lookup
# or TCP dial costs a backoff-retry instead of the whole (long) compile:
# 1) --install-deps-only pulls everything the manifest declares from Flathub: the
# GNOME 50 runtime/SDK + the rust-stable (//25.08, rustc 1.96) and llvm20 SDK
# extensions, plus the runtime's auto codecs-extra (HEVC libavcodec).
# 2) --download-only fetches every source (all crates in cargo-sources.json) into
# the .flatpak-builder state dir. Both are resumable/idempotent, so re-running
# after a partial failure is safe and cheap.
# --disable-rofiles-fuse is the container-safe path (no FUSE).
# 10 attempts (~9min budget), matching the remote-add bootstrap above — same shared,
# load-sensitive runner, same flathub.org resolution path.
bash scripts/ci/retry.sh 10 flatpak-builder --user --force-clean --disable-rofiles-fuse \
--install-deps-from=flathub --install-deps-only \
"$PWD/build-dir" "$MANIFEST"
bash scripts/ci/retry.sh 10 flatpak-builder --user --force-clean --disable-rofiles-fuse \
--download-only \
"$PWD/build-dir" "$MANIFEST"
- name: Build the flatpak (offline — deps + sources prefetched above)
run: |
# Everything is already local (state dir warmed by the prefetch step), so this long
# step needs no network; --install-deps-from stays as a no-op safety net.
# --default-branch=$FLATPAK_BRANCH pins the ref to app/io.unom.Punktfunk/x86_64/<branch>
# (canary or stable) so the matching hosted .flatpakref resolves deterministically
# (manifest sets no branch).
flatpak-builder --user --force-clean --disable-rofiles-fuse \
--default-branch="$FLATPAK_BRANCH" \
--install-deps-from=flathub \
--repo="$PWD/repo" \
"$PWD/build-dir" "$MANIFEST"
- name: Export single-file bundle
run: |
# Branch must be passed explicitly (matches --default-branch above); build-bundle
# otherwise defaults to `master` and errors "Refspec … not found".
flatpak build-bundle "$PWD/repo" "$BUNDLE" "$APP_ID" "$FLATPAK_BRANCH"
ls -lh "$BUNDLE"
- name: Publish to the Gitea generic registry
env:
TOKEN: ${{ secrets.REGISTRY_TOKEN }}
run: |
BASE="https://$REGISTRY/api/packages/$OWNER/generic/$PACKAGE"
# 1) Versioned URL. A re-tagged release re-fires this workflow and the registry 409s on
# duplicate uploads — delete any prior copy first (404 on the first publish is fine).
curl -fsS -o /dev/null --user "enricobuehler:$TOKEN" -X DELETE \
"$BASE/$VERSION/$BUNDLE" || true
curl -fsS --user "enricobuehler:$TOKEN" --upload-file "$BUNDLE" \
"$BASE/$VERSION/$BUNDLE"
echo "published $BASE/$VERSION/$BUNDLE"
# 2) Channel alias (stable release -> latest/, canary main build -> canary/) for the
# Decky fallback + scripts. The generic registry rejects re-uploading an existing
# version/file (409), so delete the prior alias file first (ignore 404 on run #1).
curl -fsS -o /dev/null --user "enricobuehler:$TOKEN" -X DELETE \
"$BASE/$ALIAS/punktfunk-client.flatpak" || true
curl -fsS --user "enricobuehler:$TOKEN" --upload-file "$BUNDLE" \
"$BASE/$ALIAS/punktfunk-client.flatpak"
echo "published $BASE/$ALIAS/punktfunk-client.flatpak"
# Sign the OSTree repo flatpak-builder already produced and publish it to flatpak.unom.io on
# unom-1, so users get `flatpak update` (the single-file bundle above has no remote). Mirrors
# docker.yml's deploy-docs (DEPLOY_* = the unom-ci-deploy key). No-ops cleanly until the GPG
# secret + DEPLOY_* exist, so the bundle build stays green during setup.
- name: Sign + deploy the OSTree repo to unom-1 (flatpak.unom.io)
env:
FLATPAK_GPG_PRIVATE_KEY: ${{ secrets.FLATPAK_GPG_PRIVATE_KEY }}
DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }}
DEPLOY_USER: ${{ secrets.DEPLOY_USER }}
DEPLOY_PORT: ${{ secrets.DEPLOY_PORT }}
DEPLOY_SSH_KEY: ${{ secrets.DEPLOY_SSH_KEY }}
run: |
set -euo pipefail
if [ -z "${FLATPAK_GPG_PRIVATE_KEY:-}" ] || [ -z "${DEPLOY_HOST:-}" ]; then
echo "::warning::FLATPAK_GPG_PRIVATE_KEY/DEPLOY_* not set — skipping repo deploy (bundle still published)."
exit 0
fi
# 1) Import the signing key into a throwaway keyring; sign the repo.
export GNUPGHOME="$(mktemp -d)"; chmod 700 "$GNUPGHOME"
echo "$FLATPAK_GPG_PRIVATE_KEY" | base64 -d | gpg --batch --import
KEYID="$(gpg --list-keys --with-colons | awk -F: '/^fpr:/{print $10; exit}')"
# build-sign signs the COMMIT objects; build-update-repo signs the SUMMARY. Both are
# required — clients with gpg-verify=true verify the commit, so summary-only signing
# fails the pull with "GPG verification enabled, but no signatures found".
flatpak build-sign "$PWD/repo" "$APP_ID" "$FLATPAK_BRANCH" \
--gpg-sign="$KEYID" --gpg-homedir="$GNUPGHOME"
flatpak build-update-repo --generate-static-deltas \
--gpg-sign="$KEYID" --gpg-homedir="$GNUPGHOME" "$PWD/repo"
# The regenerated summary advertises exactly these refs — must include EVERY channel that
# has ever published (the seed step ensures the other channel's commit is present). If this
# ever shows only one branch on a repo that had two, the seed didn't run — investigate.
echo "published summary advertises:"; ls "$PWD/repo/refs/heads/app/$APP_ID/x86_64/" 2>/dev/null || echo " (none)"
# 2) Build the install descriptors (GPGKey = the committed public key, base64).
GPGKEY="$(base64 -w0 packaging/flatpak/unom-flatpak.gpg)"
rm -rf site && mkdir -p site
cat > site/unom.flatpakrepo <<EOF
[Flatpak Repo]
Title=unom
Url=$REPO_URL/repo/
Homepage=https://punktfunk.unom.io
Comment=unom Flatpak applications
GPGKey=$GPGKEY
EOF
# Two refs, one per channel. Both descriptor files are regenerated every run and rsync'd
# without --delete; the repo SUMMARY carries both branches because the build was seeded
# from the live repo above (so build-update-repo below re-signs a summary listing every
# published channel, not just this run's). The stable ref resolves for good once any
# release has built the `stable` branch. A box installs ONE; `flatpak update` then tracks
# that channel's branch.
write_ref() { # <filename> <branch> <title>
cat > "site/$1" <<EOF
[Flatpak Ref]
Name=$APP_ID
Branch=$2
Url=$REPO_URL/repo/
Title=$3
Homepage=https://punktfunk.unom.io
IsRuntime=false
GPGKey=$GPGKEY
RuntimeRepo=https://dl.flathub.org/repo/flathub.flatpakrepo
EOF
}
write_ref "${APP_ID}.flatpakref" stable "Punktfunk"
write_ref "${APP_ID}.Canary.flatpakref" canary "Punktfunk (Canary)"
cat > site/index.html <<EOF
<!doctype html><meta charset=utf-8><title>unom flatpak repo</title>
<h1>unom Flatpak repository</h1>
<p>Install the Punktfunk Linux client (auto-adds Flathub for the GNOME runtime, then tracks updates).</p>
<p><b>Stable</b> (recommended — only moves on releases):</p>
<pre>flatpak install --user $REPO_URL/${APP_ID}.flatpakref
flatpak run $APP_ID</pre>
<p><b>Canary</b> (latest main build, unstable):</p>
<pre>flatpak install --user $REPO_URL/${APP_ID}.Canary.flatpakref</pre>
<p>Or add the whole remote: <code>flatpak remote-add --user --if-not-exists unom $REPO_URL/unom.flatpakrepo</code></p>
EOF
# 3) Ship to unom-1 and (re)start the static server. rsync WITHOUT --delete keeps old
# objects so clients mid-update aren't broken; the fresh signed summary advertises latest.
install -d -m700 ~/.ssh
printf '%s\n' "$DEPLOY_SSH_KEY" > ~/.ssh/deploy; chmod 600 ~/.ssh/deploy
SSH="ssh -i $HOME/.ssh/deploy -p ${DEPLOY_PORT:-22} -o StrictHostKeyChecking=accept-new"
DEST="${DEPLOY_USER}@${DEPLOY_HOST}"
# All idempotent — retried because the runner's link to unom-1 drops TCP dials under
# load (the same flake that hits docker.yml's deploy-docs with "dial tcp: i/o timeout").
bash scripts/ci/retry.sh 5 $SSH "$DEST" "mkdir -p ~/$DEPLOY_DIR/site/repo"
bash scripts/ci/retry.sh 5 rsync -az --info=stats1 -e "$SSH" repo/ "$DEST:$DEPLOY_DIR/site/repo/"
bash scripts/ci/retry.sh 5 rsync -az -e "$SSH" site/unom.flatpakrepo "site/${APP_ID}.flatpakref" "site/${APP_ID}.Canary.flatpakref" site/index.html "$DEST:$DEPLOY_DIR/site/"
bash scripts/ci/retry.sh 5 rsync -az -e "$SSH" packaging/flatpak/server/compose.production.yml packaging/flatpak/server/Caddyfile "$DEST:$DEPLOY_DIR/"
bash scripts/ci/retry.sh 5 $SSH "$DEST" "cd ~/$DEPLOY_DIR && docker compose -f compose.production.yml up -d"
echo "deployed → $REPO_URL/${APP_ID}.flatpakref"
- name: Attach bundle to the Gitea release (stable tags only)
if: startsWith(gitea.ref, 'refs/tags/v')
env:
GITEA_TOKEN: ${{ secrets.REGISTRY_TOKEN }}
run: |
. scripts/ci/gitea-release.sh
RID=$(ensure_release "$GITHUB_REF_NAME" "$GITHUB_REF_NAME" auto)
upsert_asset "$RID" "$BUNDLE"