Fix dependabot milestone handling and branding footer automation#1013
Conversation
|
Warning Review limit reached
More reviews will be available in 42 minutes and 7 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more credits in the billing tab to continue. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits. 🚦 How do rate limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, the refill rate gradually slows as usage increases. The highest same-day bursts are limited more strictly. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Repository YAML (base), Organization UI (inherited) Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (15)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
✅ Template check passed after update. Thanks for fixing the PR description. |
🎨 Mermaid Diagram Validation✅ All Mermaid diagram checks passed.
|
🔍 Reviewer Summary for PR #1013CI Status: ❌ Recommendations
|
Metadata governance
|
There was a problem hiding this comment.
Code Review
This pull request standardizes the footer branding across all Markdown files in the repository and updates the .github/scripts/validate-footers.js script to enforce these branded footers and backfill them from category defaults. It also updates metadata governance documentation in docs/AUTOMATION.md. The review comments correctly identify two critical issues in the updated validation script: a data loss bug in replaceFooterTail where frontmatter separators are mistaken for footer separators, and a classification bug in inferCategory where README files inside template directories are incorrectly categorized as templates instead of readmes due to pattern matching order.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| function replaceFooterTail(content, footerTemplate) { | ||
| const footerBlock = `\n---\n\n${footerTemplate.trimEnd()}\n`; | ||
| const separators = []; | ||
| const lines = content.split("\n"); | ||
|
|
||
| lines.forEach((line, idx) => { | ||
| if (line.trim() === "---") { | ||
| separators.push(idx); | ||
| } | ||
| }); | ||
|
|
||
| if (separators.length === 0) { | ||
| if (content.endsWith("\n")) { | ||
| return `${content}${footerBlock.trimStart()}`; | ||
| } | ||
|
|
||
| return `${content}\n${footerBlock.trimStart()}`; | ||
| } | ||
|
|
||
| const lastSeparatorIdx = separators[separators.length - 1]; | ||
| const contentWithoutTail = lines.slice(0, lastSeparatorIdx).join("\n").replace(/\s+$/, ""); | ||
| return `${contentWithoutTail}${footerBlock}`; |
There was a problem hiding this comment.
The current implementation of replaceFooterTail has a critical bug that results in data loss.
If a Markdown file has frontmatter (which starts and ends with --- separators) but does not yet have a footer, separators.length will be 2. The code will set lastSeparatorIdx to the second separator (the closing frontmatter separator) and slice the content from 0 to lastSeparatorIdx. This completely discards the entire body of the document, leaving only the frontmatter and the new footer.
To prevent this, we must identify and skip the frontmatter separators when searching for the footer separator.
function replaceFooterTail(content, footerTemplate) {
const footerBlock = "\n---\n\n" + footerTemplate.trimEnd() + "\n";
const separators = [];
const lines = content.split("\n");
lines.forEach((line, idx) => {
if (line.trim() === "---") {
separators.push(idx);
}
});
const hasFrontmatter = lines[0]?.trim() === "---" || (lines[0]?.trim() === "" && lines[1]?.trim() === "---\n");
const footerSeparators = separators.filter((idx, sIdx) => !hasFrontmatter || sIdx >= 2);
if (footerSeparators.length === 0) {
if (content.endsWith("\n")) {
return content + footerBlock.trimStart();
}
return content + "\n" + footerBlock.trimStart();
}
const lastSeparatorIdx = footerSeparators[footerSeparators.length - 1];
const contentWithoutTail = lines.slice(0, lastSeparatorIdx).join("\n").replace(/\s+$/, "");
return contentWithoutTail + footerBlock;
}| const pathPatterns = [ | ||
| { pattern: /^\.github\/ISSUE_TEMPLATE\/.*\.md$/i, category: "issue-template" }, | ||
| { pattern: /^\.github\/PULL_REQUEST_TEMPLATE\/.*\.md$/i, category: "pull-request-template" }, | ||
| { pattern: /^agents\/.*\.(?:md|agent\.md)$/i, category: "agents" }, | ||
| { | ||
| pattern: /^instructions\/.*\.md$|.*\.instructions\.md$/i, | ||
| category: "instructions", | ||
| }, | ||
| { pattern: /^schema\/.*\.md$|.*\.schema\.md$/i, category: "schema" }, | ||
| { | ||
| pattern: /^\.github\/reports\/.*\.md$|.*audit.*\.md$/i, | ||
| category: "audit", | ||
| }, | ||
| { pattern: /.*research.*\.md$/i, category: "research" }, | ||
| { | ||
| pattern: /^scripts\/.*\.md$|^utils\/.*\.md$|.*utility.*\.md$/i, | ||
| category: "utility", | ||
| }, | ||
| { | ||
| pattern: /^docs\/.*governance.*\.md$|^governance\/.*\.md$/i, | ||
| category: "governance", | ||
| }, | ||
| { | ||
| pattern: /^docs\/.*(?:automation|ai-ops).*\.md$/i, | ||
| category: "ai-ops", | ||
| }, | ||
| { pattern: /^docs\/.*\.md$/i, category: "docs" }, | ||
| { pattern: /^(?:.*\/)?README\.md$/i, category: "readme" }, | ||
| ]; | ||
|
|
There was a problem hiding this comment.
The README.md pattern is currently placed at the very bottom of pathPatterns. Because pathPatterns.find stops at the first match, any README.md file located inside .github/ISSUE_TEMPLATE/ or .github/PULL_REQUEST_TEMPLATE/ will be incorrectly classified as "issue-template" or "pull-request-template" instead of "readme".
This causes template placeholders (like Related issues: {related_issues} or Closes: {closes_issues}) to be appended to the README files instead of the standard branded footer.
Moving the README.md pattern to the top of the array resolves this issue.
const pathPatterns = [
{ pattern: /^(?:.*\/)?README\.md$/i, category: "readme" },
{ pattern: /^\.github\/ISSUE_TEMPLATE\/.*\.md$/i, category: "issue-template" },
{ pattern: /^\.github\/PULL_REQUEST_TEMPLATE\/.*\.md$/i, category: "pull-request-template" },
{ pattern: /^agents\/.*\.(?:md|agent\.md)$/i, category: "agents" },
{
pattern: /^instructions\/.*\.md$|.*\.instructions\.md$/i,
category: "instructions",
},
{ pattern: /^schema\/.*\.md$|.*\.schema\.md$/i, category: "schema" },
{
pattern: /^\.github\/reports\/.*\.md$|.*audit.*\.md$/i,
category: "audit",
},
{ pattern: /.*research.*\.md$/i, category: "research" },
{
pattern: /^scripts\/.*\.md$|^utils\/.*\.md$|.*utility.*\.md$/i,
category: "utility",
},
{
pattern: /^docs\/.*governance.*\.md$|^governance\/.*\.md$/i,
category: "governance",
},
{
pattern: /^docs\/.*(?:automation|ai-ops).*\.md$/i,
category: "ai-ops",
},
{ pattern: /^docs\/.*\.md$/i, category: "docs" }
];Signed-off-by: Ash Shaw <ashley@lightspeedwp.agency>
|
@Mergifyio queue |
Merge Queue Status
Waiting for
All conditions
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6f146b0480
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| function getFooterSignatures() { | ||
| const canonicalTemplates = getCanonicalFooterTemplates(); | ||
| const canonicalSignatures = canonicalTemplates | ||
| .map((template) => template.split("\n").map((line) => line.trim()).find(Boolean)) |
There was a problem hiding this comment.
Skip delimiter lines when deriving footer signatures
When the canonical config/footers.config.yaml is present, each template starts with a --- divider, and this find(Boolean) records that divider as a known footer signature. In any Markdown document that uses a horizontal rule after frontmatter, hasKnownFooter() then treats everything after the last --- as an existing footer, so ensureFooter() replaces real body content with a footer. Filter out delimiter-only lines, as the validator does, before adding canonical signatures.
Useful? React with 👍 / 👎.
| function buildFooterBlock(footerText) { | ||
| return `\n---\n\n${footerText.trimEnd()}\n`; |
There was a problem hiding this comment.
Avoid wrapping canonical footers with a second divider
With the normal footer config loaded, getFooterPhrases() returns the full configured template, and those templates already include their leading --- divider. This wrapper prepends another divider, so generated footers become --- followed by another --- before the footer text; the same shape is used by the new validate-footers --fix path. Strip the configured divider or only add one for legacy fallback footers to keep generated documents in the documented single-footer format.
Useful? React with 👍 / 👎.
| const tailStart = separators[separators.length - 1] + 1; | ||
| return lines.slice(tailStart).join("\n").trim(); |
There was a problem hiding this comment.
Strip frontmatter before scanning for footer signatures
For a document with frontmatter but no footer, the closing frontmatter marker is the last ---, so this returns the whole body as the footer tail. If the body merely shows an example footer signature, as remediation/specification docs commonly do, footerHitCounts becomes non-zero and the new require_footer_in_document CI check passes even though no footer exists at the end of the file. Remove the frontmatter block before locating the footer divider.
Useful? React with 👍 / 👎.
Linked issues
Fixes #1010
Context
Reproduction
Root Cause
Fix Summary
Verification
Risk & Rollback
Changelog
Added
Changed
Fixed
Removed
Checklist (Global DoD / PR)
References