anuraghazra / github-readme-stats

:zap: Dynamically generated stats for your github readmes
https://github-readme-stats.vercel.app
MIT License
67.71k stars 22.16k forks source link

[Feature Request] Add organization stats #1

Open franky47 opened 4 years ago

franky47 commented 4 years ago

Most of my open-source work is moved to dedicated organizations (47ng, FortySevenEffects, Chiffre), for scoping and to avoid cluttering my personal repos.

I'd be happy to contribute a feature to include aggregated organization stats.

API ideas:

![Anurag's github stats](https://github-readme-stats.vercel.app/api?username=anuraghazra&orgs=acme,evilcorp,fsociety)
anuraghazra commented 4 years ago

@franky47 great idea! okay i will look into it. and try to add org support. meanwhile you can also contribute if you want.

metaskills commented 4 years ago

I did that in my fork on AWS Lambda. For the pin.js I did:

      query: `
        fragment RepoInfo on Repository {
          name
          owner {
            login
          }
const renderRepoCard = (repo) => {
  const owner = repo.owner.login;
<text x="50" y="38" class="header"><a class="header" href="https://github.com/${owner}/${name}">${name}</a></text>

You can see too that I added an <a> link to the repo name too.

anuraghazra commented 4 years ago

Will it actually show the stats including all the Orgs?

anuraghazra commented 4 years ago

@metaskills Also yes that link would work but will it work in github readmes? Hmmm i dont think soo because it is served as image not as raw html elements. ๐Ÿค”

metaskills commented 4 years ago

Oh yea... good point. Without a in your markdown, you can click it (views svg) then click it again. But easier to put the links in your markdown I suspect.

anuraghazra commented 4 years ago

Yes just wrapping the markdown image inside a link is a good way.

FairyEver commented 4 years ago

I really hope to have this function, which can count my stars in the organization๏ผ

deancn commented 4 years ago

my stars value is 0, can help check?

https://github-readme-stats.vercel.app/api/?username=deancn

terror commented 4 years ago

Hi @deancn, it is because we currently only support stars from repositories you are the owner of. Since many people want this as an enhancement I'm sure we'll be able to implement this soon.

deancn commented 4 years ago

@terror got it, thanks.

mainrs commented 4 years ago

Assuming you might be a member of some huge organization (npm, babel, rust). It might make sense to add a filter on top of it to prevent certain organizations from being included. Better than that would be an allowlist that only includes organizations that you explicitly declare: https://github-readme-stats.vercel.app/api/?username=SirWindfield?orgs=zors-engine,Spotifyd

daolou commented 4 years ago

How long this feature could be used?

RubenMateus commented 4 years ago

any news on this?

ngoldack commented 4 years ago

Any update on this?

ngoldack commented 3 years ago

@anuraghazra I tried it in go and it worked like a charm to count those stars:

package main

import (
    "encoding/json"
    "fmt"
    "io/ioutil"
    "net/http"
)

type Org struct {
    Name string `json:"login"`
}

type Repo struct {
    Name  string `json:"full_name"`
    Stars int    `json:"stargazers_count"`
}

func main() {
    url := "https://api.github.com/users/mattetti/orgs"

    resp, err := http.Get(url)
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()
    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        panic(err)
    }

    var stars int

    var orgs []Org
    json.Unmarshal(body, &orgs)
    for _, v := range orgs {

        url = fmt.Sprintf("https://api.github.com/orgs/%s/repos", v.Name)

        resp, err = http.Get(url)
        if err != nil {
            panic(err)
        }
        defer resp.Body.Close()
        body, err = ioutil.ReadAll(resp.Body)
        if err != nil {
            panic(err)
        }

        var repos []Repo
        json.Unmarshal(body, &repos)

        for _, v := range repos {
            fmt.Println(v.Name, v.Stars)
            stars += v.Stars
        }
    }
    fmt.Println("-----------------------")
    fmt.Println("### Total stars:", stars)
}

It's quite simple: you just get all org names from the api endpoint /users/${USERNAME}/orgs and then get all each repo from each org from the endpoint /orgs/${ORGNAME}/repos. Just count those stars together and you have it. But since I don't have the expierence in javascript I won't be able to implement this.

daolou commented 3 years ago

@ngoldack

this api /users/${USERNAME}/orgs seemingly inaccurate for example https://api.github.com/users/Mr-jiangzhiguo/orgs get [], but in fact, it has 3 public orgs image

mre commented 3 years ago

@Mr-jiangzhiguo, strangely when I go to your Github profile, I also can't see your organizations. I tried mine (curl https://api.github.com/users/mre/orgs) and it works. ๐Ÿค”

daolou commented 3 years ago

@Mr-jiangzhiguo, strangely when I go to your Github profile, I also can't see your organizations. I tried mine (curl https://api.github.com/users/mre/orgs) and it works. ๐Ÿค”

I got it, settings is private image

anuraghazra commented 3 years ago

It's quite simple: you just get all org names from the api endpoint /users/${USERNAME}/orgs and then get all each repo from each org from the endpoint /orgs/${ORGNAME}/repos. Just count those stars together and you have it. But since I don't have the expierence in javascript I won't be able to implement this.

Yeah logic isn't an issue here. we can of course get the data and manipulate it as per our needs.

BUT! The issue is that vercel serverless execution time is only 10sec and it's not enough to fetch all those data & then manipulate it, serverless function would time out long before we even get to fetching all org data.

and then get all each repo from each org

And this is also very expensive because the organization can have many repos and we have to fetch all of them and accumulate the star count.

dzikoysk commented 3 years ago

@anuraghazra some kind of lightweight cache could be a solution ๐Ÿค”

ngoldack commented 3 years ago

@anuraghazra or concurrency.

Another problem would be the rate limiting with too much orgs/repos

anuraghazra commented 3 years ago

some kind of lightweight cache could be a solution thinking

We already have caching, it's not the issue since the initial data wont even load because vercel would timeout.

zhangyuang commented 3 years ago

the same demands

changkun commented 3 years ago

eager to have this.

conquerv0 commented 3 years ago

Patiently waiting for an exciting update.

MrTroble commented 3 years ago

I would prefer to use a whitelist for that, that would also make it more straight forward and light (probably?)

For example: https://github-readme-stats.vercel.app/api?username=MrTroble&?orgs=Troblecodings&show_icons=true&theme=radical

This would go through the repos of Troblecodings and would account for all stars in those. This shouldn't take to long should it?

Zethson commented 3 years ago

Still relevant.

wleoncio commented 3 years ago

Just bought @anuraghazra a coffee in the name of this issue (and as a general "thank you" for making this wonderful piece of software). Maybe if more people chip in we can convince him to get this done before he gets a heart attack from all the caffeine. ๐Ÿ˜…

anuraghazra commented 3 years ago

Just bought @anuraghazra a coffee in the name of this issue (and as a general "thank you" for making this wonderful piece of software). Maybe if more people chip in we can convince him to get this done before he gets a heart attack from all the caffeine. ๐Ÿ˜…

๐Ÿ˜„ haha thank you for coffee.

Well yeah probably only viable way to get this issue done is to change the fetching system, like instead of fetching on the fly with serverless functions, we can create a github action to fetch the data, this way serverless functions won't timeout and we can fetch more data looping over all the organizations.

kaaax0815 commented 3 years ago

What is the status of this Feature?

franky47 commented 3 years ago

The GitHub REST API has an endpoint to list repositories where the authenticated user is either the owner or a member, this would make most sense for this kind of stats: if I've pushed a README update to facebook/react, its stars should not be credited to my account, but it should if I'm a core member/maintainer.

There are some drawbacks though:

Having an explicit list of orgs would be a nice API but could expose the same "cheating" behaviour: just list a few famous orgs and you're an instant 10x developer! ๐Ÿ˜…

developStorm commented 3 years ago

@franky47 * It's REST, I'm not sure if there's an equivalent in GraphQL (will have to dig it out)

Does this GraphQL query look like the same thing you're talking about? https://github.community/t/graphql-api-how-to-fetch-all-repositories-that-the-current-user-has-access-to/13792/10

developStorm commented 3 years ago

I was able to use the query params mentioned in my last comment to include org repo for top-langs card. Use @franky47's card as demo (since mine was a bit tricky๐Ÿฅฒ):

(role=OWNER as default) https://github-readme-stats-one-bice.vercel.app/api/top-langs/?username=franky47&langs_count=10&layout=compact

https://github-readme-stats-one-bice.vercel.app/api/top-langs/?username=franky47&langs_count=10&layout=compact&role=OWNER,ORGANIZATION_MEMBER,COLLABORATOR

?role= could be any combination of repositoryaffiliation enum here: https://docs.github.com/en/graphql/reference/enums#repositoryaffiliation

wleoncio commented 3 years ago

This looks promising, but when I do mine I get what looks like the language breakdown of all the code in my org repos, not of the code I contributed. I tried other combinations of parameters on that enum page but couldn't get to what I want. ๐Ÿ˜•

franky47 commented 3 years ago

Same here: the Eagle code in my demo card was probably 10+ years old example repositories with lots of hardware/PCB files that I wouldn't want shown in my stats, which brings us to filtering again.

developStorm commented 3 years ago

This looks promising, but when I do mine I get what looks like the language breakdown of all the code in my org repos, not of the code I contributed. I tried other combinations of parameters on that enum page but couldn't get to what I want. ๐Ÿ˜•

That' s right. The API endpoint used here can only get the language distribution for the whole repository but not only for individual's contribution ๐Ÿค’ It is difficult to do what you say based on the existing queries.

Since GitHub doesn't seem to have such statistics, I'm worried that the only thing we can do is probably just iterate through all the repositories for all the commits of a given user and calculate the language. And that would be very, very time-consuming - Vercel probably won't do it. I'd be happy to try to implement it if there is a way to get the language distribution data for a single user directly from GitHub API.

(We could exclude some specific repos with exclude_repo param though, if only a few repos is interfering the data)

CircuitSacul commented 3 years ago

Has this been implemented?

mainrs commented 3 years ago

Can people please stop constantly asking if this has been implemented or not? It doesn't drive development faster, it often puts pressure onto the maintainer that gets constantly reminded about this issue (and it's clear from the comments that the solution is not easy). And it notifies people that are subscribed to this thread that are interested in legitimate comments that either give feedback or bring up new ideas on how to solve the issue.

"+1", "is this implemented yet", "any updates" and similar comments are just unneccessary spam. If the feature would exist, the issue would be closed. It's that easy.

Thank you.

developStorm commented 3 years ago

Hey folks! I've made https://github.com/anuraghazra/github-readme-stats/issues/1#issuecomment-855681098 available for stars on general stats card as well. The implementation again used ownerAffiliations and you can see detailed explanation of roles you may use here.

Use @franky47's stats card as demo (again ๐Ÿ˜†):

Only include repo they owned: https://github-readme-stats-one-bice.vercel.app/api?username=franky47&show_icons=true&include_all_commits=true&count_private=true

Include all repos where they have write access to: https://github-readme-stats-one-bice.vercel.app/api?username=franky47&show_icons=true&include_all_commits=true&count_private=true&role=OWNER,ORGANIZATION_MEMBER,COLLABORATOR

* It's not that accurate to say "have write access to". Check GitHub docs linked above for more precise description.

I'm not sure if this is enough to close this issue -- let me know for any thoughts!

CircuitSacul commented 3 years ago

@SirWindfield you're right, sorry about that. My intention wasn't to put any pressure on the developers, I just couldn't tell from the comments whether or not it had been implemented (though I guess I should've noticed the issue was still open).

anuraghazra commented 3 years ago

Hey @developStorm this is great thanks for this.

Although I do have a question, it's a philosophical question matter of fact.

Like for example, I'm member of reakit organization because I contributed code to it, but is it fair to count all of the 4.8k stars as MY stars??? Technically those stars aren't gained by me, those are gained by the reakit organization.

Now if I'm added as a COLLABORATOR to the repo then maybe you can say "okay yes I gained those stars" But in case of ORGANIZATION_MEMBER it's a totally different thing.

developStorm commented 3 years ago

Hi @anuraghazra thanks for the explanation.I think the typical case where COLLABORATOR and ORGANIZATION_MEMBERยท will be used is when some users only use the organization to organize their repo. i.e. The main (if not the only) contributor of these repositories is still the user themselves, even if the repository is under some org. In that case I think it's reasonable for them to say those stars are gained by themselves. This scenario is also mentioned several times in #1.

I don't think it's necessary to overthink anti-cheating as an open source stats project. It's entirely possible for a intended user to create fake data by manually modifying the source code or SVG, etc. - no need to go through such a troublesome as joining/contributing to the organization.

Hope this makes sense โœจ

rickstaa commented 3 years ago

@developStorm thanks again for creating #1122. I think it is a very valuable addition to the github-readme-stats tool.

Here my two cents on the matter. I think I agree with @anuraghazra that removing the ORGANIZATION_MEMBER option would increase the design integrity of the github-readme-stats tool. However, as you said, if people want to cheat, they always find a way to do so. Therefore if this requires you to add a lot of code, it might not be worth it since it complicates the codebase. Maybe first let's see what the rest of the userbase/community thinks.

wleoncio commented 3 years ago

Maybe first let's see what the rest of the userbase/community thinks.

Well, can't speak for everyone, but I for one care very little about counting stars; I just wish my programming language breakdown card would reflect all my commits on GH (personal and org repositories; ideally even PR code in 3rd-party repos).

anuraghazra commented 3 years ago

@rickstaa agreed.

I'm fine with adding this ownerAffiliations feature to the stats if majority of people thinks it's a useful feature and can provide them with much better stat results.

Even though I'm still ridgid to my https://github.com/anuraghazra/github-readme-stats/issues/1#issuecomment-864451245

I also somewhat agree with @developStorm's thoughts that it's "not necessary to overthink anti-cheating as an open source stats project"

rickstaa commented 3 years ago

@wleoncio Excellent point! I missed noticing that #1122 also influences the behaviour of the "programming language breakdown card". In that case, based on https://github.com/anuraghazra/github-readme-stats/issues/1#issuecomment-864459346, I think the benefits of accepting the ORGANIZATION_MEMBER param outweigh the prevention of cheating.

rickstaa commented 3 years ago

By including the ORGANIZATION_MEMBER param. People, can decide themselves which stats they want to show on each card.

My current setup is now as follows: I include the ORGANIZATION_MEMBER param in my "programming language breakdown card", since it better represents the languages I use daily. However, for the "GitHub stats" card, however, since this would add stars that I would not want to take credit for, I omit it.

wleoncio commented 3 years ago

My current setup is now as follows: I include the ORGANIZATION_MEMBER param in my "programming language breakdown card", since it better represents the languages I use daily. However, for the "GitHub stats" card, however, since this would add stars that I would not want to take credit for, I omit it.

Sounds like a good solution for now. I'll be doing the same, plus adding exclude_repo to filter out org repos that obviously skew my card (basically, projects I am not a major contributor to) and hide to exclude languages that I don't code in but still show up due to peer contribution.

GMkonan commented 3 years ago

This issue covers only stars stats right? From what I've read and tested it seems like it. If this is correct, do you guys plan on making other stats such as PR and commits in organizations count as well? Sorry if I misunderstood something and thank you guys for everything.

developStorm commented 2 years ago

Sorry if this is bothering people on this thread.

@anuraghazra According to your reply in https://github.com/anuraghazra/github-readme-stats/issues/1#issuecomment-864858924, in conjunction with the ongoing community interest in this feature (see this discussion and the recent #1035, #1172, #1243), would you consider merging my previously initiated PR #1122, at least as an interim workaround? As the code base changes over time, resolving code conflicts can become more cumbersome, so I would appreciate a final conclusion from you as soon as possible. Thanks for your time :-)