Repository navigation
Deployment
The site is published by one GitHub Actions workflow,
.github/workflows/deploy.yml, named "Deploy to Cloudflare Pages". It is the
only deploy path; the openapi-sync workflow (below) starts it after updating
the API spec.
| Event | Behaviour |
|---|---|
push to main
|
Builds and deploys |
workflow_dispatch |
Can be started manually, but the job is skipped unless the ref is main. openapi-sync dispatches it this way |
The job carries if: github.ref == 'refs/heads/main'. That guard exists because
GitHub offers no branch filter on workflow_dispatch: anyone with write access
could otherwise run the workflow from an arbitrary branch and reach the
production secrets. A manual run from a feature branch will appear in the Actions
tab with the job skipped — that is the guard working, not a failure.
The workflow declares permissions: contents: read.
The job runs on ubuntu-latest and does four things:
-
actions/checkout— checkout, pinned to a commit SHA. -
actions/setup-node— Node.js 20 with npm caching, pinned to a commit SHA. -
npm cithennpm run build— a clean install againstpackage-lock.json, then the static Astro build intodist/. -
cloudflare/wrangler-action— pinned to a commit SHA, running the Pages deploy.
Every third-party action is pinned by full commit SHA with the tag in a trailing comment. Keep that convention when bumping a version: change both the SHA and the comment.
The wrangler action runs:
pages deploy dist --project-name=reportmate-website --branch=main
So the built dist/ directory is uploaded to a Cloudflare Pages project named
reportmate-website, on the main branch — which for a Pages project is the
production deployment.
.github/workflows/openapi-sync.yml keeps public/openapi.json, which /docs
renders, in step with the API.
| Setting | Value |
|---|---|
| Trigger | Daily at 05:23 UTC, and workflow_dispatch
|
| Guard | The job runs only on main
|
| Permissions |
contents: write, actions: write
|
It checks out reportmate-api without credentials, installs its requirements,
runs scripts/export_openapi.py, checks that the output parses as JSON and
copies it over public/openapi.json. When the file changed, it commits
Sync openapi.json with reportmate-api at <sha> as github-actions[bot],
pushes to main, and runs gh workflow run deploy.yml --ref main — a push
made with the workflow token does not trigger other workflows on its own. When
nothing changed it exits without a commit.
Two repository secrets are required. Neither is in the repo.
| Secret | Used for |
|---|---|
CLOUDFLARE_API_TOKEN |
Authenticates the Pages deploy |
CLOUDFLARE_ACCOUNT_ID |
Identifies the Cloudflare account holding the project |
A fork will not have these, so the deploy step fails there. That is expected;
forks should rely on npm run build locally.
astro.config.mjs sets site: 'https://reportmate.app', which is what canonical
links and Open Graph image URLs are built from. The custom domain itself is
attached to the Cloudflare Pages project in the Cloudflare dashboard, not in this
repository — nothing here configures DNS.
README.md says the site is "Hosted on AWS (S3 + CloudFront)" and that dist/
should be deployed to S3. The workflow deploys to Cloudflare Pages. Treat the
workflow as authoritative and the README line as stale.
Not normally necessary — merging to main is the supported path. If you do need
to publish out of band, build first and then run the same wrangler command
locally with an API token in your environment:
npm ci
npm run build
npx wrangler pages deploy dist --project-name=reportmate-website --branch=main
The next push to main re-runs the workflow and overwrites whatever you pushed,
so make sure the change is also committed.
MIT licensed — reportmate.app