From cda5a9e47927ed63de7b383992c9d8c09e3d36e8 Mon Sep 17 00:00:00 2001 From: ruscher Date: Sat, 10 Oct 2026 22:15:23 -0300 Subject: [PATCH 1/2] CI: request builds the way the BigLinux builder expects The BigLinux GitLab builder (gitlab.bigib.org/builder/packagebuilder) is started by the biglinux organization when a "Build Package" run succeeds, for the branch of that run. The repository_dispatch calls in build-package.yml targeted an organization that no longer exists and got 401 Bad credentials, hidden by curl, so the runs were green but did nothing; and since the workflow only ran on main, testing-*/stable-* release branches were never built. - Build Package: runs on main, testing-* and stable-*; its build job needs the tests, fails for any other branch, sends nothing and uses no secret. Concurrency cancels superseded runs. - Tests: reusable, and a package job builds the PKGBUILD as the builder rewrites it, runs namcap, installs, verifies and removes the package. - GitLab Status: follows the builder job through the public GitLab API and fails when it does not start or does not succeed. - docs/ci-packaging.md: evidence, flow, release checklist. --- .github/scripts/track-build.sh | 114 ++++++++++++++++++++++++++ .github/workflows/build-package.yml | 51 ++++++++++-- .github/workflows/gitlab-status.yml | 44 ++++++++++ .github/workflows/tests.yml | 33 +++++++- .gitignore | 5 ++ README.md | 19 ++++- docs/ci-packaging.md | 122 ++++++++++++++++++++++++++++ tests/check-pkgbuild.sh | 84 +++++++++++++++++++ 8 files changed, 456 insertions(+), 16 deletions(-) create mode 100755 .github/scripts/track-build.sh create mode 100644 .github/workflows/gitlab-status.yml create mode 100644 docs/ci-packaging.md create mode 100755 tests/check-pkgbuild.sh diff --git a/.github/scripts/track-build.sh b/.github/scripts/track-build.sh new file mode 100755 index 0000000..3e45f14 --- /dev/null +++ b/.github/scripts/track-build.sh @@ -0,0 +1,114 @@ +#!/bin/bash +# Follow the BigLinux builder job started for a package, using the public API +# of https://gitlab.bigib.org/builder/packagebuilder (no token needed). +# +# Environment: +# PACKAGE package (and repository) name, e.g. biglinux-welcome +# ORG GitHub organization the builder clones from, e.g. biglinux +# BRANCH branch the build was requested for, e.g. main +# SINCE ISO 8601 time the request was made (the "Build Package" run end) +# START_TIMEOUT, BUILD_TIMEOUT seconds to wait for the job to appear / end +# +# Exits non-zero when no matching job starts, or when it does not succeed. +set -euo pipefail + +: "${PACKAGE:?}" "${ORG:?}" "${BRANCH:?}" "${SINCE:?}" +START_TIMEOUT=${START_TIMEOUT:-600} +BUILD_TIMEOUT=${BUILD_TIMEOUT:-3600} +api=https://gitlab.bigib.org/api/v4/projects/builder%2Fpackagebuilder +web=https://gitlab.bigib.org/builder/packagebuilder +url="https://github.com/$ORG/$PACKAGE" +summary=${GITHUB_STEP_SUMMARY:-/dev/null} + +trap 'echo "::error::Request to the BigLinux builder failed (line $LINENO); is gitlab.bigib.org reachable?"' ERR + +get() { + curl -fsS --retry 3 --retry-delay 5 --retry-all-errors --max-time 30 "$@" +} + +# One of the header lines the build job prints ("org: biglinux", ...) +header() { + sed -nE "s/^[^ ]+ [0-9]+[OE]\+? ?$1: (.*)$/\1/p" <<<"$2" | head -n1 +} + +# Same rules as package-build in packagebuilder +case "$BRANCH" in +*update-stable*) repo=update-stable ;; +*update-testing*) repo=update-testing ;; +*unstable* | *development*) repo=unstable ;; +*testing*) repo=testing ;; +*stable*) repo=stable ;; +*) repo=unstable ;; +esac + +since=$(date -u -d "$SINCE" +%s) +after=$(date -u -d "@$((since - 120))" +%FT%TZ) +echo "Looking for the $PACKAGE build of $url (branch $BRANCH) requested at $SINCE" + +# 1. Find the job. Every request is a "trigger" pipeline whose child pipeline +# has one job named after the package. +job='' child='' rejected=" " deadline=$((SECONDS + START_TIMEOUT)) +while [ -z "$job" ]; do + while read -r pid created; do + [ "$(date -u -d "$created" +%s)" -ge $((since - 30)) ] || continue + child=$(get "$api/pipelines/$pid/bridges" | jq -r '.[0].downstream_pipeline.id // empty') + [ -n "$child" ] || continue + id=$(get "$api/pipelines/$child/jobs" | jq -r --arg n "$PACKAGE" '.[] | select(.name == $n) | .id') + if [ -z "$id" ] || [[ "$rejected" == *" $id "* ]]; then continue; fi + log=$(get "$web/-/jobs/$id/raw" || true) + [ -n "$(header git_branch "$log")" ] || continue # not started yet + if [ "$(header url "$log")" = "$url" ] && [ "$(header git_branch "$log")" = "$BRANCH" ]; then + job=$id + echo "Builder accepted the request: pipeline $web/-/pipelines/$pid, job $web/-/jobs/$job" + echo " requested by $(header 'user sender' "$log"), created $created" + break + fi + rejected+="$id " + done < <(get "$api/pipelines?source=trigger&updated_after=$after&order_by=id&sort=asc&per_page=100" | + jq -r '.[] | "\(.id) \(.created_at)"') + + if [ -z "$job" ]; then + if [ "$SECONDS" -ge "$deadline" ]; then + echo "::error::The builder started no $PACKAGE job for $url ($BRANCH) within ${START_TIMEOUT}s. See docs/ci-packaging.md." + printf '### %s: no builder job\nNo job for %s, branch %s, started within %ss of %s.\n' \ + "$PACKAGE" "$url" "$BRANCH" "$START_TIMEOUT" "$SINCE" >>"$summary" + exit 1 + fi + sleep 20 + fi +done + +# 2. Wait for it to finish +deadline=$((SECONDS + BUILD_TIMEOUT)) last= +while :; do + status=$(get "$api/pipelines/$child/jobs" | jq -r --argjson id "$job" '.[] | select(.id == $id) | .status') + [ "$status" = "$last" ] || echo "Job status: $status" + last=$status + case "$status" in + success | failed | canceled | skipped) break ;; + esac + if [ "$SECONDS" -ge "$deadline" ]; then + echo "::error::Builder job $web/-/jobs/$job still '$status' after ${BUILD_TIMEOUT}s" + exit 1 + fi + sleep 30 +done + +# 3. Report what was built and uploaded +log=$(get "$web/-/jobs/$job/raw" | sed -E 's/^[^ ]+ [0-9]+[OE]\+? ?//') +built=$(grep -m1 -oE '^==> Finished making: .*' <<<"$log" | sed 's/^==> Finished making: //' || true) +uploaded=$(grep -A1 '^sending incremental file list' <<<"$log" | grep -E '\.pkg\.tar\.[a-z]+$' || true) +{ + printf '### %s: builder job %s\n\n' "$PACKAGE" "$status" + printf '| Step | Result |\n|---|---|\n' + printf '| Request accepted | [job %s](%s/-/jobs/%s), branch %s |\n' "$job" "$web" "$job" "$BRANCH" + printf '| Package built | %s |\n' "${built:-no}" + printf '| Uploaded for the %s repository | %s |\n' "$repo" "${uploaded:-no}" +} >>"$summary" +echo "Built: ${built:-nothing}" +echo "Uploaded for the $repo repository: ${uploaded:-nothing}" + +if [ "$status" != success ] || [ -z "$built" ] || [ -z "$uploaded" ]; then + echo "::error::Builder job $web/-/jobs/$job ended '$status'" + exit 1 +fi diff --git a/.github/workflows/build-package.yml b/.github/workflows/build-package.yml index 0dfb7cf..865ba7c 100644 --- a/.github/workflows/build-package.yml +++ b/.github/workflows/build-package.yml @@ -1,20 +1,53 @@ name: Build Package +# Packages are built by the BigLinux builder on GitLab +# (https://gitlab.bigib.org/builder/packagebuilder). The biglinux organization +# starts a build when a run of the workflow with this name finishes +# successfully, for the branch of that run: main goes to the unstable +# repository, testing-* to testing and stable-* to stable. This workflow sends +# nothing itself and needs no secret: it only has to succeed when, and only +# when, the package may be built. Keep its name and the final job "build". +# See docs/ci-packaging.md. + on: - workflow_dispatch: push: - branches: [main] + branches: [main, "testing-*", "stable-*"] + workflow_dispatch: -# Only the WEBHOOK_TOKEN secret is used; the GITHUB_TOKEN needs no access -permissions: {} +permissions: + contents: read + +# A newer push to the same branch supersedes a running one: the builder always +# clones the head of the branch, so only the last run needs to request a build +concurrency: + group: build-package-${{ github.ref }} + cancel-in-progress: true jobs: + tests: + uses: ./.github/workflows/tests.yml + build: - if: github.ref == 'refs/heads/main' + needs: tests runs-on: ubuntu-latest + timeout-minutes: 5 steps: - - name: Send Hooks BigLinux Build Package - shell: bash + - name: Request the package build + env: + BRANCH: ${{ github.ref_name }} run: | - curl -X POST -H "Accept: application/json" -H "Authorization: token ${{ secrets.WEBHOOK_TOKEN }}" --data '{"event_type": "${{ github.repository }}", "client_payload": { "branch": "${{ github.ref_name }}", "url": "https://github.com/${{ github.repository }}"}}' https://api.github.com/repos/BigLinux-Package-Build/build-package/dispatches - curl -X POST -H "Accept: application/json" -H "Authorization: token ${{ secrets.WEBHOOK_TOKEN }}" --data '{"event_type": "${{ github.repository }}", "client_payload": { "branch": "${{ github.ref_name }}", "url": "https://github.com/${{ github.repository }}"}}' https://api.github.com/repos/BigLinux-Package-Build/build-package-ARM/dispatches + # A failed run requests nothing, so manual runs from other branches fail + case "$BRANCH" in + main) repo=unstable ;; + testing-*) repo=testing ;; + stable-*) repo=stable ;; + *) + echo "::error::Packages are built only from main, testing-* and stable-*, not '$BRANCH'" + exit 1 + ;; + esac + echo "Tests passed for $GITHUB_SHA." + echo "When this run ends, the builder builds branch $BRANCH for the $repo repository;" + echo "the GitLab Status workflow follows that job." + printf '### Build requested\nBranch %s (%s), %s repository.\n' "$BRANCH" "$GITHUB_SHA" "$repo" \ + >>"$GITHUB_STEP_SUMMARY" diff --git a/.github/workflows/gitlab-status.yml b/.github/workflows/gitlab-status.yml new file mode 100644 index 0000000..d220071 --- /dev/null +++ b/.github/workflows/gitlab-status.yml @@ -0,0 +1,44 @@ +name: GitLab Status + +# Follows the job the BigLinux builder starts after a successful +# "Build Package" run, and fails when it does not start or does not succeed. +# Read only: it uses the public GitLab API and no secret. The name avoids the +# words "Build" and "Package", so this run never requests a build itself. + +on: + workflow_run: + workflows: [Build Package] + types: [completed] + workflow_dispatch: + inputs: + branch: + description: Branch the build was requested for + default: main + since: + description: Time of the request (ISO 8601, e.g. 2026-10-10T08:36:18Z) + required: true + +permissions: + contents: read + +jobs: + track: + # Only the biglinux organization requests builds + if: >- + github.event_name == 'workflow_dispatch' || + (github.repository_owner == 'biglinux' && github.event.workflow_run.conclusion == 'success') + runs-on: ubuntu-latest + timeout-minutes: 75 + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + sparse-checkout: .github/scripts + + - name: Follow the builder job + env: + PACKAGE: ${{ github.event.repository.name }} + ORG: biglinux + BRANCH: ${{ github.event.workflow_run.head_branch || inputs.branch }} + SINCE: ${{ github.event.workflow_run.updated_at || inputs.since }} + run: .github/scripts/track-build.sh diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 003b719..c28ccf2 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -1,10 +1,11 @@ name: Tests +# Pushes to main run these jobs through build-package.yml, which only asks +# for a package build after they pass. on: - push: - branches: [main] pull_request: workflow_dispatch: + workflow_call: permissions: contents: read @@ -22,13 +23,15 @@ jobs: # Pinned, so new ruff releases cannot change the rule set unnoticed python -m venv /opt/ruff && /opt/ruff/bin/pip install --quiet ruff==0.17.0 - - uses: actions/checkout@v4 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false - name: Lint run: | /opt/ruff/bin/ruff check usr/share/biglinux/welcome tests generate_strings.py /opt/ruff/bin/ruff format --check usr/share/biglinux/welcome tests generate_strings.py - shellcheck tests/run-headless.sh usr/share/biglinux/welcome/scripts/*.sh update-translations.sh \ + shellcheck tests/run-headless.sh tests/check-pkgbuild.sh usr/share/biglinux/welcome/scripts/*.sh update-translations.sh \ pkgbuild/biglinux-welcome.install usr/bin/biglinux-welcome desktop-file-validate usr/share/applications/org.biglinux.welcome.desktop @@ -43,3 +46,25 @@ jobs: useradd -m tester chown -R tester: "$GITHUB_WORKSPACE" runuser -u tester -- tests/run-headless.sh -v -rs + + package: + runs-on: ubuntu-latest + container: archlinux:latest + steps: + - name: Install dependencies + run: pacman -Syu --noconfirm --needed base-devel git namcap + + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + + - name: Build the package + run: | + useradd -m builder + chown -R builder: "$GITHUB_WORKSPACE" + runuser -u builder -- tests/check-pkgbuild.sh build /tmp/pkg + + # Installs the dependencies from the Arch repositories, runs the + # .install scriptlets and checks every installed file + - name: Install, verify and remove + run: tests/check-pkgbuild.sh install /tmp/pkg diff --git a/.gitignore b/.gitignore index c33ad3b..5f88b30 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,8 @@ .ruff_cache/ .pytest_cache/ PLANNING.md +# makepkg output in pkgbuild/ +pkgbuild/src/ +pkgbuild/pkg/ +pkgbuild/biglinux-welcome/ +*.pkg.tar* diff --git a/README.md b/README.md index 66206ef..277949c 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@

