Skip to content

Allow website to fetch ideas from Info Repo#558

Merged
M4dhav merged 1 commit intoAOSSIE-Org:mainfrom
M4dhav:main
Feb 7, 2026
Merged

Allow website to fetch ideas from Info Repo#558
M4dhav merged 1 commit intoAOSSIE-Org:mainfrom
M4dhav:main

Conversation

@M4dhav
Copy link
Contributor

@M4dhav M4dhav commented Feb 4, 2026

Summary by CodeRabbit

Release Notes

  • New Features

    • Ideas are now dynamically fetched from GitHub, enabling live content updates.
    • New individual idea detail pages with rich markdown formatting and enhanced content rendering.
  • Chores

    • Added automated CI/CD workflow for rebuilding when ideas are updated.
    • Updated markdown processing dependencies for improved content handling.

@vercel
Copy link

vercel bot commented Feb 4, 2026

@M4dhav is attempting to deploy a commit to the AOSSIE Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai
Copy link

coderabbitai bot commented Feb 4, 2026

📝 Walkthrough

Walkthrough

The changes implement a GitHub-backed GSoC Ideas system with automated rebuild triggers. A new workflow orchestrates rebuilds on ideas updates. Dependencies are expanded to support enhanced Markdown processing. Core functionality includes fetching ideas from the GitHub API, rendering dynamic detail pages for each idea, and updating the ideas index to use current-year data from GitHub instead of local sources.

Changes

Cohort / File(s) Summary
GitHub Actions Workflow
.github/workflows/rebuild-on-ideas-update.yml
New workflow triggered on ideas-updated repository dispatch events. Checks out code, installs Node.js 18 and pnpm 10, builds the site in production mode, and deploys to GitHub Pages.
Markdown Processing Dependencies
package.json
Updated Markdown-related dependencies: added react-markdown, rehype-raw, and rehype-sanitize; re-added remark-gfm (v3.0.1) and aliased remark-gfm-4 (v4.0.0) for expanded Markdown parsing and sanitization capabilities.
GitHub Ideas Helper Module
src/helper/fetchGitHubIdeas.js
New module for GitHub API integration. Exports functions: getCurrentYear(), formatTitle(), extractDescription(), fetchIdeasFromGitHub(), and fetchIdeaContent() to retrieve, process, and structure GSoC ideas from the AOSSIE-Org/Info repository.
Ideas Detail Page
src/pages/ideas/[year]/[slug].jsx
New dynamic page rendering individual idea details. Implements getStaticPaths() to generate routes for all ideas, getStaticProps() to fetch idea content, and uses ReactMarkdown with custom component styling for rich content rendering with SEO metadata support.
Ideas Index Page
src/pages/ideas/index.jsx
Updated to fetch ideas from GitHub via fetchIdeasFromGitHub() instead of local data. Refactored Article and Ideas components to accept and propagate currentYear, and adjusted card link paths to use dynamic year values.

Sequence Diagram

sequenceDiagram
    participant GH as GitHub API
    participant Build as Build Process
    participant Pages as Static Pages
    participant Deploy as GitHub Pages

    Build->>GH: Fetch ideas list<br/>(GSoC-Ideas/{year})
    GH-->>Build: Return .md files
    
    Build->>GH: Fetch each idea content<br/>(raw.githubusercontent)
    GH-->>Build: Return Markdown content
    
    Build->>Build: Extract title & description<br/>via fetchGitHubIdeas helpers
    
    Build->>Pages: Generate static paths<br/>(ideas/[year]/[slug])
    Build->>Pages: Generate static props<br/>(idea details)
    
    Pages->>Pages: Render Markdown with<br/>ReactMarkdown + rehype plugins
    
    Build->>Deploy: Upload artifact
    Deploy->>Deploy: Deploy to GitHub Pages
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

🐰 A warren of ideas now springs from the GitHub net,
Where paths are carved with dynamic year and slug set,
The workflow hops when updates arise,
ReactMarkdown renders them with style and sighs,
Static pages bloom from each precious thread! 📖✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: enabling the website to fetch GSoC ideas from the Info repository instead of using local data. This is reflected across all modified files including the new fetchGitHubIdeas.js module, updated pages, and new workflow.

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

Copy link

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

