-
Notifications
You must be signed in to change notification settings - Fork 6
133 lines (117 loc) · 4.75 KB
/
update.yml
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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
name: Update
on:
workflow_dispatch:
schedule:
- cron: "0 0 * * *"
jobs:
sync:
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Update files
uses: actions/github-script@v7
with:
script: |
const { createWriteStream } = require("fs");
const { readFile, mkdir } = require("fs/promises");
const path = require("path");
const { Readable } = require("stream");
const { finished } = require("stream/promises");
const updateListPath = "portable_config/update.json";
async function getUpdateList(path) {
const json = await readFile(path, "utf8");
const data = JSON.parse(json);
return data;
}
async function getFlattedList(list) {
const results = [];
for (const { repository, branch, files } of list) {
for (const { source, target } of files) {
results.push({ repository, branch, source, target });
}
}
return results;
}
async function getDownloadList(list) {
const results = [];
for (const { repository, branch, source, target } of list) {
const isDir = source.endsWith("/") && target.endsWith("/");
if (isDir) {
const tasks = await resolveDir(repository, branch, source, target);
results.push(...tasks);
} else {
const sourceUrl = await resolveSourceUrl(repository, branch, source);
const task = { source: sourceUrl, target };
results.push(task);
}
}
return results;
}
async function resolveDir(repo, branch, directory, outputDir) {
const url = `https://api.github.com/repos/${repo}/contents/${directory}`;
const response = await fetch(url, {
headers: {
Accept: "application/vnd.github.v3+json",
"User-Agent": "github-script-action",
},
});
const items = await response.json();
const downloadTasks = [];
for (const item of items) {
const outputPath = path.join(outputDir, item.path.replace(directory, ""));
if (item.type === "dir") {
const tasks = await resolveDir(repo, branch, item.path, outputPath);
downloadTasks.push(...tasks);
} else {
const task = { source: item.download_url, target: outputPath };
downloadTasks.push(task);
}
}
return downloadTasks;
}
async function resolveSourceUrl(repo, branch, source) {
if (branch === "@gist") {
return `https://gist.github.com/${repo}/raw/${source}`;
}
if (branch === "@releases") {
return `https://github.com/${repo}/releases/latest/download/${source}`;
}
return `https://github.com/${repo}/raw/${branch}/${source}`;
}
async function removeDir(updateList) {
for (const { source, target } of updateList) {
const isDir = source.endsWith("/") && target.endsWith("/");
if (isDir) {
await io.rmRF(target);
}
}
}
async function download(sourceUrl, destinationPath) {
const response = await fetch(sourceUrl, {
headers: {
Accept: "application/octet-stream",
"User-Agent": "github-script-action",
},
});
await mkdir(path.dirname(destinationPath), { recursive: true });
const writeStream = createWriteStream(destinationPath);
await finished(Readable.fromWeb(response.body).pipe(writeStream));
}
async function downloadList(list) {
for (const { source, target } of list) {
await download(source, target);
}
}
async function main() {
const update = await getUpdateList(updateListPath);
const flatted = await getFlattedList(update);
const download = await getDownloadList(flatted);
await removeDir(flatted);
await downloadList(download);
}
main();
- name: Commit Changes
uses: stefanzweifel/git-auto-commit-action@v5
with:
commit_message: Automated Update