From 33487b38aa35e6913d9b64d3226b968b1b58fd61 Mon Sep 17 00:00:00 2001 From: Josh <98061271+Josh-Reimer@users.noreply.github.com> Date: Fri, 31 Jul 2026 06:54:51 -0230 Subject: [PATCH 1/3] Package as a Flatpak and build it in CI Adds a Flatpak manifest, launcher, desktop entry, and AppStream metainfo under flatpak/, plus a GitHub Actions workflow that builds the bundle on x86_64 and aarch64 and validates the metadata. The freedesktop runtime ships Python but not Tkinter, so the manifest builds Tcl, Tk, and CPython. Python 3.12 removed --with-tcltk-includes and locates Tk only through pkg-config, hence PKG_CONFIG_PATH on the python3 module; a post-install "import tkinter" fails the build rather than shipping an app that cannot open a window. Settings move to $XDG_CONFIG_HOME/bibleapp/settings.json. The install directory is read-only under Flatpak, so the previous location next to the script would have made save_settings() silently discard every preference. The old path is still read once so existing settings carry over. Also adds CLAUDE.md documenting the data format, the index-aligned book name lists, the theming split, and the packaging setup. Co-Authored-By: Claude Opus 5 --- .github/workflows/flatpak.yml | 60 ++++++++++++ .gitignore | 7 +- CLAUDE.md | 90 +++++++++++++++++ bible-gui-tk.py | 29 ++++-- flatpak/bibleapp | 5 + .../io.github.josh_reimer.BibleApp.desktop | 9 ++ ...o.github.josh_reimer.BibleApp.metainfo.xml | 58 +++++++++++ flatpak/io.github.josh_reimer.BibleApp.yml | 98 +++++++++++++++++++ 8 files changed, 349 insertions(+), 7 deletions(-) create mode 100644 .github/workflows/flatpak.yml create mode 100644 CLAUDE.md create mode 100755 flatpak/bibleapp create mode 100644 flatpak/io.github.josh_reimer.BibleApp.desktop create mode 100644 flatpak/io.github.josh_reimer.BibleApp.metainfo.xml create mode 100644 flatpak/io.github.josh_reimer.BibleApp.yml diff --git a/.github/workflows/flatpak.yml b/.github/workflows/flatpak.yml new file mode 100644 index 0000000..90a794f --- /dev/null +++ b/.github/workflows/flatpak.yml @@ -0,0 +1,60 @@ +name: Flatpak + +on: + push: + branches: [main] + pull_request: + workflow_dispatch: + +jobs: + # Cheap, fast job that catches the metadata problems Flathub's reviewers + # reject submissions for, without waiting on a full build. + metadata: + name: Validate metadata + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Install validators + run: | + sudo apt-get update + sudo apt-get install -y appstream desktop-file-utils + + - name: Validate AppStream metainfo + run: appstreamcli validate --no-net flatpak/io.github.josh_reimer.BibleApp.metainfo.xml + + - name: Validate desktop entry + run: desktop-file-validate flatpak/io.github.josh_reimer.BibleApp.desktop + + build: + name: Build ${{ matrix.arch }} + runs-on: ${{ matrix.runner }} + # Tcl + Tk + CPython are all compiled from source; the first build on a + # cold cache is long. Cached runs are much faster. + timeout-minutes: 90 + strategy: + fail-fast: false # an arch failure shouldn't hide the other arch's result + matrix: + include: + - arch: x86_64 + runner: ubuntu-latest + # Native arm64 runner (free for public repos). Flathub builds + # aarch64 too, so this catches arch breakage before submission. + # QEMU emulation is not a workable substitute here — emulating a + # full CPython build would blow past the job timeout. + - arch: aarch64 + runner: ubuntu-24.04-arm + + container: + image: bilelmoussaoui/flatpak-github-actions:freedesktop-24.08 + options: --privileged # flatpak-builder needs bubblewrap + + steps: + - uses: actions/checkout@v4 + + - uses: flatpak/flatpak-github-actions/flatpak-builder@v6 + with: + manifest-path: flatpak/io.github.josh_reimer.BibleApp.yml + # Downloadable from the run's Artifacts section: + # flatpak install --user bibleapp-x86_64.flatpak + bundle: bibleapp-${{ matrix.arch }}.flatpak diff --git a/.gitignore b/.gitignore index 0aebc59..68bebb0 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,9 @@ lib64 bin include bibleSearchResult.txt -.gitignore \ No newline at end of file +.gitignore +settings.json +# flatpak-builder artifacts +.flatpak-builder/ +build-dir/ +repo/ \ No newline at end of file diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..149382c --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,90 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Running the app + +```bash +python3 bible-gui-tk.py +``` + +Single-file Tkinter GUI, stdlib only. No build step, no test suite, no dependency manifest. Two virtualenvs are checked out but gitignored: `.venv` (3.12) and `venv` (3.14) — neither is required, system `python3` with tkinter works. + +The only optional dependency is `pyobjc` (`AppKit`), used solely by `_set_dock_icon()` on macOS to set the dock icon from `black-bible.png`. It is wrapped in a bare `except`, so its absence is silent and harmless. + +## Data model + +The Bible is stored as 66 plaintext files in the repo root, one per book (`genesis.txt` … `revelation.txt`), plus `Bible.txt` which is the whole KJV concatenated (loaded by `go_home()` at startup — ~4.3 MB into a single `tk.Text`). + +Line format inside a book file: + +``` +:: +``` + +Each book begins with a few non-verse header lines (title, book name, blank lines). Code that parses these files must tolerate them. Two consequences already baked into the code: + +- `ChapterVerse.get_chap()` filters by `verse.split(":")[0] == str(chap)` — header lines have no leading number so they fall out naturally. +- `get_selected_book()` derives the chapter count from `int(lines[-1].split(':')[0])`, i.e. it assumes the **last line of every book file is a verse**. Trailing blank lines or appended notes would break the chapter dropdown. + +Verse numbers are 1-based in the UI; `get_verse()` indexes `chapter[ver - 1]`. + +## Book name / filename mapping + +Three parallel lists must stay index-aligned: + +- `books_titled` in `bible-gui-tk.py` — display names in the book combobox +- `books_file_names` in `bible-gui-tk.py` — the corresponding `.txt` filenames +- `files` in `BibleFileNames.py` — same filename list, used as the default search corpus + +`get_selected_book_from_dropdown()` maps display → file purely by list position (`books_file_names[books_titled.index(...)]`), so inserting into one list without the others silently returns the wrong book. + +**Misspellings are canonical.** The lists use `philipians.txt`, `eccliasiastes.txt`, `ezekial.txt`, `first_thesselonians.txt`, `second_thesselonians.txt`. Correctly-spelled duplicates (`philippians.txt`, `first_thessalonians.txt`, `second_thessalonians.txt`) also exist on disk but are **not** referenced. Don't "fix" a name in one place only; renaming requires touching both files and the data file itself. + +`OT_FILES` / `NT_FILES` are slices of `books_file_names` at index 39 (Malachi/Matthew boundary) — they depend on the list staying in canonical Bible order. + +## Path handling + +Every data-file access goes through `_bpath(filename)`, which joins against `SCRIPT_DIR` (the directory of `bible-gui-tk.py`). This is what makes the app runnable from any cwd — new file reads should use it rather than bare relative paths. + +Note the inconsistency: `get_selected_book_from_dropdown()` returns an already-absolute path, while `get_search_files()` may return either those absolute paths (scope = "Current Book") or bare filenames from `files`/`OT_FILES`/`NT_FILES`. `linearsearch()` re-wraps everything in `_bpath()`, which happens to be idempotent for absolute paths. Preserve that property if you refactor. + +## Theming + +`THEMES` is a dict of named palettes with a fixed key set (`bg`, `fg`, `text_bg`, `text_fg`, `entry_bg`, `entry_fg`, `btn_bg`, `sel_bg`, `sel_fg`). Adding a theme means adding one entry with **all** keys — `_theme_widget()` indexes them unconditionally. + +`_theme_widget()` walks the widget tree recursively and dispatches on `winfo_class()`. Classic `tk` widgets are recolored per-class there; `ttk` widgets (Combobox, Button, Scrollbar) can't be, so they're styled through `ttk.Style()` in `apply_theme()`. `ttk.Style().theme_use("clam")` is set at import time precisely because the native macOS/Windows ttk themes ignore color overrides — don't remove it. `Toplevel` is deliberately skipped so dialogs keep native chrome. + +If you add a new widget kind, it needs a branch in `_theme_widget()` (tk) or a `style.configure` call (ttk), or it will stay unthemed. + +## Settings persistence + +`settings.json` holds `theme`, `font_family`, `font_size` and lives at `$XDG_CONFIG_HOME/bibleapp/settings.json` (default `~/.config/bibleapp/`), resolved by `_config_path()`. It is **not** next to the script: packaged installs mount the program directory read-only, so writes there fail silently. `_config_path()` falls back to the old in-tree location only if the config dir can't be created. + +`load_settings()` tries `CONFIG_FILE` then `LEGACY_CONFIG` (the old in-tree path), so existing users keep their theme on first run after upgrading; the first readable file wins and the rest are skipped. It swallows missing/corrupt files and falls back to defaults. It is called *after* `go_home()` and *before* `apply_theme()` at startup. Settings are written only when the user hits Apply/OK in the settings dialog — font-size changes from the View menu are not persisted. + +## Read-only text widget + +`bible_text_widget` is a real `tk.Text` (not disabled), kept read-only by `_block_text_edit()`, which returns `"break"` for every key except navigation keys and Ctrl/Cmd+C / Ctrl/Cmd+A. Disabling the widget instead would break selection and copy, which is why it's done this way. + +## Helper modules + +`list_and_str_ops.py`, `charEliminator.py`, and `ChapterVerse.py` all carry "DO NOT DELETE" banners. Only `ChapterVerse` is actually imported by the current GUI (`list_and_str_ops` is imported as `list`, shadowing the builtin, but unused; `charEliminator` is not imported at all). Leave them in place — the older copy of the app under `Untitled/` still uses them. + +`Untitled/` is an untracked snapshot of the pre-refactor app (no themes, no settings, relative paths). It is not the live code; edits belong in the repo root. + +## Flatpak packaging + +`flatpak/` holds the manifest, launcher, `.desktop` entry, and AppStream metainfo. App ID is `io.github.josh_reimer.BibleApp` (Flatpak IDs can't contain hyphens, so the GitHub username's `-` becomes `_`); the `.desktop` and metainfo filenames must keep matching that ID exactly. + +```bash +flatpak install -y flathub org.freedesktop.Platform//24.08 org.freedesktop.Sdk//24.08 +flatpak-builder --user --install --force-clean build-dir flatpak/io.github.josh_reimer.BibleApp.yml +flatpak run io.github.josh_reimer.BibleApp +``` + +The runtime ships Python but **not** Tkinter, so the manifest builds Tcl, Tk, and CPython. The load-bearing detail: Python 3.12 removed `--with-tcltk-includes`/`--with-tcltk-libs` and finds Tk only via pkg-config (`tcl >= 8.5.12 tk >= 8.5.12`), which is why `PKG_CONFIG_PATH=/app/lib/pkgconfig` is set on the `python3` module and why Tcl/Tk must install their `.pc` files first. A `post-install` step runs `import tkinter` so a broken chain fails the build instead of shipping an app that can't open a window. + +Files install to `/app/share/bibleapp/` (read-only), which is why settings use the XDG path above. The app module builds the working tree via `type: dir`; the Flathub copy must pin a git tag + commit instead. + +`.github/workflows/flatpak.yml` builds the manifest on x86_64 and aarch64 and uploads installable `.flatpak` bundles as run artifacts — the only way to test this from a non-Linux machine. A separate fast `metadata` job runs `appstreamcli validate` and `desktop-file-validate`, which are the checks Flathub submissions most often fail. diff --git a/bible-gui-tk.py b/bible-gui-tk.py index 0a669b6..bc01636 100644 --- a/bible-gui-tk.py +++ b/bible-gui-tk.py @@ -89,20 +89,37 @@ def _set_dock_icon(): _font_size = tk.IntVar(value=11) _current_theme = tk.StringVar(value="Light") -CONFIG_FILE = _bpath("settings.json") +def _config_path(): + """Settings live in the user's config dir, not next to the script. + + Packaged installs (Flatpak, distro packages) mount the program directory + read-only, so writing settings.json there would silently fail. + """ + base = os.environ.get("XDG_CONFIG_HOME") or os.path.expanduser("~/.config") + folder = os.path.join(base, "bibleapp") + try: + os.makedirs(folder, exist_ok=True) + except OSError: + return _bpath("settings.json") # nothing writable — keep the old spot + return os.path.join(folder, "settings.json") + +CONFIG_FILE = _config_path() +LEGACY_CONFIG = _bpath("settings.json") # pre-XDG location, still read once def load_settings(): - try: - with open(CONFIG_FILE) as f: - s = json.load(f) + for path in (CONFIG_FILE, LEGACY_CONFIG): + try: + with open(path) as f: + s = json.load(f) + except (OSError, json.JSONDecodeError): + continue # missing or corrupt — try the next one, else defaults if s.get("theme") in THEMES: _current_theme.set(s["theme"]) if s.get("font_family"): _font_family.set(s["font_family"]) if isinstance(s.get("font_size"), int): _font_size.set(s["font_size"]) - except (FileNotFoundError, json.JSONDecodeError, KeyError): - pass # first run or corrupt file — use defaults + return def save_settings(): try: diff --git a/flatpak/bibleapp b/flatpak/bibleapp new file mode 100755 index 0000000..46e0576 --- /dev/null +++ b/flatpak/bibleapp @@ -0,0 +1,5 @@ +#!/bin/sh +# Launcher installed as /app/bin/bibleapp. +# Python puts the script's own directory on sys.path, so the sibling modules +# (ChapterVerse, BibleFileNames, ...) and the .txt data resolve via _bpath(). +exec /app/bin/python3 /app/share/bibleapp/bible-gui-tk.py "$@" diff --git a/flatpak/io.github.josh_reimer.BibleApp.desktop b/flatpak/io.github.josh_reimer.BibleApp.desktop new file mode 100644 index 0000000..71343c4 --- /dev/null +++ b/flatpak/io.github.josh_reimer.BibleApp.desktop @@ -0,0 +1,9 @@ +[Desktop Entry] +Type=Application +Name=Desktop Bible +Comment=Read and search the Bible offline +Exec=bibleapp +Icon=io.github.josh_reimer.BibleApp +Terminal=false +Categories=Education;Spirituality;Literature;Viewer; +Keywords=Bible;Scripture;KJV;Verse; diff --git a/flatpak/io.github.josh_reimer.BibleApp.metainfo.xml b/flatpak/io.github.josh_reimer.BibleApp.metainfo.xml new file mode 100644 index 0000000..a5b293d --- /dev/null +++ b/flatpak/io.github.josh_reimer.BibleApp.metainfo.xml @@ -0,0 +1,58 @@ + + + io.github.josh_reimer.BibleApp + + Desktop Bible + Read and search the Bible offline + + CC0-1.0 + + LicenseRef-proprietary + + + Josh Reimer + + + +

