diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 501a2fa..cea4808 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -28,3 +28,9 @@ jobs: - name: Lint run: | pnpm run lint + + - name: Test Dry Run + run: | + pnpm run run:collect-artifacts --skipDownload + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/scripts/collectArtifacts.ts b/scripts/collectArtifacts.ts index 5ec93e4..fad7a49 100644 --- a/scripts/collectArtifacts.ts +++ b/scripts/collectArtifacts.ts @@ -1,6 +1,7 @@ import fs from "node:fs/promises"; import { Readable } from "node:stream"; import { pipeline } from "node:stream/promises"; +import { parseArgs } from "node:util"; import { Semaphore } from "@core/asyncutil"; import unzip from "unzip-stream"; import { @@ -14,6 +15,26 @@ import { DownloadData, } from "./common.ts"; +const { values: args } = parseArgs({ + options: { + skipDownload: { + type: "boolean", + }, + help: { + type: "boolean", + }, + }, + args: process.argv.slice(2), +}); + +if (args.help) { + console.log`Usage: collectArtifacts.ts [--skipDownload]`; + process.exit(0); +} +if (args.skipDownload) { + rootLogger.info("--skipDownload is set, skipping download."); +} + const branches = await octokit.paginate("GET /repos/{owner}/{repo}/branches", { owner: guestRepoOwner, repo: guestRepoName, @@ -154,29 +175,33 @@ const downloadTargets = await Promise.all( }, ); - log.info`Downloading artifact from ${innerDownloadUrl}`; - const response = await fetch(innerDownloadUrl); - if (!response.ok) { - log.error`Failed to download artifact: ${response.statusText}`; - return; - } - if (!response.body) { - log.error("Response has no body"); - return; - } const dirname = source.type === "branch" ? `branch-${source.branch.name}` : `pr-${source.pullRequest.number}`; - const destination = `${destinationDir}/${dirname}`; - log.info`Extracting artifact to ${destination}`; - await fs.mkdir(destination, { recursive: true }); - await pipeline( - Readable.fromWeb(response.body), - unzip.Extract({ - path: destination, - }), - ); + if (args.skipDownload) { + log.info`Download skipped: ${innerDownloadUrl}`; + } else { + log.info`Downloading artifact from ${innerDownloadUrl}`; + const response = await fetch(innerDownloadUrl); + if (!response.ok) { + log.error`Failed to download artifact: ${response.statusText}`; + return; + } + if (!response.body) { + log.error("Response has no body"); + return; + } + const destination = `${destinationDir}/${dirname}`; + log.info`Extracting artifact to ${destination}`; + await fs.mkdir(destination, { recursive: true }); + await pipeline( + Readable.fromWeb(response.body), + unzip.Extract({ + path: destination, + }), + ); + } log.info("Done."); return { source, dirname }; diff --git a/scripts/common.ts b/scripts/common.ts index 7c66d49..eb69ad1 100644 --- a/scripts/common.ts +++ b/scripts/common.ts @@ -4,7 +4,7 @@ import { config } from "dotenv"; import { App, Octokit } from "octokit"; import { paginateRest } from "@octokit/plugin-paginate-rest"; import { throttling } from "@octokit/plugin-throttling"; -import { Endpoints } from "@octokit/types"; +import { Endpoints, OctokitResponse } from "@octokit/types"; export type Branch = Endpoints["GET /repos/{owner}/{repo}/branches"]["response"]["data"][0]; @@ -84,27 +84,50 @@ const getEnv = (name: string) => { return value; }; -export const app = new App({ - appId: Number.parseInt(getEnv("APP_ID")), - privateKey: - process.env.PRIVATE_KEY || - (await fs.readFile(`${import.meta.dirname}/../private-key.pem`, "utf8")), - oauth: { - clientId: getEnv("CLIENT_ID"), - clientSecret: getEnv("CLIENT_SECRET"), - }, - Octokit: Octokit.plugin(paginateRest, throttling), -}); +let appInfo: + | OctokitResponse + | undefined; +export let octokit: Octokit; -export const appInfo = await app.octokit.request("GET /app"); -if (!appInfo.data) { - throw new Error("Failed to get app info."); -} -rootLogger.info`Running as ${appInfo.data.name}.`; +if (process.env.APP_ID) { + rootLogger.info`Running as GitHub App. (Read + Write)`; + const app = new App({ + appId: Number.parseInt(getEnv("APP_ID")), + privateKey: + process.env.PRIVATE_KEY || + (await fs.readFile(`${import.meta.dirname}/../private-key.pem`, "utf8")), + oauth: { + clientId: getEnv("CLIENT_ID"), + clientSecret: getEnv("CLIENT_SECRET"), + }, + Octokit: Octokit.plugin(paginateRest, throttling), + }); + + appInfo = await app.octokit.request("GET /app"); + if (!appInfo.data) { + throw new Error("Failed to get app info."); + } + rootLogger.info`Running as ${appInfo.data.name}.`; -const { data: installations } = await app.octokit.request( - "GET /app/installations", -); -const installationId = installations[0].id; + const { data: installations } = await app.octokit.request( + "GET /app/installations", + ); + const installationId = installations[0].id; -export const octokit = await app.getInstallationOctokit(installationId); + octokit = await app.getInstallationOctokit(installationId); +} else if (process.env.GITHUB_TOKEN) { + rootLogger.info`Running with GitHub Token. (Read only)`; + + octokit = new Octokit({ + auth: getEnv("GITHUB_TOKEN"), + }); +} else { + throw new Error("No GitHub App or Token provided."); +} + +export const getAppInfo = () => { + if (!appInfo) { + throw new Error("This script requires appInfo to be set."); + } + return appInfo; +}; diff --git a/scripts/updateComments.ts b/scripts/updateComments.ts index edf2023..cb1c074 100644 --- a/scripts/updateComments.ts +++ b/scripts/updateComments.ts @@ -1,6 +1,6 @@ import fs from "node:fs/promises"; import { - appInfo, + getAppInfo, commentMarker, commentMarkers, guestRepoName, @@ -11,6 +11,8 @@ import { DownloadData, } from "./common.ts"; +const appInfo = getAppInfo(); + const downloadData = JSON.parse( await fs.readFile( `${import.meta.url.replace("updateComments.ts", "")}downloads.json`, @@ -85,4 +87,4 @@ for (const { dirname, source } of downloadData) { } } -rootLogger.info`All done! ${allPullRequests} PRs, ${newComments} new comments, ${updatedComments} updated comments.`; +rootLogger.info`Done: ${newComments} new comments, ${updatedComments} updated comments / ${allPullRequests} PRs`; diff --git a/tsconfig.app.json b/tsconfig.app.json index d3f18a2..357c363 100644 --- a/tsconfig.app.json +++ b/tsconfig.app.json @@ -1,6 +1,5 @@ { "compilerOptions": { - "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", "target": "ES2020", "useDefineForClassFields": true, "module": "ESNext", diff --git a/tsconfig.node.json b/tsconfig.node.json index 1cbc876..629fb56 100644 --- a/tsconfig.node.json +++ b/tsconfig.node.json @@ -1,6 +1,5 @@ { "compilerOptions": { - "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", "target": "ES2022", "lib": ["ES2023"], "module": "ESNext",