Build and Publish HeiniRemote Agent Flatpak / build (push) Successful in 7m7s
A fresh system (e.g. Ubuntu after apt install flatpak) has no Flathub remote, so installing from the .flatpakrepo could not find the freedesktop 25.08 runtime. Found in the HeiniRemote VM test 2026-10-13. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
203 lines
9.1 KiB
YAML
203 lines
9.1 KiB
YAML
name: Build and Publish HeiniRemote Agent Flatpak
|
|
|
|
on:
|
|
# New upstream release: the daily check rebuilds when HeiniRemote has a
|
|
# version (tag or main commit) with no matching tag here yet.
|
|
schedule:
|
|
- cron: '0 3 * * *' # daily at 03:00
|
|
# Code change: rebuild whenever the packaging itself changes. Scoped to
|
|
# `main` on purpose — the job force-pushes the `pages` branch and creates
|
|
# tags, and those must NOT re-trigger it (that would loop).
|
|
push:
|
|
branches:
|
|
- main
|
|
paths-ignore:
|
|
- 'README.md'
|
|
- 'docs/**'
|
|
- 'LICENSE*'
|
|
- '.gitignore'
|
|
workflow_dispatch:
|
|
inputs:
|
|
force:
|
|
description: 'Rebuild even if this version was already published'
|
|
type: boolean
|
|
default: false
|
|
|
|
permissions:
|
|
contents: write
|
|
|
|
jobs:
|
|
build:
|
|
runs-on: ubuntu-latest
|
|
container:
|
|
# ubuntu:24.04 (glibc 2.39, GStreamer 1.24) is older than the
|
|
# freedesktop 25.08 runtime (glibc 2.41, GStreamer 1.26), so the
|
|
# cargo-built binary runs unmodified inside the runtime (same sonames,
|
|
# forward-compatible symbol versions). 25.08 is required: 24.08 ships
|
|
# libpipewire 1.2 whose buffer negotiation fails against KWin 6.7 /
|
|
# PipeWire 1.6 hosts ("pipewiresrc: error alloc buffers"). Privileged
|
|
# so Flatpak's bwrap works where needed (runtime install triggers).
|
|
image: ubuntu:24.04
|
|
options: --privileged
|
|
steps:
|
|
- name: Install build dependencies
|
|
run: |
|
|
apt-get update
|
|
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
|
ca-certificates curl git jq flatpak wl-clipboard \
|
|
librsvg2-common `# gdk-pixbuf SVG loader — build-export icon validation` \
|
|
build-essential pkg-config \
|
|
libglib2.0-dev libdbus-1-dev libxkbcommon-dev \
|
|
libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev \
|
|
libgstreamer-plugins-bad1.0-dev \
|
|
libpipewire-0.3-dev
|
|
|
|
# Plain git clone instead of actions/checkout@v4: the bare ubuntu image
|
|
# has no Node.js, so JavaScript actions fail with exit 127.
|
|
#
|
|
# Token split: the auto-provided GITHUB_TOKEN covers everything in THIS
|
|
# repo (checkout, pages push, tag, release). HeiniRemoteFlatpakActionReleases
|
|
# — a read-only PAT (repository: read) — is only needed where the private
|
|
# upstream HeiniRemote is cloned, which GITHUB_TOKEN cannot reach.
|
|
- name: Checkout
|
|
env:
|
|
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 upstream HeiniRemote version
|
|
id: ver
|
|
env:
|
|
TOKEN: ${{ secrets.HeiniRemoteFlatpakActionReleases }}
|
|
run: |
|
|
chmod +x scripts/*.sh
|
|
export UPSTREAM_URL="$(echo "${GITHUB_SERVER_URL}" | sed "s#://#://${GITHUB_ACTOR}:${TOKEN}@#")/pc-heini/HeiniRemote.git"
|
|
eval "$(scripts/get-latest-version.sh)"
|
|
{
|
|
echo "version=$version"
|
|
echo "ref=$ref"
|
|
} >> "$GITHUB_OUTPUT"
|
|
echo "Packaging HeiniRemote $version (ref $ref)"
|
|
|
|
- name: Decide whether to build
|
|
id: check
|
|
run: |
|
|
# A code push (or a manual force) rebuilds even if this version is
|
|
# already published — the point is to test the changed packaging.
|
|
if [ "${{ inputs.force }}" = "true" ] || [ "${{ github.event_name }}" = "push" ]; then
|
|
echo "build=true" >> "$GITHUB_OUTPUT"
|
|
echo "Rebuild requested (${{ github.event_name }})."
|
|
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 Rust
|
|
if: steps.check.outputs.build == 'true'
|
|
run: |
|
|
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal
|
|
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
|
|
|
|
- name: Build agent from upstream source
|
|
if: steps.check.outputs.build == 'true'
|
|
env:
|
|
TOKEN: ${{ secrets.HeiniRemoteFlatpakActionReleases }}
|
|
run: |
|
|
UPSTREAM_URL="$(echo "${GITHUB_SERVER_URL}" | sed "s#://#://${GITHUB_ACTOR}:${TOKEN}@#")/pc-heini/HeiniRemote.git"
|
|
# init+fetch instead of clone: works for tags and bare commit shas alike.
|
|
rm -rf upstream && git init -q upstream
|
|
git -C upstream remote add origin "$UPSTREAM_URL"
|
|
git -C upstream fetch -q --depth 1 origin "${{ steps.ver.outputs.ref }}"
|
|
git -C upstream checkout -q FETCH_HEAD
|
|
cargo build --release -p heiniremote-agent --manifest-path upstream/Cargo.toml
|
|
|
|
- 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//25.08 org.freedesktop.Sdk//25.08
|
|
|
|
- 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)\"/>#" \
|
|
de.pc_heini.HeiniRemoteAgent.metainfo.xml
|
|
|
|
- name: Build Flatpak into OSTree repo
|
|
if: steps.check.outputs.build == 'true'
|
|
run: |
|
|
AGENT_BIN=upstream/target/release/heiniremote-agent scripts/make-flatpak.sh
|
|
# Single-file bundle for direct installs without adding the remote.
|
|
mkdir -p dist
|
|
flatpak build-bundle repo \
|
|
"dist/heiniremote-agent-${{ steps.ver.outputs.version }}.flatpak" \
|
|
de.pc_heini.HeiniRemoteAgent stable
|
|
# Free disk before publishing (repo/ + dist/ are all we still need).
|
|
rm -rf build-dir upstream
|
|
|
|
- name: Generate .flatpakrepo
|
|
if: steps.check.outputs.build == 'true'
|
|
run: |
|
|
BASE="${{ github.server_url }}/${{ github.repository }}/raw/branch/pages"
|
|
cat > repo/heiniremote.flatpakrepo <<EOF
|
|
[Flatpak Repo]
|
|
Title=HeiniRemote Agent
|
|
Url=$BASE
|
|
RuntimeRepo=https://dl.flathub.org/repo/flathub.flatpakrepo
|
|
Homepage=https://pc-heini.de/
|
|
Comment=HeiniRemote remote maintenance agent as a Flatpak
|
|
Description=Install the HeiniRemote agent on any Linux distribution via Flatpak.
|
|
EOF
|
|
|
|
- name: Publish OSTree repo to the 'pages' branch
|
|
if: steps.check.outputs.build == 'true'
|
|
env:
|
|
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 "HeiniRemote Agent 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 and release the published version
|
|
if: steps.check.outputs.build == 'true'
|
|
env:
|
|
TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
GITEA_API: ${{ github.server_url }}/api/v1/repos/${{ github.repository }}
|
|
run: |
|
|
AUTH_URL="$(echo "${{ github.server_url }}" | sed "s#://#://${{ github.actor }}:${TOKEN}@#")/${{ github.repository }}.git"
|
|
TAG="v${{ steps.ver.outputs.version }}"
|
|
if git ls-remote --tags "$AUTH_URL" "refs/tags/$TAG" | grep -q .; then
|
|
echo "Tag $TAG already exists (force rebuild) — leaving it in place."
|
|
else
|
|
git tag "$TAG"
|
|
git push "$AUTH_URL" "$TAG"
|
|
fi
|
|
# Attach the single-file bundle to a Gitea release for direct download.
|
|
curl -fsS -X POST "$GITEA_API/releases" \
|
|
-H "Authorization: token $TOKEN" -H "Content-Type: application/json" \
|
|
-d "{\"tag_name\":\"$TAG\",\"name\":\"$TAG\"}" || true
|
|
RELEASE_ID=$(curl -fsS "$GITEA_API/releases/tags/$TAG" \
|
|
-H "Authorization: token $TOKEN" | jq -r '.id')
|
|
f="dist/heiniremote-agent-${{ steps.ver.outputs.version }}.flatpak"
|
|
curl -fsS -X POST "$GITEA_API/releases/$RELEASE_ID/assets?name=$(basename "$f")" \
|
|
-H "Authorization: token $TOKEN" \
|
|
-F "attachment=@$f" >/dev/null || echo "Asset already attached."
|