Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial release #190

Closed
wants to merge 10 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
blank_issues_enabled: false
blank_issues_enabled: true

contact_links:
- name: Ask a question
url: https://github.com/github/contributors/discussions/new
url: https://github.com/hcookie/contributors/discussions/new
about: Ask a question or start a discussion
- name: GitHub OSPO GitHub Action Overall Issue
url: https://github.com/github/github-ospo/issues/new
about: File issue for multiple GitHub OSPO GitHub Actions
26 changes: 16 additions & 10 deletions .github/workflows/contributors_report.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ on:
workflow_dispatch:
schedule:
- cron: "3 2 1 * *"

# on:
# push:
# branches: [testing]
permissions:
contents: read

Expand Down Expand Up @@ -35,13 +37,17 @@ jobs:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
START_DATE: ${{ env.START_DATE }}
END_DATE: ${{ env.END_DATE }}
REPOSITORY: github/contributors
SPONSOR_INFO: "true"
REPOSITORY: ecmwf/anemoi-training
# SPONSOR_INFO: "true"

- name: Show Contributor
shell: bash
run: cat contributors.md >> $GITHUB_STEP_SUMMARY

- name: Create issue
uses: peter-evans/create-issue-from-file@e8ef132d6df98ed982188e460ebb3b5d4ef3a9cd
with:
title: Monthly contributor report
token: ${{ secrets.GITHUB_TOKEN }}
content-filepath: ./contributors.md
assignees: zkoppert
# - name: Create issue
# uses: peter-evans/create-issue-from-file@e8ef132d6df98ed982188e460ebb3b5d4ef3a9cd
# with:
# title: Monthly contributor report
# token: ${{ secrets.GITHUB_TOKEN }}
# content-filepath: ./contributors.md
# # assignees: zkoppert
62 changes: 62 additions & 0 deletions .github/workflows/contributors_report_testing.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
---
name: Testing contributor report
# on:
# workflow_dispatch:
# schedule:
# - cron: "3 2 1 * *"
on:
push:
branches: [testing]
permissions:
contents: read

jobs:
contributor_report:
name: contributor report
runs-on: ubuntu-latest
permissions:
issues: write

steps:
- uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1

- name: Get dates for last month
shell: bash
run: |
# Calculate the first day of the previous month
start_date=$(date -d "last month" +%Y-%m-01)

# Calculate the last day of the previous month
end_date=$(date -d "$start_date +1 month -1 day" +%Y-%m-%d)

#Set an environment variable with the date range
# echo "START_DATE=$start_date" >> "$GITHUB_ENV"
# echo "END_DATE=$end_date" >> "$GITHUB_ENV"

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt

- name: Run Contributors
run: python -m contributors

env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# START_DATE: ${{ env.START_DATE }}
# END_DATE: ${{ env.END_DATE }}
REPOSITORY: ecmwf/anemoi-training,ecmwf/anemoi-datasets
SHOW_ORGANISATIONS: ecmwf
# SPONSOR_INFO: "true"

- name: Show Contributor
shell: bash
run: cat contributors.md >> $GITHUB_STEP_SUMMARY

# - name: Create issue
# uses: peter-evans/create-issue-from-file@e8ef132d6df98ed982188e460ebb3b5d4ef3a9cd
# with:
# title: Monthly contributor report
# token: ${{ secrets.GITHUB_TOKEN }}
# content-filepath: ./contributors.md
# # assignees: zkoppert
27 changes: 11 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,29 +1,24 @@
# Contributors action
# Contributors sorted by Organisation action