🤖 Fix all issues with AI agents
In @.github/workflows/rebuild-on-ideas-update.yml:
- Around line 9-12: The workflow currently grants overly broad repo permissions
by setting permissions.contents: write; change this to permissions.contents:
read to follow least-privilege practice because the job only checks out the repo
and uploads an artifact for actions/deploy-pages rather than modifying
repository contents—locate the permissions block with the "permissions" key and
replace the "contents: write" entry with "contents: read", leaving other
permissions (pages, id-token) as-is.

In `@package.json`:
- Around line 43-47: Package.json currently pins both "remark-gfm": "3.0.1" and
an alias "remark-gfm-4": "npm:remark-gfm@^4.0.0" causing v3/v4 mismatch; replace
the v3 entry by removing "remark-gfm": "3.0.1" and ensure a single dependency
"remark-gfm": "^4.0.0" (remove the alias key or rename the alias back to
remark-gfm), then update imports in next.config.mjs to reference the standard
"remark-gfm" (v4) instead of any v3 import so both Next.js config and React
component use remark-gfm v4 consistently.

In `@src/helper/fetchGitHubIdeas.js`:
- Around line 117-125: The fetchIdeasFromGitHub function builds an
unauthenticated request to contentsUrl which can be rate-limited; update the
fetch call in fetchIdeasFromGitHub to include an Authorization: `token
${process.env.GITHUB_TOKEN}` header when process.env.GITHUB_TOKEN is defined
(keep the existing Accept header) so server-side builds use authenticated GitHub
API requests and avoid the 60 requests/hour limit tied to
GITHUB_API_BASE/REPO_OWNER/REPO_NAME/IDEAS_PATH calls for getCurrentYear; ensure
the token is only read from environment (no client-side exposure) and the logic
gracefully falls back to the existing unauthenticated headers if the token is
missing.

In `@src/pages/ideas/`[year]/[slug].jsx:
- Around line 204-219: getStaticPaths currently only builds paths for the single
year returned by getCurrentYear() which causes 404s for other years; update
getStaticPaths to either (A) iterate all supported years (e.g., a list or
function like getSupportedYears()) and call fetchIdeasFromGitHub(year) for each
year to aggregate paths for every idea slug, or (B) switch the returned object
to fallback: true so Next.js will attempt rendering unmapped year/slug combos at
request time; modify the code inside getStaticPaths (references: getCurrentYear,
fetchIdeasFromGitHub, getStaticPaths, and fallback) accordingly and ensure the
final paths array contains entries for every target year if you choose option A.
🧹 Nitpick comments (3)
src/pages/ideas/index.jsx (1)

115-119: Consider an empty-state message when no ideas are returned.

If the GitHub fetch fails, the grid renders blank. A short empty-state makes this more user-friendly.

💡 Example empty-state
             <Grid container spacing={4} sx={{ justifyContent: 'center' }}>
-              {articles.map((article) => (
-                <Article key={article.slug} article={article} currentYear={currentYear} />
-              ))}
+              {articles.length === 0 ? (
+                <Typography sx={{ mt: 4, width: '100%', textAlign: 'center' }}>
+                  No ideas are available right now. Please check back later.
+                </Typography>
+              ) : (
+                articles.map((article) => (
+                  <Article key={article.slug} article={article} currentYear={currentYear} />
+                ))
+              )}
             </Grid>
src/pages/ideas/[year]/[slug].jsx (1)

15-22: Remove unreachable router.isFallback check with fallback: false.

With fallback: false in getStaticPaths, unmapped routes return 404 pages instead of rendering fallback states. The router.isFallback branch will never execute and should be removed.

🧹 Remove unreachable fallback UI
-  if (router.isFallback) {
-    return (
-      <Container className="mt-16 mb-20">
-        <div className="text-center">
-          <p className="text-lg text-zinc-600 dark:text-zinc-400">Loading...</p>
-        </div>
-      </Container>
-    );
-  }
src/helper/fetchGitHubIdeas.js (1)

141-155: Use Promise.allSettled to handle per-idea fetch failures gracefully.

Currently, Promise.all without a contentResponse.ok check means any single network failure discards all results. Additionally, if a fetch succeeds but returns an error status, the response body is parsed as content. Node.js 18.17.0+ (required by this project) fully supports Promise.allSettled, allowing you to skip failed fetches and return partial results instead of dropping everything.

🧯 More resilient fetch aggregation
    const ideasPromises = mdFiles.map(async (file) => {
      const contentResponse = await fetch(file.download_url);
      const content = await contentResponse.text();

      return {
        slug: file.name.replace(/\.md$/, ''),
        title: formatTitle(file.name),
        description: extractDescription(content),
        downloadUrl: file.download_url,
        year: year,
      };
    });

    const ideas = await Promise.all(ideasPromises);
