# jasp-desktop-bin Automated binary builds of [JASP](https://jasp-stats.org/) for Arch Linux, published to the AUR as `jasp-desktop-bin`. ## Why this exists Upstream JASP ships installers for Windows and macOS only — there is **no official Linux binary**. The official Linux channel is the Flathub build. The existing AUR package `jasp-desktop` therefore builds everything from source, including `buildAllDefaultJaspModules.R`, which compiles several hundred R packages. That is the multi-hour build this repo exists to avoid: the compile happens once, here, and users download the result. ## The constraint that shapes everything JASP does **not** bundle R or Qt6 on Linux. `Tools/CMake/R.cmake` only fetches `R.framework` on macOS; on Linux JASP links against the distribution's R and Qt6, and the R module library it ships is compiled against one specific R minor version. A binary is therefore only valid for the R minor and Qt6 minor it was built against. Two consequences: 1. A rebuild is triggered by a new JASP release **or** by Arch bumping `r` or `qt6-base`. `scripts/check-upstream.py` checks all three. 2. The generated PKGBUILD pins `depends` to those versions (`r>=4.6 r<4.7`, `qt6-base>=6.11 qt6-base<6.12`). If Arch moves ahead before a rebuild lands, pacman refuses the combination rather than leaving users with a JASP that fails to start. `jags` and `librdata-git` are AUR-only, and JASP needs `freexl >= 2.0.99` while Arch ships 2.0.0 — so the build compiles those itself, matching what upstream CI does. ## Layout | Path | Purpose | | --- | --- | | `build/build-jasp.sh` | The actual build. Runs in an `archlinux:base-devel` container, emits the tarball plus `build-info.json`. | | `scripts/check-upstream.py` | Compares upstream JASP / Arch R / Arch Qt6 against `state.json`; decides whether to build. | | `scripts/gen-pkgbuild.py` | Fills `packaging/PKGBUILD.in` from `build-info.json`; derives `pkgrel` from what is on the AUR. | | `scripts/publish-github-release.sh` | Creates the GitHub release and uploads the tarball. | | `scripts/push-aur.sh` | Generates `.SRCINFO` and pushes to `aur.archlinux.org`. | | `scripts/record-state.sh` | Commits `state.json` so the next nightly run knows what was built. | | `packaging/PKGBUILD.in` | Template for the AUR package. | | `state.json` | Last successfully built combination. | ## Flow ``` nightly (03:00) ─► check-upstream.py │ new JASP tag, or Arch bumped r / qt6-base? ▼ build-jasp.sh (Arch container, hours) │ jasp-desktop--x86_64.tar.zst + build-info.json ▼ GitHub release ──► gen-pkgbuild.py ──► push to AUR │ ▼ state.json committed back ``` ## Required configuration Set these in the Gitea repo before the first run. **Variables** (Settings → Actions → Variables): | Name | Example | Meaning | | --- | --- | --- | | `GH_OWNER` | `asgerw` | GitHub account hosting the release repo | | `GH_REPO` | `jasp-desktop-bin` | Release repo name | | `AUR_MAINTAINER` | `Asger W ` | Written into the PKGBUILD header | **Secrets** (Settings → Actions → Secrets): | Name | Meaning | | --- | --- | | `GH_TOKEN` | GitHub PAT with `contents: write` on the release repo | | `AUR_SSH_KEY` | Private SSH key registered with your AUR account | | `GITEA_TOKEN` | Token with write access to this repo, for committing `state.json` | The GitHub repo `GH_OWNER/GH_REPO` must exist and be public — the AUR PKGBUILD downloads the tarball from its releases, so it has to be reachable anonymously. ## Runner requirements The build runs for hours and needs disk. On the Gitea runner host: - `runner.timeout` in `/var/lib/gitea-worker/config.yaml` must exceed the build time (set to `16h`). - Gitea's own job timeout (`[actions] DEFAULT_ACTIONS_TIMEOUT` in `app.ini`) must match, otherwise Gitea kills the job at 3h regardless of the runner. - Roughly 40–60 GB of free disk for the build tree and staged install. ## Running it by hand ``` # Build a specific tag without waiting for the schedule Actions → Build JASP binary and publish to AUR → Run workflow jasp_tag = v0.98.1 force = true ``` ## Caveat worth knowing AUR convention is that a `-bin` package repackages binaries published by upstream. Here upstream publishes no Linux binary, so this one is built by us. That is unusual, and a maintainer or TU may question it. It is not against the rules, but the package description and this README should stay honest about where the binary comes from.