Skip to content

Commit 3f58cdd

Browse files
authored
Create builde-repos-db.yml
1 parent 877199e commit 3f58cdd

1 file changed

Lines changed: 237 additions & 0 deletions

File tree

Lines changed: 237 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,237 @@
1+
name: Build Repositories Database
2+
3+
on:
4+
schedule:
5+
- cron: '0 0 * * 0' # Runs every Sunday at midnight UTC
6+
workflow_dispatch:
7+
8+
permissions:
9+
contents: write
10+
11+
jobs:
12+
build-json:
13+
runs-on: ubuntu-latest
14+
15+
steps:
16+
- name: Checkout main repository
17+
uses: actions/checkout@v4
18+
19+
- name: Setup Node.js
20+
uses: actions/setup-node@v4
21+
with:
22+
node-version: '20'
23+
24+
- name: Fetch data and build db.json
25+
uses: actions/github-script@v7
26+
with:
27+
script: |
28+
const fs = require('fs');
29+
30+
// Utility to handle API rate limits via delay
31+
const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
32+
33+
async function generateDatabase() {
34+
const username = 'Pro-bandey';
35+
36+
// Repositories to exclude
37+
const excludedRepos = [
38+
'pro-bandey',
39+
'pro-bandey.github.io',
40+
'.github'
41+
].map(repo => repo.toLowerCase().trim());
42+
43+
console.log(`Fetching repositories for ${username}...`);
44+
45+
// Fetch all public repositories
46+
const reposResponse = await github.rest.repos.listForUser({
47+
username: username,
48+
type: 'public',
49+
per_page: 100
50+
});
51+
52+
// Filter repositories BEFORE processing
53+
const repositories = reposResponse.data.filter(repo => {
54+
const repoName = repo.name.toLowerCase().trim();
55+
56+
// Skip private repositories
57+
if (repo.private) {
58+
console.log(`Skipping private repository: ${repo.name}`);
59+
return false;
60+
}
61+
62+
// Skip excluded repositories
63+
if (excludedRepos.includes(repoName)) {
64+
console.log(`Skipping excluded repository: ${repo.name}`);
65+
return false;
66+
}
67+
68+
return true;
69+
});
70+
71+
console.log(
72+
'Repositories after filtering:',
73+
repositories.map(r => r.name)
74+
);
75+
76+
const db = [];
77+
const repoDetails = {};
78+
79+
try {
80+
console.log('Fetching repository GraphQL details (batched)...');
81+
82+
// Batch GraphQL query to avoid secondary rate limits
83+
const batchSize = 10;
84+
for (let i = 0; i < repositories.length; i += batchSize) {
85+
const batch = repositories.slice(i, i + batchSize);
86+
87+
// Construct dynamic aliases for the batched query
88+
let queryFragments = batch.map((repo, idx) => `
89+
repo_${idx}: repository(owner: "${username}", name: "${repo.name}") {
90+
name
91+
openGraphImageUrl
92+
defaultBranchRef {
93+
target {
94+
... on Commit {
95+
history {
96+
totalCount
97+
}
98+
}
99+
}
100+
}
101+
}
102+
`).join('\n');
103+
104+
const query = `query { ${queryFragments} }`;
105+
106+
const result = await github.graphql(query);
107+
108+
// Extract results back to our map
109+
Object.values(result).forEach(node => {
110+
if (node && node.name) {
111+
repoDetails[node.name] = {
112+
ogImage: node.openGraphImageUrl,
113+
commits: node.defaultBranchRef?.target?.history?.totalCount || 0
114+
};
115+
}
116+
});
117+
118+
// Sleep between batches to prevent secondary rate limiting
119+
console.log(`Batch fetched. Sleeping for 1000ms...`);
120+
await sleep(1000);
121+
}
122+
} catch (err) {
123+
console.warn(
124+
'Could not fetch GraphQL details:',
125+
err.message
126+
);
127+
}
128+
129+
// Process repositories sequentially with deliberate pacing
130+
for (const repo of repositories) {
131+
console.log(`Processing: ${repo.name}`);
132+
133+
// Fetch languages
134+
let languagesData = {};
135+
let languageBytes = {};
136+
137+
try {
138+
const langResponse = await github.rest.repos.listLanguages({
139+
owner: username,
140+
repo: repo.name
141+
});
142+
143+
const languages = langResponse.data;
144+
145+
const totalBytes = Object.values(languages).reduce(
146+
(a, b) => a + b,
147+
0
148+
);
149+
150+
if (totalBytes > 0) {
151+
for (const [lang, bytes] of Object.entries(languages)) {
152+
languagesData[lang] = parseFloat(
153+
((bytes / totalBytes) * 100).toFixed(1)
154+
);
155+
languageBytes[lang] = bytes;
156+
}
157+
}
158+
} catch (err) {
159+
console.warn(
160+
`Could not fetch languages for ${repo.name}:`,
161+
err.message
162+
);
163+
}
164+
165+
// Check README existence
166+
let readmeExists = false;
167+
168+
try {
169+
await github.rest.repos.getReadme({
170+
owner: username,
171+
repo: repo.name
172+
});
173+
174+
readmeExists = true;
175+
} catch (err) {
176+
readmeExists = false;
177+
}
178+
179+
const details = repoDetails[repo.name] || {};
180+
181+
// Add repository to database
182+
db.push({
183+
Repo: repo.name,
184+
Date: repo.created_at,
185+
UpdatedAt: repo.pushed_at || repo.updated_at,
186+
Status: 'Pub',
187+
Desc: repo.description || 'No description provided.',
188+
Langs: languagesData,
189+
LangBytes: languageBytes,
190+
PreviewUrl: repo.homepage || '',
191+
ReadMeIs: readmeExists,
192+
Banner: details.ogImage || '',
193+
Commits: details.commits || 0,
194+
Stars: repo.stargazers_count || 0,
195+
Forks: repo.forks_count || 0
196+
});
197+
198+
// Crucial: Sleep 1.5s between REST API requests to respect GitHub Secondary Rate Limits
199+
await sleep(1500);
200+
}
201+
202+
// Save db.json
203+
fs.writeFileSync('db.json', JSON.stringify(db, null, 2));
204+
205+
console.log(
206+
`Successfully created db.json with ${db.length} records.`
207+
);
208+
}
209+
210+
await generateDatabase();
211+
212+
- name: Deploy db.json to db branch
213+
run: |
214+
git config --global user.name "github-actions[bot]"
215+
git config --global user.email "github-actions[bot]@users.noreply.github.com"
216+
217+
# Save generated file temporarily
218+
mv db.json /tmp/db.json
219+
220+
# Fetch db branch if it exists
221+
git fetch origin db || true
222+
223+
# Checkout db branch or create it
224+
git checkout db || git checkout --orphan db
225+
226+
# Remove old files
227+
find . -mindepth 1 -maxdepth 1 ! -name '.git' -exec rm -rf {} +
228+
229+
# Restore db.json
230+
mv /tmp/db.json db.json
231+
232+
# Commit changes
233+
git add db.json
234+
git commit -m "Automated update of repository database" || echo "No changes to commit"
235+
236+
# Force push db branch
237+
git push origin db --force

0 commit comments

Comments
 (0)