From 4f35e196d1043cfd512c964f523633974c9826ec Mon Sep 17 00:00:00 2001 From: Anderson Laverde Date: Mon, 24 Aug 2026 12:31:17 +0100 Subject: [PATCH 01/13] feat: flatpak manifest and Flathub metadata Rebuilds the packaging on top of v1.0.0. The previous attempt called electron-builder's flatpak target from inside build-commands, which runs flatpak-builder inside a flatpak build; this uses `--linux dir` and assembles the flatpak around the unpacked tree instead. Runtime and base move to 24.08 with the node22 SDK extension, the git source points at the renamed repo at v1.0.0, and the AppStream metainfo and desktop entry Flathub requires are added. Refs #10 --- .gitignore | 7 ++ flatpak/README.md | 78 ++++++++++++++++++ flatpak/com.andersonlaverde.slacky.desktop | 12 +++ .../com.andersonlaverde.slacky.metainfo.xml | 72 +++++++++++++++++ flatpak/com.andersonlaverde.slacky.yml | 80 +++++++++++++++++++ flatpak/slacky.sh | 4 + 6 files changed, 253 insertions(+) create mode 100644 flatpak/README.md create mode 100644 flatpak/com.andersonlaverde.slacky.desktop create mode 100644 flatpak/com.andersonlaverde.slacky.metainfo.xml create mode 100644 flatpak/com.andersonlaverde.slacky.yml create mode 100755 flatpak/slacky.sh diff --git a/.gitignore b/.gitignore index 7fd582d..f4486c4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,10 @@ node_modules/ dist/* .DS_Store + +# flatpak build artifacts +flatpak/generated-sources.json +flatpak-node/ +flatpak-node-generator.py +.flatpak-builder/ +build-dir/ diff --git a/flatpak/README.md b/flatpak/README.md new file mode 100644 index 0000000..35e5254 --- /dev/null +++ b/flatpak/README.md @@ -0,0 +1,78 @@ +# Flatpak / Flathub packaging + +Files here build Slacky as a flatpak and prepare the Flathub submission for +[#10](https://github.com/andirsun/Slacky/issues/10). + +| File | Purpose | +| --- | --- | +| `com.andersonlaverde.slacky.yml` | flatpak-builder manifest | +| `com.andersonlaverde.slacky.metainfo.xml` | AppStream metadata (mandatory on Flathub) | +| `com.andersonlaverde.slacky.desktop` | Desktop entry | +| `slacky.sh` | Launcher, wraps the app in zypak | + +## Why this does not use electron-builder's flatpak target + +electron-builder's `flatpak` target shells out to `flatpak-builder` itself. The +first attempt at this manifest called `npm run pack -- --linux flatpak` from +inside `build-commands`, which runs flatpak-builder inside a flatpak build — that +is what wedged it. The manifest now runs `electron-builder --linux dir`, which +only produces an unpacked tree, and the flatpak is assembled around that tree. + +## Prerequisites + +flatpak-builder does not run on macOS. Build on Linux; to produce the arm64 +package you need arm64 hardware or `qemu-user-static` binfmt emulation. + +```sh +flatpak install -y flathub org.freedesktop.Platform//24.08 org.freedesktop.Sdk//24.08 \ + org.freedesktop.Sdk.Extension.node22//24.08 org.electronjs.Electron2.BaseApp//24.08 +``` + +## Generating `generated-sources.json` + +The build sandbox has no network, so every npm tarball and the Electron binary +have to be declared as sources up front. That file is generated, not written by +hand, and is not committed — regenerate it whenever `package-lock.json` changes: + +```sh +# Needs network. Run from the repo root. +pip install --user requirements-parser # dependency of the generator +curl -LO https://raw.githubusercontent.com/flatpak/flatpak-builder-tools/master/node/flatpak-node-generator.py +python3 flatpak-node-generator.py npm package-lock.json -o flatpak/generated-sources.json +``` + +The generator also emits `flatpak-node/electron-builder-arch-args.sh`, which the +manifest sources so electron-builder targets the architecture being built. + +## Building and running locally + +```sh +flatpak-builder --user --install --force-clean build-dir \ + flatpak/com.andersonlaverde.slacky.yml +flatpak run com.andersonlaverde.slacky +``` + +## Before submitting to Flathub + +- [ ] **Add a real screenshot.** `com.andersonlaverde.slacky.metainfo.xml` points + at `build/screenshots/main-window.png`, which does not exist yet. Flathub + rejects submissions whose screenshot URLs do not resolve. +- [ ] Validate the metadata: + ```sh + appstreamcli validate flatpak/com.andersonlaverde.slacky.metainfo.xml + desktop-file-validate flatpak/com.andersonlaverde.slacky.desktop + flatpak run --command=flatpak-builder-lint org.flatpak.Builder \ + manifest flatpak/com.andersonlaverde.slacky.yml + ``` +- [ ] Confirm huddles work — mic, camera and screen share — since `--device=all` + is the permission most likely to be questioned in review. +- [ ] Bump `tag:` and `commit:` in the manifest to the release being published, + and add a matching `` entry to the metainfo. +- [ ] Submit: open a pull request against + [flathub/flathub](https://github.com/flathub/flathub) on the `new-pr` + branch adding this manifest. Flathub then creates + `flathub/com.andersonlaverde.slacky`, and future releases are published by + updating the manifest in *that* repo, not this one. +- [ ] Slacky bundles no Slack trademark assets beyond the app icon; double-check + the icon before submission, since Flathub review looks at third-party + branding. diff --git a/flatpak/com.andersonlaverde.slacky.desktop b/flatpak/com.andersonlaverde.slacky.desktop new file mode 100644 index 0000000..e625ea8 --- /dev/null +++ b/flatpak/com.andersonlaverde.slacky.desktop @@ -0,0 +1,12 @@ +[Desktop Entry] +Type=Application +Name=Slacky +GenericName=Slack Client +Comment=Slack client for Linux arm64 systems +Exec=slacky %U +Icon=com.andersonlaverde.slacky +Terminal=false +Categories=Network;InstantMessaging; +Keywords=slack;chat;messaging;huddle;workspace; +StartupWMClass=Slacky +MimeType=x-scheme-handler/slack; diff --git a/flatpak/com.andersonlaverde.slacky.metainfo.xml b/flatpak/com.andersonlaverde.slacky.metainfo.xml new file mode 100644 index 0000000..8533a83 --- /dev/null +++ b/flatpak/com.andersonlaverde.slacky.metainfo.xml @@ -0,0 +1,72 @@ + + + com.andersonlaverde.slacky + + Slacky + Slack client for Linux arm64 systems + + CC0-1.0 + MIT + + + Anderson Laverde + + + +

+ Slacky is a desktop Slack client for Linux machines running on arm64 + hardware, where the official Slack desktop app is not available. It wraps + the Slack web client in a native window so it behaves like a normal + desktop application. +

+

Features:

+
    +
  • Sign in to several Slack workspaces and switch between them
  • +
  • Desktop notifications that focus the window when clicked
  • +
  • Huddles, including pop-out huddle windows
  • +
  • Google single sign-on completed inside the app
  • +
  • slack:// deep links open in Slacky rather than a browser
  • +
+
+ + com.andersonlaverde.slacky.desktop + + + + + https://raw.githubusercontent.com/andirsun/Slacky/main/build/screenshots/main-window.png + The Slack workspace running in Slacky + + + + https://github.com/andirsun/Slacky + https://github.com/andirsun/Slacky/issues + https://github.com/andirsun/Slacky + + + + intense + intense + + + + + +

+ First stable release: multiple workspaces, native huddle pop-out + windows, in-app Google SSO, window focus on notification click, and + arm64 AppImage, deb and rpm packages. +

+
+ https://github.com/andirsun/Slacky/releases/tag/v1.0.0 +
+
+
diff --git a/flatpak/com.andersonlaverde.slacky.yml b/flatpak/com.andersonlaverde.slacky.yml new file mode 100644 index 0000000..ee3595c --- /dev/null +++ b/flatpak/com.andersonlaverde.slacky.yml @@ -0,0 +1,80 @@ +app-id: com.andersonlaverde.slacky +runtime: org.freedesktop.Platform +runtime-version: '24.08' +sdk: org.freedesktop.Sdk +base: org.electronjs.Electron2.BaseApp +base-version: '24.08' +command: slacky +separate-locales: false + +sdk-extensions: + - org.freedesktop.Sdk.Extension.node22 + +finish-args: + # Electron's zygote/renderer processes talk to each other over the X11 and + # IPC sockets; without --share=ipc it falls back to slow shared memory. + - --share=ipc + - --socket=x11 + - --socket=wayland + - --share=network + # Huddles: microphone and speakers via PulseAudio, GPU acceleration and the + # webcam via --device=all. Screen sharing goes through the portal, which is + # available to every sandbox by default. + # + # --device=all is broader than --device=dri and a Flathub reviewer may ask + # about it. It is here because Chromium reaches /dev/video* directly for + # getUserMedia rather than going through the camera portal; narrow this to + # --device=dri if huddle video ever works without it. + - --socket=pulseaudio + - --device=all + # Desktop notifications and the tray icon. + - --talk-name=org.freedesktop.Notifications + - --talk-name=org.kde.StatusNotifierWatcher + # File uploads and downloads land in the usual places. + - --filesystem=xdg-download + - --filesystem=xdg-documents + - --filesystem=xdg-pictures:ro + +modules: + - name: slacky + buildsystem: simple + build-options: + append-path: /usr/lib/sdk/node22/bin + env: + # Everything below keeps npm and electron-builder from touching the + # network, which the flatpak build sandbox does not have. The caches + # are pre-populated by the sources in generated-sources.json. + XDG_CACHE_HOME: /run/build/slacky/flatpak-node/cache + npm_config_cache: /run/build/slacky/flatpak-node/npm-cache + npm_config_nodedir: /usr/lib/sdk/node22 + npm_config_offline: 'true' + ELECTRON_SKIP_BINARY_DOWNLOAD: '1' + ELECTRON_CACHE: /run/build/slacky/flatpak-node/electron-cache + electron_config_cache: /run/build/slacky/flatpak-node/electron-cache + ELECTRON_BUILDER_CACHE: /run/build/slacky/flatpak-node/electron-builder-cache + build-commands: + - npm ci --offline + - npm run build + # Source the arch args generated by flatpak-node-generator so the build + # targets the architecture flatpak-builder is building for. + - . flatpak-node/electron-builder-arch-args.sh + # `--linux dir` produces an unpacked tree and nothing else. Do NOT use + # electron-builder's own `flatpak` target here: it shells out to + # flatpak-builder, and running flatpak-builder inside a flatpak build is + # what wedged the original attempt at this manifest. + - ./node_modules/.bin/electron-builder --linux dir $ELECTRON_BUILDER_ARCH_ARGS + - mkdir -p /app/main + - cp -a dist/packages/linux*unpacked/* /app/main/ + # zypak lets Electron's sandbox work inside flatpak's own sandbox. + - install -Dm755 flatpak/slacky.sh /app/bin/slacky + - install -Dm644 build/icons/icon.png /app/share/icons/hicolor/512x512/apps/com.andersonlaverde.slacky.png + - install -Dm644 flatpak/com.andersonlaverde.slacky.desktop /app/share/applications/com.andersonlaverde.slacky.desktop + - install -Dm644 flatpak/com.andersonlaverde.slacky.metainfo.xml /app/share/metainfo/com.andersonlaverde.slacky.metainfo.xml + sources: + - type: git + url: https://github.com/andirsun/Slacky.git + tag: v1.0.0 + # Keep this commit in sync with the tag above; Flathub requires both. + commit: c0dbd8fe2dd6602574f501454e518f17d1236a92 + # Generated by flatpak-node-generator, see flatpak/README.md. + - generated-sources.json diff --git a/flatpak/slacky.sh b/flatpak/slacky.sh new file mode 100755 index 0000000..951c9c3 --- /dev/null +++ b/flatpak/slacky.sh @@ -0,0 +1,4 @@ +#!/bin/bash +# Electron ships its own sandbox, which cannot nest inside flatpak's. zypak +# redirects it onto the flatpak sandbox instead of disabling it. +exec zypak-wrapper.sh /app/main/slacky "$@" From e010a10ecd937fa89f2fcb998a1c5962c7438b29 Mon Sep 17 00:00:00 2001 From: Anderson Laverde Date: Mon, 24 Aug 2026 12:39:03 +0100 Subject: [PATCH 02/13] ci: build the flatpak on arm64 for every packaging change Builds the manifest on ubuntu-24.04-arm and uploads the bundle as an artifact, plus a job validating the AppStream and desktop metadata. CI generates generated-sources.json and swaps the manifest's git source for a dir source so it builds the commit under test instead of the last published tag. Refs #10 --- .github/workflows/flatpak.yml | 108 ++++++++++++++++++++++++++++++++++ flatpak/README.md | 13 ++++ 2 files changed, 121 insertions(+) create mode 100644 .github/workflows/flatpak.yml diff --git a/.github/workflows/flatpak.yml b/.github/workflows/flatpak.yml new file mode 100644 index 0000000..3c5b35e --- /dev/null +++ b/.github/workflows/flatpak.yml @@ -0,0 +1,108 @@ +name: Flatpak + +on: + push: + branches: [main] + paths: ['flatpak/**', 'src/**', 'package.json', 'package-lock.json', 'electron-builder.yml', '.github/workflows/flatpak.yml'] + pull_request: + paths: ['flatpak/**', 'src/**', 'package.json', 'package-lock.json', 'electron-builder.yml', '.github/workflows/flatpak.yml'] + workflow_dispatch: + +concurrency: + group: flatpak-${{ github.ref }} + cancel-in-progress: true + +env: + MANIFEST: flatpak/com.andersonlaverde.slacky.yml + APP_ID: com.andersonlaverde.slacky + +jobs: + metadata: + name: Validate metadata + runs-on: ubuntu-24.04-arm + steps: + - uses: actions/checkout@v4 + + - name: Install validators + run: | + sudo apt-get update + sudo apt-get install -y --no-install-recommends appstream desktop-file-utils + + - name: Validate AppStream metainfo + run: appstreamcli validate --explain flatpak/${{ env.APP_ID }}.metainfo.xml + + - name: Validate desktop entry + run: desktop-file-validate flatpak/${{ env.APP_ID }}.desktop + + build: + name: Build flatpak (arm64) + runs-on: ubuntu-24.04-arm + timeout-minutes: 90 + steps: + - uses: actions/checkout@v4 + + - name: Install flatpak-builder + run: | + sudo apt-get update + sudo apt-get install -y --no-install-recommends flatpak flatpak-builder + flatpak remote-add --user --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo + + - name: Install runtimes + run: | + flatpak install --user -y --noninteractive flathub \ + org.freedesktop.Platform//24.08 \ + org.freedesktop.Sdk//24.08 \ + org.freedesktop.Sdk.Extension.node22//24.08 \ + org.electronjs.Electron2.BaseApp//24.08 + + # The build sandbox has no network, so every npm tarball and the Electron + # binary have to be declared as sources up front. See flatpak/README.md. + - name: Generate offline npm sources + run: | + python3 -m venv .venv + .venv/bin/pip install --quiet aiohttp requirements-parser PyYAML + curl -sSfLO https://raw.githubusercontent.com/flatpak/flatpak-builder-tools/master/node/flatpak-node-generator.py + .venv/bin/python flatpak-node-generator.py npm package-lock.json -o flatpak/generated-sources.json + + # The committed manifest builds a published tag, which is what Flathub + # needs but would make CI test the last release instead of this commit. + # Swap that one source for the checked-out tree. + - name: Point the manifest at the checked-out tree + run: | + .venv/bin/python - <<'PY' + import yaml, os + path = os.environ['MANIFEST'] + with open(path) as f: + manifest = yaml.safe_load(f) + sources = manifest['modules'][0]['sources'] + sources[:] = [ + {'type': 'dir', 'path': '..', 'skip': ['.git', '.venv', 'node_modules', 'dist', 'build-dir']} + if isinstance(s, dict) and s.get('type') == 'git' else s + for s in sources + ] + with open(path, 'w') as f: + yaml.safe_dump(manifest, f, sort_keys=False) + PY + cat "$MANIFEST" + + - name: Cache build downloads + uses: actions/cache@v4 + with: + path: .flatpak-builder/downloads + key: flatpak-downloads-${{ hashFiles('package-lock.json') }} + restore-keys: flatpak-downloads- + + - name: Build + run: | + flatpak-builder --user --force-clean --disable-rofiles-fuse \ + --repo=repo build-dir "$MANIFEST" + + - name: Bundle + run: | + flatpak build-bundle repo slacky.flatpak "$APP_ID" --runtime-repo=https://dl.flathub.org/repo/flathub.flatpakrepo + + - uses: actions/upload-artifact@v4 + with: + name: slacky-flatpak-arm64 + path: slacky.flatpak + if-no-files-found: error diff --git a/flatpak/README.md b/flatpak/README.md index 35e5254..105477e 100644 --- a/flatpak/README.md +++ b/flatpak/README.md @@ -44,6 +44,19 @@ python3 flatpak-node-generator.py npm package-lock.json -o flatpak/generated-sou The generator also emits `flatpak-node/electron-builder-arch-args.sh`, which the manifest sources so electron-builder targets the architecture being built. +## CI + +`.github/workflows/flatpak.yml` builds this manifest on `ubuntu-24.04-arm` for +every pull request that touches the app or the packaging, and uploads the +resulting `slacky.flatpak` as a run artifact you can install with +`flatpak install --user slacky.flatpak`. A separate job validates the AppStream +and desktop metadata. + +CI generates `generated-sources.json` itself, and rewrites the manifest's `git` +source to a `dir` source so it builds the commit under test rather than the last +published tag. The committed manifest keeps the `git` source, which is what +Flathub requires. + ## Building and running locally ```sh From 6479b637b88490169b18dd5beafb001d09c9d832 Mon Sep 17 00:00:00 2001 From: Anderson Laverde Date: Mon, 24 Aug 2026 12:43:32 +0100 Subject: [PATCH 03/13] fix: correct the flatpak manifest against the upstream reference Aligns with flatpak-builder-tools' electron-builder example: - drop ELECTRON_SKIP_BINARY_DOWNLOAD, which would have stopped the Electron binary from being unpacked at all, plus the redundant cache variables that XDG_CACHE_HOME already covers - source electron-builder-arch-args.sh in the same command that uses it, since each build-command runs in its own shell - zypak-wrapper, not zypak-wrapper.sh - npm install --offline, matching the npm example - pin executableName so the wrapper can rely on /app/main/slacky Also installs flatpak-node-generator from its pip package; the single file script the workflow fetched no longer exists upstream (404). Refs #10 --- .github/workflows/flatpak.yml | 27 ++++++++++++++++++++++---- electron-builder.yml | 3 +++ flatpak/com.andersonlaverde.slacky.yml | 25 ++++++++++-------------- flatpak/slacky.sh | 2 +- 4 files changed, 37 insertions(+), 20 deletions(-) diff --git a/.github/workflows/flatpak.yml b/.github/workflows/flatpak.yml index 3c5b35e..419c892 100644 --- a/.github/workflows/flatpak.yml +++ b/.github/workflows/flatpak.yml @@ -28,8 +28,27 @@ jobs: sudo apt-get update sudo apt-get install -y --no-install-recommends appstream desktop-file-utils + # --no-net keeps this to structural validation. The screenshot URL is + # checked separately below, because it is a Flathub submission + # requirement rather than something that blocks a build. - name: Validate AppStream metainfo - run: appstreamcli validate --explain flatpak/${{ env.APP_ID }}.metainfo.xml + run: appstreamcli validate --explain --no-net flatpak/${{ env.APP_ID }}.metainfo.xml + + - name: Check screenshots resolve + run: | + urls=$(grep -oP '(?<=)[^<]+' flatpak/${{ env.APP_ID }}.metainfo.xml) + missing=0 + for url in $urls; do + if curl -sSfLI --max-time 30 "$url" >/dev/null 2>&1; then + echo "ok $url" + else + echo "::warning file=flatpak/${{ env.APP_ID }}.metainfo.xml::Screenshot $url does not resolve. Flathub rejects submissions with unreachable screenshots." + missing=1 + fi + done + if [ "$missing" = 1 ]; then + echo "Screenshots are still outstanding; see the checklist in flatpak/README.md." + fi - name: Validate desktop entry run: desktop-file-validate flatpak/${{ env.APP_ID }}.desktop @@ -60,9 +79,9 @@ jobs: - name: Generate offline npm sources run: | python3 -m venv .venv - .venv/bin/pip install --quiet aiohttp requirements-parser PyYAML - curl -sSfLO https://raw.githubusercontent.com/flatpak/flatpak-builder-tools/master/node/flatpak-node-generator.py - .venv/bin/python flatpak-node-generator.py npm package-lock.json -o flatpak/generated-sources.json + .venv/bin/pip install --quiet PyYAML \ + 'flatpak-node-generator @ git+https://github.com/flatpak/flatpak-builder-tools.git#subdirectory=node' + .venv/bin/flatpak-node-generator npm package-lock.json -o flatpak/generated-sources.json # The committed manifest builds a published tag, which is what Flathub # needs but would make CI test the last release instead of this commit. diff --git a/electron-builder.yml b/electron-builder.yml index 2b5bb6e..ac5df49 100644 --- a/electron-builder.yml +++ b/electron-builder.yml @@ -17,6 +17,9 @@ protocols: linux: category: Network synopsis: Slack client for Linux arm64 systems + # Pinned so the binary inside the unpacked build has a predictable name; the + # flatpak wrapper in flatpak/slacky.sh execs /app/main/slacky. + executableName: slacky target: - target: AppImage arch: diff --git a/flatpak/com.andersonlaverde.slacky.yml b/flatpak/com.andersonlaverde.slacky.yml index ee3595c..9a72d64 100644 --- a/flatpak/com.andersonlaverde.slacky.yml +++ b/flatpak/com.andersonlaverde.slacky.yml @@ -41,30 +41,25 @@ modules: build-options: append-path: /usr/lib/sdk/node22/bin env: - # Everything below keeps npm and electron-builder from touching the - # network, which the flatpak build sandbox does not have. The caches - # are pre-populated by the sources in generated-sources.json. + # The build sandbox has no network. Both caches are pre-populated by + # the sources in generated-sources.json; electron-builder finds the + # Electron binaries it needs under XDG_CACHE_HOME. + # (The directory format is /run/build/MODULE_NAME/flatpak-node/...) XDG_CACHE_HOME: /run/build/slacky/flatpak-node/cache npm_config_cache: /run/build/slacky/flatpak-node/npm-cache - npm_config_nodedir: /usr/lib/sdk/node22 - npm_config_offline: 'true' - ELECTRON_SKIP_BINARY_DOWNLOAD: '1' - ELECTRON_CACHE: /run/build/slacky/flatpak-node/electron-cache - electron_config_cache: /run/build/slacky/flatpak-node/electron-cache - ELECTRON_BUILDER_CACHE: /run/build/slacky/flatpak-node/electron-builder-cache build-commands: - - npm ci --offline + - npm install --offline - npm run build - # Source the arch args generated by flatpak-node-generator so the build - # targets the architecture flatpak-builder is building for. - - . flatpak-node/electron-builder-arch-args.sh # `--linux dir` produces an unpacked tree and nothing else. Do NOT use # electron-builder's own `flatpak` target here: it shells out to # flatpak-builder, and running flatpak-builder inside a flatpak build is # what wedged the original attempt at this manifest. - - ./node_modules/.bin/electron-builder --linux dir $ELECTRON_BUILDER_ARCH_ARGS + # + # The arch args generated by flatpak-node-generator have to be sourced in + # the same command that uses them: each build-command gets its own shell. + - . flatpak-node/electron-builder-arch-args.sh; ./node_modules/.bin/electron-builder --linux dir $ELECTRON_BUILDER_ARCH_ARGS - mkdir -p /app/main - - cp -a dist/packages/linux*unpacked/* /app/main/ + - cp -a dist/packages/linux*unpacked/. /app/main/ # zypak lets Electron's sandbox work inside flatpak's own sandbox. - install -Dm755 flatpak/slacky.sh /app/bin/slacky - install -Dm644 build/icons/icon.png /app/share/icons/hicolor/512x512/apps/com.andersonlaverde.slacky.png diff --git a/flatpak/slacky.sh b/flatpak/slacky.sh index 951c9c3..2890f5a 100755 --- a/flatpak/slacky.sh +++ b/flatpak/slacky.sh @@ -1,4 +1,4 @@ #!/bin/bash # Electron ships its own sandbox, which cannot nest inside flatpak's. zypak # redirects it onto the flatpak sandbox instead of disabling it. -exec zypak-wrapper.sh /app/main/slacky "$@" +exec zypak-wrapper /app/main/slacky "$@" From c505f3cabc234b3807663e76284f8abb467f9e20 Mon Sep 17 00:00:00 2001 From: Anderson Laverde Date: Mon, 24 Aug 2026 12:59:57 +0100 Subject: [PATCH 04/13] ci: cache flatpak runtimes and retry flathub downloads dl.flathub.org timed out after six minutes on the first real run. The runtimes are now cached between runs and every flathub call retries. Also bumps the actions to clear a Node 20 deprecation warning. --- .github/workflows/flatpak.yml | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/.github/workflows/flatpak.yml b/.github/workflows/flatpak.yml index 419c892..672f501 100644 --- a/.github/workflows/flatpak.yml +++ b/.github/workflows/flatpak.yml @@ -21,7 +21,7 @@ jobs: name: Validate metadata runs-on: ubuntu-24.04-arm steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v7 - name: Install validators run: | @@ -58,17 +58,34 @@ jobs: runs-on: ubuntu-24.04-arm timeout-minutes: 90 steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v7 - name: Install flatpak-builder run: | sudo apt-get update sudo apt-get install -y --no-install-recommends flatpak flatpak-builder - flatpak remote-add --user --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo + + # ~1.5 GB of runtimes, and dl.flathub.org times out often enough to + # matter. Exact key only: a half-restored ostree repo is worse than none, + # and the install step below repairs anything the cache got wrong. + - name: Cache flatpak runtimes + uses: actions/cache@v6 + with: + path: ~/.local/share/flatpak + key: flatpak-runtimes-24.08-node22-electron2 - name: Install runtimes run: | - flatpak install --user -y --noninteractive flathub \ + retry() { + for attempt in 1 2 3; do + "$@" && return 0 + echo "::warning::flathub attempt $attempt failed, retrying in 30s" + sleep 30 + done + return 1 + } + retry flatpak remote-add --user --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo + retry flatpak install --user -y --noninteractive flathub \ org.freedesktop.Platform//24.08 \ org.freedesktop.Sdk//24.08 \ org.freedesktop.Sdk.Extension.node22//24.08 \ @@ -105,7 +122,7 @@ jobs: cat "$MANIFEST" - name: Cache build downloads - uses: actions/cache@v4 + uses: actions/cache@v6 with: path: .flatpak-builder/downloads key: flatpak-downloads-${{ hashFiles('package-lock.json') }} @@ -120,7 +137,7 @@ jobs: run: | flatpak build-bundle repo slacky.flatpak "$APP_ID" --runtime-repo=https://dl.flathub.org/repo/flathub.flatpakrepo - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v7 with: name: slacky-flatpak-arm64 path: slacky.flatpak From b506497778b11beec8d48b9355ccf3d0efb08370 Mon Sep 17 00:00:00 2001 From: Anderson Laverde Date: Mon, 24 Aug 2026 13:11:16 +0100 Subject: [PATCH 05/13] ci: use the node24 SDK extension A single node22 object failed to transfer from dl.flathub.org with an HTTP/2 stream error on every retry. node24 is also what the upstream flatpak-builder-tools electron-builder example targets on 24.08. --- .github/workflows/flatpak.yml | 4 ++-- flatpak/README.md | 2 +- flatpak/com.andersonlaverde.slacky.yml | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/flatpak.yml b/.github/workflows/flatpak.yml index 672f501..afc0758 100644 --- a/.github/workflows/flatpak.yml +++ b/.github/workflows/flatpak.yml @@ -72,7 +72,7 @@ jobs: uses: actions/cache@v6 with: path: ~/.local/share/flatpak - key: flatpak-runtimes-24.08-node22-electron2 + key: flatpak-runtimes-24.08-node24-electron2 - name: Install runtimes run: | @@ -88,7 +88,7 @@ jobs: retry flatpak install --user -y --noninteractive flathub \ org.freedesktop.Platform//24.08 \ org.freedesktop.Sdk//24.08 \ - org.freedesktop.Sdk.Extension.node22//24.08 \ + org.freedesktop.Sdk.Extension.node24//24.08 \ org.electronjs.Electron2.BaseApp//24.08 # The build sandbox has no network, so every npm tarball and the Electron diff --git a/flatpak/README.md b/flatpak/README.md index 105477e..4836f16 100644 --- a/flatpak/README.md +++ b/flatpak/README.md @@ -25,7 +25,7 @@ package you need arm64 hardware or `qemu-user-static` binfmt emulation. ```sh flatpak install -y flathub org.freedesktop.Platform//24.08 org.freedesktop.Sdk//24.08 \ - org.freedesktop.Sdk.Extension.node22//24.08 org.electronjs.Electron2.BaseApp//24.08 + org.freedesktop.Sdk.Extension.node24//24.08 org.electronjs.Electron2.BaseApp//24.08 ``` ## Generating `generated-sources.json` diff --git a/flatpak/com.andersonlaverde.slacky.yml b/flatpak/com.andersonlaverde.slacky.yml index 9a72d64..1245efa 100644 --- a/flatpak/com.andersonlaverde.slacky.yml +++ b/flatpak/com.andersonlaverde.slacky.yml @@ -8,7 +8,7 @@ command: slacky separate-locales: false sdk-extensions: - - org.freedesktop.Sdk.Extension.node22 + - org.freedesktop.Sdk.Extension.node24 finish-args: # Electron's zygote/renderer processes talk to each other over the X11 and @@ -39,7 +39,7 @@ modules: - name: slacky buildsystem: simple build-options: - append-path: /usr/lib/sdk/node22/bin + append-path: /usr/lib/sdk/node24/bin env: # The build sandbox has no network. Both caches are pre-populated by # the sources in generated-sources.json; electron-builder finds the From 56c9944f9c653d59050d7c12875ca1f1bee2dd3e Mon Sep 17 00:00:00 2001 From: Anderson Laverde Date: Mon, 24 Aug 2026 13:15:56 +0100 Subject: [PATCH 06/13] ci: back off further on flathub download failures dl.flathub.org is serving the Node SDK extension truncated (3 MiB of a 22 MB object) or 503. Five attempts with exponential backoff so a transient spell resolves itself instead of failing the run. --- .github/workflows/flatpak.yml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/.github/workflows/flatpak.yml b/.github/workflows/flatpak.yml index afc0758..e63dec0 100644 --- a/.github/workflows/flatpak.yml +++ b/.github/workflows/flatpak.yml @@ -76,11 +76,16 @@ jobs: - name: Install runtimes run: | + # dl.flathub.org has served truncated objects and 503s for the Node + # SDK extension. Back off far enough to ride out a bad spell rather + # than hammering a CDN that is already unwell. retry() { - for attempt in 1 2 3; do + delay=30 + for attempt in 1 2 3 4 5; do "$@" && return 0 - echo "::warning::flathub attempt $attempt failed, retrying in 30s" - sleep 30 + echo "::warning::flathub attempt $attempt failed, retrying in ${delay}s" + sleep $delay + delay=$((delay * 2)) done return 1 } From 5834b96568a0303008770e72732a7c02cd67775f Mon Sep 17 00:00:00 2001 From: Anderson Laverde Date: Mon, 24 Aug 2026 13:33:51 +0100 Subject: [PATCH 07/13] ci: generate the offline sources before installing runtimes Fail on our own inputs before spending six minutes pulling 1.5 GB of runtimes, and keep the generator step testable while dl.flathub.org is unhealthy. --- .github/workflows/flatpak.yml | 60 +++++++++++++++++------------------ 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/.github/workflows/flatpak.yml b/.github/workflows/flatpak.yml index e63dec0..27a74b5 100644 --- a/.github/workflows/flatpak.yml +++ b/.github/workflows/flatpak.yml @@ -60,6 +60,36 @@ jobs: steps: - uses: actions/checkout@v7 + # The build sandbox has no network, so every npm tarball and the Electron + # binary have to be declared as sources up front. See flatpak/README.md. + - name: Generate offline npm sources + run: | + python3 -m venv .venv + .venv/bin/pip install --quiet PyYAML \ + 'flatpak-node-generator @ git+https://github.com/flatpak/flatpak-builder-tools.git#subdirectory=node' + .venv/bin/flatpak-node-generator npm package-lock.json -o flatpak/generated-sources.json + + # The committed manifest builds a published tag, which is what Flathub + # needs but would make CI test the last release instead of this commit. + # Swap that one source for the checked-out tree. + - name: Point the manifest at the checked-out tree + run: | + .venv/bin/python - <<'PY' + import yaml, os + path = os.environ['MANIFEST'] + with open(path) as f: + manifest = yaml.safe_load(f) + sources = manifest['modules'][0]['sources'] + sources[:] = [ + {'type': 'dir', 'path': '..', 'skip': ['.git', '.venv', 'node_modules', 'dist', 'build-dir']} + if isinstance(s, dict) and s.get('type') == 'git' else s + for s in sources + ] + with open(path, 'w') as f: + yaml.safe_dump(manifest, f, sort_keys=False) + PY + cat "$MANIFEST" + - name: Install flatpak-builder run: | sudo apt-get update @@ -96,36 +126,6 @@ jobs: org.freedesktop.Sdk.Extension.node24//24.08 \ org.electronjs.Electron2.BaseApp//24.08 - # The build sandbox has no network, so every npm tarball and the Electron - # binary have to be declared as sources up front. See flatpak/README.md. - - name: Generate offline npm sources - run: | - python3 -m venv .venv - .venv/bin/pip install --quiet PyYAML \ - 'flatpak-node-generator @ git+https://github.com/flatpak/flatpak-builder-tools.git#subdirectory=node' - .venv/bin/flatpak-node-generator npm package-lock.json -o flatpak/generated-sources.json - - # The committed manifest builds a published tag, which is what Flathub - # needs but would make CI test the last release instead of this commit. - # Swap that one source for the checked-out tree. - - name: Point the manifest at the checked-out tree - run: | - .venv/bin/python - <<'PY' - import yaml, os - path = os.environ['MANIFEST'] - with open(path) as f: - manifest = yaml.safe_load(f) - sources = manifest['modules'][0]['sources'] - sources[:] = [ - {'type': 'dir', 'path': '..', 'skip': ['.git', '.venv', 'node_modules', 'dist', 'build-dir']} - if isinstance(s, dict) and s.get('type') == 'git' else s - for s in sources - ] - with open(path, 'w') as f: - yaml.safe_dump(manifest, f, sort_keys=False) - PY - cat "$MANIFEST" - - name: Cache build downloads uses: actions/cache@v6 with: From 1944a7ec07e97d5e9ba8e273e9fd4d229fa7817a Mon Sep 17 00:00:00 2001 From: Anderson Laverde Date: Tue, 25 Aug 2026 08:16:56 +0100 Subject: [PATCH 08/13] ci: stop sleeping after the final flathub attempt The loop slept after every failed attempt including the last, so a doomed run burned an extra eight minutes before giving up. --- .github/workflows/flatpak.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/flatpak.yml b/.github/workflows/flatpak.yml index 27a74b5..6ee2d92 100644 --- a/.github/workflows/flatpak.yml +++ b/.github/workflows/flatpak.yml @@ -110,14 +110,18 @@ jobs: # SDK extension. Back off far enough to ride out a bad spell rather # than hammering a CDN that is already unwell. retry() { + attempts=4 delay=30 - for attempt in 1 2 3 4 5; do + for attempt in $(seq $attempts); do "$@" && return 0 + if [ "$attempt" -eq "$attempts" ]; then + echo "::error::flathub failed $attempts times, giving up" + return 1 + fi echo "::warning::flathub attempt $attempt failed, retrying in ${delay}s" sleep $delay delay=$((delay * 2)) done - return 1 } retry flatpak remote-add --user --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo retry flatpak install --user -y --noninteractive flathub \ From 8c5db33f94215e37cbb548bfe41f43a8a6d82b95 Mon Sep 17 00:00:00 2001 From: Anderson Laverde Date: Tue, 25 Aug 2026 08:19:23 +0100 Subject: [PATCH 09/13] build: vendor Node instead of the flathub SDK extension dl.flathub.org serves org.freedesktop.Sdk.Extension.node24's aarch64 objects broken, which blocked every build at the runtime install. Node now comes from nodejs.org as a build-only module, dropped from the finished flatpak with cleanup. This is temporary. The SDK extension is what Flathub reviewers expect, so revert once upstream is healthy. Also fixes the README's generator instructions, which still described the single-file script upstream deleted. --- .github/workflows/flatpak.yml | 6 ++++-- flatpak/README.md | 17 +++++++++++++---- flatpak/com.andersonlaverde.slacky.yml | 26 ++++++++++++++++++++++---- 3 files changed, 39 insertions(+), 10 deletions(-) diff --git a/.github/workflows/flatpak.yml b/.github/workflows/flatpak.yml index 6ee2d92..bf1afe4 100644 --- a/.github/workflows/flatpak.yml +++ b/.github/workflows/flatpak.yml @@ -102,7 +102,7 @@ jobs: uses: actions/cache@v6 with: path: ~/.local/share/flatpak - key: flatpak-runtimes-24.08-node24-electron2 + key: flatpak-runtimes-24.08-electron2 - name: Install runtimes run: | @@ -124,10 +124,12 @@ jobs: done } retry flatpak remote-add --user --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo + # The Node SDK extension is deliberately absent: the manifest vendors + # Node from nodejs.org while dl.flathub.org serves that extension + # broken. See the comment in the manifest. retry flatpak install --user -y --noninteractive flathub \ org.freedesktop.Platform//24.08 \ org.freedesktop.Sdk//24.08 \ - org.freedesktop.Sdk.Extension.node24//24.08 \ org.electronjs.Electron2.BaseApp//24.08 - name: Cache build downloads diff --git a/flatpak/README.md b/flatpak/README.md index 4836f16..3282689 100644 --- a/flatpak/README.md +++ b/flatpak/README.md @@ -25,9 +25,19 @@ package you need arm64 hardware or `qemu-user-static` binfmt emulation. ```sh flatpak install -y flathub org.freedesktop.Platform//24.08 org.freedesktop.Sdk//24.08 \ - org.freedesktop.Sdk.Extension.node24//24.08 org.electronjs.Electron2.BaseApp//24.08 + org.electronjs.Electron2.BaseApp//24.08 ``` +## Node comes from nodejs.org, temporarily + +This manifest would normally build against +`org.freedesktop.Sdk.Extension.node24`. dl.flathub.org is currently serving +that extension's `aarch64/24.08` objects broken — HTTP 503, or a 22,509,726 +byte object truncated at exactly 3 MiB — so the manifest vendors Node from +nodejs.org as a build-only module instead, and drops it from the finished +flatpak with `cleanup`. Switch back to the SDK extension once upstream is +fixed; that is what Flathub reviewers expect to see. + ## Generating `generated-sources.json` The build sandbox has no network, so every npm tarball and the Electron binary @@ -36,9 +46,8 @@ hand, and is not committed — regenerate it whenever `package-lock.json` change ```sh # Needs network. Run from the repo root. -pip install --user requirements-parser # dependency of the generator -curl -LO https://raw.githubusercontent.com/flatpak/flatpak-builder-tools/master/node/flatpak-node-generator.py -python3 flatpak-node-generator.py npm package-lock.json -o flatpak/generated-sources.json +pipx install 'git+https://github.com/flatpak/flatpak-builder-tools.git#subdirectory=node' +flatpak-node-generator npm package-lock.json -o flatpak/generated-sources.json ``` The generator also emits `flatpak-node/electron-builder-arch-args.sh`, which the diff --git a/flatpak/com.andersonlaverde.slacky.yml b/flatpak/com.andersonlaverde.slacky.yml index 1245efa..ad40caf 100644 --- a/flatpak/com.andersonlaverde.slacky.yml +++ b/flatpak/com.andersonlaverde.slacky.yml @@ -7,9 +7,6 @@ base-version: '24.08' command: slacky separate-locales: false -sdk-extensions: - - org.freedesktop.Sdk.Extension.node24 - finish-args: # Electron's zygote/renderer processes talk to each other over the X11 and # IPC sockets; without --share=ipc it falls back to slow shared memory. @@ -36,10 +33,31 @@ finish-args: - --filesystem=xdg-pictures:ro modules: + # TEMPORARY: this should be `sdk-extensions: [org.freedesktop.Sdk.Extension.node24]` + # with `append-path: /usr/lib/sdk/node24/bin` on the module below. + # dl.flathub.org is serving that extension's aarch64/24.08 objects broken + # (HTTP 503, or a 22 MB object truncated at exactly 3 MiB), so Node comes + # from nodejs.org instead. Revert to the SDK extension once that is fixed. + # + # `cleanup: ['*']` drops everything this module installs from the finished + # flatpak: Node is needed to build, not to run. + - name: node + buildsystem: simple + cleanup: + - '*' + build-commands: + - cp -a bin include lib share /app/ + sources: + - type: archive + url: https://nodejs.org/dist/v24.19.0/node-v24.19.0-linux-arm64.tar.xz + sha256: 01443c1e1a29e531ccad5a46fefa6df490d2189c49f7955904aecdbb0fe86fdc + only-arches: + - aarch64 + - name: slacky buildsystem: simple build-options: - append-path: /usr/lib/sdk/node24/bin + append-path: /app/bin env: # The build sandbox has no network. Both caches are pre-populated by # the sources in generated-sources.json; electron-builder finds the From fb17603f384e7f6d1940ca441e6fe50af2beab9e Mon Sep 17 00:00:00 2001 From: Anderson Laverde Date: Tue, 25 Aug 2026 08:22:41 +0100 Subject: [PATCH 10/13] fix: stop flatpak-builder stripping prebuilt binaries The build reached the node module and failed on eu-strip. Node and Electron both ship prebuilt, so debuginfo extraction yields nothing; elfutils is installed on the runner as well so the strip path works if anything else needs it. --- .github/workflows/flatpak.yml | 2 +- flatpak/com.andersonlaverde.slacky.yml | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/flatpak.yml b/.github/workflows/flatpak.yml index bf1afe4..39e1ad3 100644 --- a/.github/workflows/flatpak.yml +++ b/.github/workflows/flatpak.yml @@ -93,7 +93,7 @@ jobs: - name: Install flatpak-builder run: | sudo apt-get update - sudo apt-get install -y --no-install-recommends flatpak flatpak-builder + sudo apt-get install -y --no-install-recommends flatpak flatpak-builder elfutils # ~1.5 GB of runtimes, and dl.flathub.org times out often enough to # matter. Exact key only: a half-restored ostree repo is worse than none, diff --git a/flatpak/com.andersonlaverde.slacky.yml b/flatpak/com.andersonlaverde.slacky.yml index ad40caf..20e0447 100644 --- a/flatpak/com.andersonlaverde.slacky.yml +++ b/flatpak/com.andersonlaverde.slacky.yml @@ -45,6 +45,11 @@ modules: buildsystem: simple cleanup: - '*' + build-options: + # Node ships prebuilt and this module is discarded anyway, so there is + # nothing worth extracting debuginfo from. + no-debuginfo: true + strip: false build-commands: - cp -a bin include lib share /app/ sources: @@ -58,6 +63,9 @@ modules: buildsystem: simple build-options: append-path: /app/bin + # Electron's binaries are prebuilt and already stripped; extracting + # debuginfo from them yields nothing and costs minutes. + no-debuginfo: true env: # The build sandbox has no network. Both caches are pre-populated by # the sources in generated-sources.json; electron-builder finds the From 7ab93a9da1fab7670b5e0fe654def24e4727d413 Mon Sep 17 00:00:00 2001 From: Anderson Laverde Date: Tue, 25 Aug 2026 08:25:58 +0100 Subject: [PATCH 11/13] fix: build the commit under test, and install from the lockfile Two bugs the first real build exposed: The manifest rewrite hardcoded modules[0], which stopped being the app module when the node module was added. CI was building the v1.0.0 tag instead of the commit under test; the log gave it away with 'HEAD is now at c0dbd8f'. It now walks every module and fails if it does not find exactly one git source. npm install re-resolves the tree and reached for a chokidar outside the lockfile, which is therefore absent from the offline sources: ENOTCACHED. npm ci installs the lockfile exactly. --- .github/workflows/flatpak.yml | 24 +++++++++++++++++------- flatpak/com.andersonlaverde.slacky.yml | 5 ++++- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/.github/workflows/flatpak.yml b/.github/workflows/flatpak.yml index 39e1ad3..2956e83 100644 --- a/.github/workflows/flatpak.yml +++ b/.github/workflows/flatpak.yml @@ -75,16 +75,26 @@ jobs: - name: Point the manifest at the checked-out tree run: | .venv/bin/python - <<'PY' - import yaml, os + import sys, os, yaml path = os.environ['MANIFEST'] with open(path) as f: manifest = yaml.safe_load(f) - sources = manifest['modules'][0]['sources'] - sources[:] = [ - {'type': 'dir', 'path': '..', 'skip': ['.git', '.venv', 'node_modules', 'dist', 'build-dir']} - if isinstance(s, dict) and s.get('type') == 'git' else s - for s in sources - ] + local = {'type': 'dir', 'path': '..', + 'skip': ['.git', '.venv', 'node_modules', 'dist', 'build-dir']} + swapped = 0 + # Every module, not a hardcoded index: the app module is not + # necessarily first, and silently rewriting the wrong one means CI + # builds the last release instead of the commit under test. + for module in manifest['modules']: + sources = module.get('sources') + if not sources: + continue + for i, source in enumerate(sources): + if isinstance(source, dict) and source.get('type') == 'git': + sources[i] = local + swapped += 1 + if swapped != 1: + sys.exit(f'expected exactly one git source to swap, found {swapped}') with open(path, 'w') as f: yaml.safe_dump(manifest, f, sort_keys=False) PY diff --git a/flatpak/com.andersonlaverde.slacky.yml b/flatpak/com.andersonlaverde.slacky.yml index 20e0447..b328565 100644 --- a/flatpak/com.andersonlaverde.slacky.yml +++ b/flatpak/com.andersonlaverde.slacky.yml @@ -74,7 +74,10 @@ modules: XDG_CACHE_HOME: /run/build/slacky/flatpak-node/cache npm_config_cache: /run/build/slacky/flatpak-node/npm-cache build-commands: - - npm install --offline + # `npm ci`, not `npm install`: install re-resolves the tree and reached + # for a chokidar that is not in the lockfile, so not in the offline + # sources either. ci installs the lockfile exactly. + - npm ci --offline - npm run build # `--linux dir` produces an unpacked tree and nothing else. Do NOT use # electron-builder's own `flatpak` target here: it shells out to From 7ee8f035d7b39d15a62317b4bc67f71600aba942 Mon Sep 17 00:00:00 2001 From: Anderson Laverde Date: Tue, 25 Aug 2026 08:31:58 +0100 Subject: [PATCH 12/13] fix: hand electron-builder the Electron zip the sandbox already has The build got as far as packaging, then tried to reach github.com for the Electron binary. flatpak-node-generator writes the zip flat into $XDG_CACHE_HOME/electron, while @electron/get looks for it under a sha256-of-the-URL subdirectory, so the cached copy was invisible. Unpack it and pass --config.electronDist instead of depending on that cache layout. --- flatpak/com.andersonlaverde.slacky.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/flatpak/com.andersonlaverde.slacky.yml b/flatpak/com.andersonlaverde.slacky.yml index b328565..50871c5 100644 --- a/flatpak/com.andersonlaverde.slacky.yml +++ b/flatpak/com.andersonlaverde.slacky.yml @@ -79,6 +79,11 @@ modules: # sources either. ci installs the lockfile exactly. - npm ci --offline - npm run build + # flatpak-node-generator drops the Electron zip flat into the cache, but + # @electron/get looks for it under a sha256-of-the-URL subdirectory and + # so goes to github.com instead, which the sandbox cannot reach. Unpack + # it ourselves and hand electron-builder the result via electronDist. + - mkdir -p electron-dist && unzip -q "$XDG_CACHE_HOME"/electron/electron-v*-linux-arm64.zip -d electron-dist # `--linux dir` produces an unpacked tree and nothing else. Do NOT use # electron-builder's own `flatpak` target here: it shells out to # flatpak-builder, and running flatpak-builder inside a flatpak build is @@ -86,7 +91,7 @@ modules: # # The arch args generated by flatpak-node-generator have to be sourced in # the same command that uses them: each build-command gets its own shell. - - . flatpak-node/electron-builder-arch-args.sh; ./node_modules/.bin/electron-builder --linux dir $ELECTRON_BUILDER_ARCH_ARGS + - . flatpak-node/electron-builder-arch-args.sh; ./node_modules/.bin/electron-builder --linux dir --config.electronDist=electron-dist $ELECTRON_BUILDER_ARCH_ARGS - mkdir -p /app/main - cp -a dist/packages/linux*unpacked/. /app/main/ # zypak lets Electron's sandbox work inside flatpak's own sandbox. From 464e612686854be2015eedc5cc110d10f49e0167 Mon Sep 17 00:00:00 2001 From: Anderson Laverde Date: Tue, 25 Aug 2026 08:38:04 +0100 Subject: [PATCH 13/13] build: go back to the Node SDK extension, and assert the binary name dl.flathub.org has recovered, so Node comes from the SDK extension again rather than being vendored from nodejs.org; that is what Flathub expects. Also asserts /app/main/slacky exists at build time. The wrapper execs it, so a drift in executableName would otherwise surface only when a user launched the app. Documents the electronDist and npm ci reasoning in the README, since neither is guessable from the manifest alone. --- .github/workflows/flatpak.yml | 6 ++--- flatpak/README.md | 25 ++++++++++-------- flatpak/com.andersonlaverde.slacky.yml | 35 ++++++-------------------- 3 files changed, 24 insertions(+), 42 deletions(-) diff --git a/.github/workflows/flatpak.yml b/.github/workflows/flatpak.yml index 2956e83..425e226 100644 --- a/.github/workflows/flatpak.yml +++ b/.github/workflows/flatpak.yml @@ -112,7 +112,7 @@ jobs: uses: actions/cache@v6 with: path: ~/.local/share/flatpak - key: flatpak-runtimes-24.08-electron2 + key: flatpak-runtimes-24.08-node24-electron2 - name: Install runtimes run: | @@ -134,12 +134,10 @@ jobs: done } retry flatpak remote-add --user --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo - # The Node SDK extension is deliberately absent: the manifest vendors - # Node from nodejs.org while dl.flathub.org serves that extension - # broken. See the comment in the manifest. retry flatpak install --user -y --noninteractive flathub \ org.freedesktop.Platform//24.08 \ org.freedesktop.Sdk//24.08 \ + org.freedesktop.Sdk.Extension.node24//24.08 \ org.electronjs.Electron2.BaseApp//24.08 - name: Cache build downloads diff --git a/flatpak/README.md b/flatpak/README.md index 3282689..80b2f14 100644 --- a/flatpak/README.md +++ b/flatpak/README.md @@ -10,6 +10,19 @@ Files here build Slacky as a flatpak and prepare the Flathub submission for | `com.andersonlaverde.slacky.desktop` | Desktop entry | | `slacky.sh` | Launcher, wraps the app in zypak | +## Two things that are not obvious + +`electronDist` is passed explicitly because flatpak-node-generator writes the +Electron zip flat into `$XDG_CACHE_HOME/electron`, while `@electron/get` looks +for it under a `sha256`-of-the-URL subdirectory. The cached zip is therefore +invisible to electron-builder, which then tries to reach github.com and fails +in the network-less build sandbox. Unpacking it and passing `electronDist` +sidesteps the cache layout entirely. + +`npm ci`, not `npm install`: install re-resolves the dependency tree and +reaches for packages outside the lockfile, which are by definition absent from +the generated offline sources (`ENOTCACHED`). + ## Why this does not use electron-builder's flatpak target electron-builder's `flatpak` target shells out to `flatpak-builder` itself. The @@ -25,19 +38,9 @@ package you need arm64 hardware or `qemu-user-static` binfmt emulation. ```sh flatpak install -y flathub org.freedesktop.Platform//24.08 org.freedesktop.Sdk//24.08 \ - org.electronjs.Electron2.BaseApp//24.08 + org.freedesktop.Sdk.Extension.node24//24.08 org.electronjs.Electron2.BaseApp//24.08 ``` -## Node comes from nodejs.org, temporarily - -This manifest would normally build against -`org.freedesktop.Sdk.Extension.node24`. dl.flathub.org is currently serving -that extension's `aarch64/24.08` objects broken — HTTP 503, or a 22,509,726 -byte object truncated at exactly 3 MiB — so the manifest vendors Node from -nodejs.org as a build-only module instead, and drops it from the finished -flatpak with `cleanup`. Switch back to the SDK extension once upstream is -fixed; that is what Flathub reviewers expect to see. - ## Generating `generated-sources.json` The build sandbox has no network, so every npm tarball and the Electron binary diff --git a/flatpak/com.andersonlaverde.slacky.yml b/flatpak/com.andersonlaverde.slacky.yml index 50871c5..12ca5b9 100644 --- a/flatpak/com.andersonlaverde.slacky.yml +++ b/flatpak/com.andersonlaverde.slacky.yml @@ -7,6 +7,9 @@ base-version: '24.08' command: slacky separate-locales: false +sdk-extensions: + - org.freedesktop.Sdk.Extension.node24 + finish-args: # Electron's zygote/renderer processes talk to each other over the X11 and # IPC sockets; without --share=ipc it falls back to slow shared memory. @@ -33,36 +36,10 @@ finish-args: - --filesystem=xdg-pictures:ro modules: - # TEMPORARY: this should be `sdk-extensions: [org.freedesktop.Sdk.Extension.node24]` - # with `append-path: /usr/lib/sdk/node24/bin` on the module below. - # dl.flathub.org is serving that extension's aarch64/24.08 objects broken - # (HTTP 503, or a 22 MB object truncated at exactly 3 MiB), so Node comes - # from nodejs.org instead. Revert to the SDK extension once that is fixed. - # - # `cleanup: ['*']` drops everything this module installs from the finished - # flatpak: Node is needed to build, not to run. - - name: node - buildsystem: simple - cleanup: - - '*' - build-options: - # Node ships prebuilt and this module is discarded anyway, so there is - # nothing worth extracting debuginfo from. - no-debuginfo: true - strip: false - build-commands: - - cp -a bin include lib share /app/ - sources: - - type: archive - url: https://nodejs.org/dist/v24.19.0/node-v24.19.0-linux-arm64.tar.xz - sha256: 01443c1e1a29e531ccad5a46fefa6df490d2189c49f7955904aecdbb0fe86fdc - only-arches: - - aarch64 - - name: slacky buildsystem: simple build-options: - append-path: /app/bin + append-path: /usr/lib/sdk/node24/bin # Electron's binaries are prebuilt and already stripped; extracting # debuginfo from them yields nothing and costs minutes. no-debuginfo: true @@ -94,6 +71,10 @@ modules: - . flatpak-node/electron-builder-arch-args.sh; ./node_modules/.bin/electron-builder --linux dir --config.electronDist=electron-dist $ELECTRON_BUILDER_ARCH_ARGS - mkdir -p /app/main - cp -a dist/packages/linux*unpacked/. /app/main/ + # electron-builder renames the Electron binary to executableName. If that + # ever drifts, the wrapper would exec a missing path and the app would + # fail only at launch, so fail here instead. + - test -x /app/main/slacky # zypak lets Electron's sandbox work inside flatpak's own sandbox. - install -Dm755 flatpak/slacky.sh /app/bin/slacky - install -Dm644 build/icons/icon.png /app/share/icons/hicolor/512x512/apps/com.andersonlaverde.slacky.png