From 86c60f6865a453673a6801de19ca373579e67047 Mon Sep 17 00:00:00 2001 From: Yurii Motov Date: Wed, 13 May 2026 16:52:40 +0200 Subject: [PATCH 1/6] Add overview and docs for backend --- README.md | 192 +++++++++++++++++++++++++++++++++++++++++++++- backend/README.md | 71 +++++++++++++++++ 2 files changed, 260 insertions(+), 3 deletions(-) create mode 100644 backend/README.md diff --git a/README.md b/README.md index 2651125..e492bf9 100644 --- a/README.md +++ b/README.md @@ -12,8 +12,194 @@

-# covered +# Covered -Self-hosted coverage reports storage for GitHub repositories. +Self-hosted coverage report hosting for GitHub repositories — an alternative to Smokeshow, Codecov, and Coveralls for teams that prefer to keep their coverage data in-house and overcome limitations. -Docs are coming soon. +**Covered** has two parts: + +- A **FastAPI backend** that stores HTML coverage reports, serves them over HTTP, and exposes an SVG badge. +- A **CLI** that runs in CI, uploads the report, posts a `covered` commit status to GitHub, and refreshes the badge cache. + +## Architecture + +Here is a [a bit simplified] diagram of how the components interact: + +```mermaid +flowchart LR + S3[("AWS S3
HTML reports")] + + CI["Covered CLI"] + Backend["Covered backend"] + Redis[("[Optional] Redis cache")] + GH["GitHub API"] + Reader["Browser"] + + CI -->|"Upload report files"| S3 + + CI -->|"Get S3 credentials for upload session"| Backend + CI -->|"Set commit status"| GH + Reader -->|"Get badge SVG
Redirect to report URL
Serve report files"| Backend + Backend -->|"Get latest status"| GH + Backend --> |"Get cached badge or report URL"| Redis + Backend -->|"Get report files"| S3 +``` + +CLI requests temporary credentials from the backend to upload the report to S3, uploads the report, then sets a `covered` status on the commit. +When reader opens the page that contains badge, the badge is loaded from the backend, which looks up the latest `covered` status for the default branch commit, finds the corresponding coverage value, and serves the badge SVG. The badge links to the report URL, which is also served by the backend. +Optional Redis caching can be used to reduce latency and GitHub API calls for frequently accessed badges. +After uploading a report on the default branch, the CLI can also trigger a cache purge (if `-purge-cache` is specified) to ensure the badge reflects the new coverage value as soon as possible. + +## Getting started + +Setting up Covered takes two steps: + +1. **Deploy the backend** — provision S3, Redis, and a GitHub token, then deploy to FastAPI Cloud. See [backend/README.md](backend/README.md). +2. **Wire up CI** — add the `covered` CLI to your test workflow. See the [GitHub Action setup](#github-action-setup) below; full CLI options are in [cli/README.md](cli/README.md). + +## GitHub Action setup + +In CI, coverage is uploaded by the [`covered` CLI](cli/README.md), which is published to PyPI. After your test job generates an HTML coverage report (typically `htmlcov/`), the CLI uploads it to your backend, posts a `covered` commit status on the commit, and refreshes the badge cache (if configured). + +### Workflow setup + +Before adding the workflows, make sure: + +- **The backend is deployed and reachable** — see [backend/README.md](backend/README.md). +- **Your project uses `uv` with a committed `uv.lock`.** The workflows install dependencies via `uv sync --locked`. + +Covered's CLI runs in a **separate workflow** that triggers after your test workflow finishes. This split is what makes coverage work for pull requests from forks: a fork's workflow can't read your `COVERED_API_KEY` secret and can't post commit statuses, but the second workflow runs in the base repository's context and can do both. + +The first workflow runs your tests and uploads the HTML report as an artifact. The second downloads the artifact and invokes the `covered` CLI. + +#### 1. Test workflow + +```yaml +# .github/workflows/test.yml +name: Test + +on: + push: + pull_request: + +permissions: + contents: read + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 + with: + version: "0.11.7" + enable-cache: true + - run: uv sync --locked + - run: uv run coverage run -m pytest + - run: uv run coverage html # writes htmlcov/ + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: coverage-html + path: htmlcov +``` + +#### 2. Coverage upload workflow + +```yaml +# .github/workflows/coverage-upload.yml +name: Coverage upload + +on: + workflow_run: + workflows: [Test] + types: [completed] + +permissions: + contents: read + actions: read # download the artifact from the Test run + statuses: write # post the `covered` commit status + +jobs: + upload: + runs-on: ubuntu-latest + if: github.event.workflow_run.conclusion == 'success' + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: coverage-html + path: htmlcov + github-token: ${{ secrets.GITHUB_TOKEN }} + run-id: ${{ github.event.workflow_run.id }} + - uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 + with: + version: "0.11.7" + enable-cache: true + - run: uv sync --locked + - name: Upload coverage to covered + run: uv run covered htmlcov + env: + COVERED_API_URL: ${{ secrets.COVERED_API_URL }} + COVERED_API_KEY: ${{ secrets.COVERED_API_KEY }} + COVERED_GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + COVERED_REPO_OWNER: ${{ github.repository_owner }} + COVERED_REPO_NAME: ${{ github.event.repository.name }} + COVERED_COMMIT_SHA: ${{ github.event.workflow_run.head_sha }} + COVERED_COVERAGE_THRESHOLD: 99 + COVERED_PURGE_CACHE: ${{ github.event.workflow_run.head_branch == github.event.repository.default_branch }} +``` + +#### 3. Add dev dependencies + +The workflows above expect `pytest`, `coverage`, and `covered` in the synced environment. Add them as dev dependencies: + +```bash +uv add --dev pytest coverage covered +``` + +#### 4. Configure repository secrets + +In your GitHub repository settings, add: + +| Secret | Value | +|---|---| +| `COVERED_API_URL` | Base URL of your deployed backend, e.g. `https://covered.example.com`. | +| `COVERED_API_KEY` | The `API_KEY` value you configured on the backend. | + +`COVERED_GH_TOKEN` does **not** need to be a custom PAT — the workflow-provided `${{ secrets.GITHUB_TOKEN }}` is sufficient, as long as the job has `statuses: write` permission. + +--- + +A few non-obvious points worth knowing: + +- `COVERED_COMMIT_SHA` must be `github.event.workflow_run.head_sha`, **not** `github.sha`. When a workflow is triggered by `workflow_run`, `github.sha` points at the default branch, not the commit that was actually tested. +- The same applies to `COVERED_PURGE_CACHE`: use `workflow_run.head_branch` to detect the default branch. +- `actions: read` is needed because the artifact lives on a different workflow run. + +For a working pair of workflows, see this repo's [test.yml](.github/workflows/test.yml) and [coverage-upload.yml](.github/workflows/coverage-upload.yml). The full list of CLI options is in [cli/README.md](cli/README.md). + +### Adding the badge to your README + +Once the upload has run at least once on your default branch, add the badge to your repository's README: + +```markdown +[![Coverage](https://covered.example.com/badge/OWNER/REPO.svg)](https://covered.example.com/badge/redirect/OWNER/REPO/) +``` + +Replace `covered.example.com` with your backend URL and `OWNER`/`REPO` with the repository's slug. The image points to the SVG badge endpoint. The link redirects to the latest stored report. + +### Troubleshooting + +| Symptom | Likely cause | +|---|---| +| Upload fails with 403 | `COVERED_API_KEY` doesn't match the backend's `API_KEY` setting. | +| Upload succeeds but no `covered` status on the commit | The job is missing `statuses: write`, or `COVERED_GH_TOKEN` cannot post statuses on the repository. | +| Coverage parsing is skipped | The directory passed to `covered` doesn't contain `index.html` — make sure `coverage html` ran successfully. | +| Badge shows `??` | No `covered` commit status has been posted on the default branch yet — re-run the workflow on `master`/`main`. | +| Badge doesn't refresh after a push to default branch | `COVERED_PURGE_CACHE` wasn't `true` for that run, or GitHub's image proxy (Camo) hasn't yet expired its cache (~5 minutes). | + +## License + +MIT. See [LICENSE](LICENSE). diff --git a/backend/README.md b/backend/README.md new file mode 100644 index 0000000..906cbef --- /dev/null +++ b/backend/README.md @@ -0,0 +1,71 @@ +

