import { waitUntil } from "cloudflare:workers";
import { chunks, placeholders, stmt } from "../db";
import { accountDb, repoDb } from "../scoped-db";
import { deleteRunnerRow } from "../ci/runner-registration";
import { cancelActiveJob } from "../ci/jobs";
import { forgetLocator } from "../scoped-db/locators";
import { dropRepoRunners } from "../repo-account-cleanup";
import { dropMcpAccess, purgeInaccessibleFollowers } from "../access-revocation";
import { publishScopeGauges } from "../metering/scope-gauges";
/**
* Integrations and legacy webhooks are configured by a repository's admins, so they do not survive a change
* of ownership: the new owner must knowingly re-enable them. Pull mirrors would otherwise keep writing refs as
* the old admin and push mirrors would keep exporting the new owner's pushes to the old admin's GitHub repo.
* Deploy tokens were minted by the old admins, so they are revoked too. These are the D1 statements (batch them
* with the transfer); the repository's own webhooks and deploy tokens are handled by `disableRepoConfigOnTransfer`.
*/
export function repoOwnershipChangeStatements(repoId: string, actorId: string | null): D1PreparedStatement[] {
const now = Date.now();
return [
stmt(
`INSERT INTO integration_audit (id, integration_id, actor_id, action, detail, created_at)
SELECT lower(hex(randomblob(16))), id, ?, 'repo.transferred', ?, ? FROM integrations
WHERE scope_type = 'repo' AND scope_id = ? AND active = 1`,
actorId,
JSON.stringify({ reason: "Repository transferred; integration disabled until the new owner re-enables it" }),
now,
repoId,
),
stmt(
`UPDATE integrations SET active = 0, updated_at = ?,
config = json_remove(json_set(config, '$.githubMirror', 'none'), '$.githubRepo')
WHERE scope_type = 'repo' AND scope_id = ?`,
now,
repoId,
),
];
}
/**