Node 备份 GitHub 私有库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
// npm install octokit
const { Octokit } = require("octokit");
const fs = require('fs');

// https://github.com/settings/tokens
// 创建一个令牌,权限拉满,然后执行完记得删除
const octokit = new Octokit({
auth: '令牌',
});

// 保存文件夹路径
const dir = './github_download';

async function handle() {
// 文件夹要是不存在就创建
if(!fs.existsSync(dir)) {
fs.mkdirSync(dir);
}

var page = 1;

while(true) {
// 获取仓库列表,最多100条记录
const {
data
} = await octokit.request('GET /user/repos', {
page,
per_page: 100,
});

for(let i in data) {
let item = data[i];

// 非私有的跳过
if(!item.private) {
continue;
}

console.log('仓库名:' + item.full_name);

// 获取仓库分支列表
var branches = await octokit.request(`GET /repos/${item.full_name}/branches`, {
page: 1,
per_page: 100,
});

branches = branches.data;

for(let b in branches) {
let branche = branches[b];

// 过滤下机器人的分支
if(branche.name.indexOf('dependabot') === 0) {
continue;
}

console.log('分支名称:' + branche.name);

// 获取下载文件
const info = await octokit.request(`GET /repos/${item.full_name}/zipball/{ref}`, {
ref: branche.name,
});

try {
// 保存文件
fs.writeFileSync(`${dir}/${item.full_name.replace('/', '_')}_${branche.name.replace('/', '_')}.zip`, toBuffer(info.data))
} catch (err) {
}
}
}

if(data.length !== 100) {
break;
}

page++;
}
}

// https://stackoverflow.com/questions/8609289/convert-a-binary-nodejs-buffer-to-javascript-arraybuffer
function toBuffer(ab) {
const buf = Buffer.alloc(ab.byteLength);
const view = new Uint8Array(ab);
for (let i = 0; i < buf.length; ++i) {
buf[i] = view[i];
}
return buf;
}

handle();
往上