+covered
+Make it green. +

+ +# Covered backend + +FastAPI app that stores HTML coverage reports, serves them over HTTP, and exposes an SVG badge endpoint reflecting each repository's latest coverage on its default branch. + +This document is the operator manual — provisioning the external services, configuring the backend, deploying to [FastAPI Cloud](https://fastapicloud.com/), and verifying the install. For the project overview and the CI side of the picture, see the [top-level README](../README.md). + +## Prerequisites + +Before deploying the backend, you will need: + +- **An S3 bucket** to store the uploaded HTML reports. The backend writes objects under the `sites//...` prefix and reads them back when serving reports. No public access or static website hosting needs to be enabled — the backend serves files itself. + +- **An AWS IAM user for the backend**, with a long-lived access key. The user needs: + - `s3:PutObject` and `s3:GetObject` on `arn:aws:s3:::/sites/*` — used to create per-upload site directories and to serve report files. + - `sts:AssumeRole` on the upload role described below. + +- **An AWS IAM role for uploads**, whose ARN is passed to the backend as `AWS_UPLOAD_ROLE_ARN`. The backend assumes this role via STS to mint short-lived credentials that the CLI uses to upload report files directly to S3. The role needs: + - A permissions policy granting `s3:PutObject` on `arn:aws:s3:::/sites/*`. The backend further narrows this per upload via a session policy scoped to a single `site_id`, so the CLI never receives credentials that can write outside its own report directory. + - A trust policy allowing the backend IAM user to assume it. + +- **A Redis instance** reachable from the backend. It is used as a short-lived cache for rendered badge SVGs. + +- **A GitHub token** with read access to commit statuses on every repository whose coverage you want to display. A fine-grained PAT with `Commit statuses: Read-only` is sufficient; a classic PAT with `repo` (or `public_repo` for public repositories only) also works. + +## Environment variables + +The backend is configured via environment variables, loaded by `app.config.Settings` (pydantic-settings). + +| Variable | Required | Default | Description | +|---|---|---|---| +| `API_KEY` | yes | — | Token the CLI uses to authenticate with `/coverage/create-site/` and `/coverage/invalidate-cache/*`. Treat as a secret. | +| `AWS_REGION` | no | `us-east-1` | Region of the S3 bucket. | +| `AWS_BUCKET` | no | `covered` | Name of the S3 bucket reports are stored in. | +| `AWS_ACCESS_KEY_ID` | yes | — | Access key of the backend's IAM user (the one with `s3:GetObject`/`PutObject` on `/sites/*` and `sts:AssumeRole` on the upload role). | +| `AWS_SECRET_ACCESS_KEY` | yes | — | Secret access key for the above IAM user. | +| `AWS_UPLOAD_ROLE_ARN` | yes | — | ARN of the IAM role the backend assumes via STS to mint short-lived upload credentials for the CLI. | +| `REDIS_URL` | yes | — | Connection URL for Redis. Used to cache rendered badge SVGs (60 s TTL). | +| `GITHUB_TOKEN` | yes | — | GitHub token used to read commit statuses. See [Prerequisites](#prerequisites) for the required scopes. | + +## Deploying to FastAPI Cloud + +Covered is designed to run on [FastAPI Cloud](https://fastapicloud.com/). The deploy flow: + +1. **Sign up at [fastapicloud.com](https://fastapicloud.com/).** Access is waitlist-only at the moment — getting in typically takes a couple of days. + +2. **Create an app** in the FastAPI Cloud dashboard. + +3. **Configure the environment variables** on the app (the [table above](#environment-variables) lists all of them). FastAPI Cloud also offers a Redis integration that can set `REDIS_URL` for you — use it if you want, otherwise paste in the URL from your Redis provider. + +4. **Clone (or fork) this repository.** Fork if you plan to customize the backend. + +5. **Install dependencies and deploy.** From the repo root: + + ```bash + uv sync --project backend + cd backend + fastapi deploy + ``` + +6. **Authorize the CLI.** On the first deploy, the CLI opens your browser to authorize itself against your FastAPI Cloud account — grant the requested permissions. + +7. **Pick your team and app** when prompted. Typically your personal team and the app you created in step 2; leave the rest at their defaults. + +8. **Confirm and wait** for the deploy to report success. + +9. **Verify** by triggering the [`Coverage upload` workflow](../README.md#workflow-setup) in a repository configured to use this backend. If anything fails, the FastAPI Cloud dashboard logs are the first place to look. \ No newline at end of file From d382b3fd2b16c6e0a497e534bc79881c533cecce Mon Sep 17 00:00:00 2001 From: Yurii Motov Date: Wed, 13 May 2026 16:53:14 +0200 Subject: [PATCH 2/6] Fix command in `cli/README.md` --- cli/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/README.md b/cli/README.md index d34900e..6936272 100644 --- a/cli/README.md +++ b/cli/README.md @@ -33,7 +33,7 @@ covered ./htmlcov \ Every option also reads from a matching environment variable (`COVERED_API_URL`, `COVERED_API_KEY`, `COVERED_REPO_OWNER`, `COVERED_REPO_NAME`, `COVERED_COMMIT_SHA`, `COVERED_GH_TOKEN`, `COVERED_COVERAGE_THRESHOLD`, `COVERED_PURGE_CACHE`), which is the typical way to use it from CI. -`covered upload --help` lists all options. +`covered --help` lists all options. ## What it does From 90e4d204ed245f8b3a79475b7b0b6ec4856126aa Mon Sep 17 00:00:00 2001 From: Yurii Motov Date: Wed, 13 May 2026 16:56:49 +0200 Subject: [PATCH 3/6] Add empty lines for readability --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index e492bf9..ab9a064 100644 --- a/README.md +++ b/README.md @@ -46,8 +46,11 @@ flowchart LR ``` CLI requests temporary credentials from the backend to upload the report to S3, uploads the report, then sets a `covered` status on the commit. + When reader opens the page that contains badge, the badge is loaded from the backend, which looks up the latest `covered` status for the default branch commit, finds the corresponding coverage value, and serves the badge SVG. The badge links to the report URL, which is also served by the backend. + Optional Redis caching can be used to reduce latency and GitHub API calls for frequently accessed badges. + After uploading a report on the default branch, the CLI can also trigger a cache purge (if `-purge-cache` is specified) to ensure the badge reflects the new coverage value as soon as possible. ## Getting started From 10cddf28a6f27335da2191911b33db3c9ad19771 Mon Sep 17 00:00:00 2001 From: Yurii Motov Date: Thu, 14 May 2026 17:34:37 +0200 Subject: [PATCH 4/6] Update backend docs --- backend/README.md | 19 +++--- backend/aws.md | 145 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 152 insertions(+), 12 deletions(-) create mode 100644 backend/aws.md diff --git a/backend/README.md b/backend/README.md index 906cbef..dd0be81 100644 --- a/backend/README.md +++ b/backend/README.md @@ -13,17 +13,12 @@ This document is the operator manual — provisioning the external services, con Before deploying the backend, you will need: -- **An S3 bucket** to store the uploaded HTML reports. The backend writes objects under the `sites//...` prefix and reads them back when serving reports. No public access or static website hosting needs to be enabled — the backend serves files itself. +- **AWS infrastructure** — an S3 bucket, an IAM user, and an IAM role. See [aws.md](aws.md) for step-by-step setup with the exact policy JSON. The short version of what you'll end up with: + - An **S3 bucket** for HTML reports. The backend writes objects under the `sites//...` prefix and reads them back when serving reports. No public access or static website hosting — the backend serves files itself. + - An **IAM user** for the backend, with a long-lived access key. It needs `s3:PutObject` + `s3:GetObject` on `/sites/*`, and `sts:AssumeRole` on the upload role. + - An **IAM role for uploads**, with a permissions policy granting `s3:PutObject` on `/sites/*` and a trust policy allowing the IAM user to assume it. The backend assumes this role via STS to mint short-lived credentials for the CLI, further narrowed per upload by a session policy scoped to a single `site_id` — so the CLI never receives credentials that can write outside its own report directory. -- **An AWS IAM user for the backend**, with a long-lived access key. The user needs: - - `s3:PutObject` and `s3:GetObject` on `arn:aws:s3:::/sites/*` — used to create per-upload site directories and to serve report files. - - `sts:AssumeRole` on the upload role described below. - -- **An AWS IAM role for uploads**, whose ARN is passed to the backend as `AWS_UPLOAD_ROLE_ARN`. The backend assumes this role via STS to mint short-lived credentials that the CLI uses to upload report files directly to S3. The role needs: - - A permissions policy granting `s3:PutObject` on `arn:aws:s3:::/sites/*`. The backend further narrows this per upload via a session policy scoped to a single `site_id`, so the CLI never receives credentials that can write outside its own report directory. - - A trust policy allowing the backend IAM user to assume it. - -- **A Redis instance** reachable from the backend. It is used as a short-lived cache for rendered badge SVGs. +- **A Redis instance** (optional) reachable from the backend. It is used as a short-lived cache for rendered badge SVGs. - **A GitHub token** with read access to commit statuses on every repository whose coverage you want to display. A fine-grained PAT with `Commit statuses: Read-only` is sufficient; a classic PAT with `repo` (or `public_repo` for public repositories only) also works. @@ -39,7 +34,7 @@ The backend is configured via environment variables, loaded by `app.config.Setti | `AWS_ACCESS_KEY_ID` | yes | — | Access key of the backend's IAM user (the one with `s3:GetObject`/`PutObject` on `/sites/*` and `sts:AssumeRole` on the upload role). | | `AWS_SECRET_ACCESS_KEY` | yes | — | Secret access key for the above IAM user. | | `AWS_UPLOAD_ROLE_ARN` | yes | — | ARN of the IAM role the backend assumes via STS to mint short-lived upload credentials for the CLI. | -| `REDIS_URL` | yes | — | Connection URL for Redis. Used to cache rendered badge SVGs (60 s TTL). | +| `REDIS_URL` | no | — | Connection URL for Redis. Used to cache rendered badge SVGs (60 s TTL). | | `GITHUB_TOKEN` | yes | — | GitHub token used to read commit statuses. See [Prerequisites](#prerequisites) for the required scopes. | ## Deploying to FastAPI Cloud @@ -50,7 +45,7 @@ Covered is designed to run on [FastAPI Cloud](https://fastapicloud.com/). The de 2. **Create an app** in the FastAPI Cloud dashboard. -3. **Configure the environment variables** on the app (the [table above](#environment-variables) lists all of them). FastAPI Cloud also offers a Redis integration that can set `REDIS_URL` for you — use it if you want, otherwise paste in the URL from your Redis provider. +3. **Configure the environment variables** on the app (the [table above](#environment-variables) lists all of them). 4. **Clone (or fork) this repository.** Fork if you plan to customize the backend. diff --git a/backend/aws.md b/backend/aws.md new file mode 100644 index 0000000..f42a17f --- /dev/null +++ b/backend/aws.md @@ -0,0 +1,145 @@ +# AWS setup + +This guide walks through creating the S3 bucket, IAM user, and IAM role the [Covered backend](README.md) needs. If you already have AWS infrastructure to reuse, you can adapt the policies described here. + +## What you'll create + +Three resources: + +1. **An S3 bucket** — stores the uploaded HTML coverage reports. +2. **An IAM user** for the backend — provides the long-lived credentials the backend uses to read reports back from S3 and to assume the upload role. +3. **An IAM role** (the *upload role*) — assumed by the backend via STS to mint short-lived credentials. The backend hands those temporary credentials to the CLI, scoped via a session policy to a single report's directory, so the CLI can never write outside its own report. + +This two-credential design (long-lived backend user + short-lived assumed role) is what isolates each CI upload. + +## Placeholders used below + +| Placeholder | Meaning | Example | +|---|---|---| +| `covered-reports` | The S3 bucket name | `acme-covered-reports` | +| `` | AWS region | `us-east-1` | +| `` | Your 12-digit AWS account ID | `123456789012` | + +Replace them with your own values in the policy JSON. + +## 1. Create the S3 bucket + +In the [S3 Console](https://console.aws.amazon.com/s3/): + +1. Click **Create bucket**. +2. **Bucket name**: `covered-reports` (or whatever you prefer). +3. **Region**: ``. Pick one close to where the backend will run; the backend's `AWS_REGION` env var must match this. +4. Leave all other settings at their defaults. In particular, **keep "Block all public access" enabled** — the backend serves files itself; the bucket does not need to be public. +5. Click **Create bucket**. + +## 2. Create the IAM user + +We create the user before the role so the role's trust policy can reference the user's ARN. + +In the [IAM Console](https://console.aws.amazon.com/iam/), under **Users**: + +1. Click **Create user**. +2. **User name**: `covered-backend` (any name). +3. Do **not** check "Provide user access to the AWS Management Console" — the backend uses programmatic access only. +4. On the **Set permissions** step, choose **Attach policies directly** and don't select anything. Click **Next**, then **Create user**. + +Open the created user and copy its **ARN** from the **Summary** panel — it looks like `arn:aws:iam:::user/covered-backend`. You'll paste it into the role's trust policy in the next step. + +## 3. Create the upload role + +In the IAM Console, under **Roles**: + +1. Click **Create role**. +2. **Trusted entity type**: **Custom trust policy**. +3. Paste this trust policy, substituting `` and the user name if you changed it: + + ```json + { + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Principal": { "AWS": "arn:aws:iam:::user/covered-backend" }, + "Action": "sts:AssumeRole" + } + ] + } + ``` + + + +4. Click **Next**. Skip attaching any managed policy on this screen — we'll add an inline policy after creation. +5. **Role name**: `covered-upload-role` (any name). +6. Click **Create role**. + +Now open the role and add its permissions policy. On the **Permissions** tab, click **Add permissions → Create inline policy**, switch to the **JSON** editor, and paste: + +```json +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": "s3:PutObject", + "Resource": "arn:aws:s3:::covered-reports/sites/*" + } + ] +} +``` + +This is the outer bound — when the backend assumes the role, it applies a session policy that narrows access to a single `sites//*` prefix for that specific upload. + +Save the policy (name it `covered-upload-policy`). + +Finally, copy the role's **ARN** from the role's **Summary** panel — it looks like `arn:aws:iam:::role/covered-upload-role`. This is what you'll set as `AWS_UPLOAD_ROLE_ARN` on the backend. + +## 4. Attach the user's permissions policy + +Go back to the user from step 2. On the **Permissions** tab, click **Add permissions → Create inline policy**, switch to **JSON**, and paste: + +```json +{ + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "S3Access", + "Effect": "Allow", + "Action": ["s3:PutObject", "s3:GetObject"], + "Resource": "arn:aws:s3:::covered-reports/sites/*" + }, + { + "Sid": "AssumeUploadRole", + "Effect": "Allow", + "Action": "sts:AssumeRole", + "Resource": "arn:aws:iam:::role/covered-upload-role" + } + ] +} +``` + +Save the policy (name it `covered-backend-policy`). + +The backend needs `s3:PutObject` (to create the per-upload `site_id` directory) and `s3:GetObject` (to serve report files back to readers), plus `sts:AssumeRole` to mint upload credentials for the CLI. + +## 5. Create the access key + +On the user's **Security credentials** tab: + +1. Click **Create access key**. +2. **Use case**: **Other**, then click **Next**. +3. Click **Create access key**. +4. **Copy the access key ID and the secret access key now** — the secret is shown only once and can never be retrieved again. These become `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` on the backend. + +## Backend env vars, recapped + +After all five steps you have: + +| Backend env var | Value | +|---|---| +| `AWS_REGION` | The region of the bucket (e.g. `us-east-1`) | +| `AWS_BUCKET` | `covered-reports` | +| `AWS_ACCESS_KEY_ID` | From step 5 | +| `AWS_SECRET_ACCESS_KEY` | From step 5 | +| `AWS_UPLOAD_ROLE_ARN` | From step 3 | + +Set these on FastAPI Cloud following [Deploying to FastAPI Cloud](README.md#deploying-to-fastapi-cloud). From 27a81e643c890ee29e2354554d6d18e828a6a676 Mon Sep 17 00:00:00 2001 From: Yurii Motov Date: Thu, 14 May 2026 17:34:52 +0200 Subject: [PATCH 5/6] Clarify that Redis is optional --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ab9a064..a6a2af9 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ After uploading a report on the default branch, the CLI can also trigger a cache Setting up Covered takes two steps: -1. **Deploy the backend** — provision S3, Redis, and a GitHub token, then deploy to FastAPI Cloud. See [backend/README.md](backend/README.md). +1. **Deploy the backend** — provision S3, Redis (optionally), and a GitHub token, then deploy to FastAPI Cloud. See [backend/README.md](backend/README.md). 2. **Wire up CI** — add the `covered` CLI to your test workflow. See the [GitHub Action setup](#github-action-setup) below; full CLI options are in [cli/README.md](cli/README.md). ## GitHub Action setup From 4d1a48a19725add7110cd233315e2e5726d54430 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 14 May 2026 19:38:14 +0000 Subject: [PATCH 6/6] =?UTF-8?q?=F0=9F=8E=A8=20Auto=20format?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/README.md b/backend/README.md index dd0be81..0d7a4e2 100644 --- a/backend/README.md +++ b/backend/README.md @@ -63,4 +63,4 @@ Covered is designed to run on [FastAPI Cloud](https://fastapicloud.com/). The de 8. **Confirm and wait** for the deploy to report success. -9. **Verify** by triggering the [`Coverage upload` workflow](../README.md#workflow-setup) in a repository configured to use this backend. If anything fails, the FastAPI Cloud dashboard logs are the first place to look. \ No newline at end of file +9. **Verify** by triggering the [`Coverage upload` workflow](../README.md#workflow-setup) in a repository configured to use this backend. If anything fails, the FastAPI Cloud dashboard logs are the first place to look.