halkyon/snap/snapcraft.yaml
Tizian 「ティツィアーン」 1f19eadd0e
fix(snap): the Store takes the snap: no mail addresses among its links
The Store refused v0.16.0's upload with "Links must be http(s):// URLs":
contact and issues held support@halkyon.app, which snapcraft's reference
allows but the Store doesn't. Both go; the address moves into the
description, where the Store page shows it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-10-14 18:23:51 +02:00

166 lines
6.6 KiB
YAML

# The Linux app as a Snap, built in LXD on a developer's machine, in the repository
# root:
#
# snapcraft pack
#
# It builds what is committed (the source is this repository's HEAD), never the
# working tree with its build caches, and always for learn.halkyon.eu. Flutter is
# pinned like the local and CI one (FLUTTER_VERSION in .forgejo/workflows/ci.yaml):
# snapcraft's own Flutter plugin can only take a channel and can't pass
# --dart-define, so the build is spelled out below.
name: halkyon-learn
title: Halkyon Learn
base: core24
adopt-info: halkyon-learn # the version, from the app's pubspec.yaml
summary: Learn with flashcards, studied offline and synced between your devices
description: |
Halkyon Learn is a spaced-repetition learning app: studysets of flashcards with
rich text, notes, learning paths and PDFs, reviewed on an FSRS schedule. It works
offline and syncs between your devices.
It starts with an anonymous account; signing in with GitHub later keeps
everything. It connects to learn.halkyon.eu, the project's instance.
Questions and reports: support@halkyon.app
license: AGPL-3.0-or-later
source-code: https://code.halkyon.app/project-halkyon/halkyon_learn
# The project's, not an instance's: the app works with any instance.
website: https://halkyon.app/learn
# No contact or issues: the Store refuses an upload whose links aren't http(s) URLs
# ("Links must be http(s):// URLs", checked with snapcraft v9.1.4 on 2026-10-14),
# though snapcraft's reference allows mail addresses there (canonical/snapcraft#6062
# asks for them). Reports come by mail until people can open an account on the issue
# tracker, so the address is in the description.
# The app's icon with rounded corners, made by tool/app_icons.py; also the desktop file's.
icon: snap/gui/halkyon-learn.png
grade: stable
confinement: strict
platforms:
amd64:
lint:
ignore:
# PDFium is loaded by name while the app runs, which the linter can't see.
- library:
- bin/lib/libpdfium.so
apps:
halkyon-learn:
command: bin/halkyon_learn_flutter
# How the session is kept: see snap/local/secret-backend.
command-chain: [bin/secret-backend]
# GTK, WebKitGTK, GStreamer and libsecret come from the GNOME runtime; files
# and the browser go through the desktop's portals.
extensions: [gnome]
plugs:
- network
# GitHub sign-in answers on a loopback address the app listens on.
- network-bind
- audio-playback
# Never connected by itself; whoever connects it by hand gets the keyring.
- password-manager-service
# Lets Serverpod hear from NetworkManager that the network went, and end
# the sync's connection at once rather than after 40 s of silence. Not
# connected by itself until the Store grants it on a forum request;
# without it the app logs the refusal once and works on.
- network-manager-observe
parts:
flutter:
plugin: nil
source: https://github.com/flutter/flutter.git
source-tag: '3.47.5'
source-depth: 1
build-packages:
- clang
- cmake
- curl
- git
- libgtk-3-dev
- lld
- llvm-18
- ninja-build
- pkg-config
- unzip
- xz-utils
- zip
override-build: |
mkdir -p "$CRAFT_PART_INSTALL/usr/libexec" "$CRAFT_PART_INSTALL/usr/bin"
cp -r "$CRAFT_PART_SRC" "$CRAFT_PART_INSTALL/usr/libexec/flutter"
ln -s ../libexec/flutter/bin/flutter "$CRAFT_PART_INSTALL/usr/bin/flutter"
ln -s ../libexec/flutter/bin/dart "$CRAFT_PART_INSTALL/usr/bin/dart"
"$CRAFT_PART_INSTALL/usr/bin/flutter" --disable-analytics
"$CRAFT_PART_INSTALL/usr/bin/flutter" precache --linux
# Needed to build, not in the Snap.
override-prime: ''
halkyon-learn:
after: [flutter]
plugin: nil
source: .
source-type: git
# The sound player links GStreamer, which the GNOME SDK lacks; the GNOME
# runtime brings the same GStreamer (1.24) to run. The video player
# (media_kit, for Jellyfin) links libmpv, which neither has: the Snap
# brings Ubuntu's libmpv2 with what it needs (ffmpeg's libraries), or the
# app wouldn't start.
build-packages:
- libgstreamer1.0-dev
- libgstreamer-plugins-base1.0-dev
- libmpv-dev
stage-packages:
- libmpv2
override-build: |
set -eu
export PATH="$CRAFT_STAGE/usr/bin:$PATH"
cd halkyon_learn_flutter
craftctl set version="$(sed -n 's/^version: *\([^+]*\).*/\1/p' pubspec.yaml)"
flutter pub get --enforce-lockfile
flutter build linux --release \
--dart-define=SERVER_URL=https://learn.halkyon.eu/
mkdir -p "$CRAFT_PART_INSTALL/bin"
cp -r build/linux/x64/release/bundle/. "$CRAFT_PART_INSTALL/bin/"
# ffmpeg's speech recognition (libsphinxbase) links libblas.so.3 and
# liblapack.so.3, which Ubuntu keeps in blas/ and lapack/ and links into
# the library folder from its packages' install scripts
# (update-alternatives), which staging never runs: without these links
# the app doesn't start. The linter doesn't notice, as the build
# machine has them.
lib="$CRAFT_PART_INSTALL/usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR"
mkdir -p "$lib"
ln -sf blas/libblas.so.3 "$lib/libblas.so.3"
ln -sf lapack/liblapack.so.3 "$lib/liblapack.so.3"
secret-backend:
plugin: dump
source: snap/local
organize:
secret-backend: bin/secret-backend
# Staged packages bring their whole dependency tree, also what the GNOME
# runtime and the base hold already: libmpv's ffmpeg brought Ubuntu's older
# librsvg, cairo, pango, harfbuzz and gdk-pixbuf, which came first on the
# library path and hid the runtime's newer ones from its GTK (its SVG
# loader failed for a function only the runtime's librsvg has). So every
# file the runtime or the base has at the same path goes, as the GNOME
# extension's reference shows, but only under usr/ and never a directory:
# its example removes every path the base has, and core24's bin and lib are
# links, so it would take the app's bin/ with them. blas/ and lapack/ stay:
# the runtime has them too, but the links into them are the app's own.
cleanup:
after: [halkyon-learn, secret-backend]
plugin: nil
build-snaps: [core24, gnome-46-2404]
override-prime: |
set -eu
for snap in core24 gnome-46-2404; do
cd "/snap/$snap/current/usr"
find . \( -type f -o -type l \) -print0 |
while IFS= read -r -d '' path; do
case "$path" in */blas/* | */lapack/*) continue ;; esac
target="$CRAFT_PRIME/usr/$path"
if [ -L "$target" ] || [ -f "$target" ]; then
rm -f "$target"
fi
done
done