Deploying the dashboard with GitHub Actions
About the GitHub Actions only deployment
Section titled “About the GitHub Actions only deployment”The GitHub Actions only deployment is the default way to host the dashboard. Everything runs in your control repository:
- The CAO Activity workflow collects evidence.
- The CAO Dashboard workflow builds a static site and its data payload.
- GitHub Pages serves the site.
Queries run in each viewer’s browser, in a web worker over a local IndexedDB database. You don’t operate a server, a database, or a cloud account. For more information about how the browser loads data, see Browser data pipeline.
Prerequisites
Section titled “Prerequisites”| Requirement | Details |
|---|---|
| Control repository | A private repository that runs CAO. GitHub Enterprise is not required. |
| GitHub Actions | Enabled for the repository. You need GitHub-hosted ubuntu-latest runners or compatible self-hosted runners, and enough minutes for an hourly Activity run. |
| Actions cache | Stores the Activity snapshot (cao-activity-v5-*) and the built dashboard (central-agentic-ops-dashboard). If the cache is evicted, the dashboard uses the latest successful Activity artifact instead. For more information, see Cache contract. |
| Actions artifacts | Stores the cao-activity-index and central-agentic-ops-dashboard artifacts. The dashboard artifact is kept for one day. |
| GitHub Pages | The publishing source must be GitHub Actions. To make the site private, you need a plan that supports access control for Pages, such as GitHub Enterprise Cloud. Otherwise, the site is public. |
github-pages environment | Created automatically by GitHub Pages. You can protect it with required reviewers. |
| Browser | A current browser that supports web workers, IndexedDB, and JavaScript modules. The browser downloads and indexes the data on first load. |
The dashboard build, Pages artifact, and deploy jobs don’t need additional
secrets. The build job uses the automatic github.token with actions: read
and contents: read permissions. A separate job packages and uploads the Pages
artifact before the deploy job uses OpenID Connect (OIDC) with pages: write
and id-token: write permissions.
The Pages artifact and deploy jobs rely on the standard Pages actions to report
configuration and deployment errors; they do not separately verify Pages
visibility with the Actions token. The Configure Pages step sets
ignore-if-missing: true, but the pinned action does not currently support
that input, so it can still fail when Pages settings are unavailable. Confirm
the publishing source and intended access boundary in Settings > Pages
before deployment.
Choosing a credential profile
Section titled “Choosing a credential profile”The Activity collector, orchestrators, and workers call the GitHub API with a credential that you configure in the control repository. That credential determines which evidence the dashboard can show and which repositories campaigns can reach. Choose one profile before the first run.
| Profile | Best for | Credentials | Limitations |
|---|---|---|---|
| GitHub Apps | Production | A private read app and a private write app | You need permission to create and install private GitHub Apps. |
| Fine-grained PAT | Getting started and experimentation | A read PAT and write PAT for each resource owner | Not for production. The tokens are tied to one user, expire, need manual rotation, don’t support every API, and each owner pair has its own rate limit. |
At runtime, CAO uses the explicitly selected App or owner-scoped PAT profile. The repository-provided github.token remains only as a bounded control-repository fallback.
For more information, see Configure authentication.
Deploying the dashboard
Section titled “Deploying the dashboard”-
Install the dashboard. The supported CAO installer includes it through the explicit root package. Advanced users can install only the Activity and dashboard components; unpinned package coordinates resolve the latest release automatically.
Terminal window gh aw add githubnext/gh-cao/activitygh aw add githubnext/gh-cao/dashboard -
Review, commit, and push the installed files. These include
.github/workflows/cao-activity.yml,.github/workflows/cao-dashboard.yml, and theactivity/anddashboard/directories. -
Configure your cross-repository credential profile. Follow the procedure for GitHub Apps or for fine-grained PATs.
-
Run
gh cao setupin the control repository to configure GitHub Pages with GitHub Actions as its source. For a private repository it also restricts access to repository readers; this requires a plan that supports private Pages and permission to manage Pages settings. Setup fails rather than leaving a public site eligible for deployment if access cannot be restricted. If setup was already completed, confirm the Pages source and visibility in Settings > Pages. -
Optionally, protect the
github-pagesenvironment. For more information, see Managing environments for deployment in the GitHub documentation. -
Run the Activity workflow.
- Under your repository name, click Actions.
- In the left sidebar, click CAO Activity.
- Click Run workflow, then wait for the run to succeed.
The dashboard build fails if no successful Activity run exists. If the run fails, see Routine monitoring.
-
Wait for the automatically triggered CAO Dashboard workflow to finish, then open the URL from its
deployjob. Confirm that the site shows data only from your control repository.
To learn how to read the dashboard, see Dashboard and Overview.
Keeping the site up to date
Section titled “Keeping the site up to date”The CAO Activity workflow runs when you push changes to any of these paths on the default branch:
.github/workflows/cao.json.github/workflows/cao-dashboard.yml*/dashboard.jsondashboard/**
Dashboard has no push trigger or schedule. Every successful default-branch Activity run triggers one Dashboard build, so a relevant push produces one collection-and-publication sequence without a duplicate deployment.
Failed or cancelled Activity runs produce skipped Dashboard runs rather than publishing an invalid snapshot. If every Activity-triggered Dashboard run is skipped, inspect the upstream Activity run first. A confirmed API capacity limit is recoverable: Activity indexes retained and downloaded runs, marks the affected repository coverage as partial, and skips further issue-status and operational-value API work. Authentication, visibility, and invalid-data failures still block publication.
An automatically triggered Dashboard build restores the exact triggering Activity run and attempt’s cache, falling back only to that run’s artifact. It cannot silently publish a different run’s older snapshot. Manual dispatch can still rebuild from the last cached snapshot without collecting fresh evidence.
Configuration reference
Section titled “Configuration reference”| Setting | Location | Default | Description |
|---|---|---|---|
control-plane.campaigns.dashboard.deploy | .github/workflows/cao.json | true | A boolean. When false, the workflow still builds and caches the dashboard artifact but doesn’t deploy it to Pages. |
| Activity schedule | .github/workflows/cao-activity.yml | Hourly | Controls how fresh the evidence is. Change it in the campaign source and run gh aw update. Don’t edit the installed lock file. |
| Activity retention | Ingestion steps in cao-activity.yml and cao-dashboard.yml | 30 days | Limits the size of the payload that browsers download. For more information, see Update and retain browser data. |
| Pages visibility | Repository Pages settings | Depends on your plan | Controls who can read the site. |
Pages destinations follow each campaign’s rollout mode. In review mode, the dashboard publishes to access-controlled review Pages. In live mode, it publishes to production Pages. For more information, see Pages report routing.
Publishing from an existing Pages workflow
Section titled “Publishing from an existing Pages workflow”If another workflow already publishes your Pages site, set control-plane.campaigns.dashboard.deploy to false. In your existing workflow, find the latest successful cao-dashboard.yml run on the default branch, download its central-agentic-ops-dashboard artifact into your site output, and deploy the combined result.
Monitoring the deployment
Section titled “Monitoring the deployment”This option has no server, so there’s no server-side OpenTelemetry endpoint to configure for the dashboard. Use these signals instead.
| Signal | What to check |
|---|---|
| Workflow health | GitHub Actions run history is the primary record. When an Activity or dashboard job fails, CAO opens or updates a CAO Activity workflow failure or CAO Dashboard workflow failure issue with a stable failure code, such as CAO_DASHBOARD_DEPLOY_FAILED. |
| Data health | The build runs activity/cao.mjs validate-activity-data and activity/cao.mjs doctor against the restored database. The results appear in the job log. |
| Credential health | Skipped create-github-app-token steps, admission capacity gates, and authentication failures show which credential a run used. For details, see the GitHub Apps and fine-grained PAT profiles. |
| Agentic workflow traces | Orchestrators and workers export OpenTelemetry spans through gh-aw. To turn on export, set the GH_AW_DEFAULT_OTLP_ENDPOINT variable and the GH_AW_DEFAULT_OTLP_HEADERS secret at the repository, organization, or enterprise level. For more information, see Optional observability. |
| Browser diagnostics | Add ?debug=1, ?debug=*, or a category filter such as ?debug=data:query,-render:* to the dashboard URL. The browser console then shows structured diagnostics that contain no sensitive data. ?debug=data:query shows timings for each query stage. |
| Local reproduction | In a checkout of the catalog repository, run npm run dashboard:local -- --repo OWNER/REPOSITORY to download the published data and preview it locally. To query the same data with SQLite, see Use local SQLite. |
What this deployment guarantees
Section titled “What this deployment guarantees”- Exact source. The site is built from the exact workflow commit (
github.workflow_sha). It publishes only the payload files listed in the manifest. - Complete payloads. Every payload file is hash-verified before the browser loads it. If the payload is incomplete, the build fails instead of publishing partial data.
- No long-lived credentials. The build, Pages artifact, and deploy jobs don’t hold long-lived credentials. The deploy job uses OIDC.
- One deployment at a time. A running dashboard build finishes publishing its snapshot without being cancelled by newer triggers. GitHub Actions keeps at most one pending eligible build, replacing it when a newer eligible run arrives. Ineligible triggers use separate concurrency groups and cannot displace that pending build.
- Safe failures. If a build or deployment fails, the previously deployed site stays in place.
What this deployment does not guarantee
Section titled “What this deployment does not guarantee”- Freshness. The site is a snapshot of the last successful deployment. It can lag behind the latest Activity run.
- Confidentiality. A private repository doesn’t make its Pages site private. Access control depends on the Pages visibility settings that your plan supports.
- Durability. Actions caches can be evicted, and artifacts expire. The site isn’t an archive. Target repository history and Actions run metadata remain the source of truth. To keep history longer, see Create a historical archive.
- Scale. Each viewer’s browser downloads and queries all of the data. Large fleets can exceed browser memory or load slowly. If that happens, consider a server-backed option.
- Per-user authorization. Anyone who can read the Pages site can read all of its data. There is no per-user or per-repository filtering.
- Availability. Availability depends on GitHub Pages and GitHub Actions. CAO adds no SLA.
- Coverage. The dashboard shows only evidence that your credential can read. Repositories that the credential can’t reach appear as incomplete coverage, not as healthy repositories with no activity.
Rolling back or stopping the deployment
Section titled “Rolling back or stopping the deployment”- To roll back, run the CAO Dashboard workflow from a known-good commit, or revert the change and push.
- To stop future deployments, set
control-plane.campaigns.dashboard.deploytofalse. This setting doesn’t remove the current site. - To take the site down, unpublish it from your repository’s Pages settings, or block the
github-pagesenvironment.
If private data was exposed, treat it as a Pages incident. For more information, see Incident response.
Next steps
Section titled “Next steps”- If you haven’t set up credentials yet, configure GitHub Apps or a fine-grained PAT.
- To publish reports for reviewed campaigns, see Publishing Pages reports.
Further reading
Section titled “Further reading”- About deployment options
- Set Up CAO
- Configure authentication
- CAO Activity
- Data ingestion
- Monitor and recover
- Configuring a publishing source for your GitHub Pages site in the GitHub documentation
- Changing the visibility of your GitHub Pages site in the GitHub documentation