Files
jasp-desktop-bin/.gitea/workflows/build.yml
T
agw f3a6822744 Self-host tarballs on asger.weirsoe.dk instead of GitHub Releases
Serve from /srv/tarballz on CT148 via a 'location /tarballz/' alias, NOT
from under /var/www/asger: the asger-web deploy swaps that whole directory
atomically, so tarballs kept inside it would be deleted on the next site
deploy. CT148's rootfs was 3G with 2.7G free - one tarball would have
filled it - so it is grown to 15G; speedy's thin pool has room even though
vgs reports the VG nearly full.

Publishing uploads to a .part name and renames on arrival so a download can
never see a truncated file, verifies sha256 on the host, then fetches the
public URL and checks it against the sha256 baked into the PKGBUILD. Both
checks run before the AUR push, so the package cannot go out pointing at a
missing file. Old tarballs are pruned to the newest three.

GH_TOKEN is kept but demoted to an optional GITHUB_PAT for R module
downloads; it no longer has anything to do with publishing.
2026-09-01 22:50:00 +02:00

167 lines
5.4 KiB
YAML

name: Build JASP binary and publish to AUR
# JASP publishes no Linux binary of its own, so this builds one on Arch and
# ships it as jasp-desktop-bin. Because JASP links against the system R and Qt6,
# a rebuild is needed both when JASP releases and when Arch bumps R or Qt6 —
# check-upstream.py decides which.
on:
schedule:
- cron: '0 3 * * *'
workflow_dispatch:
inputs:
jasp_tag:
description: 'Specific JASP tag to build (blank = latest release)'
required: false
default: ''
force:
description: 'Build even if nothing changed'
type: boolean
default: false
concurrency:
group: jasp-build
cancel-in-progress: false
env:
AUR_MAINTAINER: ${{ vars.AUR_MAINTAINER }}
TARBALL_HOST: ${{ vars.TARBALL_HOST }}
TARBALL_PATH: ${{ vars.TARBALL_PATH }}
TARBALL_BASE_URL: ${{ vars.TARBALL_BASE_URL }}
WORK_DIR: /srv/jasp-build
jobs:
check:
runs-on: ubuntu-latest
outputs:
needs_build: ${{ steps.decide.outputs.needs_build }}
jasp_tag: ${{ steps.decide.outputs.jasp_tag }}
reasons: ${{ steps.decide.outputs.reasons }}
steps:
- uses: actions/checkout@v4
- name: Decide whether a rebuild is needed
id: decide
env:
JASP_TAG: ${{ inputs.jasp_tag }}
FORCE_BUILD: ${{ inputs.force }}
run: python3 scripts/check-upstream.py
build:
needs: check
if: needs.check.outputs.needs_build == 'true'
runs-on: ubuntu-latest
# The R module tree is several hundred packages compiled from source; the
# full build runs for hours. The act_runner timeout and Gitea's
# ENDLESS_TASK_TIMEOUT must both allow for this (see README).
timeout-minutes: 900
steps:
- uses: actions/checkout@v4
- name: Report plan
run: |
echo "Building JASP ${{ needs.check.outputs.jasp_tag }}"
echo "Reasons: ${{ needs.check.outputs.reasons }}"
- name: Prepare work directory
run: |
sudo rm -rf "${WORK_DIR}"
sudo mkdir -p "${WORK_DIR}/out"
sudo cp -a build packaging scripts "${WORK_DIR}/"
df -h /
- name: Build JASP in an Arch container
env:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
run: |
docker rm -f jasp-build 2>/dev/null || true
docker run --rm --name jasp-build \
-v "${WORK_DIR}:/work" \
-e JASP_TAG="${{ needs.check.outputs.jasp_tag }}" \
-e OUT_DIR=/work/out \
-e JOBS=5 \
-e GITHUB_PAT="${GH_TOKEN}" \
archlinux:base-devel \
bash /work/build/build-jasp.sh
- name: Show build result
run: |
cat "${WORK_DIR}/out/build-info.json"
ls -lh "${WORK_DIR}/out/"
- name: Generate PKGBUILD
run: |
sudo cp "${WORK_DIR}/out/build-info.json" .
python3 scripts/gen-pkgbuild.py \
--build-info build-info.json \
--template packaging/PKGBUILD.in \
--out PKGBUILD \
--base-url "${TARBALL_BASE_URL}" \
--maintainer "${AUR_MAINTAINER}"
cat PKGBUILD
# Must run before the AUR push: the PKGBUILD's sha256sum refers to this
# file, so publishing the package before the tarball exists would leave
# users with a 404.
- name: Publish tarball to asger.weirsoe.dk
env:
TARBALL_SSH_KEY: ${{ secrets.TARBALL_SSH_KEY }}
run: |
ASSET="$(python3 -c 'import json;print(json.load(open("release-meta.json"))["tarball"])')"
bash scripts/publish-tarball.sh "${WORK_DIR}/out/${ASSET}"
- name: Verify the published URL actually serves the tarball
run: |
URL="$(python3 -c 'import json;print(json.load(open("release-meta.json"))["download_url"])')"
WANT="$(python3 -c 'import json;print(json.load(open("release-meta.json"))["sha256"])')"
echo "checking $URL"
GOT="$(curl -fsSL --retry 3 "$URL" | sha256sum | awk '{print $1}')"
if [ "$GOT" != "$WANT" ]; then
echo "error: what the public URL serves does not match the PKGBUILD sha256" >&2
echo " want $WANT" >&2
echo " got $GOT" >&2
exit 1
fi
echo "public URL serves the expected bytes"
# Only the PKGBUILD and metadata cross the job boundary — the tarball
# itself already lives on GitHub Releases.
- name: Hand PKGBUILD to the AUR job
uses: actions/upload-artifact@v3
with:
name: aur-package
path: |
PKGBUILD
release-meta.json
- name: Record built state
env:
STATE_PUSH_TOKEN: ${{ secrets.STATE_PUSH_TOKEN }}
run: bash scripts/record-state.sh
- name: Clean up build tree
if: always()
run: |
sudo rm -rf "${WORK_DIR}/jasp-desktop" "${WORK_DIR}/build" "${WORK_DIR}/stage" || true
df -h /
aur:
needs: [check, build]
runs-on: ubuntu-latest
container:
image: archlinux:base-devel
steps:
- name: Install base tools
run: pacman -Syu --noconfirm git openssh pacman-contrib nodejs sudo
- uses: actions/checkout@v4
- uses: actions/download-artifact@v3
with:
name: aur-package
- name: Push to AUR
env:
AUR_SSH_PRIVATE_KEY: ${{ secrets.AUR_SSH_PRIVATE_KEY }}
run: bash scripts/push-aur.sh PKGBUILD