Skip to content

hypatia: detect workflow triggers referencing non-existent branches (from #333 cohort, pattern 4) #363

@hyperpolymath

Description

@hyperpolymath

Detector spec (from hypatia#333 Pattern 4)

Pattern 4 — Workflow triggers reference branches that don't exist in the repo

Severity: low (dead config, but signals maintenance drift)

Detection (Hypatia.Rules.StructuralDrift):

  • For each workflow file, collect on.push.branches, on.pull_request.branches, on.push.branches-ignore, etc.
  • Resolve them against the repo's actual branch list (via the git index or GitHub API).
  • Flag any branch name that:
    • Doesn't exist as a ref, AND
    • Isn't a glob pattern, AND
    • Isn't the default branch name (some teams keep master/main for migration symmetry — exempt those).

Worked examples (this session):

  • affinescript/.github/workflows/{semgrep,spark-theatre-gate}.ymlbranches: [main, master] while the repo uses main exclusively. Fix: affinescript#379 dropped master.
  • hypatia/.github/workflows/{tests,verify-proofs}.ymldevelop and master were dead. Fix: hypatia#331 dropped them.

Remediation guidance to emit:

Drop branch refs in workflow triggers that don't resolve to actual branches in this repo. Confirms intent and avoids ambiguity.

Implementation pointers

  • Detection algorithm: Collect on.push.branches, on.pull_request.branches, on.push.branches-ignore per workflow; resolve against actual repo branches; flag names that aren't refs, aren't globs, and aren't the default branch.
  • Real-world example: affinescript/.github/workflows/{semgrep,spark-theatre-gate}.yml listed master while repo uses main only; hypatia/.github/workflows/{tests,verify-proofs}.yml listed dead develop and master.
  • Landed fix (reference): affinescript#379 (dropped master in affinescript); hypatia#331 (dropped develop/master in hypatia).
  • Rule statement: Drop branch refs in workflow triggers that don't resolve to actual branches in this repo. Confirms intent and avoids ambiguity.

Acceptance

  • Rule encoded in hypatia (file path follows existing rule naming convention — lib/rules/<name>.ex if Elixir, or matching the repo's rule DSL)
  • Test fixture exercising the positive case + at least one negative case
  • Smoke test passes against the cited landed-fix repo

Source cohort: hypatia#333.

Metadata

Metadata

Assignees

No one assigned

    Labels

    cicdCI/CD pipeline, GitHub Actions, workflows, rulesets, releasesenhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions