Skip to content

feat: add support for .all-contributors#78

Merged
trueberryless merged 3 commits intomainfrom
feature/all-contributors
Mar 17, 2026
Merged

feat: add support for .all-contributors#78
trueberryless merged 3 commits intomainfrom
feature/all-contributors

Conversation

@trueberryless
Copy link
Member

@trueberryless trueberryless commented Mar 17, 2026

Description

Implement new AllContributors.astro component for the All Contributors project

Summary by CodeRabbit

  • New Features

    • Added an AllContributors component that auto-discovers and renders a responsive contributors grid with customizable styling (colors, focus states) and support for a project contributors configuration file.
    • Added a project contributors configuration (.all-contributorsrc) to list contributors.
  • Documentation

    • Added a full AllContributors documentation page with usage examples and styling options.
    • Updated docs sidebar and a parameter reference link for clarity.

@changeset-bot
Copy link

changeset-bot bot commented Mar 17, 2026

⚠️ No Changeset found

Latest commit: 5057177

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

💥 An error occurred when fetching the changed packages and changesets in this PR
Some errors occurred when validating the changesets config:
The package or glob expression "astro-contributors-docs" is specified in the `ignore` option but it is not found in the project. You may have misspelled the package name or provided an invalid glob expression. Note that glob expressions must be defined according to https://www.npmjs.com/package/micromatch.

@netlify
Copy link

netlify bot commented Mar 17, 2026

Deploy Preview for astro-contributors ready!

Name Link
🔨 Latest commit 5057177
🔍 Latest deploy log https://app.netlify.com/projects/astro-contributors/deploys/69b9023718da6d0008bdc4d5
😎 Deploy Preview https://deploy-preview-78--astro-contributors.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 17, 2026

Warning

Rate limit exceeded

@trueberryless has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 11 minutes and 26 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 1611f343-02b3-4425-97bb-424555fd5e42

📥 Commits

Reviewing files that changed from the base of the PR and between c6a1386 and 5057177.

📒 Files selected for processing (1)
  • packages/astro-contributors/libs/getAllContributorsRc.ts

Walkthrough

Adds all-contributors support: new .all-contributorsrc configuration, a documentation page, an Astro AllContributors component and export, utilities to locate/parse the RC, and a docs sidebar update. No runtime behavior outside the new package/component and docs.

Changes

Cohort / File(s) Summary
Configuration
./.all-contributorsrc
New JSON configuration listing project metadata and a contributors array with roles and avatars.
Docs config
docs/astro.config.ts
Added all-contributors to the "Start Here" sidebar items.
Documentation pages
docs/src/content/docs/all-contributors.mdx, docs/src/content/docs/parameters.mdx
New AllContributors documentation page with usage, props, and examples; minor doc link update for focusColor.
Component
packages/astro-contributors/components/AllContributors.astro
New Astro component rendering a responsive contributor grid; supports styling props and maps contributions to badges/emojis.
Package exports
packages/astro-contributors/index.ts
Re-exported the new AllContributors component from the package entry.
Utilities / Types
packages/astro-contributors/libs/getAllContributorsRc.ts
Added sync utilities and types (RcContributor, AllContributorsRc) to walk parent directories, locate and parse .all-contributorsrc, and return contributors array (findAllContributorsRc, getAllContributorsFromRc).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I dug a little file in the root,
Names and hats and badges to boot,
Cards lined up in a comfy grid,
A hop, a nibble — contributors amid,
Code, docs, and thanks — all nicely put!

🚥 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 'feat: add support for .all-contributors' clearly and concisely describes the main change: adding functionality to support the .all-contributorsrc file.
Linked Issues check ✅ Passed The PR implements all objectives from issue #6: reads and parses the .all-contributorsrc file, renders contributors through the AllContributors component, and enables standardized contributor listing.
Out of Scope Changes check ✅ Passed All changes are directly scoped to implementing .all-contributorsrc support: new component, utilities, configuration, and documentation for the AllContributors feature.

✏️ 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 feature/all-contributors
📝 Coding Plan
  • Generate coding plan for human review comments

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.