+
+    const ideaResults = await Promise.allSettled(
+      mdFiles.map(async (file) => {
+        const contentResponse = await fetch(file.download_url);
+        if (!contentResponse.ok) {
+          throw new Error(`Idea fetch failed: ${contentResponse.status} ${contentResponse.statusText}`);
+        }
+        const content = await contentResponse.text();
+        return {
+          slug: file.name.replace(/\.md$/, ''),
+          title: formatTitle(file.name),
+          description: extractDescription(content),
+          downloadUrl: file.download_url,
+          year: year,
+        };
+      })
+    );
+
+    return ideaResults
+      .filter((r) => r.status === 'fulfilled')
+      .map((r) => r.value);

Comment on lines +204 to +219
export async function getStaticPaths() {
// For static export, we need to generate all paths at build time
const currentYear = getCurrentYear();
const ideas = await fetchIdeasFromGitHub(currentYear);

const paths = ideas.map((idea) => ({
params: {
year: currentYear.toString(),
slug: idea.slug,
},
}));

return {
paths,
fallback: false,
};
Copy link

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

🏁 Script executed:

#!/bin/bash
# Look for year-specific idea links/pages that imply multi-year support
echo "=== Searching for year-specific idea references ==="
rg -n "ideas/20\d{2}" src --type jsx --type ts --type tsx || echo "No matches found"

echo -e "\n=== Files in ideas directory structure ==="
find src -type d -name "ideas" | head -20

echo -e "\n=== Checking for [year] directory patterns ==="
fd -a --type d "\[year\]" src/pages

echo -e "\n=== Checking for any hardcoded years in src ==="
rg -n "202[0-9]" src --type jsx --type ts --type tsx -A 2 -B 2 | head -50

Repository: AOSSIE-Org/website

Length of output: 403


🏁 Script executed:

#!/bin/bash
echo "=== Reading the file under review ==="
cat -n src/pages/ideas/[year]/[slug].jsx | head -250

echo -e "\n=== Finding getCurrentYear function ==="
rg -n "getCurrentYear" src -A 5

echo -e "\n=== Finding fetchIdeasFromGitHub function ==="
rg -n "fetchIdeasFromGitHub" src -A 10

echo -e "\n=== Searching for navigation/links to ideas ==="
rg -n "ideas/" src --type js --type ts -B 2 -A 2 | head -60

Repository: AOSSIE-Org/website

Length of output: 21253


Generate paths for all supported years or clearly constrain to current year only.

The getStaticPaths() with fallback: false only generates paths for currentYear. Although navigation currently avoids this by linking to dedicated year pages (e.g., /ideas/2024/index.jsx), the dynamic route structure /ideas/[year]/[slug] can technically accept any year. Attempting to access a historical year directly via the dynamic route (e.g., /ideas/2023/some-idea) will 404. Either generate static paths for all years with ideas (2022, 2023, 2024, etc.), or set fallback: true to handle unmapped years dynamically, or document that the route is current-year-only.

🤖 Prompt for AI Agents
In `@src/pages/ideas/`[year]/[slug].jsx around lines 204 - 219, getStaticPaths
currently only builds paths for the single year returned by getCurrentYear()
which causes 404s for other years; update getStaticPaths to either (A) iterate
all supported years (e.g., a list or function like getSupportedYears()) and call
fetchIdeasFromGitHub(year) for each year to aggregate paths for every idea slug,
or (B) switch the returned object to fallback: true so Next.js will attempt
rendering unmapped year/slug combos at request time; modify the code inside
getStaticPaths (references: getCurrentYear, fetchIdeasFromGitHub,
getStaticPaths, and fallback) accordingly and ensure the final paths array
contains entries for every target year if you choose option A.

@M4dhav M4dhav merged commit 5811db5 into AOSSIE-Org:main Feb 7, 2026
1 of 2 checks passed
@amrkhaled104
Copy link

@M4dhav
Since this is a new year’s data, it would be clearer to name the folder 2026 instead of 2025 to avoid confusion.

@M4dhav
Copy link
Contributor Author

M4dhav commented Feb 11, 2026

@M4dhav Since this is a new year’s data, it would be clearer to name the folder 2026 instead of 2025 to avoid confusion.

We aren't storing the ideas in this Repository anymore, and as mentioned in the PR Description, Ideas are now fetched from AOSSIE-Org/Info . So the existing folders here are for ideas from previous years

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.

2 participants