Skip to content

Conversation

@anchildress1
Copy link
Contributor

Pull Request Checklist

  • I have read and followed the CONTRIBUTING.md guidelines.
  • My contribution adds a new instruction, prompt, or chat mode file in the correct directory.
  • The file follows the required naming convention.
  • The content is clearly structured and follows the example format.
  • I have tested my instructions, prompt, or chat mode with GitHub Copilot.
  • I have run npm start and verified that README.md is up to date.

Description

@aaronpowell
I realize I probably should have started a discussion first, but I started out just playing with the contributors library and got a little carried away 😆 Tbh, I'm not incredibly attached—I just hate wasting code when it could be useful. Let me know if you want changes or something taken back out!

  • Configure custom contribution types for instructions, prompts, agents, and collections
  • Add check for missing contributors to weekly GHA workflow file output to summary
  • Include ignore list (in case users request to be removed from README)
  • Create script that pulls from all-contributors CLI check and auto-adds contributor based on merged PRs

Type of Contribution

  • New instruction file.
  • New prompt file.
  • New chat mode file.
  • New collection file.
  • Update to existing instruction, prompt, chat mode, or collection.
  • Other (please specify):
    • Enhancement to align contributors with types specific to this repo.

Additional Notes

I had to stop myself from adding a bot that does all this for you automatically! I figure less is safer, so I kept everything to the report-friendly version and an auto-add script strictly for local use. That last one I wasn't going to include at all, but then decided it could be used for automation later if one were so inclined.

This is what that report looks like with markdown formatted in workflow output summary:

Screenshot 2025-12-20 at 12 19 41 AM

By submitting this pull request, I confirm that my contribution abides by the Code of Conduct and will be licensed under the MIT License.

- Add eng/README.md documenting maintainer utilities
- Add eng/contributor-report.mjs for generating contributor reports
- Add eng/add-missing-contributors.mjs for automating contributor additions
- Add eng/utils/graceful-shutdown.mjs for script lifecycle management
- Update eng/update-readme.mjs with minor fixes
- Update package.json with new contributor scripts

Generated-by: GitHub Copilot <[email protected]>
Signed-off-by: Ashley Childress <[email protected]>
- Modify generateMarkdownReport to include per-user sections with PR details
- Remove total PR count and simplify PR link format

Commit-generated-by: GitHub Copilot <[email protected]>
Signed-off-by: Ashley Childress <[email protected]>
Copilot AI review requested due to automatic review settings December 20, 2025 05:20
Copy link
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

This PR enhances the contributor recognition system by adding custom contribution types specific to this repository (instructions, prompts, agents, collections) and implements automated contributor detection and reporting tooling.

Key changes:

  • Custom contributor types configured in .all-contributorsrc to better reflect repo-specific contributions
  • New contributor reporting scripts that analyze merged PRs and detect missing contributors
  • Updated CI workflow to automatically check and report missing contributors weekly

Reviewed changes

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

Show a summary per file
File Description
.all-contributorsrc Adds custom contribution types (instructions, prompts, agents, collections), ignore list, and migrates existing contributors to new types
package.json Adds contributors:report script and updates keywords
eng/contributor-report.mjs New script to generate markdown reports of missing contributors by analyzing merged PRs
eng/add-missing-contributors.mjs New script to automatically add missing contributors with inferred contribution types
eng/utils/graceful-shutdown.mjs Utility for graceful shutdown handling in Node scripts
eng/README.md Documentation for the new contributor tooling
.github/workflows/contributors.yml Updates workflow to check/report missing contributors and adds timeout
CONTRIBUTING.md Documents the new contributor recognition process and custom types
README.md Auto-generated changes reflecting new contributor types and badge updates
.gitignore Excludes reports directory from version control

