Compare commits

..
Author SHA1 Message Date
pc-heiniandClaude Fable 5.1 c2a25b6d5c docs: note that the repo must be public for Flatpak to reach the OSTree repo
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Bc367PQmRJroxWQu5zZTQm
2026-09-20 22:24:14 +02:00
pc-heiniandClaude Fable 5 9e4c9ed6b1 fix(ci): install librsvg2-common so build-export can validate the SVG icon
Build and Publish HeiniRemote Agent Flatpak / build (push) Successful in 8m42s
flatpak build-export checks exported icons via gdk-pixbuf; without the
librsvg loader the bare ubuntu container rejects the app icon with
'Format not recognized'.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 14:14:02 +02:00
pc-heiniandClaude Fable 5 83167b2f7c fix: emit full commit sha as ref — git fetch rejects abbreviated ids
Build and Publish HeiniRemote Agent Flatpak / build (push) Failing after 9m25s
The tagless fallback truncated the sha to 12 chars for the version string
and reused that as ref, so the upstream fetch failed with
'couldn't find remote ref'. Keep the full sha for ref, shorten only the
version suffix.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 13:52:48 +02:00
pc-heiniandClaude Fable 5 95060ddf95 ci: split tokens — GITHUB_TOKEN for own repo, read-only PAT for upstream
Build and Publish HeiniRemote Agent Flatpak / build (push) Failing after 4m31s
The package-scoped REGISTRY_TOKEN cannot clone repos (403). Own-repo
operations (checkout, pages push, tag, release) now use the auto-provided
GITHUB_TOKEN; the private upstream clone uses the new read-only secret
HeiniRemoteFlatpakActionReleases.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 13:19:20 +02:00
pc-heiniandClaude Fable 5 fa40edb680 ci: use the existing user-wide REGISTRY_TOKEN for repo access
Build and Publish HeiniRemote Agent Flatpak / build (push) Failing after 4m15s
The default GITHUB_TOKEN is scoped to this repo only and cannot clone the
private upstream HeiniRemote. Reuse the user-wide write PAT (REGISTRY_TOKEN)
that the other repos' actions already rely on, instead of requiring a new
per-repo secret.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 02:48:14 +02:00
pc-heiniandClaude Fable 5 598eea7ee6 fix(ci): derive fallback version from commit sha only, not build date
Build and Publish HeiniRemote Agent Flatpak / build (push) Failing after 5m23s
With the build date baked into the version string, the nightly cron produced
a fresh version — and thus a new tag, release and bundle — every single day
even when upstream main had not moved. Key the version to the sha alone so a
rebuild happens only when the source actually changes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 02:37:46 +02:00
pc-heiniandClaude Fable 5 dd609c5ff8 docs: point repo URLs at HeiniRemote-AgentFlatpak
Build and Publish HeiniRemote Agent Flatpak / build (push) Failing after 4m45s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 02:01:30 +02:00
pc-heiniandClaude Fable 5 801db2871b feat: Flatpak packaging for the HeiniRemote agent
Build and Publish HeiniRemote Agent Flatpak / build (push) Failing after 4m52s
Bundles the agent as de.pc_heini.HeiniRemoteAgent on the freedesktop 24.08
runtime, mirroring the o3de-flatpak CI approach (bwrap-free build, OSTree
repo force-pushed to pages, single-file bundle attached to a Gitea release).
Compiles the agent from upstream source (newest v* tag, else main).

Sandbox notes: screen capture/input via portals need no special permission;
the PTY console uses flatpak-spawn --host for a real host shell, and a native
install's agent.toml is adopted read-only.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 01:56:06 +02:00
58 changed files with 497 additions and 11 deletions

No files matched your search

+198
View File
@@ -0,0 +1,198 @@
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 matches the freedesktop 24.08 runtime closely enough
# (glibc 2.39, GStreamer 1.24) that the cargo-built binary runs
# unmodified inside the runtime. 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//24.08 org.freedesktop.Sdk//24.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
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."
+6
View File
@@ -0,0 +1,6 @@
build-dir/
repo/
publish/
upstream/
dist/
*.flatpak
View File
Whitespace-only changes.
View File
Whitespace-only changes.
+101
View File
@@ -0,0 +1,101 @@
# heiniremote-flatpak
Flatpak packaging for the [HeiniRemote](https://git.pc-heini.de/pc-heini/HeiniRemote)
customer agent (`de.pc_heini.HeiniRemoteAgent`) — an additional distribution
channel next to the plain release binary, with all dependencies (GStreamer,
libnice, wl-clipboard, …) pinned inside the freedesktop 24.08 runtime.
Same setup as [o3de-flatpak](https://git.pc-heini.de/pc-heini/o3de-flatpak):
a Gitea Action builds the Flatpak **without** `flatpak-builder` (no bubblewrap
needed in CI), exports it into an OSTree repo and force-pushes that to the
`pages` branch. The difference: the agent is compiled from upstream source
(newest `v*` tag, falling back to `main` while no release exists) instead of
repackaging a prebuilt archive.
## Install
> **Note:** this repository must stay **public**. Flatpak fetches the OSTree
> repo from the raw `pages` branch without any credentials — with the repo set
> to private, `flatpak remote-add` / `flatpak install` fail with a 404.
> (The agent's source lives in the private HeiniRemote repo; only the built
> binary is published here.)
From the Flatpak remote (gets updates via `flatpak update`):
```sh
flatpak remote-add --if-not-exists heiniremote \
https://git.pc-heini.de/pc-heini/HeiniRemote-AgentFlatpak/raw/branch/pages/heiniremote.flatpakrepo
flatpak install heiniremote de.pc_heini.HeiniRemoteAgent
```
Or as a single-file bundle (attached to each release of this repo, no remote
needed, but no auto-updates either):
```sh
flatpak install ./heiniremote-agent-<version>.flatpak
```
## Configure
The agent needs a server URL and device token. Inside the sandbox the config
path is:
```
~/.var/app/de.pc_heini.HeiniRemoteAgent/config/heiniremote/agent.toml
```
If a native install already left a config at `~/.config/heiniremote/agent.toml`,
the wrapper picks it up automatically (read-only). `HEINIREMOTE_SERVER_URL` /
`HEINIREMOTE_TOKEN` env overrides work as usual:
```sh
flatpak run --env=HEINIREMOTE_SERVER_URL=wss://… de.pc_heini.HeiniRemoteAgent
```
## Autostart
The native install runs as a systemd user service; the Flatpak equivalent is a
user unit wrapping `flatpak run`:
```ini
# ~/.config/systemd/user/heiniremote-agent.service
[Unit]
Description=HeiniRemote agent (Flatpak)
After=graphical-session.target
[Service]
ExecStart=flatpak run de.pc_heini.HeiniRemoteAgent
Restart=on-failure
[Install]
WantedBy=graphical-session.target
```
## How the sandbox is punched
Screen capture and input injection go through xdg-desktop-portal
(ScreenCast + RemoteDesktop) — that is the normal, fully sandboxed path and
needs no special permission. Two things do:
- **`--talk-name=org.freedesktop.Flatpak`** — the PTY rescue console must show
the *host*, not the sandbox. The wrapper sets `SHELL=/app/bin/host-shell`,
which execs the user's real login shell via `flatpak-spawn --host`. This is
a deliberate sandbox escape; for a remote maintenance tool the sandbox is
packaging, not a security boundary.
- **`--filesystem=xdg-config/heiniremote:ro`** — adopt a native install's
`agent.toml` (see above).
Everything else is standard: `network` (signaling + WebRTC/TURN), `wayland`
(bundled wl-copy/wl-paste), `dri` (dmabuf screencast buffers), and the
StatusNotifier names for the tray icon.
## Repo layout
| File | Role |
|---|---|
| `.gitea/workflows/build-flatpak.yml` | CI: resolve upstream version → cargo build → assemble → publish `pages` + release bundle. Daily schedule picks up new upstream versions. |
| `scripts/get-latest-version.sh` | Newest upstream `v*` tag, else `main` HEAD (`0.0.0-git.<date>.<sha>`). |
| `scripts/make-flatpak.sh` | bwrap-free assembly: `build-init` → copy files → `build-finish` → `build-export`. |
| `heiniremote-wrapper.sh` | Entry point: host-shell `$SHELL` override + config adoption. |
| `host-shell.sh` | `flatpak-spawn --host` bridge for the PTY console. |
| `de.pc_heini.HeiniRemoteAgent.*` | Desktop file, AppStream metainfo (version stamped by CI), icon. |
-7
View File
@@ -1,7 +0,0 @@
[core]
repo_version=1
mode=archive-z2
indexed-deltas=true
[flatpak]
title=HeiniRemote Agent
+9
View File
@@ -0,0 +1,9 @@
[Desktop Entry]
Type=Application
Name=HeiniRemote Agent
Comment=Remote maintenance agent — connects this machine to a HeiniRemote server
Exec=heiniremote-wrapper.sh
Icon=de.pc_heini.HeiniRemoteAgent
Terminal=false
Categories=Network;RemoteAccess;
Keywords=remote;support;fernwartung;
+24
View File
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<component type="desktop-application">
<id>de.pc_heini.HeiniRemoteAgent</id>
<metadata_license>CC0-1.0</metadata_license>
<project_license>proprietary</project_license>
<name>HeiniRemote Agent</name>
<summary>Remote maintenance agent for HeiniRemote</summary>
<description>
<p>
Customer-side agent for HeiniRemote: Wayland screen capture and input
injection via xdg-desktop-portal, plus a PTY rescue console, streamed
over WebRTC to the HeiniRemote management console. Requires a HeiniRemote
server URL and device token (agent.toml).
</p>
</description>
<launchable type="desktop-id">de.pc_heini.HeiniRemoteAgent.desktop</launchable>
<url type="homepage">https://pc-heini.de/</url>
<developer_name>PC-Heini</developer_name>
<releases>
<!-- Version/date are stamped by CI (build-flatpak.yml) before export. -->
<release version="0.0.0" date="1970-01-01"/>
</releases>
<content_rating type="oars-1.1"/>
</component>
+9
View File
@@ -0,0 +1,9 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
<!-- HeiniRemote "Fernblick": remote screen inside a screen, PC-Heini logo
yellow (#f6db3e) on an anthracite tile (variant B2 of the logo drafts). -->
<rect width="32" height="32" rx="7" fill="#1d1e20"/>
<rect x="0.5" y="0.5" width="31" height="31" rx="6.5" fill="none" stroke="#f6db3e" stroke-opacity="0.25"/>
<rect x="7" y="8.5" width="18" height="13" rx="2.5" fill="none" stroke="#f6db3e" stroke-width="2.6"/>
<rect x="14.5" y="13.5" width="7.5" height="5.5" rx="1.2" fill="#f6db3e"/>
<rect x="12" y="23.5" width="8" height="2" rx="1" fill="#f6db3e" opacity="0.85"/>
</svg>

After

Width:  |  Height:  |  Size: 657 B

+24
View File
@@ -0,0 +1,24 @@
#!/bin/sh
# Flatpak entry point for the HeiniRemote agent.
#
# Two sandbox adaptations, no agent code changes:
#
# 1. The PTY console (agent's console.rs) spawns $SHELL. Inside the sandbox
# that would be a sandboxed shell showing the Flatpak filesystem — useless
# as a rescue console. Point it at the host-shell bridge instead, which
# escapes to the real host login shell via flatpak-spawn.
#
# 2. Config migration: the agent reads $XDG_CONFIG_HOME/heiniremote/agent.toml,
# which Flatpak redirects to ~/.var/app/<id>/config/. If no config exists
# there yet but a native install left one at ~/.config/heiniremote/
# (visible read-only via --filesystem=xdg-config/heiniremote:ro), use that
# via the agent's HEINIREMOTE_CONFIG override.
export SHELL=/app/bin/host-shell
if [ -z "${HEINIREMOTE_CONFIG:-}" ] \
&& [ ! -f "${XDG_CONFIG_HOME:-$HOME/.config}/heiniremote/agent.toml" ] \
&& [ -f "$HOME/.config/heiniremote/agent.toml" ]; then
export HEINIREMOTE_CONFIG="$HOME/.config/heiniremote/agent.toml"
fi
exec /app/bin/heiniremote-agent "$@"
+3 -1
View File
@@ -1,7 +1,9 @@
[Flatpak Repo] [Flatpak Repo]
Title=HeiniRemote Agent Title=HeiniRemote Agent
# The CI job regenerates this file on the 'pages' branch with the correct URL,
# so the canonical copy to use is:
# https://git.pc-heini.de/pc-heini/HeiniRemote-AgentFlatpak/raw/branch/pages/heiniremote.flatpakrepo
Url=https://git.pc-heini.de/pc-heini/HeiniRemote-AgentFlatpak/raw/branch/pages Url=https://git.pc-heini.de/pc-heini/HeiniRemote-AgentFlatpak/raw/branch/pages
RuntimeRepo=https://dl.flathub.org/repo/flathub.flatpakrepo
Homepage=https://pc-heini.de/ Homepage=https://pc-heini.de/
Comment=HeiniRemote remote maintenance agent as a Flatpak Comment=HeiniRemote remote maintenance agent as a Flatpak
Description=Install the HeiniRemote agent on any Linux distribution via Flatpak. Description=Install the HeiniRemote agent on any Linux distribution via Flatpak.
Executable
+17
View File
@@ -0,0 +1,17 @@
#!/bin/sh
# Host-shell bridge for the agent's PTY console.
#
# The wrapper sets SHELL=/app/bin/host-shell, so the agent's PTY console
# spawns this instead of a sandboxed shell. flatpak-spawn --host (requires
# --talk-name=org.freedesktop.Flatpak) runs the command on the host with the
# PTY fds forwarded, giving the remote console a real host login shell.
#
# The inner resolution runs ON THE HOST: flatpak-spawn forwards the sandbox
# environment, so $SHELL would still point at this script — resolve the user's
# real login shell from passwd instead and fix up $SHELL before exec'ing it.
exec flatpak-spawn --host /bin/sh -c '
shell="$(getent passwd "$(id -un)" | cut -d: -f7)"
[ -x "$shell" ] || shell=/bin/sh
export SHELL="$shell"
exec "$shell" -l
'
@@ -1 +0,0 @@
fd4d461eee4b8494b978aedd83bfebcfe4c16583a474bbc82dd37bc67fd8d6a8
-1
View File
@@ -1 +0,0 @@
53c3b4d3b3bd7d560edae285d7b4d4a73916c0055de25a3250afec1888089395
-1
View File
@@ -1 +0,0 @@
d5b678279e38b6410769d2e5d6a64ce818fb8a0079aa271c35a609950b0918e4
+32
View File
@@ -0,0 +1,32 @@
#!/usr/bin/env bash
# Resolve which HeiniRemote revision to package. Prints eval-able output:
# version=<x.y.z or 0.0.0-git.<sha>>
# ref=<tag name or commit sha>
#
# Prefers the newest v* release tag on the upstream repo; while no release tag
# exists yet, falls back to the tip of main. The fallback version is derived
# ONLY from the commit sha, NOT the build date: the version must be a pure
# function of the source, so the nightly cron rebuilds when main actually
# moves — not every day just because the wall clock advanced (which would spawn
# a new tag/release/bundle daily).
# UPSTREAM_URL may carry credentials (CI injects the actions token for private
# repos); only derived values are printed.
set -euo pipefail
UPSTREAM_URL="${UPSTREAM_URL:-https://git.pc-heini.de/pc-heini/HeiniRemote.git}"
tag=$(git ls-remote --tags "$UPSTREAM_URL" 'refs/tags/v*' \
| awk -F'refs/tags/' '{print $2}' \
| grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' \
| sort -V | tail -n1 || true)
if [ -n "$tag" ]; then
echo "version=${tag#v}"
echo "ref=$tag"
else
# ref must stay the full sha: `git fetch <sha>` rejects abbreviated ids.
sha=$(git ls-remote "$UPSTREAM_URL" refs/heads/main | awk '{print $1}')
[ -n "$sha" ] || { echo "ERROR: cannot resolve upstream main" >&2; exit 1; }
echo "version=0.0.0-git.${sha:0:12}"
echo "ref=$sha"
fi
+74
View File
@@ -0,0 +1,74 @@
#!/usr/bin/env bash
# Assemble the HeiniRemote agent Flatpak WITHOUT flatpak-builder.
#
# Same approach as o3de-flatpak: flatpak-builder would run build commands
# inside a bubblewrap sandbox (needs user namespaces / privileged CI). We
# don't need that — the real build (cargo) happens outside this script, and
# flatpak build-init/build-finish/build-export only touch files and the
# OSTree repo.
#
# Inputs (env):
# AGENT_BIN path to the compiled heiniremote-agent binary (required)
# WL_CLIPBOARD_DIR dir containing wl-copy/wl-paste to bundle (default /usr/bin)
#
# Produces ./repo (an OSTree repo with branch "stable").
set -euo pipefail
cd "$(dirname "$0")/.."
APP_ID=de.pc_heini.HeiniRemoteAgent
RUNTIME_VER=24.08
BRANCH=stable
AGENT_BIN="${AGENT_BIN:?set AGENT_BIN to the compiled heiniremote-agent}"
WL_DIR="${WL_CLIPBOARD_DIR:-/usr/bin}"
rm -rf build-dir repo
echo ">> build-init"
flatpak build-init build-dir "$APP_ID" org.freedesktop.Sdk org.freedesktop.Platform "$RUNTIME_VER"
DEST=build-dir/files
echo ">> installing agent + bundled tools"
install -Dm755 "$AGENT_BIN" "$DEST/bin/heiniremote-agent"
# wl-clipboard is bundled because the agent's clipboard sync shells out to it
# (clipboard.rs); the freedesktop runtime does not ship it.
install -Dm755 "$WL_DIR/wl-copy" "$DEST/bin/wl-copy"
install -Dm755 "$WL_DIR/wl-paste" "$DEST/bin/wl-paste"
install -Dm755 heiniremote-wrapper.sh "$DEST/bin/heiniremote-wrapper.sh"
install -Dm755 host-shell.sh "$DEST/bin/host-shell"
echo ">> installing desktop metadata"
install -Dm644 "$APP_ID.desktop" "$DEST/share/applications/$APP_ID.desktop"
install -Dm644 "$APP_ID.metainfo.xml" "$DEST/share/metainfo/$APP_ID.metainfo.xml"
install -Dm644 "$APP_ID.svg" "$DEST/share/icons/hicolor/scalable/apps/$APP_ID.svg"
echo ">> build-finish (sandbox permissions)"
# ScreenCast/RemoteDesktop run through xdg-desktop-portal, which sandboxed
# apps may always talk to — no extra permission needed. What IS needed:
# network signaling wss + WebRTC/TURN
# wayland wl-copy/wl-paste talk to the compositor
# dri PipeWire screencast buffers may be dmabuf
# xdg-config/heiniremote:ro adopt an existing native install's agent.toml
# StatusNotifier* tray icon (ksni); non-fatal if absent. ksni
# owns org.kde.StatusNotifierItem-{pid}-1 and
# the wrapper exec's the agent, so inside the
# sandbox the pid is deterministically 2
# org.freedesktop.Flatpak flatpak-spawn --host for the rescue console's
# real host shell — deliberate sandbox escape,
# without it the console would show the sandbox
flatpak build-finish build-dir \
--command=heiniremote-wrapper.sh \
--share=network \
--socket=wayland \
--device=dri \
--filesystem=xdg-config/heiniremote:ro \
--talk-name=org.kde.StatusNotifierWatcher \
--own-name=org.kde.StatusNotifierItem-2-1 \
--talk-name=org.freedesktop.Flatpak
echo ">> export to OSTree repo"
# --disable-sandbox: build-export validates icons in bwrap by default, which
# fails in unprivileged CI containers; this runs the same validation in-process.
flatpak build-export --disable-sandbox repo build-dir "$BRANCH"
flatpak build-update-repo repo --title="HeiniRemote Agent" --prune --prune-depth=1
echo ">> done: ./repo"
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.