Version 3.0.1 - Tests + Build Package GTK 4 libadwaita 1.7+ Python 3.12+ @@ -249,10 +249,23 @@ RUN_NETWORK_TESTS=1 python -m pytest tests/test_installer.py -k chatai # pinne ruff check usr/share/biglinux/welcome tests generate_strings.py ruff format --check usr/share/biglinux/welcome tests generate_strings.py -shellcheck usr/share/biglinux/welcome/scripts/*.sh update-translations.sh tests/run-headless.sh +shellcheck usr/share/biglinux/welcome/scripts/*.sh update-translations.sh tests/*.sh + +tests/check-pkgbuild.sh build /tmp/pkg # build this tree as the BigLinux builder would, then namcap +sudo tests/check-pkgbuild.sh install /tmp/pkg # install, verify, remove: disposable container only ``` -The suite checks the page configuration, translations, version consistency and the installer: it runs the **real privileged helper**, unprivileged, against a fake `pacman` and `pkexec` (success, network failure, locked database, cancellation reaching pacman, Polkit dismissed/denied, verification, pinned repositories), installs ChatAI into a private package root (including tampered and path-traversal archives) and drives the real widgets. GitHub Actions (`.github/workflows/tests.yml`) runs all of this in an `archlinux` container with ruff 0.17.0. +The suite checks the page configuration, translations, version consistency and the installer: it runs the **real privileged helper**, unprivileged, against a fake `pacman` and `pkexec` (success, network failure, locked database, cancellation reaching pacman, Polkit dismissed/denied, verification, pinned repositories), installs ChatAI into a private package root (including tampered and path-traversal archives) and drives the real widgets. GitHub Actions (`.github/workflows/tests.yml`) runs all of this in an `archlinux` container with ruff 0.17.0, and also builds, installs and removes the package there. + +### Continuous integration and packages + +| Workflow | Runs on | Does | +|---|---|---| +| Tests | pull requests, manual | tests, lint, translations, package build/install/remove | +| Build Package | pushes to `main`, `testing-*`, `stable-*`, manual | the tests above, then the `build` job | +| GitLab Status | after Build Package (biglinux only), manual | follows the builder job and fails if it fails | + +The BigLinux builder ([packagebuilder](https://gitlab.bigib.org/builder/packagebuilder)) starts by itself when a **Build Package** run in `biglinux/biglinux-welcome` succeeds; no secret is needed. `main` is built for the unstable repository, a `testing-*` branch for testing and a `stable-*` branch for stable. Failed tests mean no build. Details, evidence and the release checklist: [docs/ci-packaging.md](docs/ci-packaging.md). ## Troubleshooting diff --git a/docs/ci-packaging.md b/docs/ci-packaging.md new file mode 100644 index 0000000..28ddc49 --- /dev/null +++ b/docs/ci-packaging.md @@ -0,0 +1,122 @@ +# CI and packaging + +How a commit in `biglinux/biglinux-welcome` becomes a package in the BigLinux +repositories, what was wrong before, and how to release. + +## Flow + +``` +push to main / testing-* / stable-* (biglinux/biglinux-welcome) + └─ Build Package workflow + ├─ tests tests.yml: lint, translations, test suite, package build+install+remove + └─ build needs: tests — fails for any other branch + run ends with success + └─ biglinux organization (outside this repository) triggers + gitlab.bigib.org/builder/packagebuilder with + org, url, user, package_name = repository, git_branch = branch of the run + └─ job "biglinux-welcome": clone url, checkout git_branch, rewrite PKGBUILD, + chrootbuild (Manjaro stable, x86_64), sign, rsync to the repository server + └─ GitLab Status workflow (workflow_run) follows that job through the public + GitLab API and fails if it does not start within 10 min or does not succeed +``` + +Destination repository, decided by the builder from `git_branch` +(`package-build` in packagebuilder): + +| Branch | Repository | +|---|---| +| `main` (anything not below) | unstable | +| `testing-*` | testing | +| `stable-*` | stable (also a GitHub release in `biglinux/biglinux-welcome`) | + +Only `x86_64` is built: `arch=('any')` is rewritten to `x86_64 aarch64`, but +the aarch64 step is commented out in the builder. + +## How the builder is started (evidence) + +No workflow in any BigLinux repository calls GitLab. The trigger was found by +comparing GitHub run times with GitLab pipeline creation times (2026-10-10): + +| GitHub run that ended successfully | Ended (UTC) | GitLab pipeline created | Job | +|---|---|---|---| +| biglinux-welcome "Build Package", main | 10-10 08:36:18 | 08:36:19 | 62063 | +| biglinux-welcome "Build Package", main | 10-03 09:40:19 | 09:40:20 | 60306 | +| biglinux-settings "Translate and Build Package", main | 09-13 20:06:08 | 20:06:10 | 56153 | +| biglinux-settings "Translate and Build Package", stable-2026-09-13_17-55 | 09-13 20:57:01 | 20:57:04 | 56156 | + +and no pipeline followed: "Tests" runs, a cancelled "Translate and Build +Package" run, or the creation of branches `testing-2026-10-10`, +`testing-2026-10-10-1` and `stable-2026-10-03_06-40` (no workflow ran for them). +Every build job logs `user sender: ` and the branch of the run. + +So the biglinux organization reacts to successful runs of workflows named +"… Build Package" (all of them have a final job `build`). The webhook itself +needs organization admin access to see; its exact filter (workflow name, job +name, conclusion) is inferred from the table above. Keep the workflow name +`Build Package` and the job id `build`. + +## What was wrong (before this change) + +1. `build-package.yml` sent `repository_dispatch` events to + `BigLinux-Package-Build/build-package` and `build-package-ARM`. That + organization no longer exists (`github.com/BigLinux-Package-Build` is 404), + and both calls answered `401 Bad credentials` + (run 38038451785 in biglinux, 38099995866 in the fork, where the secret is + empty). `curl` without `--fail` hid this, so the runs were green. +2. The workflow ran only for `main`. Releases to testing/stable are made by + creating `testing-*`/`stable-*` branches, which need a successful + "Build Package" run on that branch. Since 3.0.0 none ran, so + `testing-2026-10-10` and `testing-2026-10-10-1` were never built and 3.0.1 + only reached unstable (job 62063). +3. The build was requested whatever the tests said: the run that requested + it did not depend on them. +4. `WEBHOOK_TOKEN` was expanded straight into the shell command. + +The packages built from `main` were fine: job 62063 built and uploaded +`biglinux-welcome-1-3.0.1-1-x86_64.pkg.tar.zst` from `biglinux/biglinux-welcome`. + +## PKGBUILD and the builder + +The builder clones `https://github.com/biglinux/biglinux-welcome` (the +organization that sent the event), checks out the branch, then edits the +PKGBUILD: `source=(git+….git)` becomes `….git#branch=`, `arch=('any')` +becomes `('x86_64' 'aarch64')` and `git` is added to `makedepends`. +`tests/check-pkgbuild.sh build` applies the same edits and checks the result. + +- `url`/`source` must keep pointing to `github.com/biglinux/biglinux-welcome`: + that is where official packages come from. Forks are not built + (packagebuilder only accepts `org` biglinux, biglinuxaur*, xivastudio, + bigcommunity). +- The builder builds the head of the branch when the job starts, not + necessarily the commit of the run. The `concurrency` group cancels older + runs on the same branch, so the last successful run is for the head. +- `epoch=1` is required (earlier versions were dates like `26.10.03-0942`). + The builder renames `1:3.0.1` to `1-3.0.1` in the file name only. +- `BIGLINUX_WELCOME_SRC` is unset on the builder, so it uses the git source. + +## External configuration + +None is needed for builds. Recommended, by a `biglinux` admin: + +- Delete the unused `WEBHOOK_TOKEN` secret (organization or repository level). +- Protect `main` in `biglinux/biglinux-welcome` and require the **Tests** + checks (`tests`, `package`) on pull requests, so nothing untested is merged. + Direct pushes to `main` are still gated by the `build` job. +- If the organization webhook filter is ever changed, check that it still + matches "Build Package" / `build`. + +## Release checklist + +1. Bump `pkgver` (reset `pkgrel=1`) in `pkgbuild/PKGBUILD` and `APP_VERSION`; + `tests/test_release.py` checks they match. Never lower `epoch`. +2. Open a pull request; **Tests** must pass (`tests` and `package`). +3. Merge into `main` in `biglinux/biglinux-welcome` → unstable. Check that + **GitLab Status** is green; its summary links the job and the file uploaded. +4. To publish to testing: create branch `testing-YYYY-MM-DD` from `main` + (`git push origin main:refs/heads/testing-$(date +%F)`). Same for stable + with `stable-YYYY-MM-DD_HH-MM`. Check **GitLab Status** again. +5. If the builder job failed, open the job link, fix, and rerun + **Build Package** on that branch (Actions → Run workflow). + +Each branch gets one build per successful run; rerunning the workflow +requests another build of the same branch. diff --git a/tests/check-pkgbuild.sh b/tests/check-pkgbuild.sh new file mode 100755 index 0000000..53a9052 --- /dev/null +++ b/tests/check-pkgbuild.sh @@ -0,0 +1,84 @@ +#!/bin/bash +# Check pkgbuild/PKGBUILD the way the BigLinux package builder uses it. +# tests/check-pkgbuild.sh build DIR as a normal user: build this tree into DIR +# tests/check-pkgbuild.sh install DIR as root, on a disposable system only: +# install, verify and remove the package +set -euo pipefail +cd "$(dirname "$(readlink -f "$0")")/.." +root=$PWD +pkgname=biglinux-welcome +work= + +fail() { + echo "error: $*" >&2 + exit 1 +} + +build() { + local out + out=$(mkdir -p "$1" && readlink -f "$1") + work=$(mktemp -d) + trap 'rm -rf "$work"' EXIT + + # The builder (gitlab.bigib.org/builder/packagebuilder, file package-build) + # edits the PKGBUILD before building: it pins the source to the branch that + # requested the build, turns arch=('any') into x86_64/aarch64 and adds git + # to makedepends. The result must still parse and point to the right source. + cp pkgbuild/PKGBUILD "$work/" + sed -i '/source=/s/\.git"/\.git#branch=main"/' "$work/PKGBUILD" + sed -i "/\barch=/s/arch=.*/arch=('x86_64' 'aarch64')/" "$work/PKGBUILD" + sed -i "/makedepends=/s/(/\('git\' /" "$work/PKGBUILD" + (cd "$work" && makepkg --printsrcinfo) >"$work/SRCINFO" + grep -qx $'\tsource = git+https://github.com/biglinux/biglinux-welcome.git#branch=main' "$work/SRCINFO" || + fail "the builder's rewrite of source= no longer matches; see $work/SRCINFO" + grep -qx $'\tarch = x86_64' "$work/SRCINFO" || fail "the builder's rewrite of arch= no longer matches" + echo "PKGBUILD as rewritten by the builder:" + grep -E '^\s*(pkgver|pkgrel|epoch|arch|source) =' "$work/SRCINFO" + + # Build this checkout, not the published repository + (cd pkgbuild && BIGLINUX_WELCOME_SRC="$root" BUILDDIR="$work/build" PKGDEST="$out" \ + makepkg --nodeps --noconfirm --cleanbuild --force) + + # namcap warnings are informative; errors fail the check + local report + report=$(namcap pkgbuild/PKGBUILD "$out"/"$pkgname"-*.pkg.tar.*) + echo "$report" + ! grep -q ' E: ' <<<"$report" || fail "namcap reported errors" +} + +install() { + local pkg + [ "$EUID" -eq 0 ] || fail "install needs root (use a disposable container)" + pkg=$(find "$1" -maxdepth 1 -name "$pkgname-*.pkg.tar.*" ! -name '*.sig' | head -n1) + [ -n "$pkg" ] || fail "no package in $1" + + # Dependencies come from the configured repositories + pacman -U --noconfirm "$pkg" + pacman -Qkk "$pkgname" + + test -x /usr/bin/biglinux-welcome || fail "launcher not executable" + [ "$(stat -c %a /usr/share/biglinux/welcome/scripts/package-install.sh)" = 755 ] || + fail "privileged helper must be mode 755" + if pacman -Qlq "$pkgname" | grep -E '__pycache__|\.ruff_cache|\.pytest_cache|/tests/|/docs/'; then + fail "development files in the package" + fi + pacman -Qlq "$pkgname" | grep '\.py$' | + xargs python3 -c 'import ast, sys; [ast.parse(open(f).read(), f) for f in sys.argv[1:]]' + test -L /etc/systemd/user/graphical-session.target.wants/biglinux-welcome.service || + fail "post_install did not enable the user service" + python3 /usr/share/biglinux/welcome/main.py --version + + pacman -R --noconfirm "$pkgname" + ! test -e /usr/bin/biglinux-welcome || fail "files left after removal" + ! test -e /etc/systemd/user/graphical-session.target.wants/biglinux-welcome.service || + fail "pre_remove did not disable the user service" + echo "install, verification and removal passed" +} + +case "${1:-}" in +build | install) + [ -n "${2:-}" ] || fail "usage: $0 build|install DIR" + "$1" "$2" + ;; +*) fail "usage: $0 build|install DIR" ;; +esac From 17961b47bfee4b78afed9271278263c00c2a0886 Mon Sep 17 00:00:00 2001 From: ruscher Date: Sat, 10 Oct 2026 22:18:40 -0300 Subject: [PATCH 2/2] docs: a rebuild of an unchanged version replaces the uploaded file --- docs/ci-packaging.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/ci-packaging.md b/docs/ci-packaging.md index 28ddc49..61213bf 100644 --- a/docs/ci-packaging.md +++ b/docs/ci-packaging.md @@ -109,6 +109,10 @@ None is needed for builds. Recommended, by a `biglinux` admin: 1. Bump `pkgver` (reset `pkgrel=1`) in `pkgbuild/PKGBUILD` and `APP_VERSION`; `tests/test_release.py` checks they match. Never lower `epoch`. + Every successful run rebuilds the branch, also for CI- or docs-only + commits. Unlike the old date-based versions, the version does not change + by itself, so that rebuild replaces the file already uploaded with the same + version. Bump `pkgrel` when a packaging-only change must reach users. 2. Open a pull request; **Tests** must pass (`tests` and `package`). 3. Merge into `main` in `biglinux/biglinux-welcome` → unstable. Check that **GitLab Status** is green; its summary links the job and the file uploaded.