fix: replace domain-specific exit handler with generic signal handler registry (#299)
* fix: replace domain-specific exit handler with generic signal handler registry Rewrite exitHandler.ts as a generic, domain-agnostic exit signal module that exports onExitSignal(handler) returning a dispose function. - subprocess.ts now registers via onExitSignal instead of direct process.on(SIGINT/SIGTERM) calls - resolveTokens registers a signal handler that captures tokens by closure, fixing the race condition where the exit handler would read the wrong token after disposal - Remove setupExitHandler and runCleanup — domain cleanup is handled by post.ts + await using Co-authored-by: Cursor <cursoragent@cursor.com> * tweaks * simplify handler installation * extract to util * fix race in dispose * wrap dispose body in try/finally to ensure disposingRef always settles --------- Co-authored-by: Mateusz Burzyński <mateuszburzynski@gmail.com> Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: pullfrog[bot] <226033991+pullfrog[bot]@users.noreply.github.com>
This commit is contained in:
committed by
pullfrog[bot]
parent
70f1c47a28
commit
ee100354da
+24
-6
@@ -2,6 +2,7 @@ import assert from "node:assert/strict";
|
||||
import * as core from "@actions/core";
|
||||
import type { PushPermission } from "../external.ts";
|
||||
import { log } from "./cli.ts";
|
||||
import { onExitSignal } from "./exitHandler.ts";
|
||||
import { acquireNewToken } from "./github.ts";
|
||||
import { isGitHubActions } from "./globals.ts";
|
||||
|
||||
@@ -131,18 +132,35 @@ export async function resolveTokens(params: ResolveTokensParams): Promise<TokenR
|
||||
const revertGithubToken = setEnvironmentVariable("GITHUB_TOKEN", mcpToken);
|
||||
mcpTokenValue = mcpToken;
|
||||
|
||||
return {
|
||||
gitToken,
|
||||
mcpToken,
|
||||
async [Symbol.asyncDispose]() {
|
||||
let disposingRef: PromiseWithResolvers<void> | undefined;
|
||||
|
||||
const dispose = async () => {
|
||||
if (disposingRef) {
|
||||
// this can happen if the signal arrives when disposing tokens
|
||||
// we make sure to wait for the current dispose to complete
|
||||
return disposingRef.promise;
|
||||
}
|
||||
disposingRef = Promise.withResolvers();
|
||||
try {
|
||||
mcpTokenValue = undefined;
|
||||
revertGithubToken();
|
||||
// revoke both tokens
|
||||
await Promise.all([
|
||||
revokeGitHubInstallationToken(gitToken),
|
||||
revokeGitHubInstallationToken(mcpToken),
|
||||
]);
|
||||
},
|
||||
} finally {
|
||||
removeSignalHandler();
|
||||
disposingRef.resolve();
|
||||
disposingRef = undefined;
|
||||
}
|
||||
};
|
||||
|
||||
const removeSignalHandler = onExitSignal(dispose);
|
||||
|
||||
return {
|
||||
gitToken,
|
||||
mcpToken,
|
||||
[Symbol.asyncDispose]: dispose,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user