[![Python package](https://github.com/github/contributors/actions/workflows/python-ci.yml/badge.svg)](https://github.com/github/contributors/actions/workflows/python-ci.yml)
[![Docker Image CI](https://github.com/github/contributors/actions/workflows/docker-ci.yml/badge.svg)](https://github.com/github/contributors/actions/workflows/docker-ci.yml)
[![CodeQL](https://github.com/github/contributors/actions/workflows/github-code-scanning/codeql/badge.svg)](https://github.com/github/contributors/actions/workflows/github-code-scanning/codeql)[![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/github/contributors/badge)](https://scorecard.dev/viewer/?uri=github.com/github/contributors)
[![Python package](https://github.com/hcookie/contributors/actions/workflows/python-ci.yml/badge.svg)](https://github.com/hcookie/contributors/actions/workflows/python-ci.yml)
[![Docker Image CI](https://github.com/hcookie/contributors/actions/workflows/docker-ci.yml/badge.svg)](https://github.com/hcookie/contributors/actions/workflows/docker-ci.yml)
[![CodeQL](https://github.com/hcookie/contributors/actions/workflows/github-code-scanning/codeql/badge.svg)](https://github.com/hcookie/contributors/actions/workflows/github-code-scanning/codeql)[![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/github/contributors/badge)](https://scorecard.dev/viewer/?uri=github.com/github/contributors)

This is a GitHub Action that given an organization or specified repositories, produces information about the [contributors](https://chaoss.community/kb/metric-contributors/) over the specified time period.
This is a GitHub Action that given an organization or specified repositories, produces information about the [contributors](https://chaoss.community/kb/metric-contributors/) sorted by organisation.

Similar actions to help you recognize contributors by putting them into a `README` or `CONTRIBUTORS.md` include:

- [contributor-list](https://github.com/marketplace/actions/contribute-list)

This action was developed by the GitHub OSPO for our own use and developed in a way that we could open source it that it might be useful to you as well! If you want to know more about how we use it, reach out in an issue in this repository.
- [contributors](https://github.com/github/contributors)

## Example use cases

- As a maintainer, you may want to acknowledge recent contributors in a discussion post
- As an OSPO or maintainer, you may want to know who candidates are for new maintainers
- As a maintainer, you may want to acknowledge contributors from various organisations in a discussion post
- A repository wants to track contributions from organisations

## Support

If you need support using this project or have questions about it, please [open up an issue in this repository](https://github.com/github/contributors/issues). Requests made directly to GitHub staff or support team will be redirected here to open an issue. GitHub SLA's and support/services contracts do not apply to this repository.

### OSPO GitHub Actions as a Whole

All feedback regarding our GitHub Actions, as a whole, should be communicated through [issues on our github-ospo repository](https://github.com/github/github-ospo/issues/new).
If you need support using this project or have questions about it, please [open up an issue in this repository](https://github.com/github/contributors/issues).

## What is a contributor?

Expand Down Expand Up @@ -85,8 +80,8 @@ This action can be configured to authenticate with GitHub App Installation or Pe
| `END_DATE` | False | Current Date | The date at which you want to stop gathering contributor information. Must be later than the `START_DATE`. ie. Aug 2nd, 2023 would be `2023-08-02` |
| `SPONSOR_INFO` | False | False | If you want to include sponsor information in the output. This will include the sponsor count and the sponsor URL. This will impact action performance. ie. SPONSOR_INFO = "False" or SPONSOR_INFO = "True" |
| `LINK_TO_PROFILE` | False | True | If you want to link usernames to their GitHub profiles in the output. ie. LINK_TO_PROFILE = "True" or LINK_TO_PROFILE = "False" |

**Note**: If `start_date` and `end_date` are specified then the action will determine if the contributor is new. A new contributor is one that has contributed in the date range specified but not before the start date.
| `SHOW_ORGANISATIONS` | False | [] | Organisations to show in the contributors table. Will be evaluated in order, and a user only added to only the first one they are a part of. Any contributors with no organisation will be shown in independent. Set to 'all' to show all organisations.
| `CONTRIB_FILENAME` | False | "contibutors" | Filename to add contributors to. Will create both an 'md', and 'json' file with contents.

**Performance Note:** Using start and end dates will reduce speed of the action by approximately 63X. ie without dates if the action takes 1.7 seconds, it will take 1 minute and 47 seconds.

Expand Down
1 change: 1 addition & 0 deletions contributors/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Contributors Module"""
3 changes: 3 additions & 0 deletions contributors/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from contributors.contributors import main

main()
4 changes: 1 addition & 3 deletions auth.py → contributors/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,7 @@ def auth_to_github(
"""
if gh_app_id and gh_app_private_key_bytes and gh_app_installation_id:
gh = github3.github.GitHub()
gh.login_as_app_installation(
gh_app_private_key_bytes, gh_app_id, gh_app_installation_id
)
gh.login_as_app_installation(gh_app_private_key_bytes, gh_app_id, gh_app_installation_id)
github_connection = gh
elif ghe and token:
github_connection = github3.github.GitHubEnterprise(ghe, token=token)
Expand Down
68 changes: 14 additions & 54 deletions contributor_stats.py → contributors/contributor_stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@
from typing import List

import requests
from dataclasses import dataclass, field


@dataclass
class ContributorStats:
"""
A class to represent a contributor_stats object correlating to a single contributors stats.
Expand All @@ -31,47 +33,14 @@ class ContributorStats:

"""

def __new__(cls, *args, **kwargs): # pylint: disable=unused-argument
"""Create a new contributor_stats object"""
return super().__new__(cls)

def __init__(
self,
username: str,
new_contributor: bool,
avatar_url: str,
contribution_count: int,
commit_url: str,
sponsor_info: str,
):
"""Initialize the contributor_stats object"""
new_contributor = False
self.username = username
self.new_contributor = new_contributor
self.avatar_url = avatar_url
self.contribution_count = contribution_count
self.commit_url = commit_url
self.sponsor_info = sponsor_info

def __repr__(self) -> str:
"""Return the representation of the contributor_stats object"""
return (
f"contributor_stats(username={self.username}, "
f"new_contributor={self.new_contributor}, "
f"avatar_url={self.avatar_url}, "
f"contribution_count={self.contribution_count}, commit_url={self.commit_url})"
f"sponsor_info={self.sponsor_info})"
)
username: str
new_contributor: bool
avatar_url: str
contribution_count: int
commit_url: str
sponsor_info: str
organisations: list[str] = field(default_factory=list)

def __eq__(self, other) -> bool:
"""Check if two contributor_stats objects are equal"""
return (
self.username == other.username
and self.new_contributor == other.new_contributor
and self.avatar_url == other.avatar_url
and self.contribution_count == other.contribution_count
and self.commit_url == other.commit_url
)


def is_new_contributor(username: str, returning_contributors: list) -> bool:
Expand All @@ -91,7 +60,7 @@ def is_new_contributor(username: str, returning_contributors: list) -> bool:
return True


def merge_contributors(contributors: list) -> list:
def merge_contributors(contributors: list[list[ContributorStats]]) -> list[ContributorStats]:
"""
Merge contributors with the same username from multiple repositories.

Expand All @@ -109,19 +78,12 @@ def merge_contributors(contributors: list) -> list:
for merged_contributor in merged_contributors:
if merged_contributor.username == contributor.username:
# Merge the contribution counts via addition
merged_contributor.contribution_count += (
contributor.contribution_count
)
merged_contributor.contribution_count += contributor.contribution_count
# Merge the commit urls via concatenation
merged_contributor.commit_url = (
merged_contributor.commit_url
+ ", "
+ contributor.commit_url
)
merged_contributor.commit_url = merged_contributor.commit_url + ", " + contributor.commit_url
# Merge the new_contributor attribute via OR
merged_contributor.new_contributor = (
merged_contributor.new_contributor
or contributor.new_contributor
merged_contributor.new_contributor or contributor.new_contributor
)

else:
Expand Down Expand Up @@ -171,8 +133,6 @@ def get_sponsor_information(contributors: list, token: str) -> list:

# if the user has a sponsor page, add it to the contributor object
if data["repositoryOwner"]["hasSponsorsListing"]:
contributor.sponsor_info = (
f"https://github.com/sponsors/{contributor.username}"
)
contributor.sponsor_info = f"https://github.com/sponsors/{contributor.username}"

return contributors
Loading
Loading