Update #347
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
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 |