Comment on lines +81 to +92
const replacements = [
{ pattern: /\\/g, replacement: '/' },
{ pattern: /\./g, replacement: String.raw`\.` },
{ pattern: /\*\*/g, replacement: DOUBLE_WILDCARD_PLACEHOLDER },
{ pattern: /\*/g, replacement: '[^/]*' },
{ pattern: new RegExp(DOUBLE_WILDCARD_PLACEHOLDER, 'g'), replacement: '.*' },
{ pattern: /\?/g, replacement: '.' },
{ pattern: /\//g, replacement: String.raw`\/` }
];

const normalized = replacements.reduce((acc, { pattern, replacement }) => acc.replace(pattern, replacement), String(pattern));

Copy link

Copilot AI Dec 20, 2025

Choose a reason for hiding this comment

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

The glob conversion logic doesn't escape special regex characters like '+', '(', ')', '[', ']', '{', '}', '^', '$', and '|'. If any file patterns contain these characters, the regex matching will fail or behave unexpectedly.

Suggested change
const replacements = [
{ pattern: /\\/g, replacement: '/' },
{ pattern: /\./g, replacement: String.raw`\.` },
{ pattern: /\*\*/g, replacement: DOUBLE_WILDCARD_PLACEHOLDER },
{ pattern: /\*/g, replacement: '[^/]*' },
{ pattern: new RegExp(DOUBLE_WILDCARD_PLACEHOLDER, 'g'), replacement: '.*' },
{ pattern: /\?/g, replacement: '.' },
{ pattern: /\//g, replacement: String.raw`\/` }
];
const normalized = replacements.reduce((acc, { pattern, replacement }) => acc.replace(pattern, replacement), String(pattern));
// Escape all regex-special characters except glob wildcards (*, ?, /),
// then translate glob syntax to regex.
const regexSpecials = /[.+^${}()|[\]\\]/g;
let normalized = String(pattern);
// Normalize Windows-style separators to POSIX-style for matching.
normalized = normalized.replace(/\\/g, '/');
// Escape regex metacharacters so they are treated literally.
normalized = normalized.replace(regexSpecials, (match) => `\\${match}`);
// Handle glob wildcards.
normalized = normalized.replace(/\*\*/g, DOUBLE_WILDCARD_PLACEHOLDER);
normalized = normalized.replace(/\*/g, '[^/]*');
normalized = normalized.replace(new RegExp(DOUBLE_WILDCARD_PLACEHOLDER, 'g'), '.*');
normalized = normalized.replace(/\?/g, '.');
// Escape path separators for the final regex.
normalized = normalized.replace(/\//g, String.raw`\/`);

Copilot uses AI. Check for mistakes.
Comment on lines +276 to +289
const match = upstreamUrl.match(/github\.com:([^/]+)\/([^/]+?)(?:\.git)?$/);
if (match) return `${match[1]}/${match[2]}`;
}
} catch (e) {
console.debug('upstream not found, trying origin');
}

try {
const originUrl = execSync('git config --get remote.origin.url', {
encoding: 'utf8',
stdio: ['pipe', 'pipe', 'pipe']
}).trim();
const match = originUrl.match(/github\.com:([^/]+)\/([^/]+?)(?:\.git)?$/);
if (match) return `${match[1]}/${match[2]}`;
Copy link

Copilot AI Dec 20, 2025

Choose a reason for hiding this comment

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

The regex pattern for matching GitHub URLs only supports SSH format (github.com:owner/repo) but not HTTPS format (github.com/owner/repo). This will fail for users who have configured their Git remotes using HTTPS URLs.

Copilot uses AI. Check for mistakes.
Comment on lines +528 to +532
execSync(`gh pr comment ${prNumber} --repo ${repo} --body "${body.replace(/"/g, '\\"')}"`, {
encoding: 'utf8',
stdio: ['pipe', 'inherit', 'inherit'],
timeout: DEFAULT_CMD_TIMEOUT
});
Copy link

Copilot AI Dec 20, 2025

Choose a reason for hiding this comment

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

Escaped double quotes in the command body may not work correctly on all platforms. On Windows, this escaping pattern can fail. Consider using stdio 'inherit' or writing the body to a temporary file instead of escaping quotes in the shell command.

Copilot uses AI. Check for mistakes.
Comment on lines +606 to +607
if (process.argv[1] === (new URL(import.meta.url)).pathname) {
main();
Copy link

Copilot AI Dec 20, 2025

Choose a reason for hiding this comment

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

The URL constructor pathname behavior is platform-dependent. On Windows, this comparison will fail because the pathname includes the drive letter. Use fileURLToPath from 'node:url' module instead for cross-platform compatibility.

Copilot uses AI. Check for mistakes.
console.log('\n' + '='.repeat(50));
};

if (process.argv[1] === (new URL(import.meta.url)).pathname) {
Copy link

Copilot AI Dec 20, 2025

Choose a reason for hiding this comment

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

The same pathname comparison issue exists here. On Windows, this check will fail, preventing the script from running when executed directly.

Copilot uses AI. Check for mistakes.
@@ -1,9 +1,6 @@
# 🤖 Awesome GitHub Copilot Customizations
[![Powered by Awesome Copilot](https://img.shields.io/badge/Powered_by-Awesome_Copilot-blue?logo=githubcopilot)](https://aka.ms/awesome-github-copilot?style=flat-square) [![GitHub contributors from allcontributors.org](https://img.shields.io/github/all-contributors/github/awesome-copilot?style=flat-square&color=ee8449)](#contributors-)
Copy link

Copilot AI Dec 20, 2025

Choose a reason for hiding this comment

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

The ACTION link in the badge URL contains a query parameter style=flat-square that should be part of the actual URL, not the link destination. The badge parameters should be in the image URL, not the link URL.

Suggested change
[![Powered by Awesome Copilot](https://img.shields.io/badge/Powered_by-Awesome_Copilot-blue?logo=githubcopilot)](https://aka.ms/awesome-github-copilot?style=flat-square) [![GitHub contributors from allcontributors.org](https://img.shields.io/github/all-contributors/github/awesome-copilot?style=flat-square&color=ee8449)](#contributors-)
[![Powered by Awesome Copilot](https://img.shields.io/badge/Powered_by-Awesome_Copilot-blue?logo=githubcopilot&style=flat-square)](https://aka.ms/awesome-github-copilot) [![GitHub contributors from allcontributors.org](https://img.shields.io/github/all-contributors/github/awesome-copilot?style=flat-square&color=ee8449)](#contributors-)

Copilot uses AI. Check for mistakes.
Comment on lines +29 to +30
// process.exit may not be desirable in some test harnesses; swallow errors
console.warn(`${name}: process.exit failed:`, e?.message);
Copy link

Copilot AI Dec 20, 2025

Choose a reason for hiding this comment

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

The graceful-shutdown utility catches process.exit errors and logs a warning, which may hide real issues. The purpose of process.exit is to immediately terminate, so catching and swallowing errors here could mask problems in test environments or other scenarios where exit behavior is intentionally modified.

Suggested change
// process.exit may not be desirable in some test harnesses; swallow errors
console.warn(`${name}: process.exit failed:`, e?.message);
// If process.exit is stubbed or overridden (e.g. in tests), surface the failure
console.error(`${name}: process.exit failed:`, e?.message || e);
throw e;

Copilot uses AI. Check for mistakes.
Comment on lines +297 to +303
const CONTRIBUTION_TYPE_MAP = {
'instructions': { symbol: '🧭', description: 'The big AI prompt recipes (Copilot instruction sets)' },
'prompts': { symbol: '⌨️', description: 'One-shot or reusable user-level prompts' },
'agents': { symbol: '🎭', description: 'Defined Copilot personalities / roles' },
'collections': { symbol: '🎁', description: 'Bundled thematic sets (e.g., "Copilot for Docs")' }
};

Copy link

Copilot AI Dec 20, 2025

Choose a reason for hiding this comment

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

Unused variable CONTRIBUTION_TYPE_MAP.

Suggested change
const CONTRIBUTION_TYPE_MAP = {
'instructions': { symbol: '🧭', description: 'The big AI prompt recipes (Copilot instruction sets)' },
'prompts': { symbol: '⌨️', description: 'One-shot or reusable user-level prompts' },
'agents': { symbol: '🎭', description: 'Defined Copilot personalities / roles' },
'collections': { symbol: '🎁', description: 'Bundled thematic sets (e.g., "Copilot for Docs")' }
};

Copilot uses AI. Check for mistakes.
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.

1 participant

SYSTEM_READY >> ...MS