anuraghazra/github-readme-stats

Create GRS action

rickstaa opened this issue Β· 15 comments

Is your feature request related to a problem? Please describe.

Currently, the only way to create GRS cards is through the Public/Private Vercel instance. This method is user-friendly since people can request their cards from the endpoint. Unfortunately, it, however, comes with several limitations:

  • It uses the GraphQL API, which is rate limited (see https://docs.github.com/en/graphql/overview/resource-limitations). As a result, if too many people are using the Public Vercel instance simultaneously, cards can no longer be fetched.
    • Additionally, we can not improve the accuracy of our cards since fetching more data would result in higher GraphQL query costs. Because of this, the results are less accurate for users with more than 100 repositories.
    • It also prevents us from implementing top feature requests like:
  • Further, the code must run on the Vercel instance before the results are returned. This causes long loading times for the cards or even a time-out.

Describe the solution you'd like

In my discussion with @4l1fe on #1975, we concluded that the best way to solve these issues is also to give users the ability to generate the GRS cards periodically inside a GitHub action. Doing this would provide us to solve the points above for the case when users use GRS through an action.

Implementation

We can create such an action by calling the render functions directly and then saving the resulting SVGs to the system. I created the following example to show what I mean:

const fetchStats = require("../src/fetchers/stats-fetcher");
const {
  renderError,
  parseBoolean,
  parseArray,
  clampValue,
  CONSTANTS,
} = require("../src/common/utils");
const renderStatsCard = require("../src/cards/stats-card");
const fs = require("fs");

// Variables (Should be replaced with CLI arguments)
const username = "rickstaa";
const count_private = true;
const count_all_commits = true;
const hide = "";
const show_icons = true;
const hide_title = true;
const hide_border = true;
const hide_rank = true;
const include_all_commits = true;
const line_height = 25;
const title_color = "#000000";
const icon_color = "#000000";
const text_color = "#000000";
const bg_color = "#ffffff";
const custom_title = "Rick Staa";
const border_radius = "1";
const border_color = "#000000";
const theme = "light";
const locale = "en";
const disable_animations = true;

const run = async () => {
  // Retrieve stats
  const stats = await fetchStats(
    username,
    parseBoolean(count_private),
    parseBoolean(count_all_commits),
  );
  console.log(stats);

  // Create card
  const card = renderStatsCard(stats, {
    hide: parseArray(hide),
    show_icons: parseBoolean(show_icons),
    hide_title: parseBoolean(hide_title),
    hide_border: parseBoolean(hide_border),
    hide_rank: parseBoolean(hide_rank),
    include_all_commits: parseBoolean(include_all_commits),
    line_height,
    title_color,
    icon_color,
    text_color,
    bg_color,
    theme,
    custom_title,
    border_radius,
    border_color,
    locale: locale ? locale.toLowerCase() : null,
    disable_animations: parseBoolean(disable_animations),
  });
  console.log(card);

  // Save card
  if (!fs.existsSync("cards")) {
    fs.mkdirSync("cards");
  }
  fs.writeFileSync(`./cards/${username}.svg`, card);

  console.log("finish");
};

run();

We can then wrap this function inside a Javascript GitHub action and let users provide the query parameters for our cards through the action configuration file.

name: GRS card generation
on:
  schedule:
  - cron:  '0 0 */1 * *'

jobs:
  ceateGRSCards:
    name: Create and Store GRS cards
    runs-on: ubuntu-latest
    steps:
    - name: Run top issues action
      uses: anuraghazra/github-readme-stats@master
      env:
        github_token: ${{ secrets.GITHUB_TOKEN }}
      with:
        save_path: ""
        stats_card_query: ?username=anuraghazra
        lang_card_query: ?username=anuraghazra
        repo_card_query: ?username=anuraghazra&repo=github-readme-stats
        wakatime_card_query: ?username=willianrod

Alternatively, we could use Vercels query parsers to call the API endpoints directly.

Todos

  • Create a function that calls the card to render functions.

#2473 implements this

  • Create a way to store the returned cards in the system.

I think the easiest way to do this is the following:

  • Checkout Git branch

  • Write SVG to local file

  • Push to GRS branch

  • Users can use raw githubusercontent or GH Pages to access file

  • Inspiration from @Platane/snk :)

  • Wrap this functionality in a action.

I'm waiting for #2052 to be completed, as this will speed up my development.

(subscribe)

(subscribe)

Great! I need to find time to finish #2108, which will make implementing #2179 easier. All help is welcome πŸ‘πŸ».

You can use #2409 for this now right? That'll make everything easier (I can perhaps write an action myself).

