Skip to content

Commit 0f3da9b

Browse files
authored
Add a Collaborator Check
1 parent 45d79f7 commit 0f3da9b

File tree

1 file changed

+131
-0
lines changed

1 file changed

+131
-0
lines changed
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
name: Collaborator Check
2+
3+
on:
4+
workflow_dispatch:
5+
6+
jobs:
7+
check:
8+
runs-on: ubuntu-latest
9+
steps:
10+
- uses: actions/github-script@v7
11+
with:
12+
script: |
13+
const ORGANIZATION = "Magisk-Modules-Alt-Repo";
14+
const EXCLUDED_USERS = ["Atrate", "DerGoogler", "Fox2Code", "HuskyDG", "tytydraco"];
15+
const EXCLUDED_REPOS = ["HuskyDG_BootloopSaver", "vintf-bypass", "mkshrc", "node", "xhhttp"];
16+
const EXCLUDED_TOPIC_KEYWORD = "non-module";
17+
18+
async function fetchAllRepositories(org) {
19+
const repos = [];
20+
let page = 1;
21+
22+
while (true) {
23+
const { data } = await github.rest.repos.listForOrg({
24+
org,
25+
type: "all",
26+
per_page: 100,
27+
page,
28+
});
29+
30+
if (data.length === 0) break;
31+
32+
repos.push(...data);
33+
page++;
34+
}
35+
36+
return repos;
37+
}
38+
39+
async function fetchRepositoryTopics(org, repo) {
40+
try {
41+
const { data } = await github.rest.repos.getAllTopics({
42+
owner: org,
43+
repo,
44+
});
45+
return data.names || [];
46+
} catch (error) {
47+
console.error(`Error fetching topics for ${repo}: ${error.message}`);
48+
return [];
49+
}
50+
}
51+
52+
async function fetchCollaborators(org, repo) {
53+
try {
54+
const { data } = await github.rest.repos.listCollaborators({
55+
owner: org,
56+
repo,
57+
affiliation: "all",
58+
});
59+
60+
return data.map(user => user.login);
61+
} catch (error) {
62+
if (error.status === 404) {
63+
console.error(`Repository "${repo}" is not accessible.`);
64+
return [];
65+
}
66+
console.error(`Error fetching collaborators for ${repo}: ${error.message}`);
67+
return [];
68+
}
69+
}
70+
71+
async function processRepositories(org) {
72+
const allRepos = await fetchAllRepositories(org);
73+
74+
if (allRepos.length === 0) {
75+
console.log(`No repositories found for organization "${org}".`);
76+
return;
77+
}
78+
79+
console.log(`Found ${allRepos.length} repositories. Filtering excluded repositories...`);
80+
81+
const filteredRepos = [];
82+
for (const repo of allRepos) {
83+
const { name } = repo;
84+
85+
if (EXCLUDED_REPOS.includes(name)) {
86+
console.log(`Excluding repository "${name}" (explicit exclusion).`);
87+
continue;
88+
}
89+
90+
const topics = await fetchRepositoryTopics(org, name);
91+
if (topics.includes(EXCLUDED_TOPIC_KEYWORD)) {
92+
console.log(`Excluding repository "${name}" (topic "${EXCLUDED_TOPIC_KEYWORD}" found).`);
93+
continue;
94+
}
95+
96+
filteredRepos.push(name);
97+
}
98+
99+
if (filteredRepos.length === 0) {
100+
console.log(`No repositories to process after exclusions.`);
101+
return;
102+
}
103+
104+
console.log(`Processing ${filteredRepos.length} repositories after exclusions...`);
105+
106+
let unmaintainedCount = 0;
107+
108+
for (const repo of filteredRepos) {
109+
const collaborators = await fetchCollaborators(org, repo);
110+
const filteredCollaborators = collaborators.filter(user => !EXCLUDED_USERS.includes(user));
111+
112+
if (filteredCollaborators.length > 0) {
113+
console.log(`Collaborators for repository "${repo}":`);
114+
filteredCollaborators.forEach(user => console.log(`- ${user}`));
115+
} else {
116+
console.log(`No collaborators found (after exclusions) for repository "${repo}".`);
117+
unmaintainedCount++;
118+
}
119+
}
120+
121+
122+
const totalRepos = filteredRepos.length;
123+
const unmaintainedPercentage = ((unmaintainedCount / totalRepos) * 100).toFixed(2);
124+
125+
console.log(`\nSummary:`);
126+
console.log(`- Total repositories processed: ${totalRepos}`);
127+
console.log(`- Unmaintained repositories (no collaborators): ${unmaintainedCount}`);
128+
console.log(`- Percentage of unmaintained repositories: ${unmaintainedPercentage}%`);
129+
}
130+
131+
processRepositories(ORGANIZATION);

0 commit comments

Comments
 (0)