Skip to content

ci: enforce commit-trailer and commit-message policy org-wide, not in one repo #464

Description

@ss-o

Problem

Organization policy bans the Co-authored-by commit trailer, and both
decisions/0009-testing-ci-strategy.md and runbooks/onboarding.md describe it
as enforced in CI via the DISALLOWED_TRAILER_PATTERN org secret.

That enforcement does not exist anywhere. A sweep of 213 workflow files across
all 86 active repositories
, using the git trees and contents API, found no
workflow on any default branch
that checks for the trailer or references the
secret.

The only implementation is .github/workflows/commit-lint.yml in z-shell/zi,
and it exists only on the next branch — it has never been on main. So even
zi is unprotected for pull requests based on its default branch.

How it surfaced

z-shell/zsh-fancy-completions PR #45 carries a commit whose message includes the
banned trailer. Nothing flagged it. The trailer was left in place deliberately
after review; the enforcement gap is the durable issue.

Evidence

Check Result
Repos swept (active, public, non-fork) 86
Workflow files read on default branches 213
Repos with no workflows at all 23
Default-branch workflows checking the trailer 0
Implementations found on non-default branches 1 (z-shell/zi @ next)

decisions/0009-testing-ci-strategy.md and runbooks/onboarding.md both describe
this control as active. Both are inaccurate.

Caveat: the sweep covered default branches only. Non-default branches across the
org were not enumerated, so other unmerged implementations may exist.

Proposal

Enforce at the organization level rather than copying a workflow into 85 repos.

  1. Promote zi's commit-lint.yml into a reusable workflow in this repository
    with a workflow_call trigger. It currently triggers only on pull_request, so
    it cannot be called cross-repo as written. Its three jobs — commit-message
    validation (Conventional Commits + disallowed trailer), PR-title validation, and
    branch-name validation — are all org policy, not zi policy.
  2. Roll out via one of:
    • thin per-repo callers (uses: z-shell/.github/.github/workflows/commit-lint.yml@main),
      consistent with the existing reusable-workflow pattern; or
    • an organization ruleset requiring the workflow, which avoids per-repo YAML
      entirely. Needs admin:org to configure and to confirm the secret's
      visibility is set to all repositories.
  3. Update decisions/0009 and runbooks/onboarding.md once enforcement is
    real, so the docs stop describing a control that does not exist.

Blocker to resolve first

The two policies contradict each other on branch naming, so rolling the workflow
out as-is would fail valid branches org-wide:

Source Required pattern
commit-lint.yml line 92 ^(feat|fix|perf|refactor|docs|test|ci|chore|revert)/[a-z0-9-]+$
Workspace AGENTS.md — Branching and Commit Rules feature-<id>, bug-<id>, hotfix-<id>

A branch valid under one is rejected by the other. Decide which is canonical before
the branch-naming job is enforced anywhere beyond zi. The commit-message and
PR-title jobs have no such conflict and could roll out independently.

Acceptance criteria

  • Canonical branch-naming convention decided and documented in one place
  • Reusable commit-lint workflow exists in z-shell/.github with workflow_call
  • Rollout mechanism chosen (per-repo callers vs org ruleset)
  • DISALLOWED_TRAILER_PATTERN secret visibility confirmed for target repos
  • decisions/0009 and runbooks/onboarding.md updated to match reality

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:ciContinuous integration or GitHub Actions work.area:metaOrganization-wide policy, templates, or meta-repo work.meta:org-trackedIndicates this issue has cross-repository tracking implications (synced to Linear).status:blockedCannot proceed until an external dependency or decision changes.type:featureA request for new behavior or capability.type:maintenanceNon-feature maintenance, cleanup, or org work.

    Type

    No type

    Projects

    Status
    Triage

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions