Skip to content

Commit 634a083

Browse files
committed
Scipt that check which repo has private sec enabled
If archived or in an aignore list, print in yellow with (archived) or (ignored) Green if enabled Red if disabled
1 parent c6236c0 commit 634a083

File tree

2 files changed

+111
-0
lines changed

2 files changed

+111
-0
lines changed

private_sec_ignore.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
jupyterlab/scipy2018-jupyterlab-tutorial
2+
ipython/ipython.github.com

tools/private_sec_report.py

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
"""GitHub Organization Activity Tracker
2+
3+
This module tracks and reports the last activity of members across GitHub organizations.
4+
It implements disk-based caching to minimize API requests and respect rate limits.
5+
"""
6+
7+
import os
8+
import sys
9+
import asyncio
10+
import aiohttp
11+
from rich import print
12+
from datetime import datetime, timezone, timedelta
13+
import humanize
14+
from itertools import count
15+
import diskcache
16+
import pathlib
17+
from typing import Optional, List, Dict
18+
import argparse
19+
20+
default_orgs = [
21+
"binder-examples",
22+
"binderhub-ci-repos",
23+
"ipython",
24+
"jupyter",
25+
"jupyter-attic",
26+
"jupyter-book",
27+
"jupyter-governance",
28+
"jupyter-incubator",
29+
"jupyter-resources",
30+
"jupyter-server",
31+
"jupyter-standard",
32+
"jupyter-standards",
33+
"jupyter-widgets",
34+
"jupyter-xeus",
35+
"jupytercon",
36+
"jupyterhub",
37+
"jupyterlab",
38+
"voila-dashboards",
39+
"voila-gallery",
40+
"pickleshare",
41+
]
42+
43+
token = os.getenv("GH_TOKEN")
44+
if not token:
45+
print("[red]Error: GH_TOKEN environment variable not set[/red]")
46+
exit(1)
47+
48+
headers = {
49+
"Authorization": f"token {token}",
50+
"Accept": "application/vnd.github.v3+json",
51+
}
52+
53+
54+
async def list_repos(orgs):
55+
async with aiohttp.ClientSession() as session:
56+
tasks = [
57+
session.get(f"https://api.github.com/orgs/{org}/repos", headers=headers)
58+
for org in orgs
59+
]
60+
for org, response in zip(orgs, await asyncio.gather(*tasks)):
61+
repos = await response.json()
62+
for repo in repos:
63+
yield org, repo["name"]
64+
65+
66+
async def get_private_report(session, org, repo):
67+
private_report_url = (
68+
f"https://api.github.com/repos/{org}/{repo}/private-vulnerability-reporting"
69+
)
70+
async with session.get(
71+
f"https://api.github.com/repos/{org}/{repo}", headers=headers
72+
) as repo_response:
73+
repo_info = await repo_response.json()
74+
archived = repo_info.get("archived", False)
75+
async with session.get(private_report_url, headers=headers) as response:
76+
if response.status == 200:
77+
return org, repo, (await response.json()).get("enabled", False), archived
78+
else:
79+
return org, repo, False, archived
80+
81+
82+
async def main():
83+
with pathlib.Path("private_sec_ignore.txt").open("r") as ignore_file:
84+
ignore_repos = [line.strip() for line in ignore_file.readlines()]
85+
86+
async with aiohttp.ClientSession() as session:
87+
tasks = []
88+
async for org, repo in list_repos(default_orgs):
89+
tasks.append(get_private_report(session, org, repo))
90+
91+
results = await asyncio.gather(*tasks)
92+
prev_org = None
93+
for org, repo, enabled, archived in results:
94+
if org != prev_org:
95+
print()
96+
print(f"[bold]{org}[/bold]")
97+
prev_org = org
98+
if enabled:
99+
print(f" [green]{repo}: {enabled}[/green]")
100+
else:
101+
if archived:
102+
print(f" [yellow]{org}/{repo}: {enabled} (archived)[/yellow]")
103+
elif f"{org}/{repo}" in ignore_repos:
104+
print(f" [yellow]{org}/{repo}: {enabled} (ignored)[/yellow]")
105+
else:
106+
print(f" [red]{org}/{repo}: {enabled}[/red]")
107+
108+
109+
asyncio.run(main())

0 commit comments

Comments
 (0)