Skip to content

Built for people who want to own their automations. Join the waitlist for an invite.

Package listing

@kentcdodds/github

README.md

136 lines · 5.6 KB · Markdown

@kentcdodds/github

Intent

One GitHub helpers package for Kody agents, with two BYO OAuth identities: kody-bot (account: 'bot', integration github-bot) is the default for every call; Kent C. Dodds (account: 'kent', integration github-kent) is used only when the user explicitly asks to act as Kent. Agents must not infer Kent from private repos, org access, or “the bot might not have permission.”

When To Use

  • Make GitHub REST or GraphQL calls with the correct saved credential (request, graphql, paginate).
  • Verify which GitHub identity will perform an action (get-viewer).
  • Fetch PR details, CI checks, merge, or change draft/ready status (pr/* exports).
  • Create or update GitHub Actions secrets without returning plaintext (actions/put-secret).
  • Choose bot (default) or kent (explicit Kent C. Dodds only).

Required setup

Two user-owned GitHub OAuth connections to the same BYO GitHub OAuth app (not the Kody platform app), both with god-level scopes (gist, notifications, read:org, read:user, repo, user:email, workflow):

  • github-bot — kody-bot. Default account. Connect while signed into GitHub as kody-bot.
  • github-kent — Kent C. Dodds. Explicit-only account. Connect while signed into GitHub as kentcdodds.

Reconnect: /connect/oauth?provider=github-bot or /connect/oauth?provider=github-kent.

Account guide

AccountIntegrationDefaultUse when
botgithub-botYesEvery GitHub call unless the user explicitly asks for Kent.
kentgithub-kentNoOnly when the user explicitly asks to use Kent C. Dodds / kentcdodds.

All PR helpers accept optional account (default 'bot'). PR locators: { prUrl } or { owner, repo, prNumber } (number aliases prNumber).

pr/merge reliability

You do not need to handle slow GitHub merges. pr/merge bounds the direct merge attempt (default timeoutMs: 25000), and if GitHub's merge endpoint stalls it escalates to a durable Kody workflow that finishes the merge idempotently (deduped per owner/repo/PR/head SHA). The call itself stays under a ~55s total budget and either returns the completed merge or merge_dispatched with a workflowId — not a problem for the caller to retry. timed_out_unconfirmed is reserved for the rare case where workflows are unavailable. Fail-fast preflight still covers already-merged, closed, draft, dirty, blocked, and not-mergeable PRs; timings includes escalationMs and totalBudgetMs.

Exports

  • kody:@kentcdodds/github — package overview
  • kody:@kentcdodds/github/accounts — account aliases and selection guidance
  • kody:@kentcdodds/github/get-viewer — identity smoke test
  • kody:@kentcdodds/github/graphql — GraphQL helper
  • kody:@kentcdodds/github/paginate — REST pagination helper
  • kody:@kentcdodds/github/request — REST request helper (timeoutMs / signal optional; no default timeout on reads)
  • kody:@kentcdodds/github/types — shared TypeScript types
  • kody:@kentcdodds/github/pr/get-info — fetch pull request details
  • kody:@kentcdodds/github/pr/get-checks — fetch check-run status
  • kody:@kentcdodds/github/pr/merge — merge a pull request (bounded direct attempt + durable escalation)
  • kody:@kentcdodds/github/pr/merge-durable — durable workflow entry for finishing a slow merge (used by pr/merge)
  • kody:@kentcdodds/github/pr/workflows-probe — smoke-test that workflows is reachable from this package runtime
  • kody:@kentcdodds/github/pr/set-review-status — set draft, ready-for-review, or toggle (status: 'toggle'; mutation bounded by timeoutMs)
  • kody:@kentcdodds/github/actions/put-secret — create or update a repo or environment Actions secret (sealed-box encrypt; never returns the value)

Dynamic invocation

Prefer static imports (kody:@kentcdodds/github/...) — from execute they always see the current published version, and from another package they bundle a snapshot. Use packages.invoke only when the export name is data or you need this package's own runtime; pass the bare kody id github (see Kody Dynamic package invocation):

import { packages } from 'kody:runtime'

await packages.invoke({
  kodyId: 'github',
  exportName: './request',
  params: { path: '/repos/kentcdodds/kody', throwOnError: true },
})

Do not pass @kentcdodds/github as kodyId. packageId (UUID) also works.

Examples

REST request:

import githubRequest from 'kody:@kentcdodds/github/request'

const response = await githubRequest({
  account: 'bot',
  path: '/repos/kentcdodds/kody',
  throwOnError: true,
})
return response.data

PR info with account:

import getPrInfo from 'kody:@kentcdodds/github/pr/get-info'

return await getPrInfo({
  owner: 'kentcdodds',
  repo: 'kentcdodds.com',
  prNumber: 1,
  account: 'bot',
})

Merge with structured timeout recovery:

import mergePr from 'kody:@kentcdodds/github/pr/merge'

return await mergePr({
  prUrl: 'https://github.com/kentcdodds/kody/pull/969',
  mergeMethod: 'squash',
  // timeoutMs: 25000 is the default direct-attempt budget
})
// On a slow GitHub merge you may see status: 'merge_dispatched' with workflowId.
// You do not need to retry — the durable workflow finishes the merge.

Put a repo Actions secret (plaintext never returned):

import putActionsSecret from 'kody:@kentcdodds/github/actions/put-secret'

return await putActionsSecret({
  owner: 'kentcdodds',
  repo: 'kody',
  name: 'NX_SELF_HOSTED_REMOTE_CACHE_ACCESS_TOKEN',
  generateBytes: 32,
})