Aspire-powered GitHub PR dashboard for the Aspire team to triage pull requests across the Aspire repos. The dashboard loads one or more repositories, ranks review work by urgency, personalizes a "For me" queue when signed in, and shows timeline details that are easier to scan than a raw GitHub comment stream.
By default the UI watches:
microsoft/aspiremicrosoft/aspire.devmicrosoft/dcpCommunityToolkit/Aspire
You can replace those with any comma-separated owner/repo list in the dashboard.
pr-timeline-app.AppHost/- Aspire AppHost that coordinates the backend and Vite frontend for development, publishes the frontend into the backend for deployment, and defines the Azure Container Apps environment.pr-timeline-app.Server/- ASP.NET Core API for GitHub pull requests, review state, timelines, OAuth login, development token fallback, and published static files.frontend/- React/Vite dashboard UI.pr-timeline-app.Tests/- Aspire-backed smoke tests for authentication and API validation.
- .NET 10 SDK preview
- Aspire CLI from the dev channel
- Node.js
20.19+,22.12+, or newer - Optional for local development: GitHub CLI (
gh) authenticated withgh auth login - Required for manual Azure deployment: Azure CLI
Install frontend dependencies once:
npm --prefix frontend ciStart the app with Aspire:
aspire startThe AppHost path is configured in aspire.config.json. The Vite frontend is served at http://localhost:5173/. API requests under /api are proxied to the ASP.NET Core server through the Aspire-provided SERVER_HTTPS or SERVER_HTTP environment variable. The server endpoint is also shown in the Aspire dashboard.
In development, the backend can call GitHub with:
- An in-app OAuth session, when
GITHUB_CLIENT_IDandGITHUB_CLIENT_SECRETare set. GITHUB_TOKEN.GH_TOKEN.gh auth token.
Outside Development, OAuth is required and the server fails startup unless GITHUB_CLIENT_ID and GITHUB_CLIENT_SECRET are configured. The OAuth callback path is /signin-github, for example https://<app-host>/signin-github.
The app requests the repo and read:org scopes.
GET /api/github/auth-statusGET /api/github/login?returnUrl=/...POST /api/github/logoutGET /api/github/pulls?repo=owner/repo&state=open|closed|allGET /api/github/pulls/{number}/timeline?repo=owner/repo
If repo is omitted, the backend defaults to microsoft/aspire.
npm --prefix frontend ci
npm --prefix frontend run lint
npm --prefix frontend run build
dotnet restore pr-timeline-app.slnx
dotnet build pr-timeline-app.slnx --no-restoreThe test project contains Aspire-backed smoke tests for authentication and API validation. They start the AppHost with the frontend disabled.
dotnet test pr-timeline-app.slnx --no-buildThe AppHost is configured with an Azure Container Apps environment named aca. In publish/deploy mode, the ASP.NET Core server is the public entrypoint and serves the built Vite frontend from wwwroot.
The generated Container Apps deployment uses the Consumption workload profile and allows the server app to scale to zero replicas when idle. This keeps idle compute cost low while preserving the same public endpoint, with the tradeoff that the first request after an idle period can wait for a cold start.
Create a GitHub OAuth App before deploying. For a manual deployment, authenticate with Azure CLI and provide the Azure target plus GitHub OAuth parameters:
az login
export Azure__SubscriptionId=<subscription-id>
export Azure__Location=<azure-region>
export Azure__ResourceGroup=<resource-group>
export Parameters__github_client_id=<oauth-app-client-id>
export Parameters__github_client_secret=<oauth-app-client-secret>
aspire deployAfter the first deploy prints the Container App URL, update the GitHub OAuth App callback URL to https://<aca-fqdn>/signin-github, then redeploy or restart the app and test sign-in.
The .github/workflows/deploy.yml workflow deploys to Azure Container Apps after the CI workflow succeeds on main. It can also be run manually.
Configure a GitHub Environment named production with these values:
| Type | Name | Value |
|---|---|---|
| Secret | AZURE_CLIENT_ID |
Entra app registration client ID used by GitHub Actions OIDC |
| Secret | AZURE_TENANT_ID |
Azure tenant ID |
| Secret | AZURE_SUBSCRIPTION_ID |
Azure subscription ID |
| Secret | OAUTH_GITHUB_CLIENT_SECRET |
GitHub OAuth App client secret |
| Variable | AZURE_LOCATION |
Azure region, for example westus2 |
| Variable | AZURE_RESOURCE_GROUP |
Azure resource group, for example rg-pr-timeline-app-aca |
| Variable | OAUTH_GITHUB_CLIENT_ID |
GitHub OAuth App client ID |
Create a federated credential on the Entra app registration with:
issuer: https://token.actions.githubusercontent.com
subject: repo:davidfowl/pr-dashboard:environment:production
audience: api://AzureADTokenExchange
Grant that identity Contributor and User Access Administrator on the deployment resource group so Aspire can provision resources and role assignments.