Skip to content

v2.0.0-alpha.5: GitHub App Integration - #135

Merged
norberia merged 10 commits into
mainfrom
feat/github-app-integration
Mar 4, 2026
Merged

v2.0.0-alpha.5: GitHub App Integration#135
norberia merged 10 commits into
mainfrom
feat/github-app-integration

Conversation

@norberia

@norberia norberia commented Mar 4, 2026

Copy link
Copy Markdown
Collaborator

GitHub App Integration

Closes #115

Summary

This PR implements GitHub App integration to replace the legacy GitHub OAuth approach for repository operations. The integration provides better security, fine-grained permissions, and a streamlined user experience.

Changes

Phase 1: Backend Infrastructure ✅

  • Schema: Added GitHubAppInstallation model and new GitHub fields on Project (githubAppInstallationId, githubRepoId, githubRepoFullName)
  • Service Layer: Created lib/services/github-app.ts with JWT generation, installation token caching, and webhook signature verification
  • Repository Layer: Added lib/repo/github.ts for installation CRUD and project-repo linking
  • API Routes:
    • app/api/github/app/callback/route.ts - Handles GitHub App installation callback with ownership verification
    • app/api/github/app/webhook/route.ts - Processes installation lifecycle events (created/deleted/suspend/unsuspend)

Phase 2: Frontend UI ✅

  • Settings Page: app/settings/page.tsx with GitHub integration status
  • Import Dialog: components/dialog/import-github-dialog.tsx with 3-step flow (GitHub identity → GitHub App → Repo selection)
  • Components:
    • components/github/github-status-card.tsx - GitHub connection status
    • components/github/repo-selector.tsx - Searchable repo selector
    • components/github/installation-list.tsx - Installation management

Phase 3: Octokit + Merged OAuth ✅

  • Migrated from manual fetch to @octokit/rest and @octokit/app
  • Enabled "Request user authorization during installation" on GitHub App
  • Merged authentication and authorization into a single flow
  • Fixed OAuth token exchange endpoint (use github.com/login/oauth/access_token instead of API route)
  • Fixed callback response format (HTML with postMessage for popup communication)

Phase 4: Code Migration ✅

  • Updated components/layout/repo-status-indicator.tsx to prioritize new fields with fallback
  • Updated app/(dashboard)/projects/[id]/github/page.tsx with new field strategy
  • Updated lib/services/repoService.ts:
    • createGithubRepo() returns repoId and repoFullName
    • initializeRepo() saves both new and legacy fields
    • pushToGithub() uses githubRepoFullName || githubRepo pattern

Backward Compatibility

The implementation follows an expand-contract migration strategy:

const repoFullName = project.githubRepoFullName || project.githubRepo
  • ✅ Legacy data (only githubRepo) continues to work
  • ✅ New data uses the more accurate fields
  • ✅ Mixed data prioritizes new fields
  • ✅ No forced data migration required

User Flow

GitHub OAuth (Identity) → GitHub App Installation → Select Repo → Link to Project
UserIdentity             → GitHubAppInstallation  → Project.githubRepoId

Environment Variables Required

GITHUB_APP_ID=<App ID>
GITHUB_APP_PRIVATE_KEY=<PEM private key>
GITHUB_APP_WEBHOOK_SECRET=<Webhook secret>
GITHUB_APP_CLIENT_ID=<OAuth App Client ID>
GITHUB_APP_CLIENT_SECRET=<OAuth App Client Secret>
NEXT_PUBLIC_GITHUB_APP_NAME=<App slug for install URL>

Testing

  • ✅ Lint passes
  • ✅ Build succeeds
  • ✅ GitHub App installation flow works
  • ✅ OAuth code exchange succeeds
  • ✅ UserIdentity and GitHubAppInstallation created correctly
  • ✅ Popup auto-closes after installation
  • ✅ Frontend state updates correctly

Remaining Work (Phase 5 - Optional)

Phase 5 (Cleanup) is optional and can be deferred:

  • Remove deprecated githubRepo field from schema
  • Remove legacy GitHub OAuth routes
  • Update documentation

This can be done after 3-6 months when legacy data is no longer needed.

norberia and others added 10 commits February 25, 2026 18:07
Phase 1 design covering GitHub App infrastructure, OAuth replacement,
webhook sync, and installation token management.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Add GitHubAppInstallation model and GitHubInstallationStatus enum
- Add GitHub App environment variables (GITHUB_APP_ID, GITHUB_APP_PRIVATE_KEY, GITHUB_APP_WEBHOOK_SECRET)
- Add GitHub App service with JWT generation, token caching, and webhook verification
- Add repository layer for installation CRUD operations
- Add installation callback route with ownership verification
- Add webhook endpoint for installation events (created/deleted/suspend/unsuspend)
- Update plan document with identity vs authorization design decisions~
- Add settings page with GitHub integration status
- Add Import dialog with 3-step flow (identity → app → repo)
- Add callback page for popup-based installation flow
- Add Server Actions for GitHub data fetching
- Add NEXT_PUBLIC_GITHUB_APP_NAME env variable
- Improve private key resolution for PEM/base64 formats
…th flow

Phase 3 completed: Migrated to Octokit and merged authentication and authorization flow

## Completed Work

### 1. Migrate to Octokit
- Replace manual JWT signing with @octokit/app
- Octokit automatically manages installation token caching
- Use @octokit/webhooks for webhook signature verification

### 2. Merge OAuth Flow
- Implement GitHub App OAuth flow (enabled "Request user authorization during installation")
- Add exchangeCodeForUserToken() to handle OAuth code exchange
- Add refreshUserToken() to handle token refresh
- Callback creates both UserIdentity and GitHubAppInstallation

### 3. Fix Critical Issues
- Fix callback returning JSON instead of HTML page
- Fix OAuth token exchange using wrong endpoint (404 error)
- Fix frontend still using deprecated checkGitHubIdentity()
- Fix GitHub App missing Callback URL configuration

### 4. Frontend Optimization
- Remove deprecated checkGitHubIdentity() call
- Use installations.length directly to check connection status
- Simplify logic to align with Phase 3 design goals

## Modified Files

- lib/services/github-app.ts - Migrate to Octokit, fix OAuth token exchange
- app/api/github/app/callback/route.ts - Handle OAuth flow, return HTML page
- app/api/github/app/webhook/route.ts - Use @octokit/webhooks
- components/github/github-status-card.tsx - Remove deprecated function call
- lib/env.ts - Add GITHUB_APP_CLIENT_ID and GITHUB_APP_CLIENT_SECRET
- docs/plans/2026-02-25-github-app-integration-plan.md - Update progress documentation

## Verification Results

- ✅ Lint check passed
- ✅ Build successful
- ✅ GitHub App installation flow works correctly
- ✅ OAuth code exchange successful
- ✅ UserIdentity and GitHubAppInstallation created correctly
- ✅ Popup closes automatically
- ✅ Frontend state updates correctly

## Next Steps

Phase 4: Data Migration - Populate new fields when users re-associate repos
- Redefine Phase 4 as 'Code Migration' instead of 'Data Migration'
- Add detailed implementation steps for updating frontend components
- Add backward compatibility strategy with fallback logic
- Mark Phase 5 as optional with clear timing recommendations
- Add estimated workload: 1-2 hours for Phase 4

Key changes:
- Phase 4: Update frontend code to use new fields with fallback
- Phase 5: Optional cleanup, can be deferred or skipped~
- Update repo-status-indicator to prioritize new GitHub fields with fallback
- Update GitHub page to use new field strategy
- Update repoService to save both new and legacy fields
- Remove planning documents
- Bump version to 2.0.0-alpha.5

Closes #115
@github-actions

github-actions Bot commented Mar 4, 2026

Copy link
Copy Markdown

✅ PR Check Results: Passed

Build Checks

Check Status
Lint & Build ✅ Passed
Docker Build ✅ Passed

✨ Great work!

All checks passed successfully. Your PR is ready for review.

Details:

  • ✅ Code quality verified (linting passed)
  • ✅ Build successful
  • ✅ Docker image build verified (linux/amd64)
    Commit: 720cfa6696a0ab9a622fbe690c6da8b95ddf9493
    Branch: feat/github-app-integration

🔗 View Details:

@norberia
norberia merged commit 4e18742 into main Mar 4, 2026
9 checks passed
@norberia
norberia deleted the feat/github-app-integration branch March 6, 2026 06:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Upgrade oauth to using GitHub App & Bot

1 participant