mittal-parth/personal-portfolio

Feature: Use the GitHub API for the Open Source Contributions

Opened this issue ยท 12 comments

Currently, the open source contributions have to be manually typed into the /src/constants/index.js file.

It would be better if we could fetch them automatically using the GitHub API.
This should include all the PRs and issues opened by the person in all repos except the ones owned by him or that are part of his organisation(s).

It will need some discussion before proceeding, so feel free to discuss it here!

Hey I would like to work on this.

Please assign this to me.

Hi @Shivam164! Thanks for your interest.
Can you provide a workflow of how you would be proceeding with this? Thanks!

@mittal-parth first of all I willl have to see how github api works and then I will fetch data related to your open source contribution. Then I will have to make the data dynamic.

Hmm ok, go ahead!

@Shivam164 any updates?

/prbot how

Hello @mittal-parth, I'm studying some ways to implement this feature, and so far I came with some thoughts that I'd like to discuss here.

To fetch my own pull requests for example, we could make the following request

GET https://api.github.com/search/issues?q=is:pr+author:mateusabelli

Here is an example response received back, you may need to create an access token because search queries could be a bit more expensive on GH servers so they can have more limited request rates.

Click to expand
{
"total_count": 43,
"incomplete_results": false,
"items": [
  {
    "url": "https://api.github.com/repos/mittal-parth/personal-portfolio/issues/43",
    "repository_url": "https://api.github.com/repos/mittal-parth/personal-portfolio",
    "labels_url": "https://api.github.com/repos/mittal-parth/personal-portfolio/issues/43/labels{/name}",
    "comments_url": "https://api.github.com/repos/mittal-parth/personal-portfolio/issues/43/comments",
    "events_url": "https://api.github.com/repos/mittal-parth/personal-portfolio/issues/43/events",
    "html_url": "https://github.com/mittal-parth/personal-portfolio/pull/43",
    "id": 1599432588,
    "node_id": "PR_kwDOIAzWCM5KviXy",
    "number": 43,
    "title": "Add footer credit notes",
    "user": {
      "login": "mateusabelli",
      "id": 43862225,
      "node_id": "MDQ6VXNlcjQzODYyMjI1",
      "avatar_url": "https://avatars.githubusercontent.com/u/43862225?v=4",
      "gravatar_id": "",
      "url": "https://api.github.com/users/mateusabelli",
      "html_url": "https://github.com/mateusabelli",
      "followers_url": "https://api.github.com/users/mateusabelli/followers",
      "following_url": "https://api.github.com/users/mateusabelli/following{/other_user}",
      "gists_url": "https://api.github.com/users/mateusabelli/gists{/gist_id}",
      "starred_url": "https://api.github.com/users/mateusabelli/starred{/owner}{/repo}",
      "subscriptions_url": "https://api.github.com/users/mateusabelli/subscriptions",
      "organizations_url": "https://api.github.com/users/mateusabelli/orgs",
      "repos_url": "https://api.github.com/users/mateusabelli/repos",
      "events_url": "https://api.github.com/users/mateusabelli/events{/privacy}",
      "received_events_url": "https://api.github.com/users/mateusabelli/received_events",
      "type": "User",
      "site_admin": false
    },
    "labels": [

    ],
    "state": "closed",
    "locked": false,
    "assignee": null,
    "assignees": [

    ],
    "milestone": null,
    "comments": 2,
    "created_at": "2023-02-25T00:13:13Z",
    "updated_at": "2023-02-25T12:11:31Z",
    "closed_at": "2023-02-25T07:20:46Z",
    "author_association": "CONTRIBUTOR",
    "active_lock_reason": null,
    "draft": false,
    "pull_request": {
      "url": "https://api.github.com/repos/mittal-parth/personal-portfolio/pulls/43",
      "html_url": "https://github.com/mittal-parth/personal-portfolio/pull/43",
      "diff_url": "https://github.com/mittal-parth/personal-portfolio/pull/43.diff",
      "patch_url": "https://github.com/mittal-parth/personal-portfolio/pull/43.patch",
      "merged_at": "2023-02-25T07:20:46Z"
    },
    "body": "This PR is a continuation of https://github.com/mittal-parth/personal-portfolio/pull/37 made by @isurumaldeniya\r\n\r\nCloses #35\r\n\r\nI've used the same code but applied the feedback provided on their work with some changes. Please let me know what you think.\r\n\r\n| Mobile   | Desktop            |\r\n|------- |------------------------------------|\r\n| ![diff002](https://user-images.githubusercontent.com/43862225/221323841-574a4f22-4b8b-4383-a682-d94e8106f7c5.PNG)       |      ![diff001](https://user-images.githubusercontent.com/43862225/221323746-43472846-b841-4690-8f36-4d58f9bdb456.PNG) |\r\n\r\n",
    "reactions": {
      "url": "https://api.github.com/repos/mittal-parth/personal-portfolio/issues/43/reactions",
      "total_count": 1,
      "+1": 0,
      "-1": 0,
      "laugh": 0,
      "hooray": 0,
      "confused": 0,
      "heart": 1,
      "rocket": 0,
      "eyes": 0
    },
    "timeline_url": "https://api.github.com/repos/mittal-parth/personal-portfolio/issues/43/timeline",
    "performed_via_github_app": null,
    "state_reason": null,
    "score": 1.0
  }
]
}

From this data we can have some code that extracts what we need for the frontend. However some data might require a multi-pass stage, like the lines added and removed, for that we can access the diff_url. Here is an example response from it.

Click to expand
diff --git a/src/components/Footer.jsx b/src/components/Footer.jsx
index 129147b..7be2f29 100644
--- a/src/components/Footer.jsx
+++ b/src/components/Footer.jsx
@@ -57,6 +57,11 @@ const Footer = () => (
         />
       </div>
     </div>
+    <div className="text-center font-poppins font-normal text-dimWhite text-xs sm:text-sm pb-4">
+      <p>
+        Made with ๐Ÿ’™ by Parth Mittal & the Open Source Community
+      </p>
+    </div>
   </footer>
 );

The major thing that I see here for us to consider, is the data fetching and extraction. The latter seems easier to grasp but the first is tricky. Due to GH rate limits we cannot do the requests inside a React component, it would require some sort of caching.

At the moment I can only think of two options that could solve this without a dedicated backend, using a framework that generates static content at build time or finding a way to implement static generation in Vite. Please let me know what you think.

Hey @mateusabelli, thanks so much for the efforts!

As you mentioned, the GitHub API rate limits at 5,000 requests per hour if we use an access token.
For unauthenticated search requests, its limited at 60 requests per hour.

I think 5,000 requests per hour would be sufficient, considering the traffic received on my website ๐Ÿ˜›
I do not think we require caching as we can just fetch the data once on page load by wrapping it inside the useEffect hook.

Each user who decides to deploy this for their own website will have to enter their token. Since 5,000 requests are per-user requests, it should suffice.

Hey @mittal-parth I agree with you, depending on the traffic the authenticated rate limits would be enough. I'm sorry I tend to overthink when it comes to data fetching, thank you for the feedback.

I think this is a nice feature and I'd like to work on it, could you assign it to me?

That's ok, always open for discussions! ๐Ÿ˜„
Assigned!

@mateusabelli would be un-assigning this for someone else to work on. Thanks for all your efforts! :)