mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-09 20:26:33 +00:00
Merge branch 'feature/swarm-nfs' into feature/svc-net-tor
This commit is contained in:
89 files changed
+702
-237
No files matched your search
@@ -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}"
|
||||
@@ -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
|
||||
@@ -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.
|
||||
|
||||
|
||||
Reference in new issue
Block a user