Skip to content

feat: daily repo health check GitHub Action with structured report #153

Description

@markcallen

Overview

Add a scheduled GitHub Actions workflow (.github/workflows/health.yml) that runs daily, audits the health of the repository and Ballast installation, and produces a structured report surfaced as a workflow summary and optionally as a GitHub issue comment.

The /github-health-check skill provides an on-demand version of this check. This issue covers the automated daily scheduled variant with a persistent, trend-aware report format.


Goals

  • Give maintainers a daily signal on repository health without manual inspection.
  • Surface actionable items (stale PRs, failing checks, security alerts, drift from Ballast config) in one place.
  • Establish a baseline so trends (improving / degrading) are visible over time.
  • Follow GitHub Actions and open-source repo hygiene best practices.

Workflow Requirements

Schedule and Triggers

  • Run on schedule at a fixed daily time (e.g. cron: '0 7 * * *' — 07:00 UTC).
  • Support workflow_dispatch for on-demand runs.
  • Add a concurrency block so overlapping scheduled runs are cancelled:
    concurrency:
      group: ${{ github.workflow }}
      cancel-in-progress: true

Permissions

  • Use least-privilege permissions scoped to the job:
    • contents: read
    • issues: write (only if posting to issues)
    • pull-requests: read
    • security-events: read
  • Use GITHUB_TOKEN; no long-lived PAT required.

Implementation

  • Use the gh CLI (available in actions/checkout runners) and the GitHub REST/GraphQL API via gh api for all data gathering.
  • Write the report generation as a shell script (scripts/health-report.sh) so it is testable locally with gh auth login.
  • Publish the full report to the GitHub Actions workflow summary ($GITHUB_STEP_SUMMARY) so it is visible directly in the Actions UI without navigating elsewhere.
  • Optionally open or update a pinned GitHub issue tagged health-report with the latest report body (use gh issue edit to update in place).
  • Upload the raw JSON data as a workflow artifact (health-report.json) for retention and future trend analysis.

Report Sections and Requirements

Each section uses a consistent structure: a header, a status badge (✅ healthy / ⚠️ needs attention / 🔴 critical), a summary line, and a bulleted detail list with direct links.


1. CI / Workflow Health

Answers: Are our automated checks passing reliably?

  • Last 7-day pass rate for each workflow in .github/workflows/.
  • Current status of the most recent run per workflow (pass / fail / cancelled / skipped).
  • Average duration trend for the primary CI workflow (faster / slower than last week).
  • Any workflow that has not run in the past 7 days (possibly broken trigger).
  • Flag any workflow without a concurrency block (risk of redundant runs).

Threshold: 🔴 if any required workflow (lint, test, build, publish) has a <80% pass rate over 7 days.


2. Security Posture

Answers: Are there known vulnerabilities or exposed secrets?

  • Count of open Dependabot alerts by severity (critical / high / medium / low).
  • Count of open secret scanning alerts with types (e.g. GitHub token, AWS key).
  • Count of open code scanning alerts (if CodeQL or similar is enabled).
  • Date of oldest unresolved critical/high alert.
  • Whether Dependabot is enabled and has an up-to-date .github/dependabot.yml.
  • Whether branch protection requires passing status checks before merge.

Threshold: 🔴 if any critical Dependabot or secret scanning alert is unresolved. ⚠️ for high severity alerts older than 14 days.


3. Dependency and PR Hygiene

Answers: Are we keeping dependencies current and landing work promptly?

  • Count of open Dependabot PRs grouped by ecosystem (npm, go, github-actions).
  • Age of oldest open Dependabot PR (stale = >14 days).
  • Total open PRs, count stale (no activity >7 days), count awaiting review >48 h.
  • Count of draft PRs older than 7 days (possibly abandoned).
  • Count of PRs with failing checks that are not drafts.
  • Merge frequency: PRs merged in the last 7 days.

Threshold: ⚠️ if any Dependabot PR is >14 days old or any non-draft PR has been waiting for review >7 days.


4. Branch Hygiene

Answers: Is the branch graph clean?

  • Count of branches with no commit activity in >30 days (stale).
  • Count of branches that are fully merged into main but not deleted.
  • Whether main is the default branch and has branch protection enabled.
  • Required status checks configured on main (list which workflows are required).
  • Whether direct pushes to main are blocked (force-push protection).

