> For the complete documentation index, see [llms.txt](https://docs.duku.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.duku.ai/integrations/github-actions/quickstart-preview-action.md).

# Quickstart: preview action

Start Duku automatically for pull request previews.

{% hint style="warning" %}
Install the Duku AI GitHub App and link it to your Duku organisation. An org admin opens **Settings → Integrations**, selects **+ Connect** under **Source control & CI/CD**, chooses **GitHub** and selects **Install on GitHub**. If the App is already installed on your GitHub organisation, select **Link existing install** instead. An App installed straight from GitHub is not linked, and Duku posts no PR comments or check runs until it is. The App posts the PR comment and its final results. Without it, results still appear in Viewport, but no PR comment or check run is posted.
{% endhint %}

Use this workflow when each pull request gets its own preview deployment.

{% stepper %}
{% step %}

### 1. Add Preview deployments to the product

Before the first run, an org admin opens **Product settings** (the cog next to the product menu), goes to **Environments**, selects **Add environment**, sets **Type** to **Preview deployments** and selects **Create**. All pull-request previews share this one slot. Until it exists, the preview action stops with "Add Preview deployments in Product settings → Environments before using the preview action."
{% endstep %}

{% step %}

### 2. Add the required repository secret and variable

Create `PLATFORM_API_KEY` in Viewport - **Settings → API Keys**.

Add `PLATFORM_PRODUCT_ID` as a repository variable. It is not a secret.
{% endstep %}

{% step %}

### 3. Create the workflow file

Copy this file into `.github/workflows/duku-preview.yml`:

```yaml
name: Duku preview

on:
  pull_request:
    types: [opened, synchronize, reopened]
    branches: [main]

concurrency:
  group: duku-preview-${{ github.event.pull_request.number }}
  cancel-in-progress: true

jobs:
  preview:
    name: Duku preview
    runs-on: ubuntu-latest
    # The action exits in seconds; this cap only guards against network hangs.
    timeout-minutes: 5
    permissions:
      contents: read
      pull-requests: read    # for preview URL resolution
      deployments: read      # required for preview URL resolution
      checks: read           # for preview URL resolution
      statuses: read         # for preview URL resolution
    steps:
      - uses: actions/checkout@v4
      - name: Duku preview
        id: preview
        uses: duku-ai/actions/preview@preview/v0.5.0
        with:
          api-key: ${{ secrets.PLATFORM_API_KEY }}
          product-id: ${{ vars.PLATFORM_PRODUCT_ID }}
          github-token: ${{ github.token }}
          # Optional: bypass Vercel Deployment Protection on protected previews.
          # vercel-automation-bypass-secret: ${{ secrets.VERCEL_AUTOMATION_BYPASS_SECRET }}
```

{% endstep %}

{% step %}

### 4. Update the workflow values

* `branches: [main]` should match the branch you merge into.
* `api-key` reads the repository secret `PLATFORM_API_KEY`.
* `product-id` reads the repository variable `PLATFORM_PRODUCT_ID`.

`github-token` lets the action find the PR's preview URL, so it is required on `pull_request` runs unless you pass `exploration-url`. The read permissions above are all it needs - the Duku GitHub App posts the PR comment.

`deployments: read`, `checks: read`, and `statuses: read` let the action resolve the preview URL.
{% endstep %}

{% step %}

### 5. Open or update a pull request

The workflow resolves the preview URL, starts the exploration, and exits within seconds.

The `concurrency` block cancels superseded runs for the same pull request.

Results appear in Viewport. The GitHub App updates the same PR comment with final results.
{% endstep %}
{% endstepper %}

PRs opened from forks cannot read repository secrets. Duku previews require a PR from a branch in the same repository.

### Preview URL resolution

On a pull request, the `preview` action figures out which deployed URL to explore.

With `preview-url-source: auto`, it checks the PR head commit's GitHub Deployments, then Checks (when `preview-check-name-regex` is set), then Statuses (when `preview-status-context-regex` is set). `auto` never reads PR comments.

You can force a single source. You can also set `exploration-url` to skip resolution entirely.

{% hint style="info" %}
If a fresh preview takes a moment to start serving, add `wait-for-target-seconds: 120` so the run begins once it responds.
{% endhint %}

#### Example: resolve the URL from Vercel comments

```yaml
- uses: duku-ai/actions/preview@preview/v0.5.0
  with:
    api-key: ${{ secrets.PLATFORM_API_KEY }}
    product-id: ${{ vars.PLATFORM_PRODUCT_ID }}
    github-token: ${{ github.token }}
    preview-url-source: 'comments'
    preview-comment-author-logins: 'vercel[bot]'
```

`auto` is usually the right choice. Use `comments` when your deployment provider does not publish a usable GitHub Deployment.

### Read next

* [Choosing preview vs environment](/integrations/github-actions/choosing-preview-vs-environment.md)
* [Configuration reference](/integrations/github-actions/configuration-reference.md)
* [Troubleshooting](/integrations/github-actions/troubleshooting.md)
