Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 28 additions & 53 deletions .github/workflows/build-package.yml
Original file line number Diff line number Diff line change
@@ -1,32 +1,35 @@
name: Build Package

# Builds the commit under test with pkgbuild/PKGBUILD, in Arch's own
# container, validates the package and keeps it as an artifact. Pushes and
# manual runs that ask for it then hand the branch to the BigLinux package
# builders, only once that package has built and passed every check.
# container, validates the package and keeps it as an artifact.
#
# This workflow's success is what the BigLinux package builders act on: when
# a "Build Package" run of biglinux/bigamemode ends in success, they build
# its branch (on GitLab, gitlab.bigib.org/builder/packagebuilder). So it runs
# only for the branches they can build: pushes to main, testing-* and
# stable-*, and manual runs of such a branch. A failed run is not built, and
# a branch with '/' breaks their recipe, so pull requests are checked by
# package-check.yml, which calls this workflow under another name.
# See docs/ci-workflows-audit.md.

on:
pull_request:
push:
# '*' does not match '/': main, testing-*, stable-* and other plain
# branch names, which the BigLinux builders' hook has always covered.
# Topic branches (fix/…, feat/…) are built through their pull request.
# branch names. Topic branches (fix/…, feat/…) go through their pull
# request, in package-check.yml.
branches: ['*']
workflow_dispatch:
inputs:
send-to-builders:
description: Hand this branch to the BigLinux package builders once the package passes
type: boolean
default: false
workflow_call:

permissions:
contents: read

concurrency:
group: build-package-${{ github.ref }}
# A newer commit on a pull request makes the older build moot. Pushes are
# never cancelled: each one is handed to the package builders.
# github.workflow is the caller's name when package-check.yml calls this
# one, so a pull request's check never queues behind a push of its branch.
group: build-package-${{ github.workflow }}-${{ github.ref }}
# A newer commit on a pull request makes the older check moot. Pushes are
# never cancelled: each successful one is built by the BigLinux builders.
cancel-in-progress: ${{ github.event_name == 'pull_request' }}

jobs:
Expand All @@ -45,6 +48,17 @@ jobs:
# tee, fails the step.
shell: bash
steps:
- name: Refuse a branch the BigLinux builders cannot build
# A manual "Build Package" run that succeeds is built by them too,
# and their recipe breaks on '/' in a branch name. Run
# package-check.yml on such a branch instead.
if: github.workflow == 'Build Package' && contains(github.ref_name, '/')
env:
BRANCH: ${{ github.ref_name }}
run: |
echo "::error::$BRANCH has '/' in its name: a successful Build Package run is handed to the BigLinux builders, which cannot build it. Run Package check on it instead."
exit 1

- name: Prepare Arch environment
run: |
set -Eeuo pipefail
Expand Down Expand Up @@ -331,42 +345,3 @@ jobs:
package-build/build-report.md
if-no-files-found: ignore
retention-days: 14

notify-builders:
name: Hand the branch to the BigLinux package builders
needs: package
# Every push to biglinux/bigamemode, as the builders' hook always did; a
# manual run only when asked to. Never a pull request: it has no secret,
# and its code is not the branch's yet.
if: >-
github.repository == 'biglinux/bigamemode' &&
(github.event_name == 'push' ||
(github.event_name == 'workflow_dispatch' && inputs.send-to-builders))
runs-on: ubuntu-24.04
timeout-minutes: 5
# Uses only the organization's WEBHOOK_TOKEN; no GITHUB_TOKEN permission.
permissions: {}
steps:
- name: Send repository_dispatch to BigLinux-Package-Build
shell: bash
env:
WEBHOOK_TOKEN: ${{ secrets.WEBHOOK_TOKEN }}
BRANCH: ${{ github.ref_name }}
run: |
set -Eeuo pipefail
if [[ -z "$WEBHOOK_TOKEN" ]]; then
echo "::error::the WEBHOOK_TOKEN secret is not available to this run"
exit 1
fi
# x86_64 only (arch=('x86_64') in pkgbuild/PKGBUILD): no ARM builder.
payload=$(jq -cn --arg repo "$GITHUB_REPOSITORY" --arg branch "$BRANCH" \
--arg url "$GITHUB_SERVER_URL/$GITHUB_REPOSITORY" \
'{event_type: $repo, client_payload: {branch: $branch, url: $url}}')
echo "Dispatching: $payload"
# --fail-with-body: a refused token fails the run instead of passing.
curl --fail-with-body --silent --show-error --max-time 30 -X POST \
-H 'Accept: application/vnd.github+json' \
-H "Authorization: token $WEBHOOK_TOKEN" \
--data "$payload" \
https://api.github.com/repos/BigLinux-Package-Build/build-package/dispatches
echo "Branch $BRANCH handed to the BigLinux package builders." >> "$GITHUB_STEP_SUMMARY"
17 changes: 17 additions & 0 deletions .github/workflows/package-check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: Package check

