Skip to content

chore: sync workflow templates - #569

Merged
agents-workflows-bot[bot] merged 1 commit into
mainfrom
sync/workflows-c6b722d74cfd
Jun 19, 2026
Merged

chore: sync workflow templates#569
agents-workflows-bot[bot] merged 1 commit into
mainfrom
sync/workflows-c6b722d74cfd

Conversation

@stranske

@stranske stranske commented Jun 19, 2026

Copy link
Copy Markdown
Owner

Sync Summary

Files Updated

  • agents-guard.yml: Agents guard - enforces agents workflow protections (Health 45)
  • maint-76-claude-code-review.yml: Claude Code review (opt-in) - runs only on labeled PRs or manual dispatch
  • agents-guard.js: Health 45 agents guard logic used by the workflow protections
  • WORKFLOW_USER_GUIDE.md: Workflow user guide - explains the CI/agent system for repo consumers

Files Skipped

  • pr-00-gate.yml: File exists and sync_mode is create_only
  • ci.yml: File exists and sync_mode is create_only
  • renovate.json: File exists and sync_mode is create_only
  • cross-repo-smoke.yml: File exists and sync_mode is create_only
  • llm_slots.json: None

Review Checklist

  • CI passes with updated workflows
  • No repo-specific customizations were overwritten

Source: stranske/Workflows
Source SHA: 5d306dbf622f81baba35684f8f03fdad013da942
Template hash: c6b722d74cfd
Sync branch: sync/workflows-c6b722d74cfd
Consumer repo: stranske/Pension-Data
Manifest: .github/sync-manifest.yml

Summary by CodeRabbit

  • Improvements

    • Enhanced workflow approval logic that allows dependency-only updates to bypass CODEOWNER review when the agents:allow-change label is present from trusted authors or dependency bot accounts.
  • Documentation

    • Updated workflow user guide to clarify the scope and conditions for the agents:allow-change label, including auto-application for dependency updates.

Automated sync from stranske/Workflows
Template hash: c6b722d74cfd

Changes synced from sync-manifest.yml
@stranske stranske added sync Automated sync from Workflows automated Automated sync from Workflows labels Jun 19, 2026
@stranske
stranske temporarily deployed to agent-standard June 19, 2026 06:43 — with GitHub Actions Inactive
@stranske
stranske temporarily deployed to agent-standard June 19, 2026 06:43 — with GitHub Actions Inactive
@coderabbitai

coderabbitai Bot commented Jun 19, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The agents-guard script gains a dependency-upgrade bypass path: new constants identify trusted bot logins and author associations, new patch-diff helpers detect whether a workflow file diff contains only uses: reference bumps, and evaluateGuard uses both to skip CODEOWNER approval when agents:allow-change is present. The workflow passes authorAssociation into the evaluator, docs are updated, and the claude-code-action SHA is bumped.

Changes

Agents-guard dependency-PR bypass

Layer / File(s) Summary
Dependency bot constants and patch-diff analysis helpers
.github/scripts/agents-guard.js
Adds DEPENDENCY_UPDATE_BOT_LOGINS and TRUSTED_AUTHOR_ASSOCIATIONS sets, plus parseActionRef, actionRefsMatchWithoutRef, and patchChangesOnlyActionReferences to determine whether a diff contains only uses: ref-only changes.
evaluateGuard bypass logic, return fields, export, and workflow wiring
.github/scripts/agents-guard.js, .github/workflows/agents-guard.yml
evaluateGuard accepts authorAssociation, replaces prior automation bypass with dependency-upgrade bypass using the new helpers, extends the return object with bypass fields, exports patchChangesOnlyActionReferences, and the workflow extracts authorAssociation from PR context and passes it to the evaluator.
Documentation updates
WORKFLOW_USER_GUIDE.md
Narrows agents:allow-change description to dependency-only uses: updates and updates the maint-auto-label-dep-prs.yml section to reflect the guarded dependency-update lane role.

claude-code-action SHA bump

Layer / File(s) Summary
Pinned SHA update
.github/workflows/maint-76-claude-code-review.yml
Retargets anthropics/claude-code-action to a new pinned commit hash with no other changes.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'chore: sync workflow templates' accurately summarizes the main change—synchronizing workflow templates from source to consumer repository as described in the PR objectives.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch sync/workflows-c6b722d74cfd

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

@stranske
stranske temporarily deployed to agent-standard June 19, 2026 06:44 — with GitHub Actions Inactive
@github-actions

github-actions Bot commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Workflow state fingerprint for Keepalive Loop Reporter. Do not edit.

@github-actions

github-actions Bot commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Workflow state fingerprint for Agents Gate Followups. Do not edit.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/scripts/agents-guard.js:
- Around line 401-410: The regex pattern in the parseActionReferenceLine
function accepts expression-based refs like ${{...}} in the second capture group
(the ref part), which should be rejected to ensure only literal static refs are
parsed. Modify the regex pattern to exclude refs containing expression syntax,
or add validation logic after the match to reject any refs that contain $ or {{
patterns, ensuring that only literal version tags and commit SHAs are treated as
static dependency refs rather than workflow logic expressions.
- Around line 616-620: The hasProtectedChanges variable only considers files
with status 'modified', allowing newly added protected workflow files to bypass
protection checks. Update the logic that sets hasProtectedChanges to also
include files with status 'added' that match protected paths using
matchProtectedPath. Additionally, update the protectedChangesAreDependencyOnly
filter condition to include both 'modified' and 'added' files when checking if
protected changes only contain dependency references via
patchChangesOnlyActionReferences.
🪄 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 Plus

Run ID: 3c3757ad-716f-4286-91ca-0d99d31cbf91

📥 Commits

Reviewing files that changed from the base of the PR and between edab48f and 2b4ae96.

📒 Files selected for processing (4)
  • .github/scripts/agents-guard.js
  • .github/workflows/agents-guard.yml
  • .github/workflows/maint-76-claude-code-review.yml
  • WORKFLOW_USER_GUIDE.md
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • stranske/Workflows (auto-detected)
📜 Review details
🧰 Additional context used
📓 Path-based instructions (3)
.github/workflows/**/*.yml

📄 CodeRabbit inference engine (CLAUDE.md)

First-party consumers should reference reusable workflows with @main unless intentionally pinning to an exact commit SHA for a controlled reason.

Files:

  • .github/workflows/agents-guard.yml
  • .github/workflows/maint-76-claude-code-review.yml
.github/workflows/agents-*.yml

📄 CodeRabbit inference engine (CLAUDE.md)

Agent workflows (agents-*.yml) should be fixed in stranske/Workflows, not locally.

Files:

  • .github/workflows/agents-guard.yml
.github/workflows/*.yml

📄 CodeRabbit inference engine (AGENTS.md)

First-party consumers currently reference reusable workflows with @main. Match that unless you are intentionally pinning to an exact commit SHA for a controlled reason.

Files:

  • .github/workflows/agents-guard.yml
  • .github/workflows/maint-76-claude-code-review.yml
🔀 Multi-repo context stranske/Workflows

Perfect! I now have sufficient cross-repository context to complete my analysis.

Linked repositories findings

stranske/Workflows (Template Repository)

agents-guard.js changes are already tested in source:

The source template repository shows tests for the new authorAssociation parameter in .github/scripts/__tests__/agents-guard.test.js (lines 329, 345, 362, 377), confirming that:

  • Tests already validate authorAssociation: 'OWNER' usage within the evaluateGuard() function
  • The parameter is tested as part of the dependency-upgrade bypass logic
  • Tests confirm the function works with the new parameter [::stranske/Workflows::]

Template consumer-repo files are synced versions:

The consumer template located at ./templates/consumer-repo/.github/workflows/agents-guard.yml already contains:

  • Extraction of context.payload.pull_request.author_association
  • Passing authorAssociation to evaluateGuard() invocation (lines matching the PR's changes)
  • This is the source template that the PR is syncing to Pension-Data [::stranske/Workflows::]

Sync manifest controls the distribution:

The .github/sync-manifest.yml in stranske/Workflows explicitly lists:

  • .github/scripts/agents-guard.js as a synced script
  • .github/workflows/agents-guard.yml as a synced workflow
  • WORKFLOW_USER_GUIDE.md as synced documentation
  • These files are distributed from templates/consumer-repo/ to all consumer repositories [::stranske/Workflows::]

Cross-repo impact assessment:

All consumer repositories (including stranske/Pension-Data) that receive this sync will get:

  1. The new authorAssociation parameter handling in the agents-guard.yml workflow
  2. The updated evaluateGuard() function that uses author association for dependency-upgrade bypass
  3. The new patchChangesOnlyActionReferences() exported function
  4. Updated documentation clarifying the dependency-only change policy

No breaking changes for consumers: The authorAssociation parameter has a default value in the function signature, so workflows that don't pass it will continue to work with the existing behavior.

🔇 Additional comments (4)
.github/scripts/agents-guard.js (1)

13-14: LGTM!

Also applies to: 486-487, 723-727, 741-741

.github/workflows/agents-guard.yml (1)

211-212: LGTM!

Also applies to: 425-425

WORKFLOW_USER_GUIDE.md (1)

168-168: LGTM!

Also applies to: 853-853

.github/workflows/maint-76-claude-code-review.yml (1)

192-192: LGTM!

Comment on lines +401 to +410
function parseActionReferenceLine(line) {
const match = String(line || '').match(/^\s*(?:-\s*)?uses:\s*["']?([^@\s#'"]+)@([^\s#'"]+)["']?(?:\s*(?:#.*)?)?$/i);
if (!match) {
return null;
}

return {
action: match[1].toLowerCase(),
ref: match[2],
};

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 | ⚡ Quick win

Reject expression-based refs in dependency-only parsing.

The current regex accepts non-literal refs (for example ${{...}}), which can be treated as dependency-only and bypass CODEOWNER even though that is workflow logic, not a static ref bump.

Suggested hardening
 function parseActionReferenceLine(line) {
   const match = String(line || '').match(/^\s*(?:-\s*)?uses:\s*["']?([^@\s#'"]+)@([^\s#'"]+)["']?(?:\s*(?:#.*)?)?$/i);
   if (!match) {
     return null;
   }
 
+  const action = match[1];
+  const ref = match[2];
+  if (ref.includes('${{') || ref.includes('}}')) {
+    return null;
+  }
+
   return {
-    action: match[1].toLowerCase(),
-    ref: match[2],
+    action: action.toLowerCase(),
+    ref,
   };
 }
📝 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
function parseActionReferenceLine(line) {
const match = String(line || '').match(/^\s*(?:-\s*)?uses:\s*["']?([^@\s#'"]+)@([^\s#'"]+)["']?(?:\s*(?:#.*)?)?$/i);
if (!match) {
return null;
}
return {
action: match[1].toLowerCase(),
ref: match[2],
};
function parseActionReferenceLine(line) {
const match = String(line || '').match(/^\s*(?:-\s*)?uses:\s*["']?([^@\s#'"]+)@([^\s#'"]+)["']?(?:\s*(?:#.*)?)?$/i);
if (!match) {
return null;
}
const action = match[1];
const ref = match[2];
if (ref.includes('${{') || ref.includes('}}')) {
return null;
}
return {
action: action.toLowerCase(),
ref,
};
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/scripts/agents-guard.js around lines 401 - 410, The regex pattern in
the parseActionReferenceLine function accepts expression-based refs like
${{...}} in the second capture group (the ref part), which should be rejected to
ensure only literal static refs are parsed. Modify the regex pattern to exclude
refs containing expression syntax, or add validation logic after the match to
reject any refs that contain $ or {{ patterns, ensuring that only literal
version tags and commit SHAs are treated as static dependency refs rather than
workflow logic expressions.

Comment on lines 616 to +620
const hasProtectedChanges = modifiedProtectedPaths.size > 0;
// Security note: Allow `agents:allow-change` label to bypass CODEOWNER approval
// ONLY for automated dependency PRs from known bots (dependabot, renovate).
// Human PRs or other bot PRs still require CODEOWNER approval even with label.
const isAutomatedPR = normalizedAuthor && (normalizedAuthor === 'dependabot[bot]' || normalizedAuthor === 'renovate[bot]');
const needsApproval = hasProtectedChanges && !hasCodeownerApproval && !(hasAllowLabel && isAutomatedPR);
const protectedChangesAreDependencyOnly = hasProtectedChanges && relevantFiles
.filter((file) => file.status === 'modified' && matchProtectedPath(file.filename || ''))
.every((file) => patchChangesOnlyActionReferences(file.patch || ''));
const isDependencyUpdateBot = Boolean(

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 | 🔴 Critical | ⚡ Quick win

Treat added protected workflows as protected changes.

hasProtectedChanges only tracks status === 'modified', so adding a new .github/workflows/agents-*.yml file can bypass both label and CODEOWNER gating entirely.

Suggested fix
-  const hasProtectedChanges = modifiedProtectedPaths.size > 0;
-  const protectedChangesAreDependencyOnly = hasProtectedChanges && relevantFiles
-    .filter((file) => file.status === 'modified' && matchProtectedPath(file.filename || ''))
-    .every((file) => patchChangesOnlyActionReferences(file.patch || ''));
+  const changedProtectedFiles = relevantFiles.filter((file) => {
+    const current = file.filename || '';
+    const previous = file.previous_filename || '';
+    const isProtected = Boolean(
+      matchProtectedPath(current) || (previous ? matchProtectedPath(previous) : null),
+    );
+    return isProtected && (file.status === 'modified' || file.status === 'added');
+  });
+  const hasProtectedChanges = changedProtectedFiles.length > 0;
+  const protectedChangesAreDependencyOnly = hasProtectedChanges && changedProtectedFiles.every(
+    (file) => file.status === 'modified' && patchChangesOnlyActionReferences(file.patch || ''),
+  );
📝 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
const hasProtectedChanges = modifiedProtectedPaths.size > 0;
// Security note: Allow `agents:allow-change` label to bypass CODEOWNER approval
// ONLY for automated dependency PRs from known bots (dependabot, renovate).
// Human PRs or other bot PRs still require CODEOWNER approval even with label.
const isAutomatedPR = normalizedAuthor && (normalizedAuthor === 'dependabot[bot]' || normalizedAuthor === 'renovate[bot]');
const needsApproval = hasProtectedChanges && !hasCodeownerApproval && !(hasAllowLabel && isAutomatedPR);
const protectedChangesAreDependencyOnly = hasProtectedChanges && relevantFiles
.filter((file) => file.status === 'modified' && matchProtectedPath(file.filename || ''))
.every((file) => patchChangesOnlyActionReferences(file.patch || ''));
const isDependencyUpdateBot = Boolean(
const changedProtectedFiles = relevantFiles.filter((file) => {
const current = file.filename || '';
const previous = file.previous_filename || '';
const isProtected = Boolean(
matchProtectedPath(current) || (previous ? matchProtectedPath(previous) : null),
);
return isProtected && (file.status === 'modified' || file.status === 'added');
});
const hasProtectedChanges = changedProtectedFiles.length > 0;
const protectedChangesAreDependencyOnly = hasProtectedChanges && changedProtectedFiles.every(
(file) => file.status === 'modified' && patchChangesOnlyActionReferences(file.patch || ''),
);
const isDependencyUpdateBot = Boolean(
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/scripts/agents-guard.js around lines 616 - 620, The
hasProtectedChanges variable only considers files with status 'modified',
allowing newly added protected workflow files to bypass protection checks.
Update the logic that sets hasProtectedChanges to also include files with status
'added' that match protected paths using matchProtectedPath. Additionally,
update the protectedChangesAreDependencyOnly filter condition to include both
'modified' and 'added' files when checking if protected changes only contain
dependency references via patchChangesOnlyActionReferences.

@agents-workflows-bot
agents-workflows-bot Bot merged commit 79a0c58 into main Jun 19, 2026
87 of 93 checks passed
@agents-workflows-bot
agents-workflows-bot Bot deleted the sync/workflows-c6b722d74cfd branch June 19, 2026 07:16
@coderabbitai coderabbitai Bot mentioned this pull request Jun 26, 2026
2 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

automated Automated sync from Workflows sync Automated sync from Workflows

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant