Mirror your entire GitHub history — repositories, issues, pull requests, commits, releases, and CI runs — into local PostgreSQL so you can query it without API calls, rate limits, or vendor dashboards.
nself-github is part of the free plugin tier. Install directly with nself plugin install github.
The GitHub plugin provides complete synchronization between GitHub and your local database. It captures all aspects of your GitHub workflow including:
# Install the plugin
nself plugin install github
# Verify installation
nself plugin status github# Required - GitHub Personal Access Token
# Generate at: https://github.com/settings/tokens
# Required scopes: repo, read:org, workflow, read:user
GITHUB_TOKEN=ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# Required - PostgreSQL connection string
DATABASE_URL=postgresql://user:password@localhost:5432/nself
# Optional - Webhook signing secret
# Get from: Repository Settings > Webhooks > Edit > Secret
GITHUB_WEBHOOK_SECRET=your_webhook_secret
# Optional - Organization to sync (syncs all accessible repos if not set)
GITHUB_ORG=your-organization
# Optional - Specific repos to sync (comma-separated)
# Format: owner/repo,owner/repo2
GITHUB_REPOS=nself-org/cli,nself-org/plugins
# Optional - Server configuration
PORT=3002
HOST=0.0.0.0
# Optional - Sync interval in seconds (default: 3600)
GITHUB_SYNC_INTERVAL=3600When creating a Personal Access Token (PAT), enable these scopes:
| Scope | Purpose |
|---|---|
repo | Full access to repositories (issues, PRs, commits) |
read:org | Read organization data (teams, members) |
workflow | Access to GitHub Actions workflow data |
read:user | Read user profile data |
admin:repo_hook | Required for webhook management |
For fine-grained PATs, select: Repository access (All or specific), and Permissions: Issues (read), Pull requests (read), Contents (read), Metadata (read), Workflows (read), Deployments (read).
# Create all required tables
nself-github init
# Or via ɳSelf CLI
nself plugin github init# Sync all data from GitHub
nself-github sync
# Sync specific resources
nself-github sync --resources repos,issues,prs
# Incremental sync (only changes since last sync)
nself-github sync --incremental
# Sync a specific repository
nself-github sync --repo nself-org/cli# Start the server
nself-github server
# Custom port
nself-github server --port 3002
# The server exposes:
# - POST /webhook - GitHub webhook endpoint
# - GET /health - Health check
# - GET /api/* - REST API endpoints# List all synced repositories
nself-github repos list
# List with details
nself-github repos list --details
# Search repositories
nself-github repos search "keyword"
# Get repository details
nself-github repos get owner/repo
# Show repository statistics
nself-github repos stats owner/repo# List all issues
nself-github issues list
# Filter by state
nself-github issues list --state open
nself-github issues list --state closed
# Filter by repository
nself-github issues list --repo owner/repo
# Filter by labels
nself-github issues list --labels bug,urgent
# Filter by assignee
nself-github issues list --assignee username
# Get issue details
nself-github issues get owner/repo 123# List all pull requests
nself-github prs list
# Filter by state
nself-github prs list --state open
nself-github prs list --state merged
nself-github prs list --state closed
# Filter by repository
nself-github prs list --repo owner/repo
# Filter by author
nself-github prs list --author username
# Get PR details
nself-github prs get owner/repo 456# List all releases
nself-github releases list
# Filter by repository
nself-github releases list --repo owner/repo
# Get latest release
nself-github releases latest owner/repo# List workflow runs
nself-github actions list
# Filter by status
nself-github actions list --status success
nself-github actions list --status failure
# Filter by repository
nself-github actions list --repo owner/repo
# Get run details
nself-github actions get 12345678# Show sync status and statistics
nself-github status
# Output:
# Repositories: 25
# Issues: 1,234 (456 open)
# Pull Requests: 789 (23 open)
# Commits: 45,678
# Releases: 156
# Workflow Runs: 3,456
# Last Sync: 2026-01-24 12:00:00https://your-domain.com/webhooks/githubapplication/jsonGITHUB_WEBHOOK_SECRETFor org-wide webhooks:
| Resource | Synced Data | Incremental Sync |
|---|---|---|
| Repositories | All metadata, settings, topics | Yes |
| Issues | Full issue data with labels, assignees | Yes |
| Pull Requests | PR data, reviews, comments | Yes |
| Commits | Commit history with diffs | Yes |
| Releases | Release versions with assets | Yes |
| Branches | Branch list and protection rules | Yes |
| Tags | Tag list with commit refs | Yes |
| Milestones | Milestone tracking | Yes |
| Labels | All repository labels | Yes |
| Workflow Runs | GitHub Actions run history | Yes |
| Workflow Jobs | Individual job details | Yes |
| Check Suites | Check suite results | Yes |
| Check Runs | Individual check results | Yes |
| Deployments | Deployment history | Yes |
| Teams | Organization team data | Yes |
| Collaborators | Repository collaborators | Yes |
| Table | Description |
|---|---|
github_repositories | Repository metadata |
github_issues | Issues with labels, assignees |
github_pull_requests | PRs with merge info |
github_commits | Commit history |
github_releases | Release tags |
github_branches | Branch information with protection status |
github_tags | Git tags |
github_milestones | Milestone tracking |
github_labels | Repository labels |
github_workflow_runs | GitHub Actions runs |
github_workflow_jobs | Individual workflow job details |
github_check_suites | Check suite results |
github_check_runs | Individual check run results |
github_deployments | Deployment records |
github_pr_reviews | Pull request reviews |
github_issue_comments | Issue and PR comments |
github_teams | Organization teams |
github_collaborators | Repository collaborators |
github_webhook_events | Webhook event log |
| View | Description |
|---|---|
github_open_items | Open issues and PRs by repository |
github_recent_activity | Last 7 days activity |
github_workflow_stats | Workflow success rates and durations |
-- Open issues by repository
SELECT
r.full_name,
COUNT(*) as open_issues
FROM github_issues i
JOIN github_repositories r ON i.repo_id = r.id
WHERE i.state = 'open'
GROUP BY r.full_name
ORDER BY open_issues DESC;
-- PR merge rate by author
SELECT
author,
COUNT(*) as total_prs,
COUNT(*) FILTER (WHERE merged_at IS NOT NULL) as merged,
ROUND(
COUNT(*) FILTER (WHERE merged_at IS NOT NULL)::numeric /
NULLIF(COUNT(*), 0) * 100, 1
) as merge_rate_percent
FROM github_pull_requests
GROUP BY author
HAVING COUNT(*) >= 5
ORDER BY total_prs DESC
LIMIT 20;
-- Workflow success rate by repository
SELECT
r.full_name,
COUNT(*) as total_runs,
COUNT(*) FILTER (WHERE w.conclusion = 'success') as success,
COUNT(*) FILTER (WHERE w.conclusion = 'failure') as failure,
ROUND(
COUNT(*) FILTER (WHERE w.conclusion = 'success')::numeric /
NULLIF(COUNT(*), 0) * 100, 1
) as success_rate
FROM github_workflow_runs w
JOIN github_repositories r ON w.repository_id = r.id
WHERE w.created_at > NOW() - INTERVAL '30 days'
GROUP BY r.full_name
ORDER BY total_runs DESC;
-- Development velocity
SELECT
DATE_TRUNC('week', merged_at) as week,
COUNT(*) as merged_prs,
SUM(additions) as lines_added,
SUM(deletions) as lines_deleted,
ROUND(AVG(
EXTRACT(EPOCH FROM (merged_at - created_at)) / 3600
), 1) as avg_time_to_merge_hours
FROM github_pull_requests
WHERE merged_at IS NOT NULL
AND merged_at > NOW() - INTERVAL '12 weeks'
GROUP BY week
ORDER BY week DESC;query GetRepositoryStats {
github_repositories(
order_by: { stargazers_count: desc }
limit: 10
) {
full_name
stargazers_count
forks_count
open_issues_count
github_pull_requests_aggregate(
where: { state: { _eq: "open" } }
) {
aggregate {
count
}
}
}
}ENV=dev
GITHUB_TOKEN=ghp_dev_token
GITHUB_REPOS=myorg/dev-repoENV=prod
GITHUB_TOKEN=ghp_prod_token
GITHUB_ORG=myorgUse different tokens or sync different repos per environment.
# Remove plugin and data
nself plugin remove github
# Keep database tables
nself plugin remove github --keep-datahttps://your-domain.com/webhookapplication/jsonGITHUB_WEBHOOK_SECRETpush - Pushes to the repositoryissues - Issue opened, edited, deleted, closed, reopenedpull_request - PR opened, closed, merged, editedpull_request_review - PR review submittedrelease - Release created, edited, publishedworkflow_run - GitHub Actions workflow completedworkflow_job - GitHub Actions job completedcheck_suite - Check suite completedcheck_run - Check run completeddeployment - Deployment createddeployment_status - Deployment status changedcreate - Branch or tag createddelete - Branch or tag deletedstar - Repository starredfork - Repository forkedError: Bad credentialsSolution: Verify your token:
curl -H "Authorization: token $GITHUB_TOKEN" https://api.github.com/userError: API rate limit exceededCheck your rate limit status:
curl -H "Authorization: token $GITHUB_TOKEN" https://api.github.com/rate_limitSolutions:
Error: Webhook signature verification failedSolutions:
GITHUB_WEBHOOK_SECRET matches the webhook settingsapplication/jsonLOG_LEVEL=debug nself-github sync-- Create a project health dashboard view
CREATE VIEW project_health AS
SELECT
r.full_name,
r.stargazers_count AS stars,
(SELECT COUNT(*) FROM github_issues i
WHERE i.repo_id = r.id AND i.state = 'open') AS open_issues,
(SELECT COUNT(*) FROM github_pull_requests p
WHERE p.repo_id = r.id AND p.state = 'open') AS open_prs,
(SELECT AVG(CASE WHEN w.conclusion = 'success' THEN 1 ELSE 0 END) * 100
FROM github_workflow_runs w
WHERE w.repo_id = r.id
AND w.created_at > NOW() - INTERVAL '7 days') AS ci_success_rate
FROM github_repositories r;// Monitor workflow failures
async function checkWorkflowHealth(repoName: string) {
const result = await hasura.query({
query: `
query WorkflowHealth($repo: String!) {
github_workflow_runs(
where: {
repository: { full_name: { _eq: $repo } }
created_at: { _gte: "now() - interval '24 hours'" }
}
order_by: { created_at: desc }
) {
id
name
conclusion
created_at
html_url
}
}
`,
variables: { repo: repoName }
});
const failed = result.github_workflow_runs
.filter(r => r.conclusion === 'failure');
if (failed.length > 0) {
console.log(`Warning: ${failed.length} failed workflows`);
}
return result.github_workflow_runs;
}| Option | Cost | Data ownership | Self-hostable |
|---|---|---|---|
| GitHub Insights (built-in) | Included with GitHub, limited metrics | GitHub holds all data | No |
| LinearB | $17–25/developer/mo | LinearB syncs your data to their cloud | No |
| Swarmia | $25–40/developer/mo | Swarmia syncs your data to their cloud | No |
| Metabase + manual sync | $0 (open source) + engineering time | You own everything | Yes — DIY |
| nself-github | Free — no license key needed | Your Postgres, your VPS | Yes |
Free Plugin | Last Updated: May 2026 | Plugin Version 1.1.0