Three things kept the upstream sync PR (#589) from ever finishing a build: Scoped dispatches wiped the shared PR. A workflow_dispatch with `packages` regenerates only those packages from master, and pushing that to auto/sync-upstream replaced 38 pending updates with one. Scoped runs now push to their own auto/sync-{upstream,rebuilds}-<packages> branch and PR; scheduled runs keep the shared branch. build-approved stopped working after the first bot push. A GITHUB_TOKEN push creates pull_request runs held for approval but no pull_request_target run, so approve-pr.yml never saw it: its last run on the branch was the label itself (2026-09-25T19:26), and each of the next four syncs sat at action_required. The sync workflows now release the held runs for the commit they just pushed, from a separate job holding actions: write, and only for their own bot-authored, same-repo PR while build-approved is on it. Each approved push cancelled the in-flight build. Approving the 21:43 sync's build cancelled the label-triggered one still queued on strata and schist-bin. On auto/sync-* branches a new build now waits for the running one instead, then reuses its artifacts. The approval script no longer waits for a lone approved build to start before releasing tests, which a queued build would have turned into a timeout.
41 lines
1.4 KiB
Bash
Executable File
41 lines
1.4 KiB
Bash
Executable File
#!/bin/bash
|
|
# Usage: sync-pr-branch.sh BASE_BRANCH [PACKAGE...]
|
|
#
|
|
# Prints the branch a sync workflow run pushes to, as branch=/scope= lines for
|
|
# $GITHUB_OUTPUT. An unscoped (scheduled) run owns BASE_BRANCH and regenerates
|
|
# it from master every time. A run scoped to named packages regenerates only
|
|
# those, so it gets its own branch and PR: pushing it to BASE_BRANCH would
|
|
# replace every other pending update there with just the named packages.
|
|
set -euo pipefail
|
|
|
|
base=${1:?base branch required}
|
|
shift
|
|
if (( $# == 0 )); then
|
|
printf 'branch=%s\nscope=\n' "$base"
|
|
exit 0
|
|
fi
|
|
|
|
names=()
|
|
for name in "$@"; do
|
|
# Package directory names, as pacman allows them. Anything else is a typo
|
|
# or an attempt to smuggle something into a ref name or PR title.
|
|
if [[ ! $name =~ ^[a-z0-9@_+][a-z0-9@._+-]*$ ]]; then
|
|
echo "invalid package name: $name" >&2
|
|
exit 1
|
|
fi
|
|
names+=("$name")
|
|
done
|
|
mapfile -t names < <(printf '%s\n' "${names[@]}" | sort -u)
|
|
|
|
scope="${names[*]}"
|
|
slug=$(printf '%s\n' "${names[@]}" | sed 's/[^a-z0-9]\{1,\}/-/g; s/^-//; s/-$//' | paste -sd- -)
|
|
# Keep long package lists to a readable ref; the hash keeps distinct lists apart.
|
|
hash=$(printf '%s' "$scope" | sha256sum | cut -c1-10)
|
|
if [[ -z $slug ]]; then
|
|
slug=$hash
|
|
elif (( ${#slug} > 60 )); then
|
|
slug="${slug:0:48}"
|
|
slug="${slug%-}-$hash"
|
|
fi
|
|
printf 'branch=%s-%s\nscope=%s\n' "$base" "$slug" "$scope"
|