@github-actions github-actions bot added 🚧 config Configuration file updates ✒️ documentation Documentation updates, like README changes 📦 package Updates in package structure or package.json labels Mar 17, 2026
@trueberryless
Copy link
Member Author

@coderabbitai full review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 17, 2026

✅ Actions performed

Full review triggered.

1 similar comment
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 17, 2026

✅ Actions performed

Full review triggered.

Copy link
Contributor

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

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

Inline comments:
In `@packages/astro-contributors/components/AllContributors.astro`:
- Around line 120-122: The grid CSS in AllContributors.astro currently uses a
responsive auto-fill layout and ignores the .all-contributorsrc
contributorsPerLine setting; update the component to read the
contributorsPerLine value (either passed as a prop or imported from the
.all-contributorsrc parsing logic used elsewhere) and use it to build the
grid-template-columns rule (e.g. use repeat(contributorsPerLine, minmax(140px,
1fr)) with a sensible fallback to the existing auto-fill behavior) so the layout
respects the contributorsPerLine configuration.
- Around line 76-81: AllContributors: the template uses contributor.profile
directly as the anchor href, which may allow unsafe schemes; update the code
that renders the <a> with contributor.profile to validate the URL first (e.g.,
in the component script or a helper) by constructing a URL in try/catch and only
allowing protocols 'http:' or 'https:'; if validation fails, render a safe
fallback (omit href or use '#' and/or add aria-disabled) or skip rendering the
anchor, ensuring any logic lives next to the contributor rendering (reference:
contributor.profile and the contributor-card anchor) so only validated HTTP(S)
links are output.

In `@packages/astro-contributors/libs/getAllContributorsRc.ts`:
- Around line 17-25: The function findAllContributorsRc currently JSON.parse()s
.all-contributorsrc and returns it cast to AllContributorsRc without runtime
checks; update findAllContributorsRc to validate the parsed object before
returning by verifying required top-level properties (e.g., contributors is an
array) and each contributor has expected fields (name, github username,
contributions array, etc.), returning null or throwing a clear error on
validation failure; you can implement this with a lightweight manual type guard
inside findAllContributorsRc or use an existing runtime validator (zod/io-ts)
and apply the same validation for the other similar parse site (lines 36-38) so
only safe, well-typed AllContributorsRc objects are returned.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: e552b3bb-2bce-412a-a746-45452ce137b9

📥 Commits

Reviewing files that changed from the base of the PR and between a45ea08 and c6a1386.

📒 Files selected for processing (7)
  • .all-contributorsrc
  • docs/astro.config.ts
  • docs/src/content/docs/all-contributors.mdx
  • docs/src/content/docs/parameters.mdx
  • packages/astro-contributors/components/AllContributors.astro
  • packages/astro-contributors/index.ts
  • packages/astro-contributors/libs/getAllContributorsRc.ts

Copy link
Contributor

@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.

♻️ Duplicate comments (3)
packages/astro-contributors/components/AllContributors.astro (2)

75-81: ⚠️ Potential issue | 🟠 Major

Validate profile URLs before rendering anchor href.

Line 77 trusts config input directly. Non-HTTP(S) schemes should be rejected before outputting links.

Proposed fix
 const contributors = getAllContributorsFromRc();
