|
| 1 | +import { mkdir, writeFile } from 'node:fs/promises'; |
| 2 | +import { join } from 'node:path'; |
| 3 | + |
| 4 | +const owner = process.env.GITHUB_REPOSITORY_OWNER ?? 'OpenCoworkAI'; |
| 5 | +const repository = process.env.GITHUB_REPOSITORY?.split('/')[1] ?? 'open-codesign'; |
| 6 | +const token = process.env.GITHUB_TOKEN; |
| 7 | +const outputDirectory = process.env.ACTIVITY_SNAPSHOT_DIR ?? 'repository-activity'; |
| 8 | + |
| 9 | +if (!token) { |
| 10 | + throw new Error('GITHUB_TOKEN is required to collect repository activity snapshots'); |
| 11 | +} |
| 12 | + |
| 13 | +const apiBase = `https://api.github.com/repos/${owner}/${repository}`; |
| 14 | +const headers = { |
| 15 | + accept: 'application/vnd.github+json', |
| 16 | + authorization: `Bearer ${token}`, |
| 17 | + 'x-github-api-version': '2022-11-28', |
| 18 | +}; |
| 19 | + |
| 20 | +async function getJson(path) { |
| 21 | + const response = await fetch(`${apiBase}${path}`, { headers }); |
| 22 | + if (!response.ok) { |
| 23 | + const body = await response.text(); |
| 24 | + throw new Error(`GitHub API ${path} failed with ${response.status}: ${body}`); |
| 25 | + } |
| 26 | + return response.json(); |
| 27 | +} |
| 28 | + |
| 29 | +const fetchedAt = new Date().toISOString(); |
| 30 | +const [views, clones, popularPaths, popularReferrers] = await Promise.all([ |
| 31 | + getJson('/traffic/views'), |
| 32 | + getJson('/traffic/clones'), |
| 33 | + getJson('/traffic/popular/paths'), |
| 34 | + getJson('/traffic/popular/referrers'), |
| 35 | +]); |
| 36 | + |
| 37 | +const snapshot = { |
| 38 | + repository: `${owner}/${repository}`, |
| 39 | + fetched_at: fetchedAt, |
| 40 | + retention_note: |
| 41 | + 'GitHub repository metrics APIs expose only recent aggregate data. This file preserves the current aggregate response without adding product or site telemetry.', |
| 42 | + views, |
| 43 | + clones, |
| 44 | + popular_paths: popularPaths, |
| 45 | + popular_referrers: popularReferrers, |
| 46 | +}; |
| 47 | + |
| 48 | +await mkdir(outputDirectory, { recursive: true }); |
| 49 | +const day = fetchedAt.slice(0, 10); |
| 50 | +await writeFile(join(outputDirectory, `${day}.json`), `${JSON.stringify(snapshot, null, 2)}\n`); |
| 51 | + |
| 52 | +console.log( |
| 53 | + JSON.stringify( |
| 54 | + { |
| 55 | + repository: snapshot.repository, |
| 56 | + fetched_at: snapshot.fetched_at, |
| 57 | + output: `${outputDirectory}/${day}.json`, |
| 58 | + views: { count: views.count, uniques: views.uniques }, |
| 59 | + clones: { count: clones.count, uniques: clones.uniques }, |
| 60 | + top_referrer: popularReferrers[0]?.referrer ?? null, |
| 61 | + top_path: popularPaths[0]?.path ?? null, |
| 62 | + }, |
| 63 | + null, |
| 64 | + 2, |
| 65 | + ), |
| 66 | +); |
0 commit comments