Tracks pull request cycle times from GitHub — coding, pickup, review, and deploy — so teams can see where time is spent and ship faster.
Data is stored in SQLite with a multi-tenant (database-per-org) architecture.
- Node.js 22+
- pnpm
pnpm installUpFlow uses a GitHub App for OAuth login. This is required regardless of which integration method you choose below.
Create a GitHub App at https://github.com/settings/apps/new:
- Callback URL:
http://localhost:5173/api/auth/callback/github(dev) /https://your-domain/api/auth/callback/github(prod) - Expire user authorization tokens: ON
- Request user authorization (OAuth) during installation: ON
- Permissions > Account permissions > Email addresses: Read-only
Then copy .env.example and fill in the values:
cp .env.example .env| Variable | Description |
|---|---|
UPFLOW_DATA_DIR |
Data directory path (e.g. ./data) |
BETTER_AUTH_SECRET |
Secret for better-auth (min 32 chars) |
BETTER_AUTH_URL |
App URL (e.g. http://localhost:5173) |
GITHUB_CLIENT_ID |
GitHub App client ID |
GITHUB_CLIENT_SECRET |
GitHub App client secret |
UpFlow supports two ways to fetch PR data from GitHub.
The quickest way to get started on a single server. Just add a GitHub PAT to .env:
| Variable | Description |
|---|---|
INTEGRATION_PRIVATE_TOKEN |
GitHub PAT for PR data fetching |
PR data is fetched by an hourly crawl job. For the initial fetch, see Fetching PR Data below.
For multi-team rollouts where PR data should update instantly on events. This uses the same GitHub App created in Step 2, with additional permissions and configuration.
In your GitHub App settings, add the following repository permissions:
- Contents: Read-only (commits)
- Pull requests: Read-only (PRs, reviews, comments)
- Deployments: Read-only (deploy events for cycle time calculation)
- Metadata: Read-only (automatically granted)
Add to .env:
| Variable | Description |
|---|---|
GITHUB_APP_ID |
GitHub App ID |
GITHUB_APP_PRIVATE_KEY |
GitHub App private key (base64 encoded) |
GITHUB_WEBHOOK_SECRET |
Webhook signature verification secret |
The private key should be base64-encoded from the PEM file (required for platforms like Fly.io where newlines in env vars are problematic).
- Log in to UpFlow and go to Settings > Integration
- Switch the integration method to GitHub App
- Click Install GitHub App — you'll be redirected to GitHub's installation page
- Select the target Organization and configure repository access (All / Selected)
- You'll be redirected back to UpFlow once installation is complete
You can verify the connection status in Settings > Integration.
Set up the webhook to enable realtime PR data updates.
- In your GitHub App settings, set Webhook to Active
- Webhook URL:
https://your-domain/api/github/webhook - Generate a Webhook Secret and set the same value in both GitHub App settings and
GITHUB_WEBHOOK_SECRETin.env - Under Subscribe to events, enable:
- Pull request — triggers realtime crawl on PR changes
- Pull request review — captures review events
- Pull request review comment — captures review comments
pnpm db:setuppnpm devUpFlow needs to fetch PR data from GitHub to display metrics. After adding a repository in the dashboard, run:
pnpm tsx batch/cli.ts crawl <org-id>In production, crawl runs automatically every hour. With Method B (GitHub App + Webhook), data also updates in realtime on PR events.
- GitHub OAuth only: login requires the user's GitHub login to be registered in the org's GitHub Users list with Active status
- First-user bootstrap: on a fresh database with no users, the first GitHub login is allowed unconditionally and promoted to super admin
- Auto-registration: PR authors and reviewers are automatically added as inactive GitHub users during crawl — an admin enables them via Settings > GitHub Users