# The package build and every check of build-package.yml, for pull requests
# and manual runs of any branch. Under this name a successful run is not
# handed to the BigLinux package builders, which act on "Build Package"
# runs only (see build-package.yml). See docs/ci-workflows-audit.md.

on:
pull_request:
workflow_dispatch:

permissions:
contents: read

jobs:
package:
uses: ./.github/workflows/build-package.yml
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -472,8 +472,9 @@ Two workflows check every pull request (details in
`testing-*` and `stable-*`: a `makepkg` build of that very commit with
`pkgbuild/PKGBUILD`, checked with namcap, `desktop-file-validate`,
`appstreamcli` and a look at every file it installs; the package is kept as
an artifact. On a push, once all of that passes, the branch is handed to the
BigLinux package builders.
an artifact. A successful run of it is what the BigLinux package builders
build. Pull requests run the same build as `package-check.yml`, which is
not handed to them.

## Author

Expand Down
67 changes: 49 additions & 18 deletions docs/ci-workflows-audit.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ meant.

| Problem | Root cause | Fix | How it is validated |
|---|---|---|---|
| Pushes to `main`, `testing-*` and `stable-*` no longer reached the BigLinux package builders. | `30cee92` replaced the hook with big-video-converter's CI build. | `notify-builders` job: on pushes to biglinux/bigamemode (or a manual run with *send-to-builders*), **after** the package has built and passed every check. Token via `env`, payload built by `jq`, `curl --fail-with-body`. | Not run from a branch on purpose; the first push to `main` after merging is the test. See *Pending*. |
| ~~Pushes to `main`, `testing-*` and `stable-*` no longer reached the BigLinux package builders.~~ **Wrong**: see *How the BigLinux builders are triggered* below. | — | The `notify-builders` job added for it is removed. | |
| `if: always()` with `if-no-files-found: error` on the package upload. | Copied pattern. | The package is uploaded only on success; after a failure a separate upload keeps whatever logs exist, with `if-no-files-found: ignore`. | A failure shows one error: the step that failed. |
| A change in cargo's output format could fail the backend run. | The totals parser raised an error when it found no `test result:` line. | Totals are shown in the summary only; cargo's exit status decides. | |
| The first failing check hid the others (rustfmt failing skipped Clippy and the tests). | Default step semantics. | Every check runs when the setup succeeded (`!cancelled() && steps.setup.outcome == 'success'`); any failure still fails the job. | |
Expand Down Expand Up @@ -59,13 +59,48 @@ outside CI is the test above, in `bigame-core/src/graphics/optiscaler.rs`.
pull_request ─┬─► backend-tests ─── rust: fmt · clippy · test · doc · authorization · translations
push main ────┤
│
└─► build-package ─── package: prepare source of $GITHUB_SHA → makepkg -s
push main, → identify → metadata → contents → desktop
testing-*, stable-* ─────────────► → AppStream → namcap → SHA256SUMS → artifact
│
└─► notify-builders (push / opted-in manual run only)
└─► package-check ──┐
│ workflow_call
push main, ▼
testing-*, stable-* ──► build-package ─── package: prepare source of $GITHUB_SHA → makepkg -s
→ identify → metadata → contents → desktop
→ AppStream → namcap → SHA256SUMS → artifact
│
└─ a successful "Build Package" run: the BigLinux
builders build its branch
```

## How the BigLinux builders are triggered

The BigLinux builders (GitLab, `gitlab.bigib.org/builder/packagebuilder`)
build a branch of biglinux/bigamemode when a run of the workflow named
**Build Package** ends in **success**, with that run's branch. No step of the
workflow has to send anything. The builder's public job history against this
repository's runs, 2026-10-07 and 08 (UTC):

| Build Package run | Conclusion | Builder job |
|---|---|---|
| push `main`, `testing-2026-10-07` (`72fed17`, no dispatch step), ends 07:14 / 07:16 | success | `main` 07:14, `testing-2026-10-07` 07:16 |
| push `stable-2026-10-07`, ends 12:34 | success | `stable-2026-10-07` 12:34 |
| pull requests `fix/…` (4 runs), end 14:18, 14:32, 19:34, 19:05 | success | `fix/…` at the same minutes, failing at the recipe's `sed` (the `/` ends its `s/…/…/`) |
| pushes `main`, `testing-2026-10-07-1`, `-4`, `testing-2026-10-08` | failure (`notify-builders`: 401) | none |

So the `repository_dispatch` added on 2026-10-07 (`notify-builders`) did the
opposite of its purpose: its token is refused (401), the failed job failed the
run, and no push was built after it. Pull requests, built under the same
workflow name, were handed over instead.

Hence:

- **build-package.yml** ("Build Package") runs only for branches the builders
can build: pushes to plain branch names (`main`, `testing-*`, `stable-*`;
`'*'` does not match `/`) and manual runs. A manual run of a branch with `/`
fails at once, before anything is built.
- **package-check.yml** ("Package check") runs the same job for pull requests
and manual runs of any branch, through `workflow_call`. Under that name a
success is not handed over.
- There is no dispatch step and no secret.

### backend-tests.yml: the code

Runs in `archlinux:base-devel` with `--init` (the launcher's terminate test
Expand Down Expand Up @@ -130,11 +165,9 @@ uses Arch's `rust`, always the current stable release.
11. **Artifact** `bigame-mode-<pkgver>-<pkgrel>-<commit>`: the package, the
debug package, `SHA256SUMS`, `namcap.log`, `package-info.txt`,
`package-files.txt`, `build-report.md` and makepkg's logs per stage.
12. **notify-builders.** Only after all of the above, only in
biglinux/bigamemode, only for a push or a manual run that ticks
*send-to-builders*. It sends the branch name to
`BigLinux-Package-Build/build-package`. It never runs for a pull request,
which has no access to the secret.
12. **Handing over.** None in the workflow: the run's success is what the
BigLinux builders act on (see *How the BigLinux builders are
triggered*).

### namcap: what it reports today

Expand All @@ -161,8 +194,7 @@ or added here.
installed). A filter loose enough to be safe would save almost nothing.
- **Tags and releases.** Nothing is published from CI. The BigLinux builders
publish packages; the artifact is for testing.
- **Permissions.** `contents: read` at workflow level; `notify-builders` has
`permissions: {}` and only the organization's `WEBHOOK_TOKEN`. No
- **Permissions.** `contents: read` at workflow level, no secrets. No
`pull_request_target`.
- **Third-party actions.** Only `actions/checkout` (v7.0.1) and
`actions/upload-artifact` (v7.0.1), pinned by commit. The pins were
Expand Down Expand Up @@ -282,11 +314,10 @@ check the workflows themselves.
Tested while preparing this change: in a local replay of the job in
`archlinux:base-devel`, it passed with `rust-version = "1.88"`;
`cargo +1.85 check` fails as described above.
- **The builders' hook runs only from `main`.** `notify-builders` cannot run
from a pull request (no secret, and on purpose). The first push to `main`
after merging is its first real run; its summary line, *Branch main handed
to the BigLinux package builders*, and the build on the BigLinux side
confirm it.
- **The builders' trigger is seen from outside only.** It was read from the
builder's public job history, not from its configuration. The first push
to `main` after this change, a successful Build Package run followed by a
`main` job on the builder, confirms it.
- **`check()` duration.** About 10 of the package job's ~18 minutes are
`cargo test --release` linking every test binary with fat LTO
(`[profile.release]`). Testing without `--release` in `check()` would be
Expand Down