118 lines
2.9 KiB
TypeScript
118 lines
2.9 KiB
TypeScript
import yaml from "js-yaml";
|
|
|
|
type RepoRecord = {
|
|
id: string;
|
|
full_name: string;
|
|
org: string;
|
|
description: string;
|
|
visibility: "public" | "private";
|
|
status: "active" | "archived" | "experimental" | "legacy";
|
|
primary_domain: string | null;
|
|
home_pack: string;
|
|
created_at: string;
|
|
updated_at: string;
|
|
tags: string[];
|
|
owner_handles: string[];
|
|
};
|
|
|
|
type GitHubRepo = {
|
|
name: string;
|
|
full_name: string;
|
|
private: boolean;
|
|
description: string | null;
|
|
created_at: string;
|
|
updated_at: string;
|
|
};
|
|
|
|
const TOKEN = process.env.GITHUB_TOKEN;
|
|
const ORGS = process.env.GITHUB_ORGS?.split(",").map((org) => org.trim()).filter(Boolean) ?? [];
|
|
|
|
async function githubFetch(url: string) {
|
|
const headers: Record<string, string> = {
|
|
Accept: "application/vnd.github+json",
|
|
"User-Agent": "blackroad-os-archive"
|
|
};
|
|
|
|
if (TOKEN) {
|
|
headers.Authorization = `Bearer ${TOKEN}`;
|
|
}
|
|
|
|
const response = await fetch(url, { headers });
|
|
if (!response.ok) {
|
|
throw new Error(`GitHub request failed: ${response.status} ${response.statusText} for ${url}`);
|
|
}
|
|
return response.json();
|
|
}
|
|
|
|
async function fetchReposForOrg(org: string): Promise<RepoRecord[]> {
|
|
const repos: RepoRecord[] = [];
|
|
let page = 1;
|
|
while (true) {
|
|
const url = `https://api.github.com/orgs/${org}/repos?per_page=100&page=${page}`;
|
|
const data: GitHubRepo[] = await githubFetch(url);
|
|
if (!data.length) break;
|
|
|
|
data.forEach((repo) => {
|
|
let id: string;
|
|
if (repo.name.startsWith("blackroad-os-")) {
|
|
id = repo.name.replace(/^blackroad-os-/, "");
|
|
} else {
|
|
id = `other-${repo.name}`;
|
|
console.warn(
|
|
`Repository '${repo.full_name}' does not start with 'blackroad-os-'. Assigned id: '${id}'.`
|
|
);
|
|
}
|
|
repos.push({
|
|
id,
|
|
full_name: repo.full_name,
|
|
org,
|
|
description: repo.description ?? "",
|
|
visibility: repo.private ? "private" : "public",
|
|
status: "active",
|
|
primary_domain: null,
|
|
home_pack: "tbd",
|
|
created_at: repo.created_at,
|
|
updated_at: repo.updated_at,
|
|
tags: [],
|
|
owner_handles: []
|
|
});
|
|
});
|
|
|
|
if (data.length < 100) break;
|
|
page += 1;
|
|
}
|
|
|
|
return repos;
|
|
}
|
|
|
|
export async function scanGithubRepos(): Promise<RepoRecord[]> {
|
|
if (!ORGS.length) {
|
|
throw new Error("GITHUB_ORGS env var is required (comma-separated list).");
|
|
}
|
|
|
|
const results: RepoRecord[] = [];
|
|
for (const org of ORGS) {
|
|
const repos = await fetchReposForOrg(org);
|
|
results.push(...repos);
|
|
}
|
|
|
|
return results;
|
|
}
|
|
|
|
async function main() {
|
|
try {
|
|
const repos = await scanGithubRepos();
|
|
const payload = { repos };
|
|
const yamlOutput = yaml.dump(payload, { lineWidth: 120 });
|
|
process.stdout.write(`# Generated by scan_github_repos.ts\n`);
|
|
process.stdout.write(yamlOutput);
|
|
} catch (error) {
|
|
console.error((error as Error).message);
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
if (require.main === module) {
|
|
main();
|
|
}
|