Merge branch 'feature/swarm-nfs' into feature/svc-net-tor

This commit is contained in:
kevinveenbirkenbach committed 2026-08-07 17:28:13 +02:00
commit d235dd7d7e
89 files changed
+702 -237

No files matched your search

+11
View File
@@ -0,0 +1,11 @@
# Run Reruns 🔁
Shell helpers that restart the unfinished parts of GitHub Actions workflow runs that were cancelled rather than completed.
## Scope 📋
This directory contains helpers invoked from scheduled workflows. They call the GitHub Actions API to rerun the failed jobs of a cancelled run, never the run as a whole, so the work that already succeeded is kept. A run is a candidate only while it is recent and below its attempt ceiling; both bounds are passed in by the calling workflow, because a sweep without them would resurrect abandoned branches and retry a permanently cancelled run forever.
Helpers MUST NOT rerun a run whose conclusion is `failure`. A real defect has to be fixed, not retried, and the [cancel](../cancel/README.md) helpers exist precisely so that a cancellation means "interrupted", not "broken".
For the workflow catalog that drives these calls see [workflows.md](../../../docs/contributing/tools/github/actions/workflows.md).
@@ -0,0 +1,65 @@
#!/usr/bin/env bash
#
# Restart the failed jobs of every branch whose latest workflow run ended
# cancelled.
#
# Inputs via env:
# GH_TOKEN token carrying actions:write on REPOSITORY
# REPOSITORY owner/repo
# MAX_ATTEMPTS leave runs alone once they reached this attempt count;
# 0 keeps reviving a run for as long as it stays in range
# MAX_AGE_HOURS leave runs alone whose last update is older than this
set -euo pipefail
: "${GH_TOKEN:?Missing GH_TOKEN}"
: "${REPOSITORY:?Missing REPOSITORY}"
: "${MAX_ATTEMPTS:?Missing MAX_ATTEMPTS}"
: "${MAX_AGE_HOURS:?Missing MAX_AGE_HOURS}"
if ! command -v gh >/dev/null 2>&1; then
echo "ERROR: gh CLI not found." >&2
exit 1
fi
if ! command -v jq >/dev/null 2>&1; then
echo "ERROR: jq not found." >&2
exit 1
fi
cutoff="$(date -u -d "${MAX_AGE_HOURS} hours ago" +%Y-%m-%dT%H:%M:%SZ)"
echo "Rerunning cancelled runs updated after ${cutoff}, below attempt ${MAX_ATTEMPTS}"
branches="$(
gh api --paginate \
-H "Accept: application/vnd.github+json" \
"/repos/${REPOSITORY}/branches?per_page=100" |
jq -r '.[].name'
)"
while read -r branch; do
[[ -n "${branch}" ]] || continue
run_id="$(
gh run list \
--repo "${REPOSITORY}" \
--branch "${branch}" \
--limit 1 \
--json databaseId,conclusion,attempt,updatedAt |
jq -r --arg cutoff "${cutoff}" --argjson max "${MAX_ATTEMPTS}" '
.[0]
| select(.conclusion == "cancelled")
| select($max == 0 or .attempt < $max)
| select(.updatedAt > $cutoff)
| .databaseId
'
)"
[[ -n "${run_id}" ]] || continue
echo "${branch}: rerunning the failed jobs of cancelled run ${run_id}"
if ! gh run rerun "${run_id}" --repo "${REPOSITORY}" --failed; then
echo "${branch}: run ${run_id} could not be rerun, likely already restarted"
fi
done <<<"${branches}"
+28
View File
@@ -0,0 +1,28 @@
#!/usr/bin/env bash
#
# Emit due=true on GITHUB_OUTPUT when the current hour opens an interval window
# counted from 00:00 UTC. Intervals are rounded up to whole hours.
#
# Inputs via env:
# INTERVAL_MINUTES wanted interval between two sweeps
set -euo pipefail
: "${INTERVAL_MINUTES:?Missing INTERVAL_MINUTES}"
: "${GITHUB_OUTPUT:?Missing GITHUB_OUTPUT}"
hours="$(((INTERVAL_MINUTES + 59) / 60))"
if ((hours < 1)); then
hours=1
fi
hour="$((10#$(date -u +%H)))"
if ((hour % hours == 0)); then
echo "$(date -u +%H:%M) UTC opens the ${hours}h window, sweeping"
echo "due=true" >>"${GITHUB_OUTPUT}"
else
echo "$(date -u +%H:%M) UTC is inside the ${hours}h window, skipping"
echo "due=false" >>"${GITHUB_OUTPUT}"
fi
+1 -1
View File
@@ -4,7 +4,7 @@ Shell helpers that drive the scheduled `Update: Versions` workflow.
## Scope 📋
This directory contains the helpers invoked by [update.yml](../../../.github/workflows/update.yml) to bump pinned upstream versions and open a pull request once per day. The helpers are thin wrappers: the image-version and repository-ref bumpers delegate to Python CLIs under [cli/contributing/](../../../cli/contributing/) that scan `roles/*/meta/services.yml` and rewrite version pins in place; the PR-open helper commits, force-pushes the update branch, and creates or refreshes the PR via `gh`. Helpers MUST NOT be called from workflows other than `Update: Versions`; the `CI_ENABLE_AUTO_UPDATES` gate is enforced once, at the workflow's job level, and bypassing it from another caller would create PRs even when auto-updates are intentionally disabled.
This directory contains the helpers invoked by [cron-update.yml](../../../.github/workflows/cron-update.yml) to bump pinned upstream versions and open a pull request once per day. The helpers are thin wrappers: the image-version and repository-ref bumpers delegate to Python CLIs under [cli/contributing/](../../../cli/contributing/) that scan `roles/*/meta/services.yml` and rewrite version pins in place; the PR-open helper commits, force-pushes the update branch, and creates or refreshes the PR via `gh`. Helpers MUST NOT be called from workflows other than `⏰ Update: Versions`; the `CI_ENABLE_AUTO_UPDATES` gate is enforced once, at the workflow's job level, and bypassing it from another caller would create PRs even when auto-updates are intentionally disabled.
Each shim MUST resolve the repository root relative to its own location so it can run from any working directory, MUST forward arguments to the underlying CLI so `--dry-run` and similar flags keep working from the shell, and MUST exit non-zero on CLI failure so the workflow surfaces the error.