Skip to content

feat(workflows): centralize standards via reusable workflows#87

Merged
don-petry merged 3 commits intomainfrom
feat/centralize-workflow-standards
Apr 8, 2026
Merged

feat(workflows): centralize standards via reusable workflows#87
don-petry merged 3 commits intomainfrom
feat/centralize-workflow-standards

Conversation

@don-petry
Copy link
Copy Markdown
Contributor

@don-petry don-petry commented Apr 8, 2026

Summary

Extends the proven feature-ideation reusable-workflow pattern to the rest of the standardizable workflows. Builds four new reusables in .github/workflows/ and migrates the matching standards/workflows/*.yml templates from full inline copies to thin caller stubs that delegate via uses: petry-projects/.github/.github/workflows/<name>-reusable.yml@main.

Net effect: ~580 lines removed from standards/workflows; downstream repos that adopt the new stubs go from carrying ~115–220 lines per workflow to ~30 lines.

What changed

New reusables in .github/workflows/:

  • dependency-audit-reusable.yml — zero per-repo config, multi-ecosystem detection
  • dependabot-automerge-reusable.ymlsecrets: inherit for APP_ID/APP_PRIVATE_KEY
  • dependabot-rebase-reusable.yml — same secrets pattern
  • agent-shield-reusable.yml — exposes min-severity, agentshield-version, required-files, org-standards-ref as workflow_call inputs

Migrated to stubs in standards/workflows/:

Each migrated stub now carries a uniform "SOURCE OF TRUTH" header block telling agents what they may and may not edit.

Tier model

Workflow Centralized? Caller stub size
feature-ideation ✅ (already) ~30 lines
claude (this PR) ~30 lines
dependency-audit (this PR) ~30 lines
dependabot-automerge (this PR) ~30 lines
dependabot-rebase (this PR) ~30 lines
agent-shield (this PR) ~30 lines (with optional inputs)
ci / codeql / sonarcloud ❌ stack-specific per-repo template

Test plan

  • actionlint clean on all 9 changed/added files
  • No changes to existing reusables — only additions and stub migrations
  • CI on this branch
  • After merge: tag v1 (in follow-up PR B), then sweep downstream repos to adopt stubs (follow-up)

Follow-ups

  • PR B: Add SOURCE-OF-TRUTH headers to per-repo templates (ci.yml, codeql.yml, sonarcloud.yml); add tier-model section to ci-standards.md; switch all stub @main refs to @v1 and tag.
  • PR C: Extend compliance-audit-and-improvement.yml to fail when downstream copies of centralized workflows are not thin stubs.
  • Sweep: Adopt the new stubs in the 8 downstream repos.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added reusable workflows for AgentShield security scanning, Dependabot auto-merge, Dependabot rebase, and multi-ecosystem dependency auditing
    • Introduced a reusable Claude-code workflow and switched local Claude jobs to call it
  • Refactor

    • Replaced multiple inline CI jobs with thin caller jobs that delegate to centralized reusable workflows for consistency and easier maintenance

Build org-wide reusable workflows for the four standards that previously
required full inline copies in every downstream repo, and migrate the
matching standards/workflows/*.yml templates to thin caller stubs that
delegate via `uses: petry-projects/.github/.github/workflows/*-reusable.yml@main`.

This extends the pattern already proven by feature-ideation and the
existing claude-code-reusable workflow to the rest of the standard set:

  - dependency-audit-reusable.yml      (zero per-repo config)
  - dependabot-automerge-reusable.yml  (uses secrets: inherit for APP_*)
  - dependabot-rebase-reusable.yml     (uses secrets: inherit for APP_*)
  - agent-shield-reusable.yml          (inputs for severity/required-files/org-ref)

The standards/workflows/claude.yml template was also still the inline
115-line version even though claude-code-reusable.yml has existed for
weeks; migrate it to a stub matching the central repo's own claude.yml.

Each migrated stub now carries a uniform "SOURCE OF TRUTH" header block
telling agents what they may and may not edit. Net effect: ~580 lines
removed from standards/workflows, single point of maintenance for the
five centralizable workflows.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings April 8, 2026 02:46
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 8, 2026

📝 Walkthrough

Walkthrough

Adds four new reusable GitHub Actions workflows (AgentShield, Dependabot auto-merge, Dependabot rebase, Dependency audit) and replaces multiple inline org-standard workflow jobs with thin caller stubs that invoke those reusable workflows; consolidates two Claude jobs into a single reusable invocation. (≤50 words)

Changes

Cohort / File(s) Summary
AgentShield
.github/workflows/agent-shield-reusable.yml, standards/workflows/agent-shield.yml
Add reusable AgentShield workflow (ecc-agentshield scan, required-file checks, CLAUDE/AGENTS cross-reference, SKILL.md frontmatter validation). Replace inline job in standards workflow with a uses: call to the reusable workflow.
Dependabot Auto-Merge
.github/workflows/dependabot-automerge-reusable.yml, standards/workflows/dependabot-automerge.yml
Add reusable workflow to auto-approve and auto-merge eligible Dependabot PRs using a GitHub App (requires APP_ID/APP_PRIVATE_KEY). Standards workflow now calls the reusable workflow and inherits secrets.
Dependabot Rebase / Merge
.github/workflows/dependabot-rebase-reusable.yml, standards/workflows/dependabot-rebase.yml
Add reusable workflow that lists Dependabot PRs, updates branches behind main, inspects status checks, and merges serially via GitHub App token. Replace inline update/merge job with a uses: caller.
Dependency Audit
.github/workflows/dependency-audit-reusable.yml, standards/workflows/dependency-audit.yml
Add reusable multi-ecosystem dependency-audit workflow (detects lockfiles and runs npm/pnpm/govulncheck/cargo-audit/pip-audit). Standards workflow delegates to the reusable workflow.
Claude / Automation
standards/workflows/claude.yml
Consolidate two local Claude jobs into a single job that calls an org-level reusable claude-code workflow and inherits secrets; inline steps and local conditional logic removed.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately summarizes the main objective: centralizing workflow standards through reusable workflows, which is exactly what the changeset delivers.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/centralize-workflow-standards

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Centralizes org-standard GitHub Actions workflows by introducing reusable workflows under .github/workflows/ and converting the corresponding standards/workflows/*.yml templates into thin caller stubs that delegate via uses:. This reduces duplication and makes future workflow updates propagate from a single source of truth.

Changes:

  • Added 4 new reusable workflows: dependency audit, dependabot automerge, dependabot rebase, and agent-shield.
  • Migrated 5 standards workflow templates from inline implementations to thin caller stubs.
  • Standardized “SOURCE OF TRUTH” header blocks in the migrated stubs.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
standards/workflows/dependency-audit.yml Converted to thin stub delegating to the new dependency-audit reusable.
standards/workflows/dependabot-rebase.yml Converted to thin stub delegating to the new dependabot-rebase reusable.
standards/workflows/dependabot-automerge.yml Converted to thin stub delegating to the new dependabot-automerge reusable.
standards/workflows/claude.yml Converted to thin stub delegating to existing claude-code-reusable.yml.
standards/workflows/agent-shield.yml Converted to thin stub delegating to the new agent-shield reusable.
.github/workflows/dependency-audit-reusable.yml New reusable implementing multi-ecosystem dependency detection + audits.
.github/workflows/dependabot-rebase-reusable.yml New reusable implementing serialized dependabot update-branch + merge logic.
.github/workflows/dependabot-automerge-reusable.yml New reusable implementing dependabot eligibility + approve/auto-merge flow.
.github/workflows/agent-shield-reusable.yml New reusable implementing AgentShield scan + org structural checks with inputs.
Comments suppressed due to low confidence (1)

standards/workflows/dependabot-rebase.yml:38

  • permissions: {} at the workflow level combined with no job-level permissions means the called reusable cannot obtain even read scopes for GITHUB_TOKEN (permissions are an intersection for reusable workflows). The reusable uses gh api / gh pr view and needs at least contents: read + pull-requests: read; please set those permissions on this calling job (see standards/workflows/feature-ideation.yml for the same inheritance pattern).
permissions: {}

jobs:
  dependabot-rebase:
    uses: petry-projects/.github/.github/workflows/dependabot-rebase-reusable.yml@main
    secrets: inherit


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

env:
PR_URL: ${{ github.event.pull_request.html_url }}
GH_TOKEN: ${{ steps.app-token.outputs.token }}
dependabot-automerge:
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

permissions: {} at the workflow level combined with no job-level permissions means the called reusable cannot elevate the GITHUB_TOKEN scopes it needs. The reusable’s job requests at least contents: read and pull-requests: read, but those will be effectively reduced to none, causing dependabot/fetch-metadata / gh API reads to fail. Define the required permissions on this calling job (same pattern used by standards/workflows/feature-ideation.yml).

Suggested change
dependabot-automerge:
dependabot-automerge:
permissions:
contents: read
pull-requests: read

Copilot uses AI. Check for mistakes.
# Copy to .github/workflows/dependency-audit.yml
# ─────────────────────────────────────────────────────────────────────────────
# SOURCE OF TRUTH: petry-projects/.github/standards/workflows/dependency-audit.yml
# Standard: petry-projects/.github/standards/ci-standards.md#5-dependency-audit-dependency-auditym
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The “Standard:” link target looks incorrect (...#5-dependency-audit-dependency-auditym is missing the trailing l, and the section in standards/ci-standards.md is numbered ### 6. Dependency Audit). This breaks the reference in the SOURCE OF TRUTH header; update the URL anchor to match the actual heading.

Suggested change
# Standard: petry-projects/.github/standards/ci-standards.md#5-dependency-audit-dependency-auditym
# Standard: petry-projects/.github/standards/ci-standards.md#6-dependency-audit

Copilot uses AI. Check for mistakes.
# Reusable dependency vulnerability audit — single source of truth for the org.
# Repo-level dependency-audit.yml files call this to avoid duplicating the
# multi-ecosystem detection and audit logic.
# Standard: https://github.com/petry-projects/.github/blob/main/standards/ci-standards.md#5-dependency-audit-dependency-auditym
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment reference to ci-standards uses an anchor ending in ...dependency-auditym (missing l) and appears to reference section #5-... even though the doc section is ### 6. Dependency Audit. Please fix the Standard URL anchor so it resolves correctly.

Suggested change
# Standard: https://github.com/petry-projects/.github/blob/main/standards/ci-standards.md#5-dependency-audit-dependency-auditym
# Standard: https://github.com/petry-projects/.github/blob/main/standards/ci-standards.md#6-dependency-audit-dependency-audityml

Copilot uses AI. Check for mistakes.
Comment on lines +16 to +19
# Dependency vulnerability audit — thin caller for the org-level reusable.
# To adopt: copy this file to .github/workflows/dependency-audit.yml in your repo.
# Add "dependency-audit / Detect ecosystems" as a required status check
# in branch protection.
Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This stub instructs users to require the status check dependency-audit / Detect ecosystems, but existing docs/templates in this repo still reference requiring dependency-audit (e.g., standards/dependabot-policy.md and .github/workflows/dependency-audit.yml). Please align the guidance (and/or update the referenced docs) to the actual check context name produced by the reusable call, to avoid misconfigured branch protection.

Copilot uses AI. Check for mistakes.
Comment on lines +16 to +18
permissions:
contents: read

Copy link

Copilot AI Apr 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This reusable is a multi-job workflow but sets top-level permissions: contents: read and relies on implicit inheritance for all jobs. Per the repo’s permissions policy, multi-job workflows should reset top-level permissions to {} and scope permissions per job (standards/ci-standards.md#permissions-policy). Update this workflow to declare job-level permissions instead of a shared top-level grant.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/agent-shield-reusable.yml:
- Around line 100-130: The frontmatter check currently uses grep patterns
'^name:' and '^description:' which only match fields at column 0; update the
validation to accept optional leading whitespace by changing those checks to
search for '^[[:space:]]*name:' and '^[[:space:]]*description:' (i.e., modify
the two grep invocations that read the frontmatter variable inside the while
loop), so indented YAML keys like "metadata: \n  name: ..." are treated as
present while keeping the same error handling and status logic.

In @.github/workflows/dependabot-rebase-reusable.yml:
- Around line 117-123: The current jq logic for CHECKS_PASS and CHECKS_PENDING
treats an empty statusCheckRollup as passing (vacuous truth); update the gh pr
view/jq pipeline to compute a completed checks count (e.g., COMPLETED_COUNT from
[.statusCheckRollup[]? | select(.name != null and .status == "COMPLETED") |
.conclusion] | length) and then require COMPLETED_COUNT > 0 in addition to
CHECKS_PASS being true and CHECKS_PENDING == 0 before treating the PR as
merge-ready; adjust the existing CHECKS_PASS and CHECKS_PENDING usage
accordingly so repos with no status checks won’t auto-merge.

In @.github/workflows/dependency-audit-reusable.yml:
- Around line 166-175: The loop currently iterates every Cargo.toml (causing
repeated audits for workspace members); change the find pipeline that feeds the
while loop so it yields each Rust workspace root once (Cargo.toml files
containing a [workspace] table) and also any standalone crate roots that are not
members of a workspace, then iterate those unique roots in the existing while
read loop. In practice update the generator used before "while IFS= read -r dir;
do" to filter results by detecting "[workspace]" in Cargo.toml (e.g. grep/awk on
each Cargo.toml to emit its dirname only if it contains "[workspace]") and
include non-member Cargo.toml dirs once (exclude files under discovered
workspace member paths), so the loop over the block that contains the cargo
generate-lockfile/cargo audit commands runs per workspace root instead of per
Cargo.toml.
- Around line 197-205: The loop currently makes the requirements.txt branch
unreachable when a directory has pyproject.toml; update the logic so both audits
run when both files exist (or choose the authoritative source explicitly).
Concretely, inside the while loop around the pip-audit calls (the block that
checks [ -f "$dir/pyproject.toml" ] and [ -f "$dir/requirements.txt" ]), invoke
pip-audit on pyproject.toml and then separately invoke pip-audit -r
"$dir/requirements.txt" if that file exists, setting status=1 on any failure;
alternatively, replace the if/elif with separate if checks to ensure
requirements.txt is not skipped. Ensure you update the pip-audit invocations
referenced in this loop so both files are audited when present.

In `@standards/workflows/dependency-audit.yml`:
- Around line 16-19: Update the guidance comment that tells users which status
check to add: the reusable workflow job is named detect (lowercase), so change
the suggested required status check string from "dependency-audit / Detect
ecosystems" to "dependency-audit / detect" in the header comment; locate the
comment around the top of standards/workflows/dependency-audit.yml referencing
the status check and replace the incorrect capitalized name with the exact job
name "dependency-audit / detect".
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 79c89396-0419-4acc-8b68-c3d208796542

📥 Commits

Reviewing files that changed from the base of the PR and between 2272db6 and a62d3ca.

📒 Files selected for processing (9)
  • .github/workflows/agent-shield-reusable.yml
  • .github/workflows/dependabot-automerge-reusable.yml
  • .github/workflows/dependabot-rebase-reusable.yml
  • .github/workflows/dependency-audit-reusable.yml
  • standards/workflows/agent-shield.yml
  • standards/workflows/claude.yml
  • standards/workflows/dependabot-automerge.yml
  • standards/workflows/dependabot-rebase.yml
  • standards/workflows/dependency-audit.yml

Comment on lines +100 to +130
- name: Validate SKILL.md frontmatter
run: |
status=0

while IFS= read -r file; do
frontmatter=$(awk \
'/^---$/{n++; next} n==1{print} n>=2{exit}' \
"$file")

if [ -z "$frontmatter" ]; then
echo "::error file=$file::Missing YAML frontmatter"
status=1
continue
fi

if ! echo "$frontmatter" | grep -q '^name:'; then
echo "::error file=$file::Missing 'name' field"
status=1
fi
if ! echo "$frontmatter" | grep -q '^description:'; then
echo "::error file=$file::Missing 'description' field"
status=1
fi
done < <(find . -name 'SKILL.md' \
-not -path '*/node_modules/*' \
-not -path '*/.git/*')

if [ "$status" -eq 0 ]; then
echo "All SKILL.md frontmatter validated."
fi
exit $status
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Frontmatter validation assumes fields at column 0.

The grep patterns ^name: and ^description: (lines 115, 119) only match fields at the start of a line. Valid YAML frontmatter could have these fields indented (e.g., nested under a parent key):

---
metadata:
  name: "My Skill"
  description: "Does things"
---

This would fail validation despite being valid YAML with the required fields present.

If indented fields should be supported, consider relaxing the patterns:

♻️ Optional: Support indented frontmatter fields
-            if ! echo "$frontmatter" | grep -q '^name:'; then
+            if ! echo "$frontmatter" | grep -qE '^\s*name:'; then
               echo "::error file=$file::Missing 'name' field"
               status=1
             fi
-            if ! echo "$frontmatter" | grep -q '^description:'; then
+            if ! echo "$frontmatter" | grep -qE '^\s*description:'; then
               echo "::error file=$file::Missing 'description' field"
               status=1
             fi

If the org standard explicitly requires top-level name: and description: fields, the current behavior is correct and this is a non-issue.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/agent-shield-reusable.yml around lines 100 - 130, The
frontmatter check currently uses grep patterns '^name:' and '^description:'
which only match fields at column 0; update the validation to accept optional
leading whitespace by changing those checks to search for '^[[:space:]]*name:'
and '^[[:space:]]*description:' (i.e., modify the two grep invocations that read
the frontmatter variable inside the while loop), so indented YAML keys like
"metadata: \n  name: ..." are treated as present while keeping the same error
handling and status logic.

Comment on lines +117 to +123
CHECKS_PASS=$(gh pr view "$PR_NUMBER" --repo "$REPO" \
--json statusCheckRollup \
--jq '[.statusCheckRollup[]? | select(.name != null and .status == "COMPLETED") | .conclusion] | all(. == "SUCCESS" or . == "NEUTRAL" or . == "SKIPPED")')

CHECKS_PENDING=$(gh pr view "$PR_NUMBER" --repo "$REPO" \
--json statusCheckRollup \
--jq '[.statusCheckRollup[]? | select(.name != null and .status != "COMPLETED")] | length')
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Edge case: Empty statusCheckRollup may produce unexpected results.

When statusCheckRollup is empty or contains no items with status == "COMPLETED", the jq expression:

[.statusCheckRollup[]? | select(.name != null and .status == "COMPLETED") | .conclusion] | all(. == "SUCCESS" or ...)

Returns true for an empty array (vacuous truth). Combined with CHECKS_PENDING being 0 for an empty array, a PR with no status checks would be considered merge-ready.

If repos without required status checks should not auto-merge, consider adding an explicit check:

🛡️ Proposed fix to require at least one completed check
+            CHECKS_COUNT=$(gh pr view "$PR_NUMBER" --repo "$REPO" \
+              --json statusCheckRollup \
+              --jq '[.statusCheckRollup[]? | select(.name != null)] | length')
+
+            if [[ "$CHECKS_COUNT" -eq 0 ]]; then
+              echo "  Skipping — no status checks configured"
+              continue
+            fi
+
             CHECKS_PASS=$(gh pr view "$PR_NUMBER" --repo "$REPO" \
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/dependabot-rebase-reusable.yml around lines 117 - 123, The
current jq logic for CHECKS_PASS and CHECKS_PENDING treats an empty
statusCheckRollup as passing (vacuous truth); update the gh pr view/jq pipeline
to compute a completed checks count (e.g., COMPLETED_COUNT from
[.statusCheckRollup[]? | select(.name != null and .status == "COMPLETED") |
.conclusion] | length) and then require COMPLETED_COUNT > 0 in addition to
CHECKS_PASS being true and CHECKS_PENDING == 0 before treating the PR as
merge-ready; adjust the existing CHECKS_PASS and CHECKS_PENDING usage
accordingly so repos with no status checks won’t auto-merge.

Comment on lines +166 to +175
# cargo audit operates on Cargo.lock at workspace root
# For workspaces, a single audit at root covers all crates
status=0
while IFS= read -r dir; do
echo "::group::cargo audit $dir"
if ! (cd "$dir" && cargo generate-lockfile 2>/dev/null; cargo audit); then
status=1
fi
echo "::endgroup::"
done < <(find . -name 'Cargo.toml' -not -path '*/target/*' -exec dirname {} \; | sort -u)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Audit each Rust workspace once, not once per Cargo.toml.

The comment on Lines 166-167 says a single workspace-root audit covers all crates, but the loop still enumerates every Cargo.toml. In a workspace this reruns the same advisory scan for each member and can regenerate the shared lockfile multiple times. Filter the input set down to workspace roots before invoking cargo audit.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/dependency-audit-reusable.yml around lines 166 - 175, The
loop currently iterates every Cargo.toml (causing repeated audits for workspace
members); change the find pipeline that feeds the while loop so it yields each
Rust workspace root once (Cargo.toml files containing a [workspace] table) and
also any standalone crate roots that are not members of a workspace, then
iterate those unique roots in the existing while read loop. In practice update
the generator used before "while IFS= read -r dir; do" to filter results by
detecting "[workspace]" in Cargo.toml (e.g. grep/awk on each Cargo.toml to emit
its dirname only if it contains "[workspace]") and include non-member Cargo.toml
dirs once (exclude files under discovered workspace member paths), so the loop
over the block that contains the cargo generate-lockfile/cargo audit commands
runs per workspace root instead of per Cargo.toml.

Comment on lines +197 to +205
while IFS= read -r dir; do
echo "::group::pip-audit $dir"
if [ -f "$dir/pyproject.toml" ]; then
if ! pip-audit "$dir"; then
status=1
fi
elif [ -f "$dir/requirements.txt" ]; then
if ! pip-audit -r "$dir/requirements.txt"; then
status=1
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Don't let pyproject.toml suppress the requirements.txt audit.

Line 199 makes the requirements.txt branch unreachable for any directory that has both files. If that directory's pinned dependency set lives in requirements.txt, this workflow will silently skip auditing it. Prefer auditing the requirements file independently, or only taking the project-path branch when pyproject.toml is the real dependency source.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/dependency-audit-reusable.yml around lines 197 - 205, The
loop currently makes the requirements.txt branch unreachable when a directory
has pyproject.toml; update the logic so both audits run when both files exist
(or choose the authoritative source explicitly). Concretely, inside the while
loop around the pip-audit calls (the block that checks [ -f
"$dir/pyproject.toml" ] and [ -f "$dir/requirements.txt" ]), invoke pip-audit on
pyproject.toml and then separately invoke pip-audit -r "$dir/requirements.txt"
if that file exists, setting status=1 on any failure; alternatively, replace the
if/elif with separate if checks to ensure requirements.txt is not skipped.
Ensure you update the pip-audit invocations referenced in this loop so both
files are audited when present.

Comment on lines +16 to +19
# Dependency vulnerability audit — thin caller for the org-level reusable.
# To adopt: copy this file to .github/workflows/dependency-audit.yml in your repo.
# Add "dependency-audit / Detect ecosystems" as a required status check
# in branch protection.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check the job names defined in the reusable workflow
fd -t f 'dependency-audit-reusable.yml' .github/workflows --exec cat {} \; | grep -E '^\s+[a-z-]+:$' | head -20

Repository: petry-projects/.github

Length of output: 277


Correct the status check name in the guidance comment.

The header comment advises adding "dependency-audit / Detect ecosystems" as a required status check. However, the reusable workflow's job is named detect (lowercase), so the actual status check name is dependency-audit / detect. Update line 18-19 to reflect the correct name:

Suggested fix
 # Dependency vulnerability audit — thin caller for the org-level reusable.
 # To adopt: copy this file to .github/workflows/dependency-audit.yml in your repo.
-# Add "dependency-audit / Detect ecosystems" as a required status check
+# Add "dependency-audit / detect" as a required status check
 # in branch protection.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# Dependency vulnerability audit — thin caller for the org-level reusable.
# To adopt: copy this file to .github/workflows/dependency-audit.yml in your repo.
# Add "dependency-audit / Detect ecosystems" as a required status check
# in branch protection.
# Dependency vulnerability audit — thin caller for the org-level reusable.
# To adopt: copy this file to .github/workflows/dependency-audit.yml in your repo.
# Add "dependency-audit / detect" as a required status check
# in branch protection.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@standards/workflows/dependency-audit.yml` around lines 16 - 19, Update the
guidance comment that tells users which status check to add: the reusable
workflow job is named detect (lowercase), so change the suggested required
status check string from "dependency-audit / Detect ecosystems" to
"dependency-audit / detect" in the header comment; locate the comment around the
top of standards/workflows/dependency-audit.yml referencing the status check and
replace the incorrect capitalized name with the exact job name "dependency-audit
/ detect".

Reusable workflows can be granted no more permissions than the calling
workflow has. The dependabot-automerge and dependabot-rebase stubs had
`permissions: {}` at workflow level with no job-level overrides, which
intersected to zero — the reusable's `gh pr ...` calls would fail
because GITHUB_TOKEN had no scopes.

Fix: declare `contents: read` and `pull-requests: read` on the calling
job, matching the scopes the reusable's job already declares. Caught
by Copilot review on #87.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@don-petry
Copy link
Copy Markdown
Contributor Author

Addressed Copilot review feedback in bc19033: granted contents: read and pull-requests: read to the dependabot-automerge and dependabot-rebase calling jobs so the reusable's gh pr ... calls work.

CodeRabbit's five suggestions all flag pre-existing logic in the inherited templates (SKILL.md frontmatter regex, vacuous-truth status checks for empty rollups, cargo workspace dedup, pip requirements unreachable branch, status-check name string). Intentionally preserving behavior in this centralization PR — those are good follow-up issues but changing semantics here would expand scope and risk regressions in downstream repos that have been running the existing logic. Will file as separate issues.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@standards/workflows/dependabot-rebase.yml`:
- Around line 1-18: Update the immutable-stub contract text to include the
job-level permissions: stanza in the "MUST NOT change" list so adopters don't
remove it; specifically mention the permissions: stanza alongside the existing
items (trigger event, concurrency group name, the uses: line, and secrets:
inherit) and call out that this is required because the reusable workflow clears
the default workflow token unless explicit permissions are preserved.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 7e779c27-1ddf-4ad7-99fc-d1ef66a848e3

📥 Commits

Reviewing files that changed from the base of the PR and between a62d3ca and bc19033.

📒 Files selected for processing (2)
  • standards/workflows/dependabot-automerge.yml
  • standards/workflows/dependabot-rebase.yml

CodeRabbit follow-up on #87: now that the dependabot stubs declare a
job-level permissions block (required for the reusable's gh API calls),
add it to the "MUST NOT change" list so future adopters don't strip it.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud bot commented Apr 8, 2026

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@standards/workflows/dependabot-rebase.yml`:
- Around line 39-43: The workflow caller sets permissions to read-only which
prevents the reusable workflow (uses:
petry-projects/.github/.github/workflows/dependabot-rebase-reusable.yml@main)
from performing gh api branch updates and merges; change the permissions block
so that at minimum contents: write and pull-requests: write are granted (and
keep secrets: inherit) so the reusable workflow can perform branch updates and
merges when invoked.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: f53626c3-923f-4173-8432-a1732b3f6442

📥 Commits

Reviewing files that changed from the base of the PR and between bc19033 and ff437f2.

📒 Files selected for processing (2)
  • standards/workflows/dependabot-automerge.yml
  • standards/workflows/dependabot-rebase.yml

Comment on lines 39 to +43
permissions:
contents: read
pull-requests: read
steps:
- name: Check app secrets
env:
APP_ID: ${{ secrets.APP_ID }}
run: |
if [[ -z "$APP_ID" ]]; then
echo "::error::APP_ID secret is missing. Set APP_ID and APP_PRIVATE_KEY in org secrets. See standards/dependabot-policy.md"
exit 1
fi

- name: Generate app token
id: app-token
uses: actions/create-github-app-token@f8d387b68d61c58ab83c6c016672934102569859 # v3
with:
app-id: ${{ secrets.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}

- name: Update and merge Dependabot PRs
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
REPO: ${{ github.repository }}
run: |
# Find open Dependabot PRs
PRS=$(gh pr list --repo "$REPO" --author "app/dependabot" \
--json number,headRefName \
--jq '.[] | "\(.number) \(.headRefName)"')

if [[ -z "$PRS" ]]; then
echo "No open Dependabot PRs"
exit 0
fi

MERGED=false

while IFS=' ' read -r PR_NUMBER HEAD_REF; do
BEHIND=$(gh api "repos/$REPO/compare/main...$HEAD_REF" \
--jq '.behind_by')

if [[ "$BEHIND" -gt 0 ]]; then
echo "PR #$PR_NUMBER ($HEAD_REF) is $BEHIND commit(s) behind — merging main into branch"
gh api "repos/$REPO/pulls/$PR_NUMBER/update-branch" \
-X PUT -f update_method=merge \
--silent || echo "Warning: failed to update PR #$PR_NUMBER"
continue
fi

echo "PR #$PR_NUMBER ($HEAD_REF) is up to date — checking if merge-ready"

# Skip if we already merged one (strict mode means others are now behind)
if [[ "$MERGED" == "true" ]]; then
echo " Skipping — already merged a PR this run"
continue
fi

# Check if auto-merge is enabled (set by the automerge workflow)
AUTO_MERGE=$(gh pr view "$PR_NUMBER" --repo "$REPO" \
--json autoMergeRequest --jq '.autoMergeRequest != null')

if [[ "$AUTO_MERGE" != "true" ]]; then
echo " Skipping — auto-merge not enabled"
continue
fi

# Check if all required checks pass (look at overall rollup)
CHECKS_PASS=$(gh pr view "$PR_NUMBER" --repo "$REPO" \
--json statusCheckRollup \
--jq '[.statusCheckRollup[]? | select(.name != null and .status == "COMPLETED") | .conclusion] | all(. == "SUCCESS" or . == "NEUTRAL" or . == "SKIPPED")')

CHECKS_PENDING=$(gh pr view "$PR_NUMBER" --repo "$REPO" \
--json statusCheckRollup \
--jq '[.statusCheckRollup[]? | select(.name != null and .status != "COMPLETED")] | length')

if [[ "$CHECKS_PENDING" -gt 0 ]]; then
echo " Skipping — $CHECKS_PENDING check(s) still pending"
continue
fi

if [[ "$CHECKS_PASS" != "true" ]]; then
echo " Skipping — some checks failed"
continue
fi

echo " All checks pass — merging PR #$PR_NUMBER"
if gh api "repos/$REPO/pulls/$PR_NUMBER/merge" \
-X PUT -f merge_method=squash \
--silent; then
echo " Merged PR #$PR_NUMBER"
MERGED=true
else
echo " Warning: failed to merge PR #$PR_NUMBER"
fi
done <<< "$PRS"
uses: petry-projects/.github/.github/workflows/dependabot-rebase-reusable.yml@main
secrets: inherit
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify caller permissions are read-only while reusable performs write actions.
rg -n --type=yaml 'contents:\s*read|pull-requests:\s*read' \
  standards/workflows/dependabot-rebase.yml \
  .github/workflows/dependabot-rebase-reusable.yml

rg -n --type=yaml 'update-branch|/pulls/\$PR_NUMBER/merge|gh pr merge' \
  .github/workflows/dependabot-rebase-reusable.yml

Repository: petry-projects/.github

Length of output: 568


Change caller permissions to write scopes; read-only blocks branch updates and merges.

The caller job at lines 40–41 sets read-only scopes (contents: read, pull-requests: read), but the called reusable workflow performs gh api calls to update branches and merge PRs. When a reusable workflow is called with secrets: inherit, it inherits the caller's permissions, making the read-only scopes insufficient and causing the workflow to fail.

Fix
    permissions:
-     contents: read
-     pull-requests: read
+     contents: write
+     pull-requests: write
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
permissions:
contents: read
pull-requests: read
steps:
- name: Check app secrets
env:
APP_ID: ${{ secrets.APP_ID }}
run: |
if [[ -z "$APP_ID" ]]; then
echo "::error::APP_ID secret is missing. Set APP_ID and APP_PRIVATE_KEY in org secrets. See standards/dependabot-policy.md"
exit 1
fi
- name: Generate app token
id: app-token
uses: actions/create-github-app-token@f8d387b68d61c58ab83c6c016672934102569859 # v3
with:
app-id: ${{ secrets.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
- name: Update and merge Dependabot PRs
env:
GH_TOKEN: ${{ steps.app-token.outputs.token }}
REPO: ${{ github.repository }}
run: |
# Find open Dependabot PRs
PRS=$(gh pr list --repo "$REPO" --author "app/dependabot" \
--json number,headRefName \
--jq '.[] | "\(.number) \(.headRefName)"')
if [[ -z "$PRS" ]]; then
echo "No open Dependabot PRs"
exit 0
fi
MERGED=false
while IFS=' ' read -r PR_NUMBER HEAD_REF; do
BEHIND=$(gh api "repos/$REPO/compare/main...$HEAD_REF" \
--jq '.behind_by')
if [[ "$BEHIND" -gt 0 ]]; then
echo "PR #$PR_NUMBER ($HEAD_REF) is $BEHIND commit(s) behind — merging main into branch"
gh api "repos/$REPO/pulls/$PR_NUMBER/update-branch" \
-X PUT -f update_method=merge \
--silent || echo "Warning: failed to update PR #$PR_NUMBER"
continue
fi
echo "PR #$PR_NUMBER ($HEAD_REF) is up to date — checking if merge-ready"
# Skip if we already merged one (strict mode means others are now behind)
if [[ "$MERGED" == "true" ]]; then
echo " Skipping — already merged a PR this run"
continue
fi
# Check if auto-merge is enabled (set by the automerge workflow)
AUTO_MERGE=$(gh pr view "$PR_NUMBER" --repo "$REPO" \
--json autoMergeRequest --jq '.autoMergeRequest != null')
if [[ "$AUTO_MERGE" != "true" ]]; then
echo " Skipping — auto-merge not enabled"
continue
fi
# Check if all required checks pass (look at overall rollup)
CHECKS_PASS=$(gh pr view "$PR_NUMBER" --repo "$REPO" \
--json statusCheckRollup \
--jq '[.statusCheckRollup[]? | select(.name != null and .status == "COMPLETED") | .conclusion] | all(. == "SUCCESS" or . == "NEUTRAL" or . == "SKIPPED")')
CHECKS_PENDING=$(gh pr view "$PR_NUMBER" --repo "$REPO" \
--json statusCheckRollup \
--jq '[.statusCheckRollup[]? | select(.name != null and .status != "COMPLETED")] | length')
if [[ "$CHECKS_PENDING" -gt 0 ]]; then
echo " Skipping — $CHECKS_PENDING check(s) still pending"
continue
fi
if [[ "$CHECKS_PASS" != "true" ]]; then
echo " Skipping — some checks failed"
continue
fi
echo " All checks pass — merging PR #$PR_NUMBER"
if gh api "repos/$REPO/pulls/$PR_NUMBER/merge" \
-X PUT -f merge_method=squash \
--silent; then
echo " Merged PR #$PR_NUMBER"
MERGED=true
else
echo " Warning: failed to merge PR #$PR_NUMBER"
fi
done <<< "$PRS"
uses: petry-projects/.github/.github/workflows/dependabot-rebase-reusable.yml@main
secrets: inherit
permissions:
contents: write
pull-requests: write
uses: petry-projects/.github/.github/workflows/dependabot-rebase-reusable.yml@main
secrets: inherit
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@standards/workflows/dependabot-rebase.yml` around lines 39 - 43, The workflow
caller sets permissions to read-only which prevents the reusable workflow (uses:
petry-projects/.github/.github/workflows/dependabot-rebase-reusable.yml@main)
from performing gh api branch updates and merges; change the permissions block
so that at minimum contents: write and pull-requests: write are granted (and
keep secrets: inherit) so the reusable workflow can perform branch updates and
merges when invoked.

@don-petry
Copy link
Copy Markdown
Contributor Author

@coderabbitai this analysis is incorrect for the dependabot-rebase reusable. The reusable uses a GitHub App token (GH_TOKEN: ${{ steps.app-token.outputs.token }}, generated via actions/create-github-app-token from APP_ID/APP_PRIVATE_KEY org secrets) for all write operations — gh api PUT update-branch and gh api PUT merge. The GITHUB_TOKEN (whose scopes are determined by the caller's permissions: block) is not used for any write call in this workflow. Read scopes on the caller are therefore sufficient. Granting contents: write would be incorrect defense-in-depth — it would imply the workflow writes via GITHUB_TOKEN, which it intentionally does not, because the resulting push must trigger on: push in this same workflow (forming the self-sustaining merge chain), and GITHUB_TOKEN-authored pushes cannot trigger workflows.

Resolving this thread; merging.

@don-petry don-petry merged commit 9524890 into main Apr 8, 2026
20 checks passed
@don-petry don-petry deleted the feat/centralize-workflow-standards branch April 8, 2026 03:11
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 8, 2026

Tip

For best results, initiate chat on the files or code changes.

@don-petry, thank you for the detailed correction — you're absolutely right. I misread the token routing. The key design points are clear:

  1. All write operations (gh api PUT update-branch, gh api PUT merge) use the GitHub App token from actions/create-github-app-token, not GITHUB_TOKEN.
  2. GITHUB_TOKEN is read-only in this workflow by design — granting contents: write would be a misleading signal implying writes go through GITHUB_TOKEN.
  3. The GitHub App token is architecturally required precisely because GITHUB_TOKEN-authored pushes do not trigger on: push workflows, whereas GitHub App-authored pushes do — which is what sustains the merge chain.

My suggestion to add contents: write was incorrect. Apologies for the noise.


✏️ Learnings added
Learnt from: don-petry
URL: https://github.com/petry-projects/.github/pull/87

Timestamp: 2026-04-08T03:11:34.628Z
Learning: In `petry-projects/.github` `.github/workflows/dependabot-rebase-reusable.yml`, ALL write operations (update-branch via `gh api PUT /repos/.../pulls/{number}/update-branch` and merge via `gh api PUT /repos/.../pulls/{number}/merge`) are performed using a GitHub App token generated by `actions/create-github-app-token` from `APP_ID`/`APP_PRIVATE_KEY` secrets — NOT via `GITHUB_TOKEN`. The caller's `permissions:` block governs only `GITHUB_TOKEN` scopes, so read-only permissions (`contents: read`, `pull-requests: read`) are correct and sufficient. Granting `contents: write` would be incorrect because: (1) no write call uses `GITHUB_TOKEN`, and (2) the GitHub App token is intentionally used so that the resulting branch push triggers `on: push` in this same workflow (self-sustaining merge chain) — `GITHUB_TOKEN`-authored pushes cannot trigger workflows and would break this chain. Do not suggest adding `contents: write` to the caller or reusable for this workflow.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


🧠 Learnings used
Learnt from: CR
Repo: petry-projects/.github PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-08T01:43:24.250Z
Learning: All review threads must be resolved before merge; agents MUST address and resolve Copilot, CodeRabbit, and human review comments

Learnt from: don-petry
Repo: petry-projects/.github PR: 15
File: .github/workflows/dependency-audit.yml:173-173
Timestamp: 2026-04-05T18:54:44.821Z
Learning: In the petry-projects org, `.github/workflows/dependency-audit.yml` (and likely other standard CI workflows) are copies of an upstream template. Any bug fixes or improvements must be applied to the template source, not to the individual repository copies. Do not suggest inline changes to per-repo workflow copies; instead, note that the fix belongs in the template.

Learnt from: CR
Repo: petry-projects/.github PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-08T01:43:24.250Z
Learning: Applies to dependabot.yml : Configure Dependabot auto-merge for patch and minor dependency bumps using gh pr merge --squash --auto; require manual review for major version bumps

Learnt from: CR
Repo: petry-projects/.github PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-08T01:43:24.250Z
Learning: Applies to .github/workflows/*.yml : For Dependabot PRs, skip the Claude Code action step (github.event.pull_request.user.login != 'dependabot[bot]') since CLAUDE_CODE_OAUTH_TOKEN is not available to Dependabot

Learnt from: don-petry
Repo: petry-projects/.github PR: 12
File: scripts/compliance-audit.sh:35-35
Timestamp: 2026-04-05T17:57:02.593Z
Learning: In the petry-projects/.github repository, `standards/ci-standards.md` defines exactly 6 universally required workflows for every repository under the "Required Workflows" section ("Every repository MUST have these workflows"): `ci.yml`, `codeql.yml`, `sonarcloud.yml`, `claude.yml`, `dependabot-automerge.yml`, and `dependency-audit.yml`. All six are mandatory — including the two Dependabot workflows. The `REQUIRED_WORKFLOWS` array in `scripts/compliance-audit.sh` correctly lists all six.

Learnt from: don-petry
Repo: petry-projects/.github PR: 15
File: .github/workflows/dependency-audit.yml:161-161
Timestamp: 2026-04-05T18:54:53.767Z
Learning: In the petry-projects/.github repository, `dtolnay/rust-toolchainstable` used in `.github/workflows/dependency-audit.yml` (and related standard workflow templates under `standards/workflows/`) intentionally references the `stable` branch. SHA pinning and updates for this action are managed by Dependabot (github-actions ecosystem). Do not flag this as an unpinned action — it is part of the approved standard template and the branch reference is intentional.

Learnt from: don-petry
Repo: petry-projects/.github PR: 24
File: standards/ci-standards.md:165-165
Timestamp: 2026-04-05T20:25:04.620Z
Learning: In `petry-projects` org workflows, the `anthropics/claude-code-action` is pinned to the SHA corresponding to the specific release version (e.g., `anthropics/claude-code-action6e2bd52842c65e914eba5c8badd17560bd26b5de # v1.0.89`). The version comment reflects the specific release tag (e.g., `v1.0.89`), not the floating `v1` tag. All org repos standardize on the same pinned SHA, and Dependabot (github-actions ecosystem) keeps the SHA up to date. Do not flag the specific version comment as incorrect — `# v1.0.89` is intentional and the current org-wide standard.

Learnt from: CR
Repo: petry-projects/.github PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-08T01:43:24.250Z
Learning: Applies to .github/workflows/*.yml : Configure required status checks on the default branch: CodeQL Analyze, SonarCloud, Claude Code review (if applicable), linter, formatter, type checker, tests, coverage

don-petry pushed a commit to petry-projects/ContentTwin that referenced this pull request Apr 8, 2026
Replace inline copies of standardized workflows with the canonical
thin caller stubs from petry-projects/.github/standards/workflows/.
Each stub delegates to a versioned reusable workflow at
petry-projects/.github/.github/workflows/<name>-reusable.yml@v1, so
future updates to the standard propagate automatically and drift is
caught by the org-wide compliance audit.

See petry-projects/.github#87, #88, #89 for context.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
don-petry pushed a commit to petry-projects/google-app-scripts that referenced this pull request Apr 8, 2026
Replace inline copies of standardized workflows with the canonical
thin caller stubs from petry-projects/.github/standards/workflows/.
Each stub delegates to a versioned reusable workflow at
petry-projects/.github/.github/workflows/<name>-reusable.yml@v1, so
future updates to the standard propagate automatically and drift is
caught by the org-wide compliance audit.

See petry-projects/.github#87, #88, #89 for context.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
don-petry pushed a commit to petry-projects/markets that referenced this pull request Apr 8, 2026
Replace inline copies of standardized workflows with the canonical
thin caller stubs from petry-projects/.github/standards/workflows/.
Each stub delegates to a versioned reusable workflow at
petry-projects/.github/.github/workflows/<name>-reusable.yml@v1, so
future updates to the standard propagate automatically and drift is
caught by the org-wide compliance audit.

See petry-projects/.github#87, #88, #89 for context.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
don-petry pushed a commit to petry-projects/bmad-bgreat-suite that referenced this pull request Apr 8, 2026
Replace inline copies of standardized workflows with the canonical
thin caller stubs from petry-projects/.github/standards/workflows/.
Each stub delegates to a versioned reusable workflow at
petry-projects/.github/.github/workflows/<name>-reusable.yml@v1, so
future updates to the standard propagate automatically and drift is
caught by the org-wide compliance audit.

See petry-projects/.github#87, #88, #89 for context.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
don-petry added a commit to petry-projects/broodly that referenced this pull request Apr 8, 2026
Replace inline copies of standardized workflows with the canonical
thin caller stubs from petry-projects/.github/standards/workflows/.
Each stub delegates to a versioned reusable workflow at
petry-projects/.github/.github/workflows/<name>-reusable.yml@v1, so
future updates to the standard propagate automatically and drift is
caught by the org-wide compliance audit.

See petry-projects/.github#87, #88, #89 for context.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
don-petry pushed a commit to petry-projects/TalkTerm that referenced this pull request Apr 8, 2026
Replace inline copies of standardized workflows with the canonical
thin caller stubs from petry-projects/.github/standards/workflows/.
Each stub delegates to a versioned reusable workflow at
petry-projects/.github/.github/workflows/<name>-reusable.yml@v1, so
future updates to the standard propagate automatically and drift is
caught by the org-wide compliance audit.

See petry-projects/.github#87, #88, #89 for context.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
don-petry added a commit to petry-projects/ContentTwin that referenced this pull request Apr 8, 2026
…#52)

Replace inline copies of standardized workflows with the canonical
thin caller stubs from petry-projects/.github/standards/workflows/.
Each stub delegates to a versioned reusable workflow at
petry-projects/.github/.github/workflows/<name>-reusable.yml@v1, so
future updates to the standard propagate automatically and drift is
caught by the org-wide compliance audit.

See petry-projects/.github#87, #88, #89 for context.

Co-authored-by: DJ <dj@Rachels-MacBook-Air.local>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
don-petry added a commit to petry-projects/google-app-scripts that referenced this pull request Apr 8, 2026
…#149)

Replace inline copies of standardized workflows with the canonical
thin caller stubs from petry-projects/.github/standards/workflows/.
Each stub delegates to a versioned reusable workflow at
petry-projects/.github/.github/workflows/<name>-reusable.yml@v1, so
future updates to the standard propagate automatically and drift is
caught by the org-wide compliance audit.

See petry-projects/.github#87, #88, #89 for context.

Co-authored-by: DJ <dj@Rachels-MacBook-Air.local>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
don-petry added a commit to petry-projects/broodly that referenced this pull request Apr 8, 2026
…#93)

Replace inline copies of standardized workflows with the canonical
thin caller stubs from petry-projects/.github/standards/workflows/.
Each stub delegates to a versioned reusable workflow at
petry-projects/.github/.github/workflows/<name>-reusable.yml@v1, so
future updates to the standard propagate automatically and drift is
caught by the org-wide compliance audit.

See petry-projects/.github#87, #88, #89 for context.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
don-petry added a commit to petry-projects/TalkTerm that referenced this pull request Apr 8, 2026
…#82)

Replace inline copies of standardized workflows with the canonical
thin caller stubs from petry-projects/.github/standards/workflows/.
Each stub delegates to a versioned reusable workflow at
petry-projects/.github/.github/workflows/<name>-reusable.yml@v1, so
future updates to the standard propagate automatically and drift is
caught by the org-wide compliance audit.

See petry-projects/.github#87, #88, #89 for context.

Co-authored-by: DJ <dj@Rachels-MacBook-Air.local>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants