# GitHub Action — tested.dev docs

One composite action: check thresholds. Optionally push a share URL or mainline coverage.

Use `tested-hq/cli/action@main` with `version: 0.1.10`. Pin `uses:` to a SHA in production. `push` defaults to `false`. No token for the gate. Node 24+. This is the CI path. You do not need a local `@tested/cli` install. App: [tested-dev-app](https://github.com/apps/tested-dev-app).

## Pull request (gate, no account)

`fetch-depth: 0` is optional. The Action fetches the PR base.

```yaml
name: tested
on:
  pull_request:
jobs:
  coverage:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: pnpm/action-setup@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 24
          cache: pnpm
      - run: pnpm install --frozen-lockfile
      - run: pnpm test -- --coverage
      - uses: tested-hq/cli/action@main   # pin uses: to a SHA in production
        with:
          version: 0.1.10
```

## Share URL (optional)

Install [tested-dev-app](https://github.com/apps/tested-dev-app), open the repo in the app, mint `TESTED_TOKEN` at `https://app.tested.dev/repos/{owner}/{name}/settings`, then:

```yaml
- uses: tested-hq/cli/action@main   # pin uses: to a SHA in production
  with:
    version: 0.1.10
    push: 'true'
    pr-number: ${{ github.event.pull_request.number }}
    token: ${{ secrets.TESTED_TOKEN }}
    # optional: base: ${{ github.event.pull_request.base.sha }}
```

## Default branch (mainline chart)

```yaml
on:
  push:
    branches: [main]
jobs:
  coverage:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      # … install + test with coverage …
      - uses: tested-hq/cli/action@main   # pin uses: to a SHA in production
        with:
          version: 0.1.10
          push: 'true'
          mainline: 'true'
          token: ${{ secrets.TESTED_TOKEN }}
```

Mainline uploads fill the project chart. They do not create a share URL.

## Require the check

After the Action has run once: repo Settings → Branches → protection rule or ruleset on the default branch → require status checks → add the job name (`coverage` in the snippet).

App-posted required checks and sticky comments need Hobby or Team. The Action job can be required in branch protection on any plan.

## Fork PRs

The gate works on fork PRs. `push: true` fails without secrets. GitHub does not pass repository secrets to workflows from forks.

## Inputs

Matches public `tested-hq/cli` `action/action.yml`.

| Input | Default | Notes |
|-------|---------|-------|
| `version` | `0.1.10` | npm version of `@tested/cli`. Ignored when `cli-path` or `cli-ref` is set |
| `cli-path` | empty | Local checkout of the CLI already on the runner |
| `cli-repository` | `tested-hq/cli` | Used only when `cli-ref` is set |
| `cli-ref` | empty | Optional git ref instead of npm. Leave empty |
| `working-directory` | `.` | Project dir with coverage + `.tested.yaml` |
| `base` | empty | PR base SHA on pull_request. Fetched if missing |
| `push` | `false` | Set `true` to call `tested push` |
| `pr-number` | empty | Required for PR share; not needed with mainline |
| `mainline` | `false` | Default-branch project coverage only |
| `token` | empty | Prefer `secrets.TESTED_TOKEN` |
| `api-url` | empty | Optional `TESTED_API_URL` override |
| `junit` | empty | JUnit XML path. Also auto-detects `junit.xml` |
| `node-version` | `24` | Node for the CLI (`setup-node`) |

## Manual (CLI already on PATH)

After install, `td` is the same CLI as `tested`.

```yaml
- run: pnpm test -- --coverage
- run: tested check
- run: tested push --pr ${{ github.event.pull_request.number }}
  env:
    TESTED_TOKEN: ${{ secrets.TESTED_TOKEN }}
```

Setup from zero: [Install](https://tested.dev/docs/install)
