> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cloudeval.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Review pull requests with GitHub Actions

> Run Cloudeval review in CI with the official composite action, access keys, report gates, PR comments, Check Runs, and artifacts.

Use the **[Cloudeval GitHub Action](https://github.com/ganakailabs/cloudeval-action)** when you want Cloudeval review results inside GitHub Actions without hand-rolling install and auth steps.

<Tip>
  Use the **[Cloudeval GitHub App](https://github.com/apps/cloudeval-ai)** for repository sync into Cloudeval. Use the **GitHub Action** for CI review, merge gates, PR comments, and report artifacts after a Cloudeval project exists.
</Tip>

<Info>
  Before connecting a private repository, read [Data and model boundaries](/trust/data-and-ai) to understand how Cloudeval imports GitHub files, stores the project snapshot, and scopes AI-assisted review today.
</Info>

<Note>
  Want to see it before wiring your own repo? Inspect the [database tier review demo PR](https://github.com/ganakailabs/cloudeval-azure-arm-review-example/pull/8), [passing baseline demo PR](https://github.com/ganakailabs/cloudeval-azure-arm-review-example/pull/6), and [risk regression demo PR](https://github.com/ganakailabs/cloudeval-azure-arm-review-example/pull/1) in the public Azure ARM review example.
</Note>

## Copy a minimal review workflow

Create `.github/workflows/cloudeval-review.yml` after the repository is linked to a Cloudeval project and the two repository secrets exist:

```yaml theme={null}
name: Cloudeval review
on:
  pull_request:

permissions:
  contents: read
  pull-requests: write
  issues: write

jobs:
  review:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: ganakailabs/cloudeval-action@v1
        with:
          access_key: ${{ secrets.CLOUDEVAL_ACCESS_KEY }}
          project_id: ${{ secrets.CLOUDEVAL_PROJECT_ID }}
          mode: review
          post_pr_comment: true
          upload_artifacts: true
```

<Note>The complete workflow later on this page adds an App-authored Check Run, SARIF upload, explicit source provenance, and deterministic-review options.</Note>

<Frame caption="Video walkthrough: automated pull-request review for infrastructure-as-code changes in GitHub.">
  <iframe src="https://www.youtube.com/embed/NCHq0AyEwAo" title="Automated review of pull-request on GitHub repo for Infrastructure-as-Code changes - Cloudeval AI" width="100%" height="415" loading="lazy" frameBorder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerPolicy="strict-origin-when-cross-origin" allowFullScreen />
</Frame>

## Public example

Use [ganakailabs/cloudeval-azure-arm-review-example](https://github.com/ganakailabs/cloudeval-azure-arm-review-example) as a clean public reference repository. It contains nested ARM templates, `.cloudeval/config.yaml`, a ready-to-copy Cloudeval review workflow, and long-lived demo pull requests:

| Demo PR                                                                                            | Expected check | What to inspect                                                                                                                |
| -------------------------------------------------------------------------------------------------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| [Database tier review](https://github.com/ganakailabs/cloudeval-azure-arm-review-example/pull/8)   | Red            | A realistic nested SQL Database change with Well-Architected, validation, cost, AI summary, and report links in one PR review. |
| [Passing baseline gates](https://github.com/ganakailabs/cloudeval-azure-arm-review-example/pull/6) | Green          | A passing review with baseline thresholds while the comment still shows CRITICAL posture, validation, cost, and report links.  |
| [Risk regression](https://github.com/ganakailabs/cloudeval-azure-arm-review-example/pull/1)        | Red            | A risky IaC change with blocking gate failures and high-risk posture signals.                                                  |
| [Cost regression](https://github.com/ganakailabs/cloudeval-azure-arm-review-example/pull/2)        | Red            | Five-digit monthly cost estimate, resource cost drivers, and a failing monthly budget gate.                                    |
| [Security hardening](https://github.com/ganakailabs/cloudeval-azure-arm-review-example/pull/3)     | Red            | Security-focused remediation work that still fails until configured thresholds are satisfied.                                  |

Use the public PRs when you want to inspect the workflow without connecting Azure or uploading private source. Fork the repo, install the [Cloudeval GitHub App](https://github.com/apps/cloudeval-ai) on the fork, create a Cloudeval project from it, then add `CLOUDEVAL_ACCESS_KEY` and `CLOUDEVAL_PROJECT_ID` secrets. The workflow intentionally skips review until those secrets exist.

For AWS CloudFormation beta, inspect [ganakailabs/cloudeval-aws-cloudformation-review-example](https://github.com/ganakailabs/cloudeval-aws-cloudformation-review-example). It includes CloudFormation YAML and JSON templates plus the same review workflow shape:

| Demo PR                                                                                                            | Expected check after setup | What to inspect                                                                                  |
| ------------------------------------------------------------------------------------------------------------------ | -------------------------- | ------------------------------------------------------------------------------------------------ |
| [Passing baseline](https://github.com/ganakailabs/cloudeval-aws-cloudformation-review-example/pull/1)              | Green                      | CloudFormation YAML and JSON sync, posture review, PR comment, and artifacts.                    |
| [Public access regression](https://github.com/ganakailabs/cloudeval-aws-cloudformation-review-example/pull/2)      | Red                        | S3 public access, SSH ingress, and public RDS findings surfaced by Checkov and Cloudeval policy. |
| [Deployment-quality regression](https://github.com/ganakailabs/cloudeval-aws-cloudformation-review-example/pull/3) | Red                        | cfn-lint catches an invalid CloudFormation reference before deployment.                          |

Use it to test good and bad AWS PRs after the repository is linked to a Cloudeval project through the GitHub App and CI secrets are configured. AWS beta review can surface cfn-lint deployment-quality checks, Checkov findings, and reviewed AWS Well-Architected mappings where available; unsupported AWS scoring areas should remain visibly unassessed.

## What it does (and does not do)

The action runs on **your** workflow runner, installs the **Cloudeval CLI** (unless you skip install), and calls the **same Cloudeval API** as the browser and CLI using a **scoped access key** (`cev_…`).

It does **not** install the GitHub App, change repository settings, branch rules, or files on its own. It **can**:

* Run `cloudeval review` for the checked-out GitHub repository and linked Cloudeval project.
* Fail a job when explicit `.cloudeval/config.yaml` `ci.gates` are not met.
* Attach **workflow artifacts** (JSON, summaries, downloaded reports).
* Attach `review/review.pdf` when `.cloudeval/config.yaml` enables PDF output.
* Add PR lifecycle reactions and post/update **one result comment** per run (same-repo pull requests; fork PRs are often restricted by GitHub token permissions).

Checked-out **code** is used by `mode: review` to identify the repository, branch, commit SHA, and dirty working tree state. See the action repo’s **[full guide](https://github.com/ganakailabs/cloudeval-action/blob/main/docs/github-action.md)** for details.

For GitHub-backed projects, the action works against the Cloudeval project snapshot created by the GitHub App sync path. The current public Pro path stores that source snapshot and generated evidence in Cloudeval-managed storage. Planned Team and Enterprise controls include private deployment, customer-managed storage, custom LLM gateways, and bring-your-own model key options; those are not self-serve Pro capabilities today.

## Current vs planned PR capabilities

The GitHub Action path is current for CI review, PR comments, optional Cloudeval App Check Runs, and optional SARIF output.

| Capability                                        | Status            | Notes                                                                                                                                           |
| ------------------------------------------------- | ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| GitHub App repository sync                        | Current           | Import and refresh the Cloudeval project from a selected repository, branch, and source root.                                                   |
| GitHub Actions composite action                   | Current           | Run Cloudeval review from a workflow runner with a scoped access key.                                                                           |
| PR comments                                       | Current           | Post or update one review result comment for same-repo pull requests when token permissions allow it.                                           |
| CI job failure via `.cloudeval/config.yaml` gates | Current           | Fail the workflow job when configured gates are not satisfied.                                                                                  |
| Workflow artifacts                                | Current           | Upload JSON, Markdown summaries, downloaded reports, optional `review/review.pdf`, and optional SARIF from the run.                             |
| GitHub Checks UI annotations                      | Current, optional | Post a Cloudeval App-authored Check Run with changed-file annotations when `github_checks: "true"` and the key has `github:checks`.             |
| SARIF / code scanning                             | Current, optional | Generate `review.sarif.json` and upload it with GitHub's SARIF upload action.                                                                   |
| PR diagram diffs                                  | Planned           | Architecture diff visualizations across pull-request changes are roadmap work.                                                                  |
| Native repo scanning without setup                | Planned           | Today, use the GitHub App plus action workflow for linked project review.                                                                       |
| Team/Enterprise private data plane                | Planned           | Self-hosted or private-network deployment, customer-managed storage, custom LLM gateway, and bring-your-own model key options are roadmap work. |

## Prerequisites

<Steps>
  <Step title="Create a CI access key">
    In the Cloudeval app, open **Developer → API & CLI access keys** and create a **GitHub Actions CI** key scoped to the target project. Review mode needs project/report capabilities, `review:summary` when AI summaries are enabled, `github:comment` when Cloudeval should post PR comments through the GitHub App identity, and `github:checks` when Cloudeval should post a native Check Run. Older keys without `github:comment` still work, but comments fall back to `github-actions[bot]`.
  </Step>

  <Step title="Create or import the Cloudeval project">
    Create or import the project from the GitHub repository through the [Cloudeval GitHub App](/guides/connect/github-repository). This links the repository, branch, commit provenance, and project.
  </Step>

  <Step title="Add repository secrets">
    Add `CLOUDEVAL_ACCESS_KEY` and, for review/reports, `CLOUDEVAL_PROJECT_ID` in the consumer repository or environment.
  </Step>

  <Step title="Pin the action">
    Prefer `uses: ganakailabs/cloudeval-action@v1` or a **full commit SHA** for supply-chain control.
  </Step>

  <Step title="Require the check">
    If Cloudeval should block merges, require the workflow job in a GitHub branch protection rule or ruleset.
  </Step>
</Steps>

## Renew an expired access key

Cloudeval access keys are time-limited and are **not renewed in place**. GitHub repository secrets are write-only, so create a new Cloudeval key and replace the secret.

If a workflow fails with `credential_expired` or `This access-key credential has expired`:

<Steps>
  <Step title="Create a replacement key">
    In Cloudeval, open **Developer → API & CLI access keys** and create a new **GitHub Actions CI** key scoped to the same project.
  </Step>

  <Step title="Keep the required capabilities">
    Include the capabilities used by the workflow: project/report review access, `review:summary` for AI summaries, `github:comment` for Cloudeval App PR comments, and `github:checks` for native Check Runs.
  </Step>

  <Step title="Replace the GitHub secret">
    In GitHub, open the repository or environment secrets and update **`CLOUDEVAL_ACCESS_KEY`** with the new value.
  </Step>

  <Step title="Re-run the workflow">
    Re-run the failed workflow. If the old key is still listed in Cloudeval, revoke or delete it after the replacement is working.
  </Step>
</Steps>

You can also create a replacement key from an authenticated local CLI session:

```bash theme={null}
cloudeval credentials create \
  --name "GitHub Actions CI - owner/repo" \
  --template ci \
  --project "$CLOUDEVAL_PROJECT_ID" \
  --expires 90d \
  --show-secret \
  --format json

gh secret set CLOUDEVAL_ACCESS_KEY --repo owner/repo
```

Run this locally or in a secure administrative environment. Do not print the replacement key in CI logs.

## PR review workflow

<Steps>
  <Step title="Add the review workflow">
    <CodeGroup>
      ```yaml review-comment.yml theme={null}
      name: Cloudeval review
      on:
        pull_request:

      permissions:
        contents: read
        pull-requests: write
        issues: write
        security-events: write # only needed for the optional SARIF upload step

      jobs:
        review:
          runs-on: ubuntu-latest
          steps:
            - uses: actions/checkout@v4
            - id: cloudeval
              uses: ganakailabs/cloudeval-action@v1
              with:
                access_key: ${{ secrets.CLOUDEVAL_ACCESS_KEY }}
                project_id: ${{ secrets.CLOUDEVAL_PROJECT_ID }}
                mode: review
                repo: ${{ github.repository }}
                ref: ${{ github.head_ref || github.ref_name }}
                commit_sha: ${{ github.event.pull_request.head.sha || github.sha }}
                post_pr_comment: true
                github_checks: true
                sarif: true
                upload_artifacts: true
            - uses: github/codeql-action/upload-sarif@v4
              if: always() && steps.cloudeval.outputs.sarif_path != ''
              with:
                sarif_file: ${{ steps.cloudeval.outputs.sarif_path }}
      ```

      ```yaml deterministic-review.yml theme={null}
      name: Cloudeval deterministic review
      on:
        pull_request:

      permissions:
        contents: read
        pull-requests: write
        issues: write
        security-events: write # only needed for the optional SARIF upload step

      jobs:
        review:
          runs-on: ubuntu-latest
          steps:
            - uses: actions/checkout@v4
            - id: cloudeval
              uses: ganakailabs/cloudeval-action@v1
              with:
                access_key: ${{ secrets.CLOUDEVAL_ACCESS_KEY }}
                project_id: ${{ secrets.CLOUDEVAL_PROJECT_ID }}
                mode: review
                post_pr_comment: true
                upload_artifacts: true
                ai_summary: "false"
      ```
    </CodeGroup>

    <Frame caption="A Cloudeval review workflow produces a GitHub Actions job summary, downloadable review artifacts, and a linked PR comment.">
      <img src="https://mintcdn.com/ganakailabs-db727e50/BrRYz9nGRkigfTsV/assets/images/cli/github-action-review-run.png?fit=max&auto=format&n=BrRYz9nGRkigfTsV&q=85&s=67342d68cb92577a689ce94c71b8677c" alt="GitHub Actions run page showing a completed Cloudeval review job with result summary, workflow run metadata, artifact, and PR comment status" width="1496" height="760" data-path="assets/images/cli/github-action-review-run.png" />
    </Frame>
  </Step>

  <Step title="Confirm what review mode runs">
    `mode: review` runs the high-level CLI command:

    ```bash theme={null}
    cloudeval review \
      --project "$CLOUDEVAL_PROJECT_ID" \
      --repo "$GITHUB_REPOSITORY" \
      --ref "$GITHUB_REF_NAME" \
      --commit-sha "$GITHUB_SHA" \
      --format json \
      --non-interactive
    ```

    By default the command waits for GitHub sync and report refresh before writing
    `review.json` and `review.md`. Use `--no-wait` only for advanced workflows that
    want to submit sync and inspect the job separately. Review output includes an
    AI-written PR summary by default; disable it with the action input
    `ai_summary: "false"` if CI must avoid model-generated prose.

    If the runner workspace has uncommitted changes, the CLI stops with:

    ```text theme={null}
    Reviews pushed commits only. Add --ignore-dirty to review HEAD anyway.
    ```

    Set `ignore_dirty: "true"` only when your workflow intentionally generates local files before review.
  </Step>

  <Step title="Enable PR comment output">
    When `post_pr_comment: true`, the action reacts to the PR with `eyes` when
    review starts and adds a completion reaction when review finishes (`+1` for
    pass, `confused` for failure). The review details are written as one
    idempotent result comment after the run has report data.

    For projects linked through the Cloudeval GitHub App, Cloudeval posts that
    comment with the app installation token so the visible author is the Cloudeval
    GitHub App and the comment uses the app logo. If the app comment route is not
    available or the access key does not include `github:comment`, the action falls
    back to `github-actions[bot]`.

    <Frame caption="When the project is linked to the GitHub App and the access key includes `github:comment`, the PR review appears as one Cloudeval App comment with source provenance.">
      <img src="https://mintcdn.com/ganakailabs-db727e50/BrRYz9nGRkigfTsV/assets/images/cli/github-action-pr-comment.png?fit=max&auto=format&n=BrRYz9nGRkigfTsV&q=85&s=02b6dcb15d459924ffde9cd9c40743cf" alt="GitHub pull request comment by the Cloudeval GitHub App showing overall review result, source provenance, AI summary, and collapsible drilldowns" width="824" height="360" data-path="assets/images/cli/github-action-pr-comment.png" />
    </Frame>

    <Frame caption="The AI summary appears directly inside the PR comment, with longer reasoning available in the expandable details section.">
      <img src="https://mintcdn.com/ganakailabs-db727e50/BrRYz9nGRkigfTsV/assets/images/cli/github-action-ai-summary.png?fit=max&auto=format&n=BrRYz9nGRkigfTsV&q=85&s=ea29646a75fc19a9ccd858a665a4fa54" alt="Expanded Cloudeval PR comment showing the AI summary and AI details section" width="824" height="780" data-path="assets/images/cli/github-action-ai-summary.png" />
    </Frame>

    For an App-branded PR comment, all three pieces must be true:

    * the Cloudeval project was created from or linked to the same GitHub repository
    * the CI access key is scoped to that project and includes `github:comment`
    * the workflow passes `project_id`, `post_pr_comment: true`, and has `pull-requests: write` plus `issues: write`
  </Step>

  <Step title="Enable GitHub Checks and SARIF">
    Add `github_checks: true` when you want a Cloudeval App-authored Check Run with inline annotations. The Cloudeval GitHub App installation must include **Checks: read and write**, and the Cloudeval CI access key must include `github:checks`.

    Add `sarif: true` when you want `review.sarif.json` written from source-mapped findings. Upload it with `github/codeql-action/upload-sarif` and grant the workflow token `security-events: write`.
  </Step>

  <Step title="Inspect review drilldowns">
    <Frame caption="Review drilldowns expand in place for Well-Architected pillar scores and monthly cost breakdowns.">
      <img src="https://mintcdn.com/ganakailabs-db727e50/BrRYz9nGRkigfTsV/assets/images/cli/github-action-review-drilldowns.png?fit=max&auto=format&n=BrRYz9nGRkigfTsV&q=85&s=a0474ed29de97bc2d9cfa06b535ad489" alt="Expanded Cloudeval PR comment showing Well-Architected pillar ratings and monthly cost drilldowns" width="824" height="980" data-path="assets/images/cli/github-action-review-drilldowns.png" />
    </Frame>

    <Frame caption="Validation and architecture signals stay in the same review comment so reviewers can check failures and graph context without leaving GitHub.">
      <img src="https://mintcdn.com/ganakailabs-db727e50/BrRYz9nGRkigfTsV/assets/images/cli/github-action-validation-architecture.png?fit=max&auto=format&n=BrRYz9nGRkigfTsV&q=85&s=a8d5f7bd00cb9d192244aebd066dbc15" alt="Expanded Cloudeval PR comment showing validation results and architecture signals" width="824" height="280" data-path="assets/images/cli/github-action-validation-architecture.png" />
    </Frame>
  </Step>
</Steps>

## Config-driven gates

<Steps>
  <Step title="Add ci.gates">
    Add `ci.gates` to `.cloudeval/config.yaml` when the review should fail the job:

    ```yaml theme={null}
    version: 1

    # Stack selection tells Cloudeval which file drives diagrams and reports.
    stacks:
      - id: primary-architecture
        name: Primary architecture
        entry: azuredeploy.json
        parameters: azuredeploy.parameters.json

    resolve:
      # Follow relative ARM templateLink files before graph/report analysis.
      linked_templates: true

    ci:
      gates:
        # block_pull_request fails the job; comment_only keeps the PR comment but does not block.
        enforcement: block_pull_request

        # Minimum Well-Architected score out of 100.
        minimum_well_architected_score: 85

        # Optional default minimum for every pillar. Per-pillar overrides below win.
        minimum_pillar_score: 80
        pillars:
          security: 90
          reliability: 85

        # Fail on high-risk architecture findings.
        fail_when_high_risk_findings_exist: true

        # Fail when policy checks or unit tests fail.
        fail_when_validation_fails: true

        # Optional monthly budget gate. Omit if cost should be reported but not gated.
        max_monthly_cost_usd: 500

      review:
        outputs:
          pdf:
            # Attach review/review.pdf to the GitHub workflow artifact.
            enabled: true
            report_type: all
            verbosity: evidence
            fail_on_error: false
    ```
  </Step>

  <Step title="Attach a PDF evidence packet">
    Keep `upload_artifacts: true` in the workflow and enable `ci.review.outputs.pdf.enabled` in `.cloudeval/config.yaml`.

    ```yaml theme={null}
    ci:
      review:
        outputs:
          pdf:
            enabled: true
            report_type: all
            verbosity: evidence
            fail_on_error: false
    ```

    The PR comment keeps the Cloudeval-hosted `PDF` badge for the latest hosted export. The GitHub `Artifacts` badge points to the workflow artifact for that run, which includes `review/review.pdf`, `review/review.md`, and `review/review.json`, even when the review gate fails.

    Supported PDF parameters:

    | Key             | Supported values                            | Default    |
    | --------------- | ------------------------------------------- | ---------- |
    | `enabled`       | `true`, `false`                             | `false`    |
    | `report_type`   | `all`, `architecture`, `cost`, `unit_tests` | `all`      |
    | `verbosity`     | `brief`, `detailed`, `evidence`             | `evidence` |
    | `fail_on_error` | `true`, `false`                             | `false`    |
  </Step>

  <Step title="Choose enforcement behavior">
    When `ci.gates` is missing, review mode returns a warning rather than failing by default. When gates exist, `enforcement: block_pull_request` fails the job on gate failures. Use `enforcement: comment_only` to publish the review without blocking merges while the team tunes thresholds. Existing `required`, `warn`, `overall_score_min`, `pillar_score_min`, `fail_on_high_risk`, `fail_on_validation_errors`, and `max_monthly_cost` keys are still accepted for compatibility.
  </Step>

  <Step title="Read the PR comment result">
    The PR comment separates the configured gate from observed posture:

    ```md theme={null}
    🟢 **Overall** : PASS
    🔴 Well-Architected Posture: 23.1/100 (CRITICAL)
    🔴 Validation: 3 unit tests failed
    🟢 Policy checks: GOOD
    🟢 Cost: 143.81 USD/mo (under 100K budget)

    #### Source

    - **Cloudeval project**: [GitHub Nested E2E](https://cloudeval.ai/app/projects/...)
    - **Repository**: `owner/repo`
    - **Ref**: `feature/infra-change`
    - **Commit**: `abc123def456`
    - **Workflow run**: https://github.com/owner/repo/actions/runs/123456789
    ```

    `Overall` is the gate result from your thresholds. `CRITICAL` is the observed architecture posture. A PR can show both when thresholds are intentionally permissive, validation/high-risk failures are disabled, or the cost budget is high.
  </Step>

  <Step title="Require the workflow check">
    To block merges, configure GitHub branch protection or a repository ruleset that requires the workflow job running Cloudeval review. GitHub Actions cannot prevent someone from clicking **Approve** on a pull request; the required status check is what prevents merge.
  </Step>

  <Step title="Use deterministic drilldowns">
    Review comments include deterministic drill-downs for:

    * Open in Cloudeval links for the project preview, architecture report, cost report, validation details, hosted PDF download, workflow run, and review artifacts
    * Well-Architected overall and pillar scores
    * cost threshold, estimated monthly cost, resource-cost pie chart, savings impact chart, and compact service-cost table
    * policy check and unit-test failures
    * optional AI summary, generated with `ai_summary_mode: ask` or `ai_summary_mode: agent`, split into a short summary plus collapsible details
    * optional `review/review.pdf` in the workflow artifact when `ci.review.outputs.pdf.enabled` is true
  </Step>
</Steps>

## GitHub Checks and SARIF

Use these when reviewers need native GitHub annotations in addition to the Cloudeval PR comment.

| Feature                 | Enable with                                                        | Required GitHub permission                  | Required Cloudeval capability    |
| ----------------------- | ------------------------------------------------------------------ | ------------------------------------------- | -------------------------------- |
| Cloudeval App Check Run | `github_checks: "true"` or `ci.review.github.checks.enabled: true` | Cloudeval GitHub App: **Checks read/write** | `github:checks`                  |
| Inline annotations      | Same as Check Run                                                  | Same as Check Run                           | `github:checks`                  |
| SARIF generation        | `sarif: "true"` or `ci.review.github.sarif.enabled: true`          | None by itself                              | project/report read capabilities |
| Code scanning upload    | `github/codeql-action/upload-sarif`                                | Workflow token: `security-events: write`    | None beyond SARIF generation     |

By default Check annotations are limited to changed files and capped at 50 annotations. Use `checks_all_files: "true"` for repository-wide annotations, `checks_include_notices: "true"` for informational findings, and `checks_annotation_limit` to tune volume.

SARIF is written to `review.sarif.json` under `review_output_dir` unless `sarif_output` is set. The action exposes `sarif_path` so the next workflow step can upload it to GitHub code scanning.

## Troubleshooting

| Failure                                         | What it means                                                         | Next step                                                                                                                |
| ----------------------------------------------- | --------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| `credential_expired`                            | The Cloudeval access key in `CLOUDEVAL_ACCESS_KEY` expired.           | Follow [Renew an expired access key](#renew-an-expired-access-key), replace the GitHub secret, then re-run the workflow. |
| Missing `CLOUDEVAL_PROJECT_ID`                  | Review mode does not know which Cloudeval project to use.             | Add the project id as a repository or environment secret, then pass `project_id: ${{ secrets.CLOUDEVAL_PROJECT_ID }}`.   |
| Project or repo not linked                      | The project does not match the GitHub repository/ref in the workflow. | Create or reconnect the project through [GitHub repository sync](/guides/connect/github-repository).                     |
| Dirty working tree                              | The runner changed files before `cloudeval review`.                   | Move generated files after review, commit the source change, or set `ignore_dirty: "true"` intentionally.                |
| App comment falls back to `github-actions[bot]` | Cloudeval could not post through the GitHub App identity.             | Confirm the project is GitHub-linked and the CI key includes `github:comment`.                                           |
| Check Run is missing                            | Native checks were not enabled or authorized.                         | Set `github_checks: true`, install the GitHub App with Checks read/write, and include `github:checks` in the key.        |

## Prompt-based merge gate

<Steps>
  <Step title="Switch to gate mode">
    Use **`mode: gate`**, set **`gate_jq`** to a jq expression that yields one number from the CLI JSON (for example `.score`), and set **`gate_threshold`** plus optional **`gate_operator`** (`ge`, `lt`, `eq`, …).
  </Step>

  <Step title="Set PR comment permissions">
    Enable **`post_pr_comment: true`** only when the job has `pull-requests: write` plus `issues: write` and the PR is from the **same** repository (not a fork), unless you use a different token strategy. These permissions are required for PR lifecycle reactions and for the `github-actions[bot]` comment fallback. GitHub App-linked projects can post the review comment through the Cloudeval App identity when the access key includes `github:comment`.
  </Step>

  <Step title="Add the gate workflow">
    ```yaml theme={null}
    permissions:
      contents: read
      pull-requests: write
      issues: write

    on:
      pull_request:

    jobs:
      cloud-eval:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v4
          - uses: ganakailabs/cloudeval-action@v1
            with:
              access_key: ${{ secrets.CLOUDEVAL_ACCESS_KEY }}
              project_id: ${{ secrets.CLOUDEVAL_PROJECT_ID }}
              mode: gate
              ask_prompt: 'Return JSON only: {"score": <0-1>, "reason": "..."} for IaC risk in this repo.'
              gate_threshold: "0.7"
              gate_jq: ".score"
              gate_operator: ge
              post_pr_comment: true
              upload_artifacts: true
    ```
  </Step>
</Steps>

## Reports on a schedule

Set **`mode: nightly`** (or **`reports`**) with **`project_id`**, configure **`reports_type`**, and optionally **`reports_wait`** so the job waits for report jobs to finish before download.

## Why reviewers can trust the output

Every PR review should make the source and evidence path visible enough for a reviewer to check the result without guessing.

| Trust signal                | Where it appears                                                                               |
| --------------------------- | ---------------------------------------------------------------------------------------------- |
| Source project              | PR comment source section and Open in Cloudeval links                                          |
| Repository, ref, and commit | PR comment source section plus workflow metadata                                               |
| Workflow run                | PR comment source section, GitHub Actions summary, and artifacts                               |
| Evidence                    | Architecture report, cost report, validation details, policy checks, and report drilldowns     |
| Next action                 | Gate result, failed checks, high-risk findings, cost threshold status, and optional AI summary |

## Reusable workflow

The action repository ships a **`workflow_call`** workflow so other repos can call one shared definition. Pass **`action_repository`** and **`action_ref`** if you fork. See **[cloudeval-reusable.yml](https://github.com/ganakailabs/cloudeval-action/blob/main/.github/workflows/cloudeval-reusable.yml)** in the action repo.

## Configuration reference

Every input and output is documented in:

* **[`action.yml` in ganakailabs/cloudeval-action](https://github.com/ganakailabs/cloudeval-action/blob/main/action.yml)** (source of truth)
* **[docs/github-action.md](https://github.com/ganakailabs/cloudeval-action/blob/main/docs/github-action.md)** (narrative guide)

## Related docs

* [Automate evaluations with the CLI](/cli/automation) — same Cloudeval service; use the action when you want a packaged GitHub-native path.
* [GitHub repository sync](/guides/connect/github-repository) — install the Cloudeval GitHub App and keep project files synced from GitHub.
* [IaC project config](/guides/projects/iac-config) — configure visualization source and CI gates.
* [Use the CLI](/cli/get-started) — local install and `cloudeval login` for interactive work.
