ci: take the package list from the UPDATE_PACKAGES variable instead of the matrix
This commit is contained in:
1 parent
2565c193e6
commit
fd0e27af6c
2 files changed
+121
-16
No files matched your search
@@ -31,7 +31,86 @@ defaults:
|
|||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
# Resolves the package list for the update matrix below, so adding or
|
||||||
|
# dropping a package is a variable edit on the org, not a commit here.
|
||||||
|
# See README "Package list".
|
||||||
|
plan:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
outputs:
|
||||||
|
packages: ${{ steps.resolve.outputs.packages }}
|
||||||
|
steps:
|
||||||
|
- name: Resolve the package list
|
||||||
|
id: resolve
|
||||||
|
# Both go through the environment, never pasted into the script: the
|
||||||
|
# variable is free-form multi-line text.
|
||||||
|
env:
|
||||||
|
UPDATE_PACKAGES: ${{ vars.UPDATE_PACKAGES }}
|
||||||
|
PACKAGE_INPUT: ${{ inputs.package }}
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
export LC_ALL=C
|
||||||
|
: "${UPDATE_PACKAGES:=}" "${PACKAGE_INPUT:=}"
|
||||||
|
re='^[A-Za-z0-9][A-Za-z0-9._+-]*$'
|
||||||
|
pkgs=()
|
||||||
|
declare -A seen=()
|
||||||
|
|
||||||
|
# add NAME: validate, then append unless already listed.
|
||||||
|
add() {
|
||||||
|
if [[ ! $1 =~ $re ]]; then
|
||||||
|
echo "::error::${from}: invalid package name '$1' (letters, digits and . _ + - only, starting with a letter or digit)" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if [ -z "${seen[$1]:-}" ]; then
|
||||||
|
seen[$1]=1
|
||||||
|
pkgs+=("$1")
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ -n "${PACKAGE_INPUT//[[:space:]]/}" ]; then
|
||||||
|
# workflow_dispatch with a package name runs only that one,
|
||||||
|
# whatever UPDATE_PACKAGES says. Surrounding whitespace is
|
||||||
|
# trimmed; the rest must be a single valid name.
|
||||||
|
from="workflow_dispatch input 'package'"
|
||||||
|
want=${PACKAGE_INPUT#"${PACKAGE_INPUT%%[![:space:]]*}"}
|
||||||
|
want=${want%"${want##*[![:space:]]}"}
|
||||||
|
add "${want}"
|
||||||
|
else
|
||||||
|
# "- a\n- b", "a\nb", "- a - b" and "a b" are the same list:
|
||||||
|
# comments go first, then every whitespace run (CR included, in
|
||||||
|
# case the value was saved with CRLF line ends) becomes a line
|
||||||
|
# break. Each line is then a name, a lone "-" list marker, or a
|
||||||
|
# "-" glued to a name.
|
||||||
|
from="UPDATE_PACKAGES"
|
||||||
|
while IFS= read -r tok; do
|
||||||
|
case ${tok} in
|
||||||
|
"" | -) continue ;;
|
||||||
|
-*) tok=${tok#-} ;;
|
||||||
|
esac
|
||||||
|
add "${tok}"
|
||||||
|
done <<< "$(printf '%s\n' "${UPDATE_PACKAGES}" | sed -e 's/#.*$//' | tr -s '[:space:]' '\n')"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Fail rather than run nothing: an empty matrix would pass and look
|
||||||
|
# exactly like a night with nothing to update.
|
||||||
|
if [ "${#pkgs[@]}" -eq 0 ]; then
|
||||||
|
echo '::error::UPDATE_PACKAGES is not set: add an org or repo variable with one package per line (leading "- " optional)' >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Names are validated above, so none needs JSON escaping.
|
||||||
|
json=
|
||||||
|
for p in "${pkgs[@]}"; do
|
||||||
|
json+="${json:+,}\"${p}\""
|
||||||
|
done
|
||||||
|
json="[${json}]"
|
||||||
|
|
||||||
|
echo "${#pkgs[@]} package(s) from ${from}:"
|
||||||
|
printf ' - %s\n' "${pkgs[@]}"
|
||||||
|
echo "matrix: ${json}"
|
||||||
|
echo "packages=${json}" >> "${GITHUB_OUTPUT}"
|
||||||
|
|
||||||
update:
|
update:
|
||||||
|
needs: plan
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
# A real Arch makepkg is required. Ubuntu's build environment silently
|
# A real Arch makepkg is required. Ubuntu's build environment silently
|
||||||
# emits an empty .SRCINFO, which the AUR then rejects -- that is what broke
|
# emits an empty .SRCINFO, which the AUR then rejects -- that is what broke
|
||||||
@@ -50,13 +129,9 @@ jobs:
|
|||||||
# One broken package must not cancel the rest of the matrix.
|
# One broken package must not cancel the rest of the matrix.
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
package:
|
# One entry per package, resolved by the plan job above from
|
||||||
- nethlink-appimage
|
# vars.UPDATE_PACKAGES or the dispatch input.
|
||||||
- open-video-downloader-appimage
|
package: ${{ fromJSON(needs.plan.outputs.packages) }}
|
||||||
- open-video-downloader-bin
|
|
||||||
- pman-helper
|
|
||||||
- reflex-appimage
|
|
||||||
- tsparams
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
# No bootstrap step: node, git, openssh, jq, curl and the makepkg
|
# No bootstrap step: node, git, openssh, jq, curl and the makepkg
|
||||||
@@ -127,12 +202,6 @@ jobs:
|
|||||||
NO_GIT_PUSH: ${{ (inputs.no_git_push == true || inputs.no_git_push == 'true') && '1' || '' }}
|
NO_GIT_PUSH: ${{ (inputs.no_git_push == true || inputs.no_git_push == 'true') && '1' || '' }}
|
||||||
run: |
|
run: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
# workflow_dispatch with a package name runs only that one.
|
|
||||||
want="${{ inputs.package }}"
|
|
||||||
if [ -n "${want}" ] && [ "${want}" != "${{ matrix.package }}" ]; then
|
|
||||||
echo "skipping ${{ matrix.package }} (dispatch asked for ${want})"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
runuser -u builder -- env \
|
runuser -u builder -- env \
|
||||||
GIT_HOST="${GIT_HOST}" \
|
GIT_HOST="${GIT_HOST}" \
|
||||||
FORCE_REBUILD="${FORCE_REBUILD}" \
|
FORCE_REBUILD="${FORCE_REBUILD}" \
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ three take the same path, and the AUR reconcile runs on every pass.
|
|||||||
| `sync-aur.sh` | reconciles the repo against the AUR |
|
| `sync-aur.sh` | reconciles the repo against the AUR |
|
||||||
| `common.sh` | logging, guards, PKGBUILD parsing and array splicing |
|
| `common.sh` | logging, guards, PKGBUILD parsing and array splicing |
|
||||||
| `test.sh` | hermetic test suite |
|
| `test.sh` | hermetic test suite |
|
||||||
| `.gitea/workflows/update.yaml` | nightly matrix job |
|
| `.gitea/workflows/update.yaml` | nightly job: `plan` reads `UPDATE_PACKAGES`, `update` runs one matrix entry per package |
|
||||||
|
|
||||||
Nothing here is package-specific. Everything that differs between packages
|
Nothing here is package-specific. Everything that differs between packages
|
||||||
lives in a `.autoupdate` manifest committed to the package repo itself.
|
lives in a `.autoupdate` manifest committed to the package repo itself.
|
||||||
@@ -40,6 +40,42 @@ icon="reflex.png"
|
|||||||
It rides along to the AUR on push, as `README.md` and `LICENSE` already do.
|
It rides along to the AUR on push, as `README.md` and `LICENSE` already do.
|
||||||
Harmless: the AUR reads only `PKGBUILD` and `.SRCINFO`.
|
Harmless: the AUR reads only `PKGBUILD` and `.SRCINFO`.
|
||||||
|
|
||||||
|
## Package list
|
||||||
|
|
||||||
|
The nightly job updates the packages named in the Gitea Actions variable
|
||||||
|
`UPDATE_PACKAGES`; nothing in this repo lists them. Set it on the `aur` org
|
||||||
|
(Settings -> Actions -> Variables), which is the recommended place; a variable
|
||||||
|
of the same name on `aur/.autoupdate` itself overrides the org one.
|
||||||
|
|
||||||
|
One package per line. A leading `- ` is optional, so YAML-list lines and bare
|
||||||
|
names both work and can be mixed; blank lines and `#` comments (whole-line or
|
||||||
|
trailing) are ignored, and duplicates are dropped. A name must match
|
||||||
|
`^[A-Za-z0-9][A-Za-z0-9._+-]*$`, otherwise the run fails naming it. The
|
||||||
|
current value:
|
||||||
|
|
||||||
|
```
|
||||||
|
- nethlink-appimage
|
||||||
|
- open-video-downloader-appimage
|
||||||
|
- open-video-downloader-bin
|
||||||
|
- pman-helper
|
||||||
|
- reflex-appimage
|
||||||
|
- tsparams
|
||||||
|
```
|
||||||
|
|
||||||
|
Add `- skeptical-updater` once `source/skeptical-updater` has its first tag.
|
||||||
|
Until then its version lookup finds no tag, which is a failed lookup (see
|
||||||
|
[Exit codes](#exit-codes)) and would turn that matrix job red every night.
|
||||||
|
|
||||||
|
The workflow's `plan` job turns the variable into the `update` matrix, one job
|
||||||
|
per package. A manual run's `package` input (Actions -> Update AUR Packages ->
|
||||||
|
Run workflow) overrides the variable and runs that one package only, listed or
|
||||||
|
not. An unset or empty variable fails the run on purpose: an empty matrix
|
||||||
|
would pass and look exactly like a night with nothing to update.
|
||||||
|
|
||||||
|
This needs Gitea 28.0 or newer, the first release that expands a matrix from
|
||||||
|
another job's outputs. Older servers expand it before `plan` has run, start a
|
||||||
|
single `update` job with an empty package name, and that job fails.
|
||||||
|
|
||||||
## What a run does
|
## What a run does
|
||||||
|
|
||||||
1. Clone the package repo, read its manifest.
|
1. Clone the package repo, read its manifest.
|
||||||
@@ -116,8 +152,8 @@ immediately instead of taking a silently wrong branch further in.
|
|||||||
## Container image
|
## Container image
|
||||||
|
|
||||||
`dockerfile` builds the environment the nightly job runs in, published to the
|
`dockerfile` builds the environment the nightly job runs in, published to the
|
||||||
Gitea registry as `git.bjphoster.com/aur/autoupdate:latest`. Without it, all six
|
Gitea registry as `git.bjphoster.com/aur/autoupdate:latest`. Without it, every
|
||||||
matrix jobs would run a full `pacman` transaction every night.
|
matrix job would run a full `pacman` transaction every night.
|
||||||
|
|
||||||
`.gitea/workflows/build-image.yaml` rebuilds and overwrites `:latest` monthly
|
`.gitea/workflows/build-image.yaml` rebuilds and overwrites `:latest` monthly
|
||||||
(Arch is rolling, so a month-old image is a month behind), on any push touching
|
(Arch is rolling, so a month-old image is a month behind), on any push touching
|
||||||
|
|||||||
Reference in new issue
Block a user