fix: handle stale Gitea webhook bridge events
This commit is contained in:
@@ -16,7 +16,7 @@ const giteaBaseUrl = requiredEnv("UNIDESK_GITEA_SERVICE_BASE_URL").replace(/\/+$
|
||||
const githubAuthHeader = `Authorization: Basic ${Buffer.from(`x-access-token:${githubToken}`).toString("base64")}`;
|
||||
const giteaAuthHeader = `Authorization: Basic ${Buffer.from(`${giteaUsername}:${giteaPassword}`).toString("base64")}`;
|
||||
|
||||
const running = new Set();
|
||||
const syncStates = new Map();
|
||||
|
||||
createServer(async (req, res) => {
|
||||
const startedAt = Date.now();
|
||||
@@ -49,21 +49,18 @@ createServer(async (req, res) => {
|
||||
writeJson(res, 202, { ok: true, event, repository, ref, disposition: "ignored-repo-or-ref", valuesPrinted: false });
|
||||
return;
|
||||
}
|
||||
if (running.has(repo.key)) {
|
||||
writeJson(res, 202, { ok: true, event, repository, ref, disposition: "already-running", repo: repo.key, valuesPrinted: false });
|
||||
const state = syncState(repo.key);
|
||||
if (state.running) {
|
||||
state.pending = true;
|
||||
log({ event: "github-to-gitea-sync-queued", repo: repo.key, repository, ref, disposition: "pending-rerun", valuesPrinted: false });
|
||||
writeJson(res, 202, { ok: true, event, repository, ref, disposition: "queued-after-running", repo: repo.key, valuesPrinted: false });
|
||||
return;
|
||||
}
|
||||
running.add(repo.key);
|
||||
state.running = true;
|
||||
state.pending = false;
|
||||
writeJson(res, 202, { ok: true, event, repository, ref, repo: repo.key, disposition: "accepted", valuesPrinted: false });
|
||||
setImmediate(() => {
|
||||
try {
|
||||
const sync = syncRepository(repo);
|
||||
log({ event: "github-to-gitea-sync", repo: repo.key, ok: sync.ok, sourceCommit: sync.sourceCommit, snapshotRef: sync.snapshotRef, error: sync.error ? redact(sync.error) : null, elapsedMs: Date.now() - startedAt, valuesPrinted: false });
|
||||
} catch (error) {
|
||||
log({ event: "github-to-gitea-sync-error", repo: repo.key, ok: false, error: redact(String(error?.message || error)), elapsedMs: Date.now() - startedAt, valuesPrinted: false });
|
||||
} finally {
|
||||
running.delete(repo.key);
|
||||
}
|
||||
runSyncLoop(repo, state, startedAt);
|
||||
});
|
||||
} catch (error) {
|
||||
log({ event: "github-to-gitea-sync-error", ok: false, error: String(error?.message || error), valuesPrinted: false });
|
||||
@@ -73,6 +70,31 @@ createServer(async (req, res) => {
|
||||
log({ event: "github-to-gitea-sync-listening", port, path, repos: repos.map((repo) => repo.key), valuesPrinted: false });
|
||||
});
|
||||
|
||||
function syncState(key) {
|
||||
let state = syncStates.get(key);
|
||||
if (!state) {
|
||||
state = { running: false, pending: false };
|
||||
syncStates.set(key, state);
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
function runSyncLoop(repo, state, startedAt) {
|
||||
let attempt = 0;
|
||||
try {
|
||||
do {
|
||||
state.pending = false;
|
||||
attempt += 1;
|
||||
const sync = syncRepository(repo);
|
||||
log({ event: "github-to-gitea-sync", repo: repo.key, ok: sync.ok, sourceCommit: sync.sourceCommit, snapshotRef: sync.snapshotRef, error: sync.error ? redact(sync.error) : null, attempt, pendingRerun: state.pending, elapsedMs: Date.now() - startedAt, valuesPrinted: false });
|
||||
} while (state.pending);
|
||||
} catch (error) {
|
||||
log({ event: "github-to-gitea-sync-error", repo: repo.key, ok: false, error: redact(String(error?.message || error)), attempt, elapsedMs: Date.now() - startedAt, valuesPrinted: false });
|
||||
} finally {
|
||||
state.running = false;
|
||||
}
|
||||
}
|
||||
|
||||
function syncRepository(repo) {
|
||||
const work = mkdtempSync(join(tmpdir(), `gitea-gh-sync-${repo.key}-`));
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user