From 73ccb6ff96ac8d5ec9bb60f2a61785e5fd6cdc76 Mon Sep 17 00:00:00 2001 From: Siarhei Bakatsiuk Date: Fri, 30 Oct 2026 08:48:19 +0300 Subject: [PATCH] ci: keep the scheduled watchers enabled through quiet spells GitHub disables every scheduled workflow in a public repository after 60 days without activity. In September-October 2026 that switched off upstream-drift in 22 of the 23 repositories of these families, and new upstream releases went unreported for weeks. keepalive.yml re-enables every active workflow weekly through the API - itself included - which restarts the 60-day clock without a commit. Workflows disabled by hand are left alone. Byte-identical across the families, like notify-parents.yml. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/keepalive.yml | 47 +++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 .github/workflows/keepalive.yml diff --git a/.github/workflows/keepalive.yml b/.github/workflows/keepalive.yml new file mode 100644 index 0000000..1371c93 --- /dev/null +++ b/.github/workflows/keepalive.yml @@ -0,0 +1,47 @@ +name: workflow keepalive + +# GitHub disables every scheduled workflow in a public repository once the repository has seen no +# activity for 60 days, and it does so silently. The watchers here - upstream-drift.yml and, where +# they exist, upstream-watch.yml and weekly-drift.yml - are meant to keep reporting while nothing +# is being committed, which is exactly when they get switched off: in October 2026 22 of the 23 +# repositories in these families had theirs disabled this way, and upstream releases went +# unreported for weeks. +# +# Re-enabling a workflow through the API restarts its 60-day clock without a commit, so this does +# that weekly for every workflow still in the `active` state - itself included, which is what +# keeps the keepalive alive. Workflows switched off by hand (`disabled_manually`) are left alone: +# that is a decision, not drift. A workflow that has already been disabled for inactivity is left +# alone too - by then this one has been disabled as well, and `gh workflow enable` is the fix. +# +# Kept byte-identical across every repository in these families that has a scheduled workflow. + +on: + schedule: + # Mondays, 05:41 UTC - off the full hour, where GitHub sheds scheduled runs under load. + - cron: '41 5 * * 1' + workflow_dispatch: + +permissions: + actions: write + +jobs: + keepalive: + # Forks keep their own schedules, or none. + if: github.repository_owner == 'sbokatuk' + name: re-enable active workflows + runs-on: ubuntu-latest + timeout-minutes: 5 + env: + GH_TOKEN: ${{ github.token }} + steps: + - name: re-enable every active workflow + run: | + set -euo pipefail + # Only files under .github/workflows: the list also carries GitHub's own dynamic + # workflows (Copilot, Pages), which cannot be enabled or disabled through this API. + gh api "repos/${GITHUB_REPOSITORY}/actions/workflows" --paginate \ + --jq '.workflows[] | select(.state == "active" and (.path | startswith(".github/workflows/"))) | [.id, .path] | @tsv' \ + | while IFS=$'\t' read -r id path; do + gh api -X PUT "repos/${GITHUB_REPOSITORY}/actions/workflows/${id}/enable" > /dev/null + printf -- '- re-enabled `%s`\n' "${path}" | tee -a "${GITHUB_STEP_SUMMARY}" + done