Hello pyReviters,
I mentioned, a month back or so, I was willing to reward contribution to the repo and community with the money collected from supporters on Open Collective pyRevitLabs · Expenses - Open Collective.
I thought first about making a bounty program, but rapidly felt this would be overwhelming. I don’t have that much time to put into it, and the management time would have been disproportionate. So like every good autocrat and coder, I made a script to harvest relevant data from the github repo (cursor and a few minutes later - see at the end of this post if you are curious)
So here they are the proud contributors, reviewers, actors, action figures of the past months in no particular order:
- @sanzoghenzo for his code reviews, answers on the forum, and his kind nudges when I derail
- @pyrevti / aka Wurschdhaud on gh, for many smart improvements and cool PRs
- @tayOthman for its support in the past year: Comments, PR, Answers, Fixing issues, you name it
- @Mohamed.Asli for his fresh and intense involvement with cool new tools
- @romangolev for his ongoing PR to refactor the Loader into C# which will be a great speed improvement _ this is both a reward and a nudge, and if someone wants to help him out… refactor: Rewrite Loader in C# by romangolev · Pull Request #2647 · pyrevitlabs/pyRevit · GitHub
All of them received a 250 € or $ gift card from whatever eshop they liked or used (or the ones I could get to process my payment methods from Czech Rep. )
Notes:
_ I know € or $ are not equal _ don’t bother, I told you I am the autocrat
_ I also know that not all contributions are equal in terms of the value, time invested, … but to me, getting to spend your own time to improve pyRevit for an extended period is something valuable in itself, and not everyone comes with the same background, so, All volunteers are welcome if they help sustain pyRevit _ you can add socialist/communist to autocrat
_ If you want to take a look at how the money is being used, this is all there pyRevitLabs · Expenses - Open Collective
GitHub stats extractor
# GitHub Issues and PRs Tracker for pyRevit
# Compatible with IronPython 2.7.12 and Python 3.x
# For IronPython 2.7.12, use urllib2
# For Python 3.x, use urllib.request
try:
import urllib2
import json
import os
PYTHON_VERSION = 2
except ImportError:
import urllib.request as urllib2
import json
import os
PYTHON_VERSION = 3
from datetime import datetime, timedelta
from collections import defaultdict
import time
# Load environment variables from .env file
def load_env_file():
"""Load environment variables from .env file"""
try:
env_file = ".env"
if os.path.exists(env_file):
with open(env_file, "r") as f:
for line in f:
line = line.strip()
if line and not line.startswith("#") and "=" in line:
key, value = line.split("=", 1)
os.environ[key.strip()] = value.strip()
except Exception as e:
print("Warning: Could not load .env file: " + str(e))
# Load environment variables
load_env_file()
def get_github_data(url, retry_count=0):
"""Make a request to GitHub API and return JSON data with rate limiting"""
try:
request = urllib2.Request(url)
request.add_header("Accept", "application/vnd.github.v3+json")
request.add_header("User-Agent", "pyRevit-issue-tracker")
# Add authentication header if token is available
github_token = os.environ.get("GITHUBTOKEN")
if github_token:
request.add_header("Authorization", "Bearer " + github_token)
response = urllib2.urlopen(request)
if PYTHON_VERSION == 3:
data = json.loads(response.read().decode("utf-8"))
else:
data = json.loads(response.read())
# Add a small delay to respect rate limits
time.sleep(0.1)
return data
except urllib2.HTTPError as e:
if e.code == 429 or e.code == 403: # Rate limit exceeded
if retry_count < 3:
wait_time = (retry_count + 1) * 5 # Wait 5, 10, 15 seconds
print("Rate limit exceeded. Waiting " + str(wait_time) + " seconds...")
time.sleep(wait_time)
return get_github_data(url, retry_count + 1)
else:
print("Rate limit exceeded. Please try again later.")
return None
else:
print("HTTP Error " + str(e.code) + ": " + str(e))
return None
except Exception as e:
print("Error fetching data: " + str(e))
return None
def get_closed_issues_for_month(year, month):
"""Get all closed issues for a specific month"""
start_date = "{:04d}-{:02d}-01".format(year, month)
if month == 12:
next_month = 1
next_year = year + 1
else:
next_month = month + 1
next_year = year
next_month_first = datetime(next_year, next_month, 1)
last_day = (next_month_first - timedelta(days=1)).day
end_date = "{:04d}-{:02d}-{:02d}".format(year, month, last_day)
search_url = (
"https://api.github.com/search/issues?q=repo:pyrevitlabs/pyRevit+is:issue+is:closed+closed:"
+ start_date
+ ".."
+ end_date
+ "&per_page=100"
)
data = get_github_data(search_url)
return data.get("items", []) if data else []
def get_merged_prs_for_month(year, month):
"""Get all merged PRs for a specific month"""
start_date = "{:04d}-{:02d}-01".format(year, month)
if month == 12:
next_month = 1
next_year = year + 1
else:
next_month = month + 1
next_year = year
next_month_first = datetime(next_year, next_month, 1)
last_day = (next_month_first - timedelta(days=1)).day
end_date = "{:04d}-{:02d}-{:02d}".format(year, month, last_day)
search_url = (
"https://api.github.com/search/issues?q=repo:pyrevitlabs/pyRevit+is:pr+is:merged+merged:"
+ start_date
+ ".."
+ end_date
+ "&per_page=100"
)
data = get_github_data(search_url)
return data.get("items", []) if data else []
def get_issue_closer(issue_number):
"""Get who closed a specific issue by checking events"""
events_url = (
"https://api.github.com/repos/pyrevitlabs/pyRevit/issues/"
+ str(issue_number)
+ "/events?per_page=100"
)
data = get_github_data(events_url)
if not data:
return None
for event in data:
if event.get("event") == "closed":
actor = event.get("actor")
if actor:
return actor.get("login")
return None
def get_pr_merger(pr_number):
"""Get who merged a specific PR by checking events"""
events_url = (
"https://api.github.com/repos/pyrevitlabs/pyRevit/issues/"
+ str(pr_number)
+ "/events?per_page=100"
)
data = get_github_data(events_url)
if not data:
return None
for event in data:
if event.get("event") == "merged":
actor = event.get("actor")
if actor:
return actor.get("login")
return None
def get_pr_comments(pr_number):
"""Get all comments for a specific PR and count by user"""
comments_url = (
"https://api.github.com/repos/pyrevitlabs/pyRevit/issues/"
+ str(pr_number)
+ "/comments?per_page=100"
)
data = get_github_data(comments_url)
if not data:
return {}
comment_counts = defaultdict(int)
for comment in data:
user = comment.get("user", {}).get("login")
if user:
comment_counts[user] += 1
return comment_counts
def process_month(year, month, query_type="issues"):
"""Process a single month and return results"""
month_names = [
"",
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December",
]
month_name = month_names[month]
results = {}
if query_type in ["issues", "both"]:
closed_issues = get_closed_issues_for_month(year, month)
if closed_issues:
closer_counts = defaultdict(int)
for issue in closed_issues:
closer = get_issue_closer(issue.get("number"))
if closer:
closer_counts[closer] += 1
results["issues"] = (closer_counts, len(closed_issues))
if query_type in ["prs", "both"]:
merged_prs = get_merged_prs_for_month(year, month)
if merged_prs:
merger_counts = defaultdict(int)
creator_counts = defaultdict(int)
comment_counts = defaultdict(int)
for pr in merged_prs:
# Track who merged the PR
merger = get_pr_merger(pr.get("number"))
if merger:
merger_counts[merger] += 1
# Track who created the PR
creator = pr.get("user", {}).get("login")
if creator:
creator_counts[creator] += 1
# Track comments on the PR
pr_comments = get_pr_comments(pr.get("number"))
for user, count in pr_comments.items():
comment_counts[user] += count
results["prs"] = (merger_counts, len(merged_prs))
results["pr_creators"] = (creator_counts, len(merged_prs))
results["pr_comments"] = (comment_counts, len(merged_prs))
return results
def process_year(year, query_type="issues"):
"""Process all months of a year and generate report"""
print("Processing " + str(year) + " (" + query_type + ")...")
month_names = [
"",
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December",
]
yearly_issue_counts = defaultdict(int)
yearly_pr_counts = defaultdict(int)
yearly_pr_creator_counts = defaultdict(int)
yearly_pr_comment_counts = defaultdict(int)
yearly_total_issues = 0
yearly_total_prs = 0
monthly_results = []
for month in range(1, 13):
month_name = month_names[month]
print(" " + month_name + "...", end=" ")
results = process_month(year, month, query_type)
if results:
monthly_results.append((month_name, results))
if "issues" in results:
closer_counts, total_issues = results["issues"]
yearly_total_issues += total_issues
for closer, count in closer_counts.items():
yearly_issue_counts[closer] += count
if "prs" in results:
merger_counts, total_prs = results["prs"]
yearly_total_prs += total_prs
for merger, count in merger_counts.items():
yearly_pr_counts[merger] += count
if "pr_creators" in results:
creator_counts, total_prs = results["pr_creators"]
for creator, count in creator_counts.items():
yearly_pr_creator_counts[creator] += count
if "pr_comments" in results:
comment_counts, total_prs = results["pr_comments"]
for user, count in comment_counts.items():
yearly_pr_comment_counts[user] += count
print("✓")
if month < 12:
time.sleep(0.2)
# Generate report
report_lines = []
report_lines.append("=== pyRevit GitHub Activity Report - " + str(year) + " ===")
report_lines.append("Repository: pyrevitlabs/pyRevit")
report_lines.append(
"Generated: " + str(datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
)
report_lines.append("")
if query_type in ["issues", "both"]:
report_lines.append("=== CLOSED ISSUES ===")
report_lines.append("-" * 50)
for month_name, results in monthly_results:
if "issues" in results:
closer_counts, total_issues = results["issues"]
if total_issues > 0:
report_lines.append(
month_name
+ " "
+ str(year)
+ ": "
+ str(total_issues)
+ " issues"
)
sorted_closers = sorted(
closer_counts.items(), key=lambda x: x[1], reverse=True
)
for closer, count in sorted_closers:
report_lines.append(
" " + closer + ": " + str(count) + " issues"
)
report_lines.append("")
report_lines.append(
"Total issues closed in " + str(year) + ": " + str(yearly_total_issues)
)
report_lines.append("")
if yearly_issue_counts:
report_lines.append("Issues closed by each person (yearly total):")
report_lines.append("-" * 50)
sorted_closers = sorted(
yearly_issue_counts.items(), key=lambda x: x[1], reverse=True
)
for closer, count in sorted_closers:
report_lines.append(closer + ": " + str(count) + " issues")
report_lines.append("")
if query_type in ["prs", "both"]:
report_lines.append("=== MERGED PULL REQUESTS ===")
report_lines.append("-" * 50)
for month_name, results in monthly_results:
if "prs" in results:
merger_counts, total_prs = results["prs"]
if total_prs > 0:
report_lines.append(
month_name + " " + str(year) + ": " + str(total_prs) + " PRs"
)
# Show who merged PRs
sorted_mergers = sorted(
merger_counts.items(), key=lambda x: x[1], reverse=True
)
for merger, count in sorted_mergers:
report_lines.append(
" Merged by " + merger + ": " + str(count) + " PRs"
)
# Show who created PRs
if "pr_creators" in results:
creator_counts, _ = results["pr_creators"]
sorted_creators = sorted(
creator_counts.items(), key=lambda x: x[1], reverse=True
)
for creator, count in sorted_creators:
report_lines.append(
" Created by " + creator + ": " + str(count) + " PRs"
)
# Show comment activity
if "pr_comments" in results:
comment_counts, _ = results["pr_comments"]
if comment_counts:
sorted_commenters = sorted(
comment_counts.items(), key=lambda x: x[1], reverse=True
)
for commenter, count in sorted_commenters:
report_lines.append(
" Comments by "
+ commenter
+ ": "
+ str(count)
+ " comments"
)
report_lines.append("")
report_lines.append(
"Total PRs merged in " + str(year) + ": " + str(yearly_total_prs)
)
report_lines.append("")
if yearly_pr_counts:
report_lines.append("PRs merged by each person (yearly total):")
report_lines.append("-" * 50)
sorted_mergers = sorted(
yearly_pr_counts.items(), key=lambda x: x[1], reverse=True
)
for merger, count in sorted_mergers:
report_lines.append(merger + ": " + str(count) + " PRs")
report_lines.append("")
if yearly_pr_creator_counts:
report_lines.append("PRs created by each person (yearly total):")
report_lines.append("-" * 50)
sorted_creators = sorted(
yearly_pr_creator_counts.items(), key=lambda x: x[1], reverse=True
)
for creator, count in sorted_creators:
report_lines.append(creator + ": " + str(count) + " PRs")
report_lines.append("")
if yearly_pr_comment_counts:
report_lines.append("PR comments by each person (yearly total):")
report_lines.append("-" * 50)
sorted_commenters = sorted(
yearly_pr_comment_counts.items(), key=lambda x: x[1], reverse=True
)
for commenter, count in sorted_commenters:
report_lines.append(commenter + ": " + str(count) + " comments")
report_lines.append("")
# Save to file
filename = "pyrevit_report_" + str(year) + "_" + query_type + ".txt"
with open(filename, "w") as f:
for line in report_lines:
f.write(line + "\n")
# Print summary
print("\n=== SUMMARY ===")
for line in report_lines:
print(line)
print("\nReport saved to: " + filename)
# Open file
try:
if os.name == "nt": # Windows
os.startfile(filename)
elif os.name == "posix": # macOS and Linux
os.system('open "' + filename + '"')
except:
print(
"Could not automatically open the file. Please open "
+ filename
+ " manually."
)
def main():
import sys
# Check authentication
github_token = os.environ.get("GITHUBTOKEN")
if github_token:
print("✓ GitHub token found - using authenticated requests")
else:
print("⚠ No GitHub token found - using unauthenticated requests")
# Parse command line arguments
if len(sys.argv) >= 4:
year = int(sys.argv[1])
query_type = sys.argv[2].lower()
if sys.argv[3].lower() == "all":
process_year(year, query_type)
else:
month = int(sys.argv[3])
results = process_month(year, month, query_type)
print(
"Results for " + str(month) + "/" + str(year) + " (" + query_type + "):"
)
for key, (counts, total) in results.items():
if key == "prs":
print("PRS MERGED: " + str(total))
for user, count in sorted(
counts.items(), key=lambda x: x[1], reverse=True
):
print(" Merged by " + user + ": " + str(count))
elif key == "pr_creators":
print("PRS CREATED: " + str(total))
for user, count in sorted(
counts.items(), key=lambda x: x[1], reverse=True
):
print(" Created by " + user + ": " + str(count))
elif key == "pr_comments":
print("PR COMMENTS: " + str(total))
for user, count in sorted(
counts.items(), key=lambda x: x[1], reverse=True
):
print(" Comments by " + user + ": " + str(count))
else:
print(key.upper() + ": " + str(total))
for user, count in sorted(
counts.items(), key=lambda x: x[1], reverse=True
):
print(" " + user + ": " + str(count))
elif len(sys.argv) >= 3:
year = int(sys.argv[1])
if sys.argv[2].lower() == "all":
process_year(year, "issues")
else:
month = int(sys.argv[2])
results = process_month(year, month, "issues")
print("Results for " + str(month) + "/" + str(year) + " (issues):")
for key, (counts, total) in results.items():
if key == "prs":
print("PRS MERGED: " + str(total))
for user, count in sorted(
counts.items(), key=lambda x: x[1], reverse=True
):
print(" Merged by " + user + ": " + str(count))
elif key == "pr_creators":
print("PRS CREATED: " + str(total))
for user, count in sorted(
counts.items(), key=lambda x: x[1], reverse=True
):
print(" Created by " + user + ": " + str(count))
elif key == "pr_comments":
print("PR COMMENTS: " + str(total))
for user, count in sorted(
counts.items(), key=lambda x: x[1], reverse=True
):
print(" Comments by " + user + ": " + str(count))
else:
print(key.upper() + ": " + str(total))
for user, count in sorted(
counts.items(), key=lambda x: x[1], reverse=True
):
print(" " + user + ": " + str(count))
else:
print("Usage:")
print(" python script_new.py YEAR TYPE MONTH # Single month")
print(" python script_new.py YEAR TYPE all # All months")
print(" python script_new.py YEAR MONTH # Single month (issues only)")
print(" python script_new.py YEAR all # All months (issues only)")
print()
print("Types: issues, prs, both")
print("Examples:")
print(" python script_new.py 2024 issues 8 # August 2024 issues")
print(" python script_new.py 2024 prs all # All 2024 PRs")
print(" python script_new.py 2024 both all # All 2024 issues and PRs")
if __name__ == "__main__":
main()
Results for 2025
=== pyRevit GitHub Activity Report - 2025 ===
Repository: pyrevitlabs/pyRevit
Generated: 2025-09-18 14:37:06
=== CLOSED ISSUES ===
January 2025: 35 issues
jmcouffin: 24 issues
sanzoghenzo: 5 issues
belphegore1: 1 issues
dosymep: 1 issues
sergeykahn: 1 issues
archeduardo5: 1 issues
svalenziano: 1 issues
github-actions[bot]: 1 issues
February 2025: 17 issues
jmcouffin: 9 issues
sanzoghenzo: 3 issues
wxWANG0128: 1 issues
CMIller3906: 1 issues
szcsaba87: 1 issues
baaswietse: 1 issues
agialanella: 1 issues
March 2025: 10 issues
jmcouffin: 8 issues
rbunns: 1 issues
zsenarchitect: 1 issues
April 2025: 8 issues
jmcouffin: 6 issues
KonradZaremba: 1 issues
github-actions[bot]: 1 issues
May 2025: 8 issues
jmcouffin: 7 issues
sanzoghenzo: 1 issues
June 2025: 11 issues
jmcouffin: 7 issues
ScottMycoMech: 1 issues
sanzoghenzo: 1 issues
Wanderson97-ss: 1 issues
olalancette: 1 issues
July 2025: 4 issues
jmcouffin: 2 issues
arkitek2s: 1 issues
JCurvey: 1 issues
August 2025: 26 issues
jmcouffin: 21 issues
tay0thman: 3 issues
Wurschdhaud: 1 issues
MohamedAsli: 1 issues
September 2025: 16 issues
jmcouffin: 7 issues
MohamedAsli: 7 issues
Emmawadlow: 1 issues
RichardPinka: 1 issues
Total issues closed in 2025: 135
Issues closed by each person (yearly total):
jmcouffin: 91 issues
sanzoghenzo: 10 issues
MohamedAsli: 8 issues
tay0thman: 3 issues
github-actions[bot]: 2 issues
belphegore1: 1 issues
dosymep: 1 issues
sergeykahn: 1 issues
archeduardo5: 1 issues
svalenziano: 1 issues
wxWANG0128: 1 issues
CMIller3906: 1 issues
szcsaba87: 1 issues
baaswietse: 1 issues
agialanella: 1 issues
rbunns: 1 issues
zsenarchitect: 1 issues
KonradZaremba: 1 issues
ScottMycoMech: 1 issues
Wanderson97-ss: 1 issues
olalancette: 1 issues
arkitek2s: 1 issues
JCurvey: 1 issues
Wurschdhaud: 1 issues
Emmawadlow: 1 issues
RichardPinka: 1 issues
=== MERGED PULL REQUESTS ===
January 2025: 25 PRs
Merged by jmcouffin: 23 PRs
Merged by sanzoghenzo: 2 PRs
Created by jmcouffin: 11 PRs
Created by sanzoghenzo: 7 PRs
Created by thumDer: 2 PRs
Created by dependabot[bot]: 2 PRs
Created by devloai[bot]: 1 PRs
Created by reformstudios: 1 PRs
Created by Malouche-git: 1 PRs
Comments by github-actions[bot]: 440 comments
Comments by jmcouffin: 57 comments
Comments by sanzoghenzo: 25 comments
Comments by devloai[bot]: 6 comments
Comments by dosymep: 2 comments
Comments by thumDer: 1 comments
Comments by Malouche-git: 1 comments
February 2025: 24 PRs
Merged by jmcouffin: 21 PRs
Merged by sanzoghenzo: 3 PRs
Created by jmcouffin: 5 PRs
Created by dependabot[bot]: 5 PRs
Created by nasmovk: 3 PRs
Created by thumDer: 2 PRs
Created by sanzoghenzo: 2 PRs
Created by Malouche-git: 2 PRs
Created by tay0thman: 1 PRs
Created by mangrove-art: 1 PRs
Created by devloai[bot]: 1 PRs
Created by jorisvandermeulen: 1 PRs
Created by trgiangv: 1 PRs
Comments by github-actions[bot]: 142 comments
Comments by jmcouffin: 26 comments
Comments by devloai[bot]: 9 comments
Comments by sanzoghenzo: 7 comments
Comments by nasmovk: 6 comments
Comments by Malouche-git: 6 comments
Comments by thumDer: 2 comments
Comments by jorisvandermeulen: 2 comments
Comments by trgiangv: 2 comments
March 2025: 12 PRs
Merged by jmcouffin: 12 PRs
Created by dependabot[bot]: 5 PRs
Created by jmcouffin: 3 PRs
Created by Wurschdhaud: 2 PRs
Created by jonatanjacobsson: 1 PRs
Created by 924312: 1 PRs
Comments by github-actions[bot]: 171 comments
Comments by jmcouffin: 2 comments
April 2025: 25 PRs
Merged by jmcouffin: 25 PRs
Created by jmcouffin: 7 PRs
Created by dependabot[bot]: 6 PRs
Created by tay0thman: 5 PRs
Created by Wurschdhaud: 1 PRs
Created by devloai[bot]: 1 PRs
Created by jonatanjacobsson: 1 PRs
Created by nodatasheet: 1 PRs
Created by leyarx: 1 PRs
Created by iorhanV: 1 PRs
Created by dnenov: 1 PRs
Comments by github-actions[bot]: 524 comments
Comments by jmcouffin: 23 comments
Comments by devloai[bot]: 9 comments
Comments by tay0thman: 6 comments
Comments by dnenov: 2 comments
Comments by nodatasheet: 1 comments
Comments by sanzoghenzo: 1 comments
May 2025: 15 PRs
Merged by jmcouffin: 15 PRs
Created by dependabot[bot]: 5 PRs
Created by jmcouffin: 4 PRs
Created by tay0thman: 3 PRs
Created by Wurschdhaud: 1 PRs
Created by 924312: 1 PRs
Created by nasmovk: 1 PRs
Comments by github-actions[bot]: 290 comments
Comments by jmcouffin: 5 comments
Comments by devloai[bot]: 3 comments
June 2025: 17 PRs
Merged by jmcouffin: 17 PRs
Created by jmcouffin: 7 PRs
Created by dependabot[bot]: 7 PRs
Created by frank-e-loftus: 1 PRs
Created by OnePowerUser88: 1 PRs
Created by jaredholloway94: 1 PRs
Comments by github-actions[bot]: 160 comments
Comments by devloai[bot]: 7 comments
Comments by jmcouffin: 4 comments
Comments by jaredholloway94: 2 comments
July 2025: 11 PRs
Merged by jmcouffin: 11 PRs
Created by dependabot[bot]: 6 PRs
Created by rayala30: 1 PRs
Created by 924312: 1 PRs
Created by Wurschdhaud: 1 PRs
Created by tay0thman: 1 PRs
Created by jmcouffin: 1 PRs
Comments by github-actions[bot]: 530 comments
Comments by sanzoghenzo: 4 comments
Comments by Wurschdhaud: 2 comments
Comments by jmcouffin: 1 comments
August 2025: 31 PRs
Merged by jmcouffin: 29 PRs
Merged by tay0thman: 2 PRs
Created by jmcouffin: 11 PRs
Created by dependabot[bot]: 5 PRs
Created by MohamedAsli: 4 PRs
Created by tay0thman: 3 PRs
Created by Wurschdhaud: 3 PRs
Created by Denver-22: 3 PRs
Created by czwangxtt: 1 PRs
Created by Behind100proxies: 1 PRs
Comments by github-actions[bot]: 949 comments
Comments by jmcouffin: 22 comments
Comments by devloai[bot]: 8 comments
Comments by MohamedAsli: 7 comments
Comments by Denver-22: 3 comments
Comments by sanzoghenzo: 2 comments
Comments by tay0thman: 1 comments
Comments by Behind100proxies: 1 comments
September 2025: 20 PRs
Merged by jmcouffin: 19 PRs
Merged by MohamedAsli: 1 PRs
Created by Wurschdhaud: 7 PRs
Created by dependabot[bot]: 6 PRs
Created by MohamedAsli: 3 PRs
Created by IGF-Zhang: 1 PRs
Created by jmcouffin: 1 PRs
Created by frank-e-loftus: 1 PRs
Created by nasmovk: 1 PRs
Comments by github-actions[bot]: 152 comments
Comments by jmcouffin: 15 comments
Comments by Wurschdhaud: 2 comments
Comments by MohamedAsli: 1 comments
Total PRs merged in 2025: 180
PRs merged by each person (yearly total):
jmcouffin: 172 PRs
sanzoghenzo: 5 PRs
tay0thman: 2 PRs
MohamedAsli: 1 PRs
PRs created by each person (yearly total):
jmcouffin: 50 PRs
dependabot[bot]: 47 PRs
Wurschdhaud: 15 PRs
tay0thman: 13 PRs
sanzoghenzo: 9 PRs
MohamedAsli: 7 PRs
nasmovk: 5 PRs
thumDer: 4 PRs
devloai[bot]: 3 PRs
Malouche-git: 3 PRs
924312: 3 PRs
Denver-22: 3 PRs
jonatanjacobsson: 2 PRs
frank-e-loftus: 2 PRs
reformstudios: 1 PRs
mangrove-art: 1 PRs
jorisvandermeulen: 1 PRs
trgiangv: 1 PRs
nodatasheet: 1 PRs
leyarx: 1 PRs
iorhanV: 1 PRs
dnenov: 1 PRs
OnePowerUser88: 1 PRs
jaredholloway94: 1 PRs
rayala30: 1 PRs
czwangxtt: 1 PRs
Behind100proxies: 1 PRs
IGF-Zhang: 1 PRs
PR comments by each person (yearly total):
github-actions[bot]: 3358 comments
jmcouffin: 155 comments
devloai[bot]: 42 comments
sanzoghenzo: 39 comments
MohamedAsli: 8 comments
Malouche-git: 7 comments
tay0thman: 7 comments
nasmovk: 6 comments
Wurschdhaud: 4 comments
thumDer: 3 comments
Denver-22: 3 comments
dosymep: 2 comments
jorisvandermeulen: 2 comments
trgiangv: 2 comments
dnenov: 2 comments
jaredholloway94: 2 comments
nodatasheet: 1 comments
Behind100proxies: 1 comments