You can use #2409 for this now right? That'll make everything easier (I can perhaps write an action myself).

Let's discuss these things on discord (see my README).

You can use #2409 for this now right? That'll make everything easier (I can perhaps write an action myself).

Let's discuss these things on discord (see my README).

I prefer GitHub, if you don't mind. It's easier to track changes and features, and I can go back to older issues and comments. Linking and discussing code is also better.

I've created #2443 which we can use to have discussions, and that'll keep everything in one place. We can also consider multiple PRs and Issues at once (like how #2409 might make #2179 easier to implement).

The idea is great.
However, i am concerned about it. Using Github Actions frequently and widely can cause your Github repository to be disabled (forks and upstream together).

For example, Project LSPosed/MagiskOnWSA was disabled because it violated GitHub's terms of service, due to tons of users forking the repository and building the project themselves on Github Actions. See their new Repository's README for more Info.

Another example will be luolongfei/freenom, a project that renews freenom domain automatically with Github Actions. This repository was also Disabled because it violated GitHub's terms of service (The author however got it back) due to many users forking the repository and creating their own action to renew their domains.

I personally have alot of automation scripts using Github Actions before, but most of the script's repository was disabled.
There are also cases that people's Github account got banned because their repository keep getting disabled due to Github Actions.

The idea is great. However, i am concerned about it. Using Github Actions frequently and widely can cause your Github repository to be disabled (forks and upstream together).

For example, Project LSPosed/MagiskOnWSA was disabled because it violated GitHub's terms of service, due to tons of users forking the repository and building the project themselves on Github Actions. See their new Repository's README for more Info.

Another example will be luolongfei/freenom, a project that renews freenom domain automatically with Github Actions. This repository was also Disabled because it violated GitHub's terms of service (The author however got it back) due to many users forking the repository and creating their own action to renew their domains.

I personally have alot of automation scripts using Github Actions before, but most of the script's repository was disabled. There are also cases that people's Github account got banned because their repository keep getting disabled due to Github Actions.

Ah, that makes sense; those repositories were using Github Actions in a way that is not to be used. πŸ˜… My proposal was to create a new repository with a simple github action that spins up a node container, imports the GRS npm package, and then runs the query parameters using the containers PAT. This action would then generate an image in the repository, which can be referred to under a specific name in README.md. πŸ–ΌοΈ I wanted to deploy this github action on https://github.com/marketplace so that users can easily add it to their README.md. 😁

Let me know if I overlooked something, but I think that is within GitHubs terms of service since all my other actions and many very popular actions work that way πŸ˜….

@rickstaa https://github.com/LSPosed/MagiskOnWSA was using it in the TOS (to build the project, dev purpose) and they still got banned. Clearly github wants you to NOT use actions too frequently.

Also, setting up Actions is way harder then Vercel. People are already refusing to deploy their own Vercel instance, do you think they will do someting way harder just for a stats on README.md?

@rickstaa https://github.com/LSPosed/MagiskOnWSA was using it in the TOS (to build the project, dev purpose), and they still got banned. Clearly, github wants you to NOT use actions too frequently.

Also, setting up Actions is way harder then Vercel. People are already refusing to deploy their own Vercel instance, do you think they will do someting way harder just for a stats on README.md?

I don't think GitHub doesn't care about people running their actions too frequently since users pay for these executions anywayπŸ€”. In https://github.com/LSPosed/MagiskOnWSA's situation, where they build the project inside a GitHub action, I can see how that gives problems.

In our situation, however, it will be a regular github action, and people, therefore, do not need to fork the GitHub repository in order to use it. They will use it by importing it through the marketplace in their local action YAML file (see (see https://github.com/rickstaa/action-create-tag for an example). It, therefore, does not count against our budget as the action itself is not included in the .github folder and is, therefore, not run on forks. But thanks a lot for bringing this unique problem to my attention. I was not aware of it 😁.

Nevertheless, it doesn't have to be a GitHub action. We can also make deploying your own Vercel instance easier and more tempting so that more people will switch to deploying their own Vercel instance (see #2415 (comment)).

That said I think for having more accurate card data that looks at more than 100 repositories a GitHub action is still needed since also on a Private Vercel instance you will likely run into rate limits if we paginate through al pages on very active users. πŸ˜…

goodproject

Will be fixed by #2537. Also, I'm seeing this only now; might have saved me some trouble during development 😒

@rickstaa any news about this PR?

@rickstaa any news about this PR?

Hey, @D3vil0p3r! @rickstaa currently busy with his master thesis defence. When he finish we are going to resolve several issues important for this repository including creation of GitHub action in the order discussed there #2052 (comment).