feat: add repository-scoped GitHub authority

This commit is contained in:
Codex
2026-07-13 12:35:00 +02:00
parent 3aaa2616e8
commit 89b618ded8
9 changed files with 379 additions and 68 deletions
@@ -751,13 +751,13 @@ export async function syncRepository(repo, delivery, runtime) {
let requestedObject = await executeResult(["git", "-C", work, "cat-file", "-e", `${delivery.requestedCommit}^{commit}`]);
if (requestedObject.status !== 0) {
const branchFetch = await executeResult([
"git", "-C", work, "-c", `http.extraHeader=${runtime.githubAuthHeader}`,
"git", "-C", work, "-c", `http.extraHeader=${runtime.githubAuthHeaders[repo.key]}`,
"fetch", "--no-tags", repo.upstream.cloneUrl,
`+refs/heads/${repo.upstream.branch}:refs/remotes/github/${repo.upstream.branch}`,
]);
requestedObject = await executeResult(["git", "-C", work, "cat-file", "-e", `${delivery.requestedCommit}^{commit}`]);
if (requestedObject.status !== 0) {
const exactFetch = await executeResult(["git", "-C", work, "-c", `http.extraHeader=${runtime.githubAuthHeader}`, "fetch", "--no-tags", repo.upstream.cloneUrl, `${delivery.requestedCommit}:refs/remotes/github/delivery`]);
const exactFetch = await executeResult(["git", "-C", work, "-c", `http.extraHeader=${runtime.githubAuthHeaders[repo.key]}`, "fetch", "--no-tags", repo.upstream.cloneUrl, `${delivery.requestedCommit}:refs/remotes/github/delivery`]);
if (exactFetch.status !== 0) {
return {
ok: false,
@@ -931,14 +931,19 @@ export function retryDelayMs(syncAttempt, initialDelayMs, maxDelayMs) {
}
export function loadRuntimeConfig() {
const githubToken = requiredEnv("GITHUB_TOKEN");
const giteaUsername = requiredEnv("GITEA_USERNAME");
const giteaPassword = requiredEnv("GITEA_PASSWORD");
const repos = JSON.parse(readFileSync(process.env.UNIDESK_GITEA_REPOS_PATH || "/etc/gitea-github-sync/repos.json", "utf8"));
const defaultTokenEnv = requiredEnv("UNIDESK_GITEA_GITHUB_DEFAULT_TOKEN_ENV");
const githubAuthHeaders = Object.fromEntries(repos.map((repo) => {
const token = requiredEnv(repo.githubCredential?.tokenEnv || defaultTokenEnv);
return [repo.key, `Authorization: Basic ${Buffer.from(`x-access-token:${token}`).toString("base64")}`];
}));
return {
port: Number.parseInt(process.env.UNIDESK_GITEA_WEBHOOK_PORT || "8080", 10),
path: process.env.UNIDESK_GITEA_WEBHOOK_PATH || "/_unidesk/github-to-gitea",
responseBudgetMs: positiveIntegerEnv("UNIDESK_GITEA_WEBHOOK_RESPONSE_BUDGET_MS"),
repos: JSON.parse(readFileSync(process.env.UNIDESK_GITEA_REPOS_PATH || "/etc/gitea-github-sync/repos.json", "utf8")),
repos,
webhookSecret: requiredEnv("GITHUB_WEBHOOK_SECRET"),
giteaBaseUrl: requiredEnv("UNIDESK_GITEA_SERVICE_BASE_URL").replace(/\/+$/u, ""),
inbox: {
@@ -958,7 +963,7 @@ export function loadRuntimeConfig() {
},
shutdownGraceMs: positiveIntegerEnv("UNIDESK_GITEA_WEBHOOK_SHUTDOWN_GRACE_MS"),
maxBodyBytes: positiveIntegerEnv("UNIDESK_GITEA_WEBHOOK_MAX_BODY_BYTES"),
githubAuthHeader: `Authorization: Basic ${Buffer.from(`x-access-token:${githubToken}`).toString("base64")}`,
githubAuthHeaders,
giteaAuthHeader: `Authorization: Basic ${Buffer.from(`${giteaUsername}:${giteaPassword}`).toString("base64")}`,
log,
run,