+const toSafeHttpUrl = (value: string): string | null => {
+  try {
+    const url = new URL(value);
+    return url.protocol === "http:" || url.protocol === "https:"
+      ? url.toString()
+      : null;
+  } catch {
+    return null;
+  }
+};
@@
-      {contributors.map((contributor) => (
-        <a
-          href={contributor.profile}
+      {contributors.map((contributor) => {
+        const safeProfile = toSafeHttpUrl(contributor.profile);
+        if (!safeProfile) return null;
+        return (
+        <a
+          href={safeProfile}
           class="contributor-card"
           target="_blank"
           rel="noopener noreferrer"
         >
@@
-        </a>
-      ))}
+        </a>
+      )})}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/astro-contributors/components/AllContributors.astro` around lines 75
- 81, The template in AllContributors.astro uses contributor.profile directly in
the anchor href inside contributors.map, which can emit non-HTTP(S) schemes; add
a URL validation/sanitization step (e.g., an isValidHttpUrl or
sanitizeProfileUrl helper) that accepts only http and https schemes and returns
either the validated URL or null/empty, then use that sanitized value in the
anchor (or render a non-link fallback) to avoid outputting unsafe schemes;
update the contributors.map anchor logic to reference the sanitized variable
instead of contributor.profile.

120-122: 🧹 Nitpick | 🔵 Trivial

Consider honoring .all-contributorsrc contributorsPerLine for output parity.

Line 121 hardcodes responsive auto-fill and ignores the explicit per-line layout config.

Proposed refactor
-import { getAllContributorsFromRc } from "../libs/getAllContributorsRc";
+import { findAllContributorsRc, getAllContributorsFromRc } from "../libs/getAllContributorsRc";
@@
 const contributors = getAllContributorsFromRc();
+const rc = findAllContributorsRc();
+const contributorsPerLine =
+  Number.isInteger(rc?.contributorsPerLine) && (rc?.contributorsPerLine ?? 0) > 0
+    ? rc!.contributorsPerLine
+    : undefined;
@@
 const styleOverride = {
   ...(focusColor && { "--ac-focus-color": focusColor }),
   ...(bgColor && { "--ac-bg-color": bgColor }),
   ...(borderColor && { "--ac-border-color": borderColor }),
   ...(textColor && { "--ac-text-color": textColor }),
   ...(badgeBgColor && { "--ac-badge-bg-color": badgeBgColor }),
   ...(badgeTextColor && { "--ac-badge-text-color": badgeTextColor }),
+  ...(contributorsPerLine && {
+    "--ac-grid-template-columns": `repeat(${contributorsPerLine}, minmax(140px, 1fr))`,
+  }),
 };
@@
-    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
+    grid-template-columns: var(
+      --ac-grid-template-columns,
+      repeat(auto-fill, minmax(140px, 1fr))
+    );
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/astro-contributors/components/AllContributors.astro` around lines
120 - 122, The grid currently hardcodes "grid-template-columns:
repeat(auto-fill, minmax(140px, 1fr))" which ignores the .all-contributorsrc
contributorsPerLine setting; update the AllContributors.astro component to read
the contributorsPerLine value (either from the passed prop or the parsed
.all-contributorsrc config used by this component) and use it to compute the CSS
rule, e.g. set "grid-template-columns: repeat({contributorsPerLine},
minmax(140px, 1fr))" with a safe fallback to auto-fill when contributorsPerLine
is absent or invalid; adjust the code that renders the style block in
AllContributors.astro (where grid-template-columns is defined) to reference that
variable.
packages/astro-contributors/libs/getAllContributorsRc.ts (1)

23-25: ⚠️ Potential issue | 🟠 Major

Harden .all-contributorsrc parsing with runtime validation and parse guards.

Lines 25 and 38 currently trust unvalidated JSON; malformed content can throw or propagate invalid contributor objects to rendering.

Proposed fix
 export interface AllContributorsRc {
   contributors: RcContributor[];
   [key: string]: any;
 }
 
