---
title: GitHub Actions
description: Automatically deploy documentation on every push using GitHub Actions.
icon: github
---

# GitHub Actions

Set up automatic documentation deployment with GitHub Actions. Deploy to production on merge to main, and create preview deployments for pull requests.

## Basic Workflow

Create `.github/workflows/docs.yml`:

```yaml
name: Deploy Documentation

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      
      - name: Setup Bun
        uses: oven-sh/setup-bun@v1
      
      - name: Install Syntext CLI
        run: curl -fsSL https://get.syntext.dev | sh
      
      - name: Deploy
        run: |
          if [ "${{ github.event_name }}" = "pull_request" ]; then
            stx deploy --preview
          else
            stx deploy
          fi
        env:
          SYNTEXT_API_KEY: ${{ secrets.SYNTEXT_API_KEY }}
```

## Setting Up Secrets

1. Go to your repository on GitHub
2. Navigate to **Settings** → **Secrets and variables** → **Actions**
3. Click **New repository secret**
4. Add `SYNTEXT_API_KEY` with your API key

<Warning>
Never commit your API key. Always use GitHub Secrets.
</Warning>

## With Caching

Speed up builds with caching:

```yaml
name: Deploy Documentation

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      
      - name: Setup Bun
        uses: oven-sh/setup-bun@v1
      
      - name: Cache Syntext
        uses: actions/cache@v3
        with:
          path: |
            ~/.syntext
            .syntext/cache
          key: syntext-${{ runner.os }}-${{ hashFiles('syntext.json', 'docs/**') }}
          restore-keys: |
            syntext-${{ runner.os }}-
      
      - name: Install Syntext CLI
        run: curl -fsSL https://get.syntext.dev | sh
      
      - name: Deploy
        run: |
          if [ "${{ github.event_name }}" = "pull_request" ]; then
            stx deploy --preview
          else
            stx deploy
          fi
        env:
          SYNTEXT_API_KEY: ${{ secrets.SYNTEXT_API_KEY }}
```

## PR Preview Comments

Post preview URLs as PR comments:

```yaml
name: Deploy Documentation

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

permissions:
  contents: read
  pull-requests: write

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      
      - name: Setup Bun
        uses: oven-sh/setup-bun@v1
      
      - name: Install Syntext CLI
        run: curl -fsSL https://get.syntext.dev | sh
      
      - name: Deploy Preview
        id: preview
        if: github.event_name == 'pull_request'
        run: |
          OUTPUT=$(stx deploy --preview --json)
          URL=$(echo "$OUTPUT" | jq -r '.url')
          echo "url=$URL" >> $GITHUB_OUTPUT
        env:
          SYNTEXT_API_KEY: ${{ secrets.SYNTEXT_API_KEY }}
      
      - name: Comment on PR
        if: github.event_name == 'pull_request'
        uses: actions/github-script@v6
        with:
          script: |
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: `📚 **Documentation Preview**\n\n${{ steps.preview.outputs.url }}`
            })
      
      - name: Deploy Production
        if: github.event_name == 'push'
        run: stx deploy
        env:
          SYNTEXT_API_KEY: ${{ secrets.SYNTEXT_API_KEY }}
```

## Conditional Deployment

Only deploy when docs change:

```yaml
on:
  push:
    branches: [main]
    paths:
      - 'docs/**'
      - 'syntext.json'
      - 'openapi.json'
```

## Monorepo Setup

For monorepos with docs in a subdirectory:

```yaml
jobs:
  deploy:
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: ./packages/docs
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      
      # ... rest of workflow
```

## Multiple Documentation Sites

Deploy multiple docs sites from one repo:

```yaml
jobs:
  deploy-api-docs:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: curl -fsSL https://get.syntext.dev | sh
      - run: stx deploy
        working-directory: ./docs/api
        env:
          SYNTEXT_API_KEY: ${{ secrets.API_DOCS_KEY }}
  
  deploy-user-docs:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: curl -fsSL https://get.syntext.dev | sh
      - run: stx deploy
        working-directory: ./docs/users
        env:
          SYNTEXT_API_KEY: ${{ secrets.USER_DOCS_KEY }}
```

## Deployment Status Check

Add deployment status as a required check:

1. Go to **Settings** → **Branches**
2. Add branch protection rule for `main`
3. Enable **Require status checks to pass**
4. Select the deployment job

## Troubleshooting

### Build Fails with "No config found"

Ensure `syntext.json` exists in the working directory:

```yaml
- run: ls -la
- run: cat syntext.json
```

### Authentication Error

Verify your API key is set correctly:

```yaml
- run: echo "API key length: ${#SYNTEXT_API_KEY}"
  env:
    SYNTEXT_API_KEY: ${{ secrets.SYNTEXT_API_KEY }}
```
