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.
167 lines
5.4 KiB
YAML
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
|