+function isRcContributor(value: unknown): value is RcContributor {
+  if (!value || typeof value !== "object") return false;
+  const v = value as Record<string, unknown>;
+  return (
+    typeof v.login === "string" &&
+    typeof v.name === "string" &&
+    typeof v.avatar_url === "string" &&
+    typeof v.profile === "string" &&
+    Array.isArray(v.contributions) &&
+    v.contributions.every((c) => typeof c === "string")
+  );
+}
+
+function isAllContributorsRc(value: unknown): value is AllContributorsRc {
+  if (!value || typeof value !== "object") return false;
+  const v = value as Record<string, unknown>;
+  return Array.isArray(v.contributors) && v.contributors.every(isRcContributor);
+}
+
 export function findAllContributorsRc(): AllContributorsRc | null {
@@
     if (fs.existsSync(filePath)) {
-      const content = fs.readFileSync(filePath, "utf-8");
-      return JSON.parse(content) as AllContributorsRc;
+      try {
+        const content = fs.readFileSync(filePath, "utf-8");
+        const parsed = JSON.parse(content) as unknown;
+        return isAllContributorsRc(parsed) ? parsed : null;
+      } catch {
+        return null;
+      }
     }
@@
 export function getAllContributorsFromRc(): RcContributor[] {
   const data = findAllContributorsRc();
-  return data?.contributors || [];
+  return Array.isArray(data?.contributors) ? data.contributors : [];
 }

Also applies to: 36-38

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

In `@packages/astro-contributors/libs/getAllContributorsRc.ts` around lines 23 -
25, The code currently calls JSON.parse on the .all-contributorsrc content (via
fs.existsSync, fs.readFileSync and JSON.parse returning AllContributorsRc)
without runtime validation; wrap the parse in a try/catch and add a runtime
shape check (or use a small schema validator like zod) inside
getAllContributorsRc to ensure the parsed object matches the AllContributorsRc
shape (e.g., has a contributors array and expected fields) before returning it,
and if validation fails return a safe default or throw a clear error; apply the
same guarded parse/validation to the alternate parse path that also uses
JSON.parse so malformed JSON or wrong shapes won’t leak into rendering.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@packages/astro-contributors/components/AllContributors.astro`:
- Around line 75-81: The template in AllContributors.astro uses
contributor.profile directly in the anchor href inside contributors.map, which
can emit non-HTTP(S) schemes; add a URL validation/sanitization step (e.g., an
isValidHttpUrl or sanitizeProfileUrl helper) that accepts only http and https
schemes and returns either the validated URL or null/empty, then use that
sanitized value in the anchor (or render a non-link fallback) to avoid
outputting unsafe schemes; update the contributors.map anchor logic to reference
the sanitized variable instead of contributor.profile.
- Around line 120-122: The grid currently hardcodes "grid-template-columns:
repeat(auto-fill, minmax(140px, 1fr))" which ignores the .all-contributorsrc
contributorsPerLine setting; update the AllContributors.astro component to read
the contributorsPerLine value (either from the passed prop or the parsed
.all-contributorsrc config used by this component) and use it to compute the CSS
rule, e.g. set "grid-template-columns: repeat({contributorsPerLine},
minmax(140px, 1fr))" with a safe fallback to auto-fill when contributorsPerLine
is absent or invalid; adjust the code that renders the style block in
AllContributors.astro (where grid-template-columns is defined) to reference that
variable.

In `@packages/astro-contributors/libs/getAllContributorsRc.ts`:
- Around line 23-25: The code currently calls JSON.parse on the
.all-contributorsrc content (via fs.existsSync, fs.readFileSync and JSON.parse
returning AllContributorsRc) without runtime validation; wrap the parse in a
try/catch and add a runtime shape check (or use a small schema validator like
zod) inside getAllContributorsRc to ensure the parsed object matches the
AllContributorsRc shape (e.g., has a contributors array and expected fields)
before returning it, and if validation fails return a safe default or throw a
clear error; apply the same guarded parse/validation to the alternate parse path
that also uses JSON.parse so malformed JSON or wrong shapes won’t leak into
rendering.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 8fef0df5-660c-4959-8254-e2ee72d94988

📥 Commits

Reviewing files that changed from the base of the PR and between a45ea08 and c6a1386.

📒 Files selected for processing (7)
  • .all-contributorsrc
  • docs/astro.config.ts
  • docs/src/content/docs/all-contributors.mdx
  • docs/src/content/docs/parameters.mdx
  • packages/astro-contributors/components/AllContributors.astro
  • packages/astro-contributors/index.ts
  • packages/astro-contributors/libs/getAllContributorsRc.ts

@trueberryless trueberryless merged commit 7263a98 into main Mar 17, 2026
6 of 8 checks passed
@trueberryless trueberryless deleted the feature/all-contributors branch March 17, 2026 07:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🚧 config Configuration file updates ✒️ documentation Documentation updates, like README changes 📦 package Updates in package structure or package.json

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Suggestion] Use .all-contributorsrc file to render contributors

1 participant