Threshold: ⚠️ if >5 stale or fully-merged branches exist. 🔴 if main has no branch protection.


5. Issue Health

Answers: Are open issues being triaged and resolved?

  • Total open issues and trend vs. 7 days ago (growing / shrinking / stable).
  • Count of issues with no response (no comment, no label, no assignee) older than 7 days.
  • Count of issues open >30 days with no activity (stale).
  • Count of issues labelled bug open >14 days.
  • Count of issues labelled health-report (the pinned daily report issue — should be exactly 1).

Threshold: ⚠️ if >10 issues have had no triage activity in >7 days.


6. Release and Publish Health

Answers: Is the release pipeline working and are we shipping regularly?

  • Date and tag of the most recent GitHub release.
  • Days since last release (flag if >30 days and the repo is actively developed).
  • Status of the most recent publish workflow run (pass / fail).
  • Whether the version in package.json / go.mod / pyproject.toml matches the latest release tag.
  • Whether the latest release has release notes.

Threshold: ⚠️ if the last publish workflow run failed or if the version file is out of sync with the latest tag.


7. Repository Configuration

Answers: Does the repo have the baseline hygiene files and settings?

  • Required files present: README.md, LICENSE, CONTRIBUTING.md or AGENTS.md, SECURITY.md, CHANGELOG.md.
  • .github/CODEOWNERS present.
  • .github/dependabot.yml present and covers both npm/go/pip and github-actions.
  • Discussions enabled or issues enabled (at least one engagement channel).
  • Repository description and homepage URL set.
  • Topics / tags set (helps discoverability).

Threshold: ⚠️ for any missing required file. 🔴 if LICENSE is absent.


8. Ballast Installation Health

Answers: Is Ballast configured correctly and are rule files current?

  • .rulesrc.json is present and parseable.
  • ballastVersion in .rulesrc.json matches the latest published Ballast release on npm (ballast-typescript).
  • All configured targets (cursor, claude, codex, opencode, gemini) have their expected rule directories and files present.
  • All configured agents have corresponding rule files for each target (no missing rule files).
  • taskSystem field is present in .rulesrc.json when the tasks agent is configured.
  • Skills listed in .rulesrc.json have corresponding .skill files.
  • Run ballast doctor and report its exit code and output summary.

Threshold: 🔴 if .rulesrc.json is missing or ballast doctor exits non-zero. ⚠️ if ballastVersion is more than one minor version behind the latest release.


Report Format (Markdown Summary)

# 🏥 Daily Repository Health Report — 2026-04-27

| Area | Status | Summary |
|------|--------|---------|
| CI / Workflows || All 5 workflows passing (7-day rate: 97%) |
| Security | ⚠️ | 3 high Dependabot alerts open >7 days |
| Dependencies / PRs || 2 Dependabot PRs open, oldest 3 days |
| Branch Hygiene || 1 stale branch, main protected |
| Issues || 12 open, 0 untriaged >7 days |
| Releases || Last release v5.8.0 on 2026-04-20 |
| Repo Config || All required files present |
| Ballast Health || v5.8.0 installed, doctor exit 0 |

---

## ⚠️ Needs Attention

- **Security**: [dependabot/npm_and_yarn/…](#) — high severity, open 9 days → [View alert]()
- **Security**: [dependabot/npm_and_yarn/…](#) — high severity, open 12 days → [View alert]()

## Details

<details><summary>CI / Workflow Health</summary>…</details>
<details><summary>Security Posture</summary>…</details>
…

Acceptance Criteria

  • .github/workflows/health.yml runs on schedule (0 7 * * *) and workflow_dispatch.
  • All 8 report sections are populated with real data from the GitHub API.
  • Report is written to $GITHUB_STEP_SUMMARY and visible in the Actions UI.
  • Raw data is uploaded as health-report.json artifact with 90-day retention.
  • A pinned issue tagged health-report is created/updated with the report on each run.
  • ballast doctor is run as part of the Ballast Health section.
  • The workflow uses least-privilege permissions and GITHUB_TOKEN only.
  • The report generation logic lives in scripts/health-report.sh and can be run locally.
  • A README badge links to the health workflow status.
  • All thresholds defined above are implemented with correct status indicators.

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Fields

    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