Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions scripts/compliance-audit.sh
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,18 @@ check_reusable_workflows_disabled() {
continue # hybrid (workflow_call + real trigger) — exempt, must stay active
fi

# Naming lint — a pure reusable must carry the `-reusable.yml` suffix so its
# "library, safe to disable, never runnable" nature is legible from the
# filename. Detection above is by triggers, never by name (a name can lie);
# this is a separate readability finding. Grandfathered: the legacy
# `pr-review.yml` engine is tracked for rename in .github-private#1127 —
# suppress its naming finding until the rename lands.
if [[ "$wf" != *-reusable.yml ]] && [ "$repo/$wf" != ".github-private/pr-review.yml" ]; then
Comment thread
don-petry marked this conversation as resolved.
Resolved
add_finding "$repo" "reusable-workflows" "reusable-naming-$wf" "warning" \
"Pure reusable workflow \`$wf\` (workflow_call-only) does not use the required \`-reusable.yml\` name suffix; rename it to \`<purpose>-reusable.yml\` so its reusable nature is legible from the filename" \
"standards/ci-standards.md#pure-reusable-workflows-must-be-disabled"
Comment thread
don-petry marked this conversation as resolved.
Resolved
fi

# Pure reusable — check its enabled/disabled state.
local state
state=$(gh_api "repos/$ORG/$repo/actions/workflows/$wf" --jq '.state' 2>/dev/null || echo "")
Expand Down
18 changes: 15 additions & 3 deletions standards/ci-standards.md
Original file line number Diff line number Diff line change
Expand Up @@ -166,9 +166,21 @@ release-strategy initiative

**Standard.** A **pure reusable workflow** — one whose `on:` block declares
**`workflow_call` and nothing else** — MUST be set to `disabled_manually` in the
Actions UI. This applies to the single-source-of-truth `*-reusable.yml`
definition files hosted in `petry-projects/.github` and
`petry-projects/.github-private`.
Actions UI, and MUST be named with a **`-reusable.yml`** suffix. Both apply to
the single-source-of-truth reusable definition files hosted in
`petry-projects/.github` and `petry-projects/.github-private`.

**Naming.** The `-reusable.yml` suffix makes the "this is a library, safe to
disable, never runnable on its own" property legible from the filename alone — a
reader (or an auditor) should not have to open the file and parse its `on:` block
to know it is a reusable. The suffix is a **readability aid, not the detection
mechanism**: compliance tooling classifies by triggers, never by name (a name can
lie — see the `pr-review.yml` engine, a pure reusable that predates this rule).
When you extract logic into a new reusable, name it `<purpose>-reusable.yml` from
the start. *Grandfathered exception:* `.github-private/.github/workflows/pr-review.yml`
is a pure reusable that keeps its legacy name until it can be renamed in lockstep
with its caller path and `pr-review/*` release-channel tags — tracked in
`petry-projects/.github-private#1127`.
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved

**Why.** A pure reusable has no independent event triggers, so it can never run
on its own — it executes **only** when another workflow invokes it via `uses:`.
Expand Down
Loading