Skip to content

Connecting GitHub ​

Moʻolelo indexes issues and pull requests from the repositories you list. It uses GitHub's REST API for backfill and webhooks for steady-state.

Prerequisites ​

  • A GitHub account with repo scope on the repositories you want indexed.
  • The repositories' webhook secret (you'll generate this when you register the webhook).
  • Network reachability: Moʻolelo's webhook endpoint must be reachable from GitHub's webhook IP ranges (or you set up a self-hosted GitHub Enterprise webhook delivery).

Step 1 — generate a Personal Access Token ​

A fine-grained PAT scoped to the repositories you want indexed is sufficient. The PAT needs Issues: read and Pull requests: read permissions.

For a deployment that watches many repositories, a GitHub App is more manageable; the configuration shape is the same in either case (you store the access token in the connector configuration).

Step 2 — register the connector ​

Insert a row into connector_configs:

sql
INSERT INTO connector_configs
  (tenant_id, source, instance, mode, resources, raw_config)
VALUES (
  'default',                                -- your tenant id
  'github',                                 -- the source identifier
  'acme',                                   -- your GitHub org name (the "instance")
  'backfill',                               -- start with backfill
  '["acme/wiki", "acme/handbook"]'::jsonb,  -- repositories to watch
  '{
    "api_base": "https://api.github.com",
    "auth_token": "ghp_xxxxxxxxxxxx"
  }'::jsonb
);

Within milliseconds the connector starts walking the repositories' issues and pull requests. Progress is durable — if the backfill is interrupted, it resumes from the last record that landed in storage.

For GitHub Enterprise Server, set api_base to your enterprise URL (https://github.example.com/api/v3).

Step 3 — register the webhook on the GitHub side ​

Generate a strong random secret. On each repository's webhook settings page (or at the org level if you prefer one webhook per org), create a webhook with:

  • Payload URL: https://<your-moolelo-host>/webhooks/github/<instance>
  • Content type: application/json
  • Secret: the random string you generated.
  • Events: select "Issues", "Issue comments", and "Pull requests" — at minimum.

The same secret value goes into Moʻolelo's deployment as the WEBHOOK_INGRESS_GITHUB_SECRET environment variable on the webhook receiver. See Configuring webhooks for the details.

Step 4 — flip to webhook mode ​

Once the backfill completes (you'll see this in the operational logs as "backfill: done"), update the connector to webhook mode:

sql
UPDATE connector_configs
SET mode = 'webhook'
WHERE tenant_id = 'default' AND source = 'github';

The connector now waits for webhook deliveries instead of polling. If you ever need to recapture a missed period (for example after a network partition), insert a new tenant config row in backfill mode targeted at a specific repository — the connector will catch up without re-publishing already-indexed records.

What gets indexed ​

Per record, Moʻolelo indexes:

  • Title — as a separate chunk, weighted higher in lexical scoring.
  • Body — split into paragraph-sized chunks with their original heading path preserved as structural metadata.
  • Author — for residency routing (if your tenant has subject-level residency configured).
  • Source URL — for click-through from search results back to GitHub.
  • Labels and assignees — surfaced as structured metadata.

What is not indexed today:

  • Comments. (Coming in a later release; comments require a separate API walk during backfill.)
  • Code in repository files. The walking-skeleton scope is structured records; full-codebase indexing arrives when your tenant turns it on.
  • Wiki pages. GitHub wikis use a different API surface and aren't part of the issue/PR connector.

Permissions visible in search results ​

GitHub's permission model is simple: a record is visible to a user if and only if the user has read access to the repository. Moʻolelo extracts each indexed record's repository, checks the calling user's GitHub login against the repository's collaborators / team memberships, and filters accordingly.

When the calling user lacks GitHub read access on a repository, results from that repository do not appear in the response. There is no "preview" leakage of restricted record titles or snippets.

Troubleshooting ​

  • No records appearing after the connector starts. Check that the PAT has Issues: read and Pull requests: read permissions on at least one repository in the resources list. Hit https://api.github.com/repos/<owner>/<name>/issues directly with the same token to confirm.
  • Webhook deliveries 401-rejected. The secret on the GitHub webhook page does not match WEBHOOK_INGRESS_GITHUB_SECRET. Re-paste the secret on the GitHub side and confirm.
  • Backfill loops without progress. Check Postgres for the connector cursor row in connector_cursors. If updated_at is stuck, the GitHub API is rate-limiting you — Moʻolelo automatically backs off and retries, but a heavily-rate-limited token may take hours to make progress.

Moʻolelo — self-hosted federated enterprise knowledge platform.