Home

madison / open-git

public
Overview Code History Branches Pull requestsIssuesInsights Campfire Docs
main
HomeOverview Code PRsIssues

Docs

Markdown docs from docs.

DocsAPI
Pages
Bot marketplace (moved)Dashboard list "table" patternGitHub two-way syncHow install worksUninstall, unpublish, and billingSign in with open-gitCreate a botSDK and a working exampleReceive webhooksOrganizations and Repository RBACUI Component Audit
Uninstall, unpublish, and billing

Uninstall, unpublish, and billing

The user uninstalls

They click Uninstall on Settings → Connections or the manage page. You receive installation.deleted (installation_id only). Tokens for that install are revoked. Old comments and checks stay on the pull request.

if (event === "installation.deleted") {
  await db.installs.markDeleted(payload.installation_id)
  return
}

They can also remove one repository from the install. You get installation.repos_changed with the repository ids that remain.

if (event === "installation.repos_changed") {
  await db.installs.update(payload.installation_id, {
    repositoryIds: payload.repositories ?? [],
  })
}

If they revoke Sign in with open-git (Settings → Connections → Authorized applications), that is not an uninstall unless they choose Revoke and uninstall. Revoke access only clears Connected on installs they can manage. Stop treating them as signed in. The bot grant is unchanged until they uninstall. Revoke and uninstall sends installation.deleted for each of those installs, then removes them.

You unpublish

On the bot page, Unpublish:

  • POSTs installation.deleted to every install (and waits for those deliveries) before marking the bot unpublished
  • Sets every install to disabled and revokes API tokens
  • Disables the linked OAuth client (consent shows the app as unavailable)
  • Keeps the listing URL reserved. /bots/{slug} shows “This bot is no longer published.” The listing path 404s.

There is no republish control. Treat unpublish as taking the product down. Handle those installation.deleted events the same as a user uninstall.

You change permissions or rotate keys

Changing the permission set revokes outstanding installation tokens. Mint again on the next event. Rotating the install private key also revokes every token and issues a new key (shown once). Rotating the webhook secret replaces the 64-hex secret; your server must start verifying with the new value.

// After you paste a new webhook secret into your host
process.env.OPEN_GIT_BOT_WEBHOOK_SECRET = "the-new-secret"

Billing stays on your side

open-git will not add entitled: false to an install. That would let you kill their grant from our API.

If a trial ends, skip the job — or post a check that points at your subscribe page:

async function reviewPullRequest(options: {
  installationId: string
  owner: string
  repository: string
  number: number
  sha: string
}) {
  const install = await db.installs.get(options.installationId)
  const { api } = await installationClient(options.installationId)

  if (!install?.entitled) {
    await api.upsertCheck(options.owner, options.repository, options.sha, {
      name: "your-bot",
      status: "failed",
      summary: "Subscribe to run this check.",
      detailsUrl: "https://your-app.com/subscribe",
    })
    return
  }

  await api.upsertCheck(options.owner, options.repository, options.sha, {
    name: "your-bot",
    status: "success",
    summary: "All clear.",
  })
}

If they unlink in your product, stop working and clear Connected:

await db.installs.update(installationId, { entitled: false })
await markDisconnected(installationId)

We will not delete the install for you.

One open-git user can be two of your customers (work and personal). Link per installation_id, not “this sub paid once globally.”

// Work and personal are two rows, same sub
await db.customers.upsert({
  openGitUserId: sub,
  installationId,
  plan: "team",
})

One of your orgs will have many installs (one per company account). That is expected.