Created
February 6, 2024 17:43
-
-
Save smeijer/2d29f29f5663103a74879d60f7a59b06 to your computer and use it in GitHub Desktop.
sync github repositories
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/bin/env node | |
import fs from 'fs'; | |
import { promisify } from 'util'; | |
import path from 'path'; | |
import { spawn } from 'child_process'; | |
const fsExists = promisify(fs.exists); | |
if (!process.env.GITHUB_TOKEN) throw new Error("process.env.GITHUB_TOKEN is required"); | |
if (!process.env.GITHUB_USER) throw new Error("process.env.GITHUB_USER is required"); | |
async function* fetchRepositoriesForUser(user) { | |
let page = 1; | |
let perPage = 50; | |
while (true) { | |
const url = `https://api.github.com/users/${user}/repos?per_page=${perPage}&page=${page}`; | |
const response = await fetch(url, { | |
headers: { | |
'Authorization': `token ${process.env.GITHUB_TOKEN}` | |
} | |
}); | |
if (!response.ok) { | |
throw new Error(`GitHub API responded with a status of ${response.status}`); | |
} | |
const result = await response.json(); | |
for (const repo of result) { | |
yield repo; | |
} | |
if (result.length < perPage) return; | |
page++; | |
} | |
}; | |
function git(command, cwd) { | |
return new Promise((resolve, reject) => { | |
const gitProcess = spawn('git', command, { cwd, stdio: 'inherit' }); | |
gitProcess.on('close', (code) => { | |
if (code === 0) { | |
resolve(code); | |
} else { | |
reject(new Error(`git command exited with code ${code}`)); | |
} | |
}); | |
}); | |
} | |
async function syncRepository(repo) { | |
const targetDirectory = path.join(process.cwd(), repo.full_name); | |
const exists = await fsExists(targetDirectory); | |
if (!exists) { | |
await git(['clone', repo.ssh_url, targetDirectory], process.cwd()); | |
} else { | |
await git(['pull'], targetDirectory); | |
} | |
}; | |
for await (const repo of fetchRepositoriesForUser(process.env.GITHUB_USER)) { | |
console.log(`Sync ${repo.full_name}`) | |
await syncRepository(repo); | |
} | |
How do you install the dependencies for an script like this one?
Only node native modules are used, so it doesn't require an install.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
GitHub shouldn't be the only place where we keep our repositories. This script will download all your github repos, and keep the in sync. Run with
node
after setting theGITHUB_TOKEN
andGITHUB_USER
environment variables. Ideally, you'd add it to a cronjob.