+ A simple desktop Bible. The complete King James Version is bundled with + the application, so it works with no network connection. +

+
    +
  • Navigate by book, chapter, and verse
  • +
  • Search the whole Bible, one testament, or just the current book
  • +
  • Optional whole-word matching
  • +
  • Light, Dark, Sepia, and High Contrast themes
  • +
  • Adjustable reading font and size, remembered between sessions
  • +
+
+ + io.github.josh_reimer.BibleApp.desktop + + + + + Reading and searching scripture + https://github.com/user-attachments/assets/b2b31fe7-78a5-4cda-ba50-cac73d1167a1 + + + + https://github.com/Josh-Reimer/BibleApp-linux + https://github.com/Josh-Reimer/BibleApp-linux/issues + + + + + + +

First Flatpak release.

+
+
+
+
diff --git a/flatpak/io.github.josh_reimer.BibleApp.yml b/flatpak/io.github.josh_reimer.BibleApp.yml new file mode 100644 index 0000000..5f1ec12 --- /dev/null +++ b/flatpak/io.github.josh_reimer.BibleApp.yml @@ -0,0 +1,98 @@ +# Flatpak manifest for BibleApp. +# +# flatpak install -y flathub org.freedesktop.Platform//24.08 org.freedesktop.Sdk//24.08 +# flatpak-builder --user --install --force-clean build-dir flatpak/io.github.josh_reimer.BibleApp.yml +# flatpak run io.github.josh_reimer.BibleApp +# +# The freedesktop runtime ships Python but not Tkinter, so Tcl, Tk, and a +# CPython linked against them are built here. That is nearly all of the build +# time; the app itself is 36 KB of Python plus 8.6 MB of scripture. +id: io.github.josh_reimer.BibleApp +runtime: org.freedesktop.Platform +runtime-version: '24.08' +sdk: org.freedesktop.Sdk +command: bibleapp + +finish-args: + # Tk 8.6 is an X11 toolkit; under Wayland it runs through XWayland. + - --socket=x11 + - --share=ipc + # Deliberately no --share=network and no --filesystem=*: the app only reads + # its own bundled text and writes settings inside the sandbox. + +cleanup: + - /include + - /lib/pkgconfig + - /share/man + - /share/doc + - '*.a' + - '*.la' + +modules: + - name: tcl + buildsystem: autotools + subdir: unix + config-opts: + - --enable-threads + - --enable-64bit + sources: + - type: archive + url: https://downloads.sourceforge.net/project/tcl/Tcl/8.6.15/tcl8.6.15-src.tar.gz + sha256: 861e159753f2e2fbd6ec1484103715b0be56be3357522b858d3cbb5f893ffef1 + + - name: tk + buildsystem: autotools + subdir: unix + config-opts: + - --with-tcl=/app/lib + - --enable-threads + - --enable-64bit + sources: + - type: archive + url: https://downloads.sourceforge.net/project/tcl/Tcl/8.6.15/tk8.6.15-src.tar.gz + sha256: 550969f35379f952b3020f3ab7b9dd5bfd11c1ef7c9b7c6a75f5c49aca793fec + + - name: python3 + buildsystem: autotools + config-opts: + - --enable-shared + - --with-ensurepip=no + build-options: + # Python 3.12 dropped --with-tcltk-includes/--with-tcltk-libs; it now + # finds Tk solely through pkg-config ("tcl >= 8.5.12 tk >= 8.5.12"), + # which is why Tcl and Tk must install their .pc files into /app first. + env: + PKG_CONFIG_PATH: /app/lib/pkgconfig + ldflags: -Wl,-rpath,/app/lib + post-install: + # _tkinter is the entire reason for building Python — fail the build + # loudly here rather than shipping an app that cannot open a window. + - /app/bin/python3 -c "import tkinter" + - rm -rf /app/lib/python3.12/test /app/lib/python3.12/idlelib /app/lib/python3.12/lib2to3 + sources: + - type: archive + url: https://www.python.org/ftp/python/3.12.11/Python-3.12.11.tgz + sha256: 7b8d59af8216044d2313de8120bfc2cc00a9bd2e542f15795e1d616c51faf3d6 + + - name: bibleapp + buildsystem: simple + build-commands: + - install -Dm755 flatpak/bibleapp /app/bin/bibleapp + - install -d /app/share/bibleapp + - install -Dm644 -t /app/share/bibleapp *.py + - install -Dm644 -t /app/share/bibleapp *.txt + - install -Dm644 black-bible.png + /app/share/icons/hicolor/256x256/apps/io.github.josh_reimer.BibleApp.png + - install -Dm644 flatpak/io.github.josh_reimer.BibleApp.desktop + /app/share/applications/io.github.josh_reimer.BibleApp.desktop + - install -Dm644 flatpak/io.github.josh_reimer.BibleApp.metainfo.xml + /app/share/metainfo/io.github.josh_reimer.BibleApp.metainfo.xml + sources: + # Builds the working tree, so local edits are picked up immediately. + # The copy submitted to Flathub must instead pin an immutable revision: + # - type: git + # url: https://github.com/Josh-Reimer/BibleApp-linux.git + # tag: v1.0.0 + # commit: + - type: dir + path: .. From fd3775d3a15ca3ac3b73b6bbfe3a896a2aa820cc Mon Sep 17 00:00:00 2001 From: Josh <98061271+Josh-Reimer@users.noreply.github.com> Date: Fri, 31 Jul 2026 07:00:18 -0230 Subject: [PATCH 2/3] CI: build aarch64 without the container image The flatpak-github-actions image is published for x86_64 only, so the arm64 runner failed at docker pull with "no matching manifest for linux/arm64/v8" before any build work started. Install flatpak from apt on the native arm runner and drive flatpak-builder directly instead. Ubuntu 24.04 confines unprivileged user namespaces with AppArmor, which blocks bubblewrap, so the job relaxes that sysctl before building. Co-Authored-By: Claude Opus 5 --- .github/workflows/flatpak.yml | 78 +++++++++++++++++++++++++---------- 1 file changed, 57 insertions(+), 21 deletions(-) diff --git a/.github/workflows/flatpak.yml b/.github/workflows/flatpak.yml index 90a794f..2190ab0 100644 --- a/.github/workflows/flatpak.yml +++ b/.github/workflows/flatpak.yml @@ -26,35 +26,71 @@ jobs: - name: Validate desktop entry run: desktop-file-validate flatpak/io.github.josh_reimer.BibleApp.desktop - build: - name: Build ${{ matrix.arch }} - runs-on: ${{ matrix.runner }} - # Tcl + Tk + CPython are all compiled from source; the first build on a - # cold cache is long. Cached runs are much faster. + # Tcl + Tk + CPython are all compiled from source, so a cold-cache build is + # long on both architectures. + build-x86_64: + name: Build x86_64 + runs-on: ubuntu-latest timeout-minutes: 90 - strategy: - fail-fast: false # an arch failure shouldn't hide the other arch's result - matrix: - include: - - arch: x86_64 - runner: ubuntu-latest - # Native arm64 runner (free for public repos). Flathub builds - # aarch64 too, so this catches arch breakage before submission. - # QEMU emulation is not a workable substitute here — emulating a - # full CPython build would blow past the job timeout. - - arch: aarch64 - runner: ubuntu-24.04-arm - container: image: bilelmoussaoui/flatpak-github-actions:freedesktop-24.08 options: --privileged # flatpak-builder needs bubblewrap - steps: - uses: actions/checkout@v4 - uses: flatpak/flatpak-github-actions/flatpak-builder@v6 with: manifest-path: flatpak/io.github.josh_reimer.BibleApp.yml + # The action appends the arch, giving artifact "bibleapp-x86_64". # Downloadable from the run's Artifacts section: - # flatpak install --user bibleapp-x86_64.flatpak - bundle: bibleapp-${{ matrix.arch }}.flatpak + # flatpak install --user bibleapp.flatpak + bundle: bibleapp.flatpak + + # Native arm64 runner (free for public repos). Cannot reuse the job above: + # the flatpak-github-actions container image is published for x86_64 only + # ("no matching manifest for linux/arm64/v8"), so flatpak is installed from + # apt and flatpak-builder is driven directly. + build-aarch64: + name: Build aarch64 + runs-on: ubuntu-24.04-arm + timeout-minutes: 90 + steps: + - uses: actions/checkout@v4 + + - name: Allow unprivileged user namespaces + # Ubuntu 24.04 confines unprivileged userns via AppArmor, which stops + # bubblewrap — and therefore flatpak-builder — from building sandboxes. + run: sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0 + + - name: Install flatpak + run: | + sudo apt-get update + sudo apt-get install -y flatpak flatpak-builder + flatpak remote-add --user --if-not-exists \ + flathub https://dl.flathub.org/repo/flathub.flatpakrepo + flatpak install --user -y flathub \ + org.freedesktop.Platform//24.08 org.freedesktop.Sdk//24.08 + + # Lets repeat runs skip recompiling modules whose manifest entry is + # unchanged, which is nearly all of the build time. + - name: Cache flatpak-builder state + uses: actions/cache@v4 + with: + path: .flatpak-builder + key: flatpak-builder-aarch64-${{ hashFiles('flatpak/io.github.josh_reimer.BibleApp.yml') }} + restore-keys: flatpak-builder-aarch64- + + - name: Build + run: | + flatpak-builder --user --disable-rofiles-fuse --force-clean \ + --repo=repo build-dir flatpak/io.github.josh_reimer.BibleApp.yml + + - name: Bundle + run: | + flatpak build-bundle repo bibleapp-aarch64.flatpak \ + io.github.josh_reimer.BibleApp + + - uses: actions/upload-artifact@v4 + with: + name: bibleapp-aarch64 + path: bibleapp-aarch64.flatpak From 1a6df70ef46032fb79b0c2f5676415b83e408081 Mon Sep 17 00:00:00 2001 From: Josh <98061271+Josh-Reimer@users.noreply.github.com> Date: Fri, 31 Jul 2026 07:09:07 -0230 Subject: [PATCH 3/3] Make Tcl/Tk shared libraries writable before debuginfo stripping Tcl and Tk install their shared libraries mode 555. flatpak-builder's eu-strip pass then fails with "Permission denied" on libtcl8.6.so wherever rofiles-fuse is not mediating writes, which is how the aarch64 job runs. The x86_64 job happened to survive this because the container build uses rofiles-fuse. Co-Authored-By: Claude Opus 5 --- flatpak/io.github.josh_reimer.BibleApp.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/flatpak/io.github.josh_reimer.BibleApp.yml b/flatpak/io.github.josh_reimer.BibleApp.yml index 5f1ec12..79bcfd3 100644 --- a/flatpak/io.github.josh_reimer.BibleApp.yml +++ b/flatpak/io.github.josh_reimer.BibleApp.yml @@ -35,6 +35,11 @@ modules: config-opts: - --enable-threads - --enable-64bit + post-install: + # Tcl and its bundled packages install their shared libraries mode 555. + # flatpak-builder's debuginfo strip then dies with "Permission denied" + # wherever rofiles-fuse isn't mediating writes (the aarch64 job). + - find /app/lib -name '*.so' -exec chmod u+w {} + sources: - type: archive url: https://downloads.sourceforge.net/project/tcl/Tcl/8.6.15/tcl8.6.15-src.tar.gz @@ -47,6 +52,8 @@ modules: - --with-tcl=/app/lib - --enable-threads - --enable-64bit + post-install: + - find /app/lib -name '*.so' -exec chmod u+w {} + # same 555 issue as tcl sources: - type: archive url: https://downloads.sourceforge.net/project/tcl/Tcl/8.6.15/tk8.6.15-src.tar.gz