Skip to content

Harden CI against scheduled-workflow inactivity disable #684

@rly

Description

@rly

Background

PR #683 surfaced that check_sphinx_links.yml had been auto-disabled by GitHub on grounds of inactivity (state: disabled_inactivity), so it stopped running on PRs even though the YAML still listed pull_request: as a trigger. Once a workflow enters that state, GitHub ignores all triggers, not just schedule:. The result: PR gating disappeared silently for ~5 months.

GitHub only emails repo admins when this happens, which is easy to miss, and there's no first-party feature to surface it elsewhere.

Proposal

1. Decouple the schedule from the PR-gating workflow

A workflow with no schedule: trigger is not subject to inactivity disable. Restructure the linkcheck job using a reusable workflow so that there is no logic duplication:

  • check_sphinx_links.yml — declares on: { pull_request:, workflow_call: } and contains the actual steps. Runs directly on PRs. Cannot be auto-disabled.
  • check_sphinx_links_scheduled.yml — declares on: { schedule:, workflow_dispatch: } and is a one-job caller that does uses: ./.github/workflows/check_sphinx_links.yml. This file can still be auto-disabled, but doing so no longer breaks PR gating.

2. Add an audit workflow that opens an issue when any workflow is disabled

A small workflow that runs daily on a schedule and on push: branches: [dev] (so it stays active itself). It:

  • Calls GET /repos/{owner}/{repo}/actions/workflows.
  • Filters for state == 'disabled_inactivity' (and optionally disabled_manually).
  • Opens an issue listing the affected workflows, deduped against any existing open issue with the same title (or a known label).

This way, if a schedule-only workflow ever gets disabled again, we find out within a day instead of five months.

Acceptance criteria

  • PR-triggered linkcheck runs in a workflow that has no schedule: trigger.
  • Scheduled linkcheck lives in its own file and reuses the PR workflow via workflow_call (no duplicated steps).
  • New audit workflow exists, runs on a daily schedule and on push to dev, and opens an issue when a workflow is in disabled_inactivity.
  • Audit workflow is verified end-to-end (e.g., manually disabling a workflow once and confirming the issue gets created).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions