Skip to content

Feat/adding more centralised jobs#8

Merged
palisadoes merged 3 commits into
PalisadoesFoundation:mainfrom
yashgoyal0110:feat/adding-more-centralised-jobs
Jan 1, 2026
Merged

Feat/adding more centralised jobs#8
palisadoes merged 3 commits into
PalisadoesFoundation:mainfrom
yashgoyal0110:feat/adding-more-centralised-jobs

Conversation

@yashgoyal0110

@yashgoyal0110 yashgoyal0110 commented Jan 1, 2026

Copy link
Copy Markdown
Member

Fixes: #7

Summary by CodeRabbit

  • New Features
    • Org-wide auto-assignment with per-user open-issue limits and self-assign/unassign commands
    • Automatic handling of "unapproved" label on assignment and unassignment
    • Enhanced auto-labeling rules and label synonyms configuration
    • CodeRabbit review approval enforcement for pull requests
    • PR greeting with review policy and enforcement of issue linkage/assignee
    • Configurable stale issue/PR automation and skip-list for PR checks

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai

coderabbitai Bot commented Jan 1, 2026

Copy link
Copy Markdown

Walkthrough

Adds seven new reusable GitHub Actions workflows and a label config to automate issue assignment with an org-wide assignment limit, label lifecycle on assign/unassign, PR review enforcement and policy checks, and stale content management.

Changes

Cohort / File(s) Summary
Org-wide Auto-Assign
.github/workflows/auto-assign.yml
New workflow to handle /assign and /unassign comments, enforce a per-user org-wide max open-assigned-issues (default 2), ignore bots, validate contributor status (check merged PRs for first-timers), paginate org repos/issues when counting assignments, and post informative comments on success/failure.
Issue Label Lifecycle
.github/workflows/issue-assigned.yml, .github/workflows/issue-unassigned.yml
Two reusable workflows: one removes any "unapprov*" label when issues are assigned; the other adds an unapproved label when a user is unassigned. Both use actions/github-script and handle missing/404 cases gracefully.
Auto-labeling Config & Workflow
.github/workflows/issue.yml, .github/workflows/auto-label.json5
Reusable auto-label workflow invoking an external auto-label action and post-processing labels to add good first issue and/or security based on detected labels; includes a label synonyms config .github/workflows/auto-label.json5.
Pull Request Policy & Review
.github/workflows/pull-request-target.yml, .github/workflows/pull-request-review.yml
Two reusable workflows: one posts a PR review-policy greeting and enforces PR→issue linkage/assignee via an external action; the other enforces that a CodeRabbit account (coderabbit/coderabbitai) has an APPROVED review (waits 30s, fetches reviews, validates latest CR review).
Stale Content Management
.github/workflows/stale.yml
Reusable workflow using actions/stale@v10 configured to mark/close stale issues/PRs (stale after 10 days, close after 360 days) with custom messages and exemptions.
Config / Skip List
.github/workflows/config/check-pr-issue-skip-usernames.txt
Adds a skip-list of usernames for the PR-issue linkage check (dependabot, noman2002, palisadoes).

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant User as Commenting User
  participant GH as GitHub Events / Issue
  participant Action as auto-assign Workflow
  participant API as GitHub REST API (Org, Search, Issues)
  Note over Action,API: Org-wide assignment flow (new/changed)

  User->>GH: Posts "/assign" comment
  GH->>Action: workflow_call / event triggers
  Action->>API: Fetch comment author, ignore bots
  Action->>API: Check issue creator association
  alt First-time contributor
    Action->>API: Search merged PRs for user
    API-->>Action: merged PRs found? 
  end
  Action->>API: List org repos (paginated, skip archived)
  loop per repo until limit reached
    Action->>API: List open issues assigned to user (paginated)
    API-->>Action: Count assignments
  end
  Action->>API: Re-verify counts (race-mitigation)
  alt Under limit and issue unassigned
    Action->>API: Add assignee to issue
    API-->>Action: Success
    Action->>GH: Post success comment
  else Limit reached or other assignee present
    Action->>GH: Post warning/error comment
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰 I hopped through workflows, tidy and spry,
Assigns and labels now leap to the sky.
Reviews and stale checks in neat little rows,
Branches and issues where automation grows.
Hop on, dear repo — let's watch CI glow!

Pre-merge checks

✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Feat/adding more centralised jobs' accurately describes the main objective of adding centralized GitHub Actions workflows to the .github repository.
Linked Issues check ✅ Passed All required workflows from issue #7 are added to .github/workflows/ with proper configuration and no functionality is affected.
Out of Scope Changes check ✅ Passed All changes directly support centralizing GitHub Actions workflows as specified in issue #7; no unrelated modifications detected.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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.

❤️ Share

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

@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: 10

🧹 Nitpick comments (14)
.github/workflows/issue-unassigned.yml (2)

3-7: Remove redundant GITHUB_TOKEN secret.

The actions/github-script action automatically has access to secrets.GITHUB_TOKEN by default. Explicitly requiring and passing it as a secret is unnecessary and adds complexity.

🔎 Proposed refactor
 on:
   workflow_call:
-    secrets:
-      GITHUB_TOKEN:
-        required: true

And update line 21:

       - name: Add unapproved label
         uses: actions/github-script@v7
-        with:
-          github-token: ${{ secrets.GITHUB_TOKEN }}
-          script: |
+        with:
+          script: |

13-15: Remove unnecessary contents: read permission.

This workflow only manipulates issue labels and doesn't access repository contents. The contents: read permission is not required.

🔎 Proposed refactor
     permissions:
       issues: write
-      contents: read
.github/workflows/issue-assigned.yml (2)

6-8: Remove unnecessary contents: read permission.

This workflow only manipulates issue labels and doesn't access repository contents.

🔎 Proposed refactor
 permissions:
-  contents: read
   issues: write

28-30: Consider exact label name matching.

The current substring search label.name.toLowerCase().includes('unapprov') could match unintended labels like "re-unapproved" or "unapproved-old". Since the companion workflow in issue-unassigned.yml adds specifically "unapproved", an exact match would be more precise.

🔎 Proposed refactor
-            const unapprovedLabel = labelList.find(label =>
-              label.name.toLowerCase().includes('unapprov')
-            );
+            const unapprovedLabel = labelList.find(label =>
+              label.name === 'unapproved'
+            );
.github/workflows/issue.yml (1)

3-7: Remove redundant GITHUB_TOKEN secret.

Both Renato66/auto-label@v3 and actions/github-script can access the default secrets.GITHUB_TOKEN automatically. Explicitly requiring it as a secret is unnecessary.

🔎 Proposed refactor
 on:
   workflow_call:
-    secrets:
-      GITHUB_TOKEN:
-        required: true

And update references on lines 29 and 34 to use secrets.GITHUB_TOKEN directly (which works without the explicit declaration).

.github/workflows/pull-request-target.yml (1)

3-7: Remove redundant GITHUB_TOKEN secret.

The actions used in this workflow can access the default secrets.GITHUB_TOKEN automatically without explicit declaration.

🔎 Proposed refactor
 on:
   workflow_call:
-    secrets:
-      GITHUB_TOKEN:
-        required: true
.github/workflows/pull-request-review.yml (3)

3-7: Consider documenting expected caller triggers.

This reusable workflow expects context.payload.pull_request to be available (line 28), which means the calling workflow must be triggered by a pull request event (e.g., pull_request, pull_request_review). Consider adding a comment documenting this requirement for callers.


18-20: Hardcoded 30s sleep may be fragile.

The 30-second wait for "review status propagation" is arbitrary. In high-load scenarios or with GitHub API delays, this may be insufficient. Conversely, it adds latency for every workflow run. Consider making this configurable via a workflow input with a sensible default, or implementing a polling mechanism.

🔎 Example: Make wait time configurable
 on:
   workflow_call:
+    inputs:
+      wait_seconds:
+        description: 'Seconds to wait for review status propagation'
+        required: false
+        type: number
+        default: 30
     secrets:
       GITHUB_TOKEN:
         required: true

Then use ${{ inputs.wait_seconds }} in the sleep command.


31-35: Add pagination for large PR review counts.

github.rest.pulls.listReviews returns paginated results (default 30 per page). For PRs with extensive review history, this may miss older reviews. While CodeRabbit reviews are typically recent, using github.paginate() ensures robustness.

🔎 Proposed fix to add pagination
-            const { data: reviews } = await github.rest.pulls.listReviews({
-              owner,
-              repo,
-              pull_number
-            });
+            const reviews = await github.paginate(github.rest.pulls.listReviews, {
+              owner,
+              repo,
+              pull_number,
+              per_page: 100
+            });
.github/workflows/auto-assign.yml (5)

9-10: Consider exposing MAX_OPEN_ASSIGNMENTS as a workflow input.

The assignment limit is hardcoded as an environment variable. Making it a workflow input would allow callers to configure different limits per-repository without modifying this workflow.

🔎 Example: Add as workflow input
 on:
   workflow_call:
+    inputs:
+      max_open_assignments:
+        description: 'Maximum open issues per user across org'
+        required: false
+        type: number
+        default: 2
     secrets:
       ORG_ACCESS_TOKEN:
         required: true
-
-env:
-  MAX_OPEN_ASSIGNMENTS: 2

Then reference ${{ inputs.max_open_assignments }} in the script.


60-60: Unnecessary fallback to pull_request.

Line 16 already ensures this job only runs when github.event.issue.pull_request == null, so context.payload.pull_request will never be defined. The fallback is dead code.

🔎 Proposed simplification
-            const issue = context.payload.issue || context.payload.pull_request;
+            const issue = context.payload.issue;

277-280: Silent skip when another user is assigned may confuse users.

When the issue is already assigned to someone else, the workflow silently returns without notifying the requesting user. Consider posting a comment explaining why the assignment was skipped.

🔎 Proposed improvement
             if (currentAssignees.length > 0) {
-              console.log("Issue already assigned to someone else, skipping.");
+              await github.rest.issues.createComment({
+                owner,
+                repo,
+                issue_number: issueNumber,
+                body: `ℹ️ @${user} This issue is already assigned to @${currentAssignees.join(', @')}. Please find another issue or wait for it to become available.`,
+              });
+              console.log("Issue already assigned to someone else, notified user.");
               return;
             }

377-417: Duplicate code between initial count and re-check.

The org-wide counting logic (lines 297-319) is largely duplicated in the re-check (lines 380-401). Consider extracting this into a reusable helper function to reduce duplication and maintenance burden.

🔎 Suggested refactor
async function countOrgAssignments(github, owner, user, activeRepos, maxAssignments) {
  let count = 0;
  for (const r of activeRepos) {
    if (count >= maxAssignments) break;
    try {
      const assignedIssues = [];
      for await (const response of github.paginate.iterator(
        github.rest.issues.listForRepo,
        { owner, repo: r.name, state: "open", assignee: user, per_page: 100 }
      )) {
        assignedIssues.push(...response.data);
        if (assignedIssues.length >= maxAssignments) break;
      }
      count += assignedIssues.length;
    } catch (repoError) {
      console.warn(`Skipping ${r.name}: ${repoError.message}`);
    }
  }
  return count;
}

Then call this function for both the initial check and re-check.


414-417: Error during re-check is swallowed; consider logging more context.

When the re-check fails, the workflow proceeds with assignment anyway. This is a reasonable fallback, but logging the full error context (not just the message) would aid debugging.

🔎 Proposed improvement
             } catch (error) {
-              console.error("Error during assignment re-check:", error);
+              console.error("Error during assignment re-check:", error.message, error.stack);
               // Continue with assignment since we already passed the first check
+              console.log("Proceeding with assignment despite re-check failure");
             }
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 635901b and 03d762d.

📒 Files selected for processing (7)
  • .github/workflows/auto-assign.yml
  • .github/workflows/issue-assigned.yml
  • .github/workflows/issue-unassigned.yml
  • .github/workflows/issue.yml
  • .github/workflows/pull-request-review.yml
  • .github/workflows/pull-request-target.yml
  • .github/workflows/stale.yml
🔇 Additional comments (7)
.github/workflows/stale.yml (1)

5-14: LGTM!

The input defaults are well-configured. The 360-day close threshold is appropriately conservative for issue/PR lifecycle management.

.github/workflows/pull-request-target.yml (1)

10-41: LGTM!

The PR greeting message is well-structured and provides helpful guidance to contributors with clear links to policies and documentation.

.github/workflows/pull-request-review.yml (2)

38-45: CodeRabbit username filtering logic is sound.

The case-insensitive matching for both coderabbit and coderabbitai usernames, along with excluding COMMENTED state reviews, correctly identifies actionable CodeRabbit reviews.


52-65: Sorting and approval check logic is correct.

The descending sort by submitted_at and the check for APPROVED state on the latest review correctly implements the enforcement logic. The success/failure messages are clear.

.github/workflows/auto-assign.yml (3)

84-103: hasMergedPRs helper is well-implemented.

The function uses the search API efficiently with per_page: 1, includes proper error handling with a fail-safe default, and has good logging. The query construction is correct.


218-269: Unassign logic is robust.

The /unassign handling correctly validates the exact command, checks if the user is actually assigned, and has proper error handling with fallback comments. Good defensive coding.


419-453: Final assignment block has proper error handling.

The assignment logic correctly adds the assignee, posts a success comment, and handles failures with informative error comments. The nested try-catch for the error comment is good defensive coding.

Comment on lines +64 to +68
// Default assignment limit is 2 if not configured
const maxAssignments = parseInt(process.env.MAX_OPEN_ASSIGNMENTS || '2');
if (isNaN(maxAssignments)) {
throw new Error(`Invalid MAX_OPEN_ASSIGNMENTS value: "${process.env.MAX_OPEN_ASSIGNMENTS}". Must be a positive integer.`);
}

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

Add validation for positive integer.

The validation checks for NaN but doesn't verify that maxAssignments is a positive integer (> 0). A value of 0 or negative would effectively block all assignments silently.

🔎 Proposed fix
             const maxAssignments = parseInt(process.env.MAX_OPEN_ASSIGNMENTS || '2');
-            if (isNaN(maxAssignments)) {
-              throw new Error(`Invalid MAX_OPEN_ASSIGNMENTS value: "${process.env.MAX_OPEN_ASSIGNMENTS}". Must be a positive integer.`);
-            }            
+            if (isNaN(maxAssignments) || maxAssignments < 1) {
+              throw new Error(`Invalid MAX_OPEN_ASSIGNMENTS value: "${process.env.MAX_OPEN_ASSIGNMENTS}". Must be a positive integer >= 1.`);
+            }
📝 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
// Default assignment limit is 2 if not configured
const maxAssignments = parseInt(process.env.MAX_OPEN_ASSIGNMENTS || '2');
if (isNaN(maxAssignments)) {
throw new Error(`Invalid MAX_OPEN_ASSIGNMENTS value: "${process.env.MAX_OPEN_ASSIGNMENTS}". Must be a positive integer.`);
}
// Default assignment limit is 2 if not configured
const maxAssignments = parseInt(process.env.MAX_OPEN_ASSIGNMENTS || '2');
if (isNaN(maxAssignments) || maxAssignments < 1) {
throw new Error(`Invalid MAX_OPEN_ASSIGNMENTS value: "${process.env.MAX_OPEN_ASSIGNMENTS}". Must be a positive integer >= 1.`);
}
🤖 Prompt for AI Agents
In .github/workflows/auto-assign.yml around lines 64 to 68, the code only checks
for NaN but does not ensure the parsed MAX_OPEN_ASSIGNMENTS is a positive
integer, so values like 0 or negatives would silently block assignments; change
the parsing/validation to ensure the value is a finite integer > 0 (e.g., parse
as a Number, verify Number.isInteger(value) and value > 0) and throw an error
with the current env value if the check fails.

Comment on lines +288 to +293
const repos = await github.paginate(github.rest.repos.listForOrg, {
org: owner,
type: "all",
per_page: 100,
max_items: 500, // Limit to first 500 repos to avoid excessive API calls
});

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

🌐 Web query:

Octokit github.paginate max_items parameter options

💡 Result:

Short answer: octokit.paginate (REST) has no built-in max_items parameter. Control pagination by per_page (max 100) and either stop early in your mapFunction or use the iterator to break manually. The GraphQL paginate plugin likewise returns all pages unless you limit via your query variables (first/last) or stop iteration yourself. Sources: Octokit paginate plugin docs and GitHub REST pagination docs. [1][2][3]

References:

  • Octokit paginate (plugin) docs — octokit.paginate, per_page and mapFunction details. [1]
  • GitHub REST pagination (per_page up to 100). [2]
  • Octokit GraphQL paginate plugin (iterator / query-based limits). [3]

🏁 Script executed:

# Let's examine the actual code in the workflow file at the mentioned lines
cat .github/workflows/auto-assign.yml | sed -n '288,313p'

Repository: PalisadoesFoundation/.github

Length of output: 1174


🏁 Script executed:

# Check lines 386-396 for the third occurrence mentioned in the review
cat .github/workflows/auto-assign.yml | sed -n '386,396p'

Repository: PalisadoesFoundation/.github

Length of output: 547


Remove max_items from github.paginate calls — it is not a valid Octokit parameter and will be silently ignored.

Octokit's paginate method does not support max_items. This parameter will be ignored, causing all pages to be fetched instead of limiting to 500, leading to excessive API calls. Use the iterator form to properly limit results.

🔎 Proposed fix using paginate.iterator
-              const repos = await github.paginate(github.rest.repos.listForOrg, {
-                org: owner,
-                type: "all",
-                per_page: 100,
-                max_items: 500,  // Limit to first 500 repos to avoid excessive API calls                      
-              });
+              const repos = [];
+              for await (const response of github.paginate.iterator(github.rest.repos.listForOrg, {
+                org: owner,
+                type: "all",
+                per_page: 100,
+              })) {
+                repos.push(...response.data);
+                if (repos.length >= 500) break;  // Limit to first 500 repos
+              }

Apply similar changes to the listForRepo calls at lines 303-313 and 386-396.

Also applies to: 303-313, 386-396

🤖 Prompt for AI Agents
In .github/workflows/auto-assign.yml around lines 288-293 (and also apply to
303-313 and 386-396), remove the invalid max_items option from github.paginate
calls and replace with the paginate.iterator pattern: call
github.paginate.iterator(...) with the same listForOrg/listForRepo parameters
(without max_items), iterate pages, push items into a results array and stop
once you reach 500 items (break the loop), ensuring you only fetch as many pages
as needed; do this for each occurrence mentioned so the workflow limits API
calls correctly.

Comment on lines +19 to +23
script: |
const { owner, repo } = context.repo;
const issue_number = context.issue.number;

const apiParams = { owner, repo, issue_number };

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Add validation for context.issue.number.

When invoked via workflow_call, the context.issue object may not be populated. Validate that issue_number exists before making API calls.

🔎 Proposed fix
           script: |
             const { owner, repo } = context.repo;
             const issue_number = context.issue.number;
 
+            if (!issue_number) {
+              console.log('No issue number found in context, skipping');
+              return;
+            }
+
             const apiParams = { owner, repo, issue_number };
📝 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
script: |
const { owner, repo } = context.repo;
const issue_number = context.issue.number;
const apiParams = { owner, repo, issue_number };
script: |
const { owner, repo } = context.repo;
const issue_number = context.issue.number;
if (!issue_number) {
console.log('No issue number found in context, skipping');
return;
}
const apiParams = { owner, repo, issue_number };
🤖 Prompt for AI Agents
In .github/workflows/issue-assigned.yml around lines 19 to 23, the workflow
assumes context.issue.number exists but context.issue can be empty when invoked
via workflow_call; add a validation guard that checks context.issue and
context.issue.number before constructing apiParams, and if missing either fail
the job with a clear error message (e.g., via core.setFailed or exit) or skip
the API call path; ensure subsequent code only runs when issue_number is present
to avoid calling the GitHub API with an undefined issue number.

Comment on lines +22 to +32
script: |
const { owner, repo } = context.repo;
const issue_number = context.issue.number;

try {
// Fetch full issue (ensures complete label list)
const { data: issue } = await github.rest.issues.get({
owner,
repo,
issue_number
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Add validation for context.issue.number.

When invoked via workflow_call, the context.issue object may not always be populated depending on the triggering event. Add validation to ensure context.issue.number exists before proceeding.

🔎 Proposed fix
           script: |
             const { owner, repo } = context.repo;
             const issue_number = context.issue.number;
 
+            if (!issue_number) {
+              console.log('No issue number found in context, skipping');
+              return;
+            }
+
             try {
               // Fetch full issue (ensures complete label list)
               const { data: issue } = await github.rest.issues.get({
📝 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
script: |
const { owner, repo } = context.repo;
const issue_number = context.issue.number;
try {
// Fetch full issue (ensures complete label list)
const { data: issue } = await github.rest.issues.get({
owner,
repo,
issue_number
});
script: |
const { owner, repo } = context.repo;
const issue_number = context.issue.number;
if (!issue_number) {
console.log('No issue number found in context, skipping');
return;
}
try {
// Fetch full issue (ensures complete label list)
const { data: issue } = await github.rest.issues.get({
owner,
repo,
issue_number
});
🤖 Prompt for AI Agents
.github/workflows/issue-unassigned.yml around lines 22 to 32: the workflow
assumes context.issue.number exists which can be undefined when triggered via
workflow_call; add a guard that checks context.issue and context.issue.number
before using them and bail out early (log or set a neutral outcome) if absent,
so the rest of the script only runs when a valid issue number is present.

Comment on lines +19 to +24
- name: Checkout only label config
uses: actions/checkout@v4
with:
sparse-checkout: |
.github/workflows/auto-label.json5
sparse-checkout-cone-mode: false

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check if the auto-label configuration file exists
if [ -f ".github/workflows/auto-label.json5" ]; then
  echo "Configuration file exists"
  cat ".github/workflows/auto-label.json5"
else
  echo "WARNING: Configuration file .github/workflows/auto-label.json5 does not exist"
  echo "Searching for similar files..."
  fd -t f "auto-label" .github/
fi

Repository: PalisadoesFoundation/.github

Length of output: 180


🏁 Script executed:

#!/bin/bash
# Search for label configuration files with various extensions
echo "=== Searching for label config files ==="
fd -t f "label" .github/ | grep -E "\.(json|json5|yaml|yml)$"

# Also check what's in the .github/workflows directory
echo -e "\n=== Files in .github/workflows ==="
ls -la .github/workflows/

# Check the issue.yml workflow to understand how it uses the config file
echo -e "\n=== Examining issue.yml workflow ==="
cat -n .github/workflows/issue.yml

Repository: PalisadoesFoundation/.github

Length of output: 3135


The auto-label configuration file is missing and must be created.

The workflow references .github/workflows/auto-label.json5 in the sparse checkout, but this file does not exist in the repository. The Renato66/auto-label@v3 action requires this configuration file to define labeling rules. Without it, the workflow will fail. Create the file with appropriate label configuration rules or update the workflow if auto-labeling is not intended.

🤖 Prompt for AI Agents
.github/workflows/issue.yml around lines 19 to 24: the workflow sparsely checks
out .github/workflows/auto-label.json5 which does not exist, causing the
Renato66/auto-label@v3 step to fail; either create
.github/workflows/auto-label.json5 with the required labeling rules (matchers,
labels, scope and format expected by Renato66/auto-label) and commit it, or
remove/update the sparse-checkout lines and the auto-label step if automatic
labeling is not intended so the workflow no longer references a missing file.

Comment on lines +35 to +44
script: |
const { owner, repo } = context.repo;
const issue_number = context.issue.number;

const { data: labels } =
await github.rest.issues.listLabelsOnIssue({
owner,
repo,
issue_number
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Add validation for context.issue.number.

The post-processing step should validate that issue_number exists in the context before making API calls.

🔎 Proposed fix
           script: |
             const { owner, repo } = context.repo;
             const issue_number = context.issue.number;
 
+            if (!issue_number) {
+              console.log('No issue number found in context, skipping');
+              return;
+            }
+
             const { data: labels } =
               await github.rest.issues.listLabelsOnIssue({
🤖 Prompt for AI Agents
In .github/workflows/issue.yml around lines 35 to 44, validate that
context.issue.number is present before calling
github.rest.issues.listLabelsOnIssue: add a guard that checks context.issue &&
typeof context.issue.number !== 'undefined' (or Number.isInteger) and if missing
log a clear message and exit/return (or call core.setFailed) to avoid making the
API call with an undefined issue_number; only destructure and call github.rest
when the check passes.

Comment on lines +49 to +62
if (hasAny(["dependencies"])) {
await github.rest.issues.addLabels({
owner,
repo,
issue_number,
labels: ["good first issue", "security"]
});
} else if (hasAny(["security", "ui/ux", "test", "ci/cd"])) {
await github.rest.issues.addLabels({
owner,
repo,
issue_number,
labels: ["good first issue"]
});

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

Review the automatic "good first issue" labeling logic.

The current logic automatically marks issues as "good first issue" based solely on category labels:

  • Issues with "dependencies" are automatically labeled as both "good first issue" AND "security"
  • Issues with "security", "ui/ux", "test", or "ci/cd" labels are automatically marked "good first issue"

This assumption may not hold:

  • Dependency upgrades can be complex and security-sensitive, not suitable for first-time contributors
  • Security, UI/UX, test, and CI/CD issues span a wide complexity range

Consider making "good first issue" an explicit label that maintainers assign based on actual complexity assessment rather than automatic assignment.

🤖 Prompt for AI Agents
In .github/workflows/issue.yml around lines 49–62, the workflow automatically
assigns "good first issue" based solely on category labels (dependencies,
security, ui/ux, test, ci/cd); remove this automatic assignment and require an
explicit maintainer action or explicit "good first issue" marker before adding
that label. Update the logic to stop adding "good first issue" in those
branches; instead either (a) only add the label when the issue already contains
an explicit "good first issue" label set by a human, or (b) add a bot comment
notifying maintainers to review and add "good first issue" manually (or use a
new "good-first-candidate" label that still requires maintainer promotion).
Ensure the workflow no longer treats category labels as sufficient criteria for
adding "good first issue."

Comment thread .github/workflows/pull-request-target.yml
Comment on lines +55 to +64
- name: Check PR linked issue and assignee
uses: arkid15r/check-pr-issue-action@0.1.3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
close_pr_on_failure: 'true'
check_issue_reference: 'true'
require_assignee: 'true'
no_assignee_message: 'The linked issue must be assigned to the PR author.'
no_issue_message: 'The PR must be linked to an issue assigned to the PR author.'
skip_users_file_path: '.github/workflows/config/check-pr-issue-skip-usernames.txt'

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

🧩 Analysis chain

🌐 Web query:

arkid15r/check-pr-issue-action github action close_pr_on_failure

💡 Result:

I couldn't find an arkid15r/check-pr-issue-action repo or any references to a close_pr_on_failure input. Do you want me to (pick one):

  • search GitHub for that specific repo/action and its inputs now, or
  • explain how to implement a close_on_failure behavior in a GitHub Action (example workflow + script)?

🌐 Web query:

arkid15r check-pr-issue-action repository documentation

💡 Result:

I couldn't find a public repository named "arkid15r/check-pr-issue-action". Do you mean a different repo name or can you share the repository URL (or a link to its README)? If you want, I can search GitHub for similar actions (e.g., "check-pr", "pr-status", "check-pr-issue-action") — confirm and I’ll run the search.


🏁 Script executed:

# Search the repository for any usage documentation or README about this action
cd /tmp && git clone https://github.com/arkid15r/check-pr-issue-action.git 2>&1 | head -20

Repository: PalisadoesFoundation/.github

Length of output: 173


🏁 Script executed:

# Once cloned, check the README and action.yml to understand the behavior
cat /tmp/check-pr-issue-action/README.md 2>/dev/null | head -100
cat /tmp/check-pr-issue-action/action.yml 2>/dev/null

Repository: PalisadoesFoundation/.github

Length of output: 54


🏁 Script executed:

# Search for references to arkid15r or check-pr-issue in the repository
rg "arkid15r|check-pr-issue" --type yaml --type yml

Repository: PalisadoesFoundation/.github

Length of output: 99


🏁 Script executed:

# List all files in .github/workflows to understand the repository structure
fd . .github/workflows -type f

Repository: PalisadoesFoundation/.github

Length of output: 242


🏁 Script executed:

# Check if there are any action definitions locally
fd action.yml . --type f

Repository: PalisadoesFoundation/.github

Length of output: 54


🏁 Script executed:

# Also search for any documentation about this workflow requirement
fd -e md -e txt . .github | head -20

Repository: PalisadoesFoundation/.github

Length of output: 54


🏁 Script executed:

# Find the workflow file mentioned in the review
find .github -name "pull-request-target.yml"

Repository: PalisadoesFoundation/.github

Length of output: 113


🏁 Script executed:

# Search for arkid15r in the repository
grep -r "arkid15r" . 2>/dev/null | head -20

Repository: PalisadoesFoundation/.github

Length of output: 166


🏁 Script executed:

# Search for check-pr-issue references
grep -r "check-pr-issue" . 2>/dev/null

Repository: PalisadoesFoundation/.github

Length of output: 365


🏁 Script executed:

# List the contents of .github/workflows directory
ls -la .github/workflows/

Repository: PalisadoesFoundation/.github

Length of output: 883


🏁 Script executed:

# Read the pull-request-target.yml file to see the full context
cat -n .github/workflows/pull-request-target.yml

Repository: PalisadoesFoundation/.github

Length of output: 2430


🏁 Script executed:

# Search for GitHub Actions marketplace or documentation about this action
# Try searching for it on GitHub directly by looking for common patterns
grep -r "github.com/arkid15r" . 2>/dev/null

Repository: PalisadoesFoundation/.github

Length of output: 54


🏁 Script executed:

# Search GitHub API for the action or check if it's a known action
python3 << 'EOF'
import urllib.request
import json

# Try to fetch the action from GitHub
url = "https://api.github.com/repos/arkid15r/check-pr-issue-action"
try:
    with urllib.request.urlopen(url, timeout=5) as response:
        data = json.loads(response.read().decode())
        print("Repository found!")
        print(f"Description: {data.get('description', 'N/A')}")
        print(f"URL: {data.get('html_url', 'N/A')}")
        print(f"Last updated: {data.get('updated_at', 'N/A')}")
except Exception as e:
    print(f"Repository not found or error: {e}")
EOF

Repository: PalisadoesFoundation/.github

Length of output: 230


🏁 Script executed:

# Check if the skip_users_file_path file exists in the repository
ls -la .github/workflows/config/ 2>/dev/null || echo "Config directory not found"

Repository: PalisadoesFoundation/.github

Length of output: 98


🏁 Script executed:

# Look for any documentation or comments about the action policy
grep -r "close_pr" . --include="*.md" --include="*.txt" 2>/dev/null | head -10

Repository: PalisadoesFoundation/.github

Length of output: 54


🏁 Script executed:

# Check if there's a custom action defined anywhere in the repository
find . -name "action.yml" -o -name "action.yaml" 2>/dev/null

Repository: PalisadoesFoundation/.github

Length of output: 54


🏁 Script executed:

# Look for GitHub Actions marketplace references or action definitions
find . -type f \( -name "*.yml" -o -name "*.yaml" \) -exec grep -l "action:" {} \; 2>/dev/null

Repository: PalisadoesFoundation/.github

Length of output: 54


🏁 Script executed:

# Check the entire .github structure
find .github -type f | sort

Repository: PalisadoesFoundation/.github

Length of output: 449


🏁 Script executed:

# Search for any references to check-pr-issue in broader context
grep -r "check-pr-issue" . 2>/dev/null

Repository: PalisadoesFoundation/.github

Length of output: 365


Fix missing configuration file and verify action availability.

The skip_users_file_path references .github/workflows/config/check-pr-issue-skip-usernames.txt, which does not exist in the repository. When this file is missing, the action's behavior becomes unpredictable, especially with close_pr_on_failure: 'true' enabled.

Additionally, the action arkid15r/check-pr-issue-action@0.1.3 cannot be verified as publicly available or accessible. Confirm the action exists and create the missing configuration file or remove the skip_users_file_path reference.

The aggressive close_pr_on_failure: 'true' setting combined with a missing configuration file creates risk of PRs being closed inappropriately.

🤖 Prompt for AI Agents
In .github/workflows/pull-request-target.yml around lines 55–64 the workflow
references an external action arkid15r/check-pr-issue-action@0.1.3 and a
skip_users_file_path .github/workflows/config/check-pr-issue-skip-usernames.txt
that does not exist; confirm the action is a valid, publicly accessible action
(or replace with a known verified alternative/owner) and either create the
referenced config file at
.github/workflows/config/check-pr-issue-skip-usernames.txt with the intended
skip usernames, or remove the skip_users_file_path entry if the skip list is not
needed; additionally, change close_pr_on_failure from 'true' to 'false' until
the action and config path are verified to avoid accidental PR closures.

Comment on lines +31 to +48
stale-issue-message: >
This issue did not get any activity in the past 10 days and will be
closed in 360 days if no update occurs. Please check if the develop
branch has fixed it and report again or close the issue.

stale-pr-message: >
This pull request did not get any activity in the past 10 days and
will be closed in 360 days if no update occurs. Please verify it has
no conflicts with the develop branch and rebase if needed.

close-issue-message: >
This issue did not get any activity in the past 360 days and thus
has been closed. Please check if the newest release or develop
branch has it fixed.

close-pr-message: >
This pull request did not get any activity in the past 360 days and
thus has been closed.

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

Hardcoded day values in messages don't match dynamic inputs.

The stale/close messages hardcode "10 days" and "360 days", but these values are configurable via inputs.days_before_stale and inputs.days_before_close. If a calling workflow provides different values, the messages will be misleading.

🔎 Proposed fix

Make the messages generic or use variables:

           stale-issue-message: >
-            This issue did not get any activity in the past 10 days and will be
-            closed in 360 days if no update occurs. Please check if the develop
+            This issue has been marked as stale due to inactivity and will be
+            closed if no update occurs. Please check if the develop
             branch has fixed it and report again or close the issue.
 
           stale-pr-message: >
-            This pull request did not get any activity in the past 10 days and
-            will be closed in 360 days if no update occurs. Please verify it has
+            This pull request has been marked as stale due to inactivity and
+            will be closed if no update occurs. Please verify it has
             no conflicts with the develop branch and rebase if needed.
 
           close-issue-message: >
-            This issue did not get any activity in the past 360 days and thus
-            has been closed. Please check if the newest release or develop
+            This issue has been closed due to prolonged inactivity. Please check if the newest release or develop
             branch has it fixed.
 
           close-pr-message: >
-            This pull request did not get any activity in the past 360 days and
-            thus has been closed.
+            This pull request has been closed due to prolonged inactivity.

Note: The actions/stale action doesn't support variable interpolation in messages, so keeping them generic is the best approach.

🤖 Prompt for AI Agents
.github/workflows/stale.yml lines 31-48: the stale/close messages embed
hardcoded "10 days" and "360 days" which can mismatch the configurable inputs
(inputs.days_before_stale / inputs.days_before_close); update the four message
values (stale-issue-message, stale-pr-message, close-issue-message,
close-pr-message) to be generic and avoid specific day counts (e.g., "This issue
did not get any activity and will be closed if no update occurs." / "This pull
request did not get any activity and will be closed if no update occurs." /
"This issue has been closed due to inactivity." / "This pull request has been
closed due to inactivity.") so they remain accurate regardless of provided
inputs.

@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: 0

♻️ Duplicate comments (1)
.github/workflows/stale.yml (1)

21-38: Hardcoded day values in messages don't match the reusable workflow pattern.

As noted in the previous review, the messages hardcode "10 days" and "360 days", which matches lines 43-44 but reduces flexibility for a centralized reusable workflow.

🧹 Nitpick comments (1)
.github/workflows/stale.yml (1)

3-4: Consider adding inputs to make this reusable workflow configurable.

The workflow uses workflow_call but doesn't define any inputs. For a centralized workflow intended to be reused across repositories, consider adding configurable inputs such as days_before_stale, days_before_close, stale_issue_label, exempt_labels, etc. This would allow calling workflows to customize behavior without duplicating the entire workflow file.

🔎 Example inputs definition
 on:
   workflow_call:
+    inputs:
+      days_before_stale:
+        description: 'Days before marking as stale'
+        type: number
+        default: 10
+      days_before_close:
+        description: 'Days before closing stale items'
+        type: number
+        default: 360
+      exempt_issue_labels:
+        description: 'Comma-separated labels to exempt issues'
+        type: string
+        default: 'wip'

Then reference these as ${{ inputs.days_before_stale }} in the action configuration.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 03d762d and c563765.

📒 Files selected for processing (3)
  • .github/workflows/auto-label.json5
  • .github/workflows/config/check-pr-issue-skip-usernames.txt
  • .github/workflows/stale.yml
✅ Files skipped from review due to trivial changes (1)
  • .github/workflows/config/check-pr-issue-skip-usernames.txt
🔇 Additional comments (2)
.github/workflows/auto-label.json5 (1)

1-15: No action needed. The Renato66/auto-label action explicitly supports JSON5 format as its default configuration format (default path: .github/workflows/auto-label.json5), and the file's syntax is correct.

.github/workflows/stale.yml (1)

17-17: No action needed — actions/stale@v10 is the current stable version.

The v10 major version reference is appropriate and will automatically use the latest stable patch (v10.1.0). This follows GitHub Actions best practices.

@palisadoes
palisadoes merged commit 3db8609 into PalisadoesFoundation:main Jan 1, 2026
1 check passed
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.

.github: Centralize GitHub Actions in the .github repo

2 participants