Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
143 changes: 143 additions & 0 deletions .github/workflows/flatpak.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
name: Flatpak

on:
workflow_dispatch:
inputs:
release_tag:
description: 'Release tag to build the Flatpak from (leave empty to build from current commit)'
required: false
release:
types: [published]

# Builds the Drop Desktop Flatpak.
#
# Strategy: Companion to the main release workflow.
# On release, it downloads the pre-built .deb from the release assets,
# bundles system tray libraries from apt, and builds the Flatpak.
#
# For workflow_dispatch without a tag, it builds everything from source.

jobs:
flatpak-build:
runs-on: ubuntu-24.04
permissions:
contents: write

steps:
- uses: actions/checkout@v4
with:
submodules: true

- name: Install Flatpak SDK
run: |
sudo apt-get update
sudo apt-get install -y flatpak flatpak-builder
flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo

- name: Install GNOME Platform 48
run: |
flatpak install --system flathub org.gnome.Platform//48 org.gnome.Sdk//48 -y

- name: Install system tray libraries
run: |
sudo apt-get install -y \
libayatana-appindicator3-dev \
libdbusmenu-gtk3-dev

- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 10
run_install: false

- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: lts/*

- name: Install Rust
uses: dtolnay/rust-toolchain@stable

- name: Rust cache
uses: swatinem/rust-cache@v2
with:
workspaces: './src-tauri -> target'

- name: Install system deps for Tauri
run: |
sudo apt-get install -y \
libwebkit2gtk-4.1-dev \
librsvg2-dev \
patchelf \
xdg-utils

- name: Determine build mode
id: build_mode
run: |
if [[ -n "${{ github.event.inputs.release_tag }}" ]]; then
echo "source=release" >> "$GITHUB_OUTPUT"
echo "tag=${{ github.event.inputs.release_tag }}" >> "$GITHUB_OUTPUT"
elif [[ "${{ github.event_name }}" == "release" ]]; then
echo "source=release" >> "$GITHUB_OUTPUT"
echo "tag=${{ github.event.release.tag_name }}" >> "$GITHUB_OUTPUT"
else
echo "source=source" >> "$GITHUB_OUTPUT"
fi

# ── Mode A: Build from source (workflow_dispatch without tag) ──
- name: (Source) Install frontend dependencies
if: steps.build_mode.outputs.source == 'source'
run: pnpm install

- name: (Source) Build Tauri .deb
if: steps.build_mode.outputs.source == 'source'
run: pnpm tauri build --bundles deb

# ── Mode B: Download from release ──
- name: (Release) Download .deb from release
if: steps.build_mode.outputs.source == 'release'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
TAG="${{ steps.build_mode.outputs.tag }}"
gh release download "$TAG" --pattern '*_amd64.deb' --dir flatpak/
# Rename to expected path

# ── Common: Prepare inputs for flatpak-builder ──
- name: Prepare libraries and .deb for Flatpak build
run: |
# Copy system tray libraries from host
bash flatpak/prepare-libs.sh

# If we downloaded from a release, rename to expected name
if [ -z "$(ls flatpak/drop-app.deb 2>/dev/null)" ]; then
if ls flatpak/*_amd64.deb 1>/dev/null 2>&1; then
mv flatpak/*_amd64.deb flatpak/drop-app.deb
else
# Source build — create symlink
bash flatpak/prepare-deb.sh
fi
fi

- name: Build Flatpak
uses: flatpak/flatpak-github-actions/flatpak-builder@v6
with:
bundle: org.droposs.client.flatpak
manifest-path: flatpak/org.droposs.client.yml
cache-key: flatpak-${{ github.event.release.tag_name || github.sha }}
branch: master

- name: Upload Flatpak to release
if: steps.build_mode.outputs.source == 'release'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
TAG="${{ steps.build_mode.outputs.tag }}"
gh release upload "$TAG" org.droposs.client.flatpak

- name: Upload Flatpak as workflow artifact
if: steps.build_mode.outputs.source == 'source'
uses: actions/upload-artifact@v4
with:
name: org.droposs.client-flatpak
path: org.droposs.client.flatpak
51 changes: 51 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,54 @@ src-tauri/perf*
/squashfs-root

/target/

# ── GSD baseline (auto-generated) ──
.gsd
.gsd-id
.mcp.json
.bg-shell/
Thumbs.db
nul
nul.*
con
con.*
prn
prn.*
aux
aux.*
com[1-9]
com[1-9].*
lpt[1-9]
lpt[1-9].*
*.swp
*.swo
*~
.idea/
.vscode/
*.code-workspace
.env
.env.*
!.env.example
node_modules/
.next/
dist/
build/
__pycache__/
*.pyc
.venv/
venv/
target/
vendor/
coverage/
.cache/
tmp/
.agents/
skills-lock.json

# ── Flatpak build artifacts ──
.flatpak-builder/
flatpak-build-dir/
flatpak/drop-app.deb
flatpak/libs/
flatpak/deb-check/
org.droposs.client.flatpak
113 changes: 113 additions & 0 deletions flatpak/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
#!/usr/bin/env bash
# build.sh — Build the Drop Desktop Flatpak from scratch.
#
# Usage:
# ./flatpak/build.sh # Build flatpak
# ./flatpak/build.sh --bundle # Build and create portable .flatpak bundle
# ./flatpak/build.sh --clean # Clean build artifacts only
#
# Prerequisites:
# - flatpak, flatpak-builder installed
# - GNOME Platform/SDK 48 installed:
# flatpak install --user flathub org.gnome.Platform//48 org.gnome.Sdk//48
# - pnpm, node, rust/cargo installed for Tauri build
#
# The build process:
# 1. Build the Tauri app → produces .deb
# 2. Prepare system tray libraries from host
# 3. Create symlink from versioned .deb to flatpak/drop-app.deb
# 4. Run flatpak-builder
# 5. Optionally bundle to .flatpak file

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
BUNDLE_FILE="${PROJECT_DIR}/org.droposs.client.flatpak"
BUILD_DIR="${PROJECT_DIR}/flatpak-build-dir"

# ── Parse arguments ──
do_bundle=false
do_clean=false
for arg in "$@"; do
case "$arg" in
--bundle) do_bundle=true ;;
--clean) do_clean=true ;;
--help)
echo "Usage: $0 [--bundle] [--clean]"
echo " --bundle Create portable .flatpak bundle after build"
echo " --clean Remove build artifacts only"
exit 0
;;
*)
echo "Unknown option: $arg"
echo "Usage: $0 [--bundle] [--clean]"
exit 1
;;
esac
done

# ── Clean mode ──
if [ "$do_clean" = true ]; then
echo "==> Cleaning build artifacts..."
rm -rf "$BUILD_DIR"
rm -f "$SCRIPT_DIR/drop-app.deb"
rm -rf "$SCRIPT_DIR/libs"
rm -f "$BUNDLE_FILE"
rm -rf "$PROJECT_DIR/.flatpak-builder"
echo " Done."
exit 0
fi

# ── Step 0: Verify prerequisites ──
echo "==> [1/4] Verifying prerequisites..."

if ! command -v flatpak &>/dev/null; then
echo "Error: flatpak not found. Install it first." >&2
exit 1
fi
if ! command -v flatpak-builder &>/dev/null; then
echo "Error: flatpak-builder not found. Install it first." >&2
exit 1
fi

# Check GNOME runtime/SDK are available
if ! flatpak info org.gnome.Platform//48 &>/dev/null; then
echo "Installing GNOME Platform 48..."
flatpak install --user flathub org.gnome.Platform//48 org.gnome.Sdk//48 -y
fi

echo " All prerequisites met."

# ── Step 1: Build Tauri app ──
echo "==> [2/4] Building Tauri app..."
cd "$PROJECT_DIR"

# Build frontend + Tauri binary + .deb package
pnpm tauri build --bundles deb
echo " Tauri build complete."

# ── Step 2: Prepare system tray libraries ──
echo "==> [3/4] Preparing system tray libraries..."
bash "$SCRIPT_DIR/prepare-libs.sh"

# ── Step 3: Prepare .deb for flatpak ──
echo "==> [4/4] Building Flatpak..."
bash "$SCRIPT_DIR/prepare-deb.sh"

# ── Step 4: Run flatpak-builder ──
flatpak-builder --user --force-clean "$BUILD_DIR" "$SCRIPT_DIR/org.droposs.client.yml"
flatpak-builder --user --install "$BUILD_DIR" "$SCRIPT_DIR/org.droposs.client.yml"

echo ""
echo "=== Flatpak build complete ==="
echo " Run: flatpak run org.droposs.client"

# ── Optional: create portable bundle ──
if [ "$do_bundle" = true ]; then
echo "==> Creating portable bundle..."
flatpak build-bundle ~/.local/share/flatpak/repo "$BUNDLE_FILE" org.droposs.client
echo " Bundle: $BUNDLE_FILE ($(du -h "$BUNDLE_FILE" | cut -f1))"
fi

echo ""
Loading