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

# CI/CD Integration

> Automate Kodexa metadata deployments using kdx sync deploy in GitHub Actions, GitLab CI, Jenkins, and other CI/CD pipelines for repeatable rollouts.

Automate your Kodexa metadata deployments by integrating `kdx sync deploy` into your CI/CD pipelines. Whether you use GitHub Actions, GitLab CI, Jenkins, or another system, the pattern is the same: install the kdx CLI, configure environment credentials, and run `kdx sync deploy`.

<Info>
  For GitHub Actions, the **kdx-sync-action** handles CLI installation, caching, and output parsing automatically: [kodexa-ai/kdx-sync-action](https://github.com/kodexa-ai/kdx-sync-action)
</Info>

## GitHub Actions with kdx-sync-action

The recommended approach for GitHub Actions is the `kdx-sync-action` composite action, which wraps the kdx CLI with automatic binary management and deployment output parsing.

### Quick Start

Deploy to Kodexa in 4 steps:

#### 1. Define Branch and Tag Mappings

Create `sync-config.yaml` in your repository root:

```yaml theme={null}
metadata_dir: kodexa-metadata

branch_mappings:
  - pattern: "main"
    target: production
    environment: prod

  - pattern: "staging"
    target: staging
    environment: staging

  - pattern: "feature/*"
    target: development
    environment: dev

tag_mappings:
  - pattern: "v*.*.*"
    target: production
    environment: prod

  - pattern: "rc-*"
    target: staging
    environment: staging

environments:
  prod:
    url: https://platform.kodexa-enterprise.com
    api_key_env: KODEXA_PROD_API_KEY

  staging:
    url: https://staging.kodexa-enterprise.com
    api_key_env: KODEXA_STAGING_API_KEY

  dev:
    url: https://dev.kodexa-enterprise.com
    api_key_env: KODEXA_DEV_API_KEY

targets:
  production:
    manifests:
      - organizations/acme-corp/manifest.yaml
      - organizations/acme-corp/modules/*/manifest.yaml

  staging:
    manifests:
      - organizations/acme-corp/manifest.yaml

  development:
    manifests:
      - organizations/acme-corp/manifest.yaml
```

#### 2. Add Secrets

In GitHub repository settings, navigate to **Secrets and variables** then **Actions**, and add:

* `KODEXA_PROD_API_KEY`
* `KODEXA_STAGING_API_KEY`
* `KODEXA_DEV_API_KEY`

<Tip>
  Use GitHub environments to add protection rules like required approvals for production deployments.
</Tip>

#### 3. Create Workflow

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

```yaml theme={null}
name: Deploy

on:
  push:
    branches: [main, staging, 'feature/**']
    tags:
      - 'v*.*.*'
      - 'rc-*'

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: kodexa-ai/kdx-sync-action@v2
        env:
          KODEXA_PROD_API_KEY: ${{ secrets.KODEXA_PROD_API_KEY }}
          KODEXA_STAGING_API_KEY: ${{ secrets.KODEXA_STAGING_API_KEY }}
          KODEXA_DEV_API_KEY: ${{ secrets.KODEXA_DEV_API_KEY }}
```

#### 4. Push and Deploy

```bash theme={null}
git add .
git commit -m "Configure automated deployments"
git push origin main
```

The branch or tag determines the deployment target automatically:

* Push to `main` deploys to production
* Push to `feature/new-thing` deploys to dev
* Tag `v1.0.0` deploys to production

### kdx-sync-action Reference

#### Inputs

All inputs are optional:

| Input              | Description                        | Default         |
| ------------------ | ---------------------------------- | --------------- |
| `sync-config`      | Path to sync-config.yaml           | Auto-discovered |
| `metadata-dir`     | Metadata directory override        | Auto-discovered |
| `dry-run`          | Preview only (`true`/`false`)      | `false`         |
| `kdx-version`      | kdx CLI version to use             | `latest`        |
| `threads`          | Number of parallel threads         | `8`             |
| `filter`           | Resource filter pattern            | -               |
| `branch`           | Override branch detection          | -               |
| `tag`              | Override with tag mapping          | -               |
| `slack-channel-id` | Slack channel ID for notifications | -               |
| `slack-token`      | Slack Bot Token for posting        | -               |
| `annotate-summary` | Add summary to GitHub job          | `false`         |

#### Outputs

| Output              | Description                 |
| ------------------- | --------------------------- |
| `targets-deployed`  | Number of targets deployed  |
| `resources-created` | Resources created           |
| `resources-updated` | Resources updated           |
| `resources-skipped` | Resources unchanged         |
| `json-report`       | JSON deployment report data |
| `json-report-path`  | Path to JSON report file    |

#### Using Outputs

```yaml theme={null}
- id: deploy
  uses: kodexa-ai/kdx-sync-action@v2
  env:
    KODEXA_PROD_API_KEY: ${{ secrets.KODEXA_PROD_API_KEY }}

- name: Show deployment summary
  run: |
    echo "Targets: ${{ steps.deploy.outputs.targets-deployed }}"
    echo "Created: ${{ steps.deploy.outputs.resources-created }}"
    echo "Updated: ${{ steps.deploy.outputs.resources-updated }}"
    echo "Skipped: ${{ steps.deploy.outputs.resources-skipped }}"
```

### Workflow Examples

#### Pull Request Validation

Validate changes and comment on PRs before merging:

```yaml theme={null}
name: Validate PR

on:
  pull_request:
    paths:
      - 'kodexa-metadata/**'
      - 'sync-config.yaml'

jobs:
  validate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - id: preview
        uses: kodexa-ai/kdx-sync-action@v2
        with:
          dry-run: true
        env:
          KODEXA_DEV_API_KEY: ${{ secrets.KODEXA_DEV_API_KEY }}

      - uses: actions/github-script@v7
        with:
          script: |
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: `## Deployment Preview

              **Targets**: ${{ steps.preview.outputs.targets-deployed }}
              **Create**: ${{ steps.preview.outputs.resources-created }}
              **Update**: ${{ steps.preview.outputs.resources-updated }}
              **Skip**: ${{ steps.preview.outputs.resources-skipped }}

              Changes validated. Safe to merge.`
            });
```

#### Production with Required Approval

```yaml theme={null}
name: Production Deployment

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    environment: production  # Requires approval in Settings > Environments
    steps:
      - uses: actions/checkout@v4

      - uses: kodexa-ai/kdx-sync-action@v2
        env:
          KODEXA_PROD_API_KEY: ${{ secrets.KODEXA_PROD_API_KEY }}
```

#### Tag-Based Release Workflow

```yaml theme={null}
name: Release Deployment

on:
  push:
    tags:
      - 'v*.*.*'
      - 'v*-*'

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: kodexa-ai/kdx-sync-action@v2
        env:
          KODEXA_PROD_API_KEY: ${{ secrets.KODEXA_PROD_API_KEY }}
          KODEXA_STAGING_API_KEY: ${{ secrets.KODEXA_STAGING_API_KEY }}
```

With tag mappings in `sync-config.yaml`:

```yaml theme={null}
tag_mappings:
  - pattern: "v*.*.*"
    target: production
    environment: prod

  - pattern: "v*-*"
    target: staging
    environment: staging
```

Release workflow:

```bash theme={null}
# Create release candidate - deploys to staging
git tag v1.5.0-rc1
git push --tags

# After testing, create production release - deploys to production
git tag v1.5.0
git push --tags
```

#### Scheduled Synchronization

```yaml theme={null}
name: Scheduled Sync

on:
  schedule:
    - cron: '0 2 * * *'  # Daily at 2 AM UTC
  workflow_dispatch:

jobs:
  sync:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: kodexa-ai/kdx-sync-action@v2
        env:
          KODEXA_PROD_API_KEY: ${{ secrets.KODEXA_PROD_API_KEY }}

      - name: Notify on failure
        if: failure()
        run: echo "Scheduled sync failed at $(date)"
```

## Multi-Environment Promotion

A common pattern is promoting configurations across environments using branches:

```text theme={null}
feature/xyz   -->  dev   -->  staging  -->  production
     |               |           |              |
   develop         main     release/*      v*.*.* tags
```

Each branch/tag maps to a target and environment in `sync-config.yaml`. Merging a PR to `main` automatically deploys to production.

```yaml theme={null}
# sync-config.yaml
branch_mappings:
  - pattern: "develop"
    target: development
    environment: dev

  - pattern: "main"
    target: production
    environment: prod

  - pattern: "release/*"
    target: staging
    environment: staging

tag_mappings:
  - pattern: "v*.*.*"
    target: production
    environment: prod
```

This approach gives you:

* **Feature isolation** -- develop and test without affecting other environments
* **Progressive rollout** -- changes flow through dev, staging, then production
* **Immutable releases** -- tags provide a fixed point for production deployments
* **Automated promotion** -- merging a PR triggers deployment to the target environment

## Pulling Changes Back to Git

Use `mode: pull` to sync changes FROM a running Kodexa instance back into your git repository. This captures edits made in the platform UI and surfaces them as pull requests for team review.

### Scheduled Sync

Run daily (or on any schedule) to keep git in sync with UI changes:

```yaml theme={null}
name: Sync Pull
on:
  schedule:
    - cron: '0 6 * * *'  # Daily at 6am UTC
  workflow_dispatch:       # Allow manual trigger

jobs:
  pull:
    runs-on: ubuntu-latest
    permissions:
      contents: write
      pull-requests: write
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - uses: kodexa-ai/kdx-sync-action@v3
        with:
          mode: pull
          target: production
          environment: prod
          discover: true
          annotate-summary: true
        env:
          KODEXA_PROD_API_KEY: ${{ secrets.KODEXA_PROD_API_KEY }}
```

The action will:

1. Pull all resources from the production environment
2. Discover and merge any new resources into the manifest
3. Commit changes to a `sync/prod` branch
4. Open (or update) a PR for team review

<Tip>
  This is especially useful when team members edit resources in the platform UI. The scheduled pull captures those changes and brings them back into version control automatically.
</Tip>

### On-Demand Pull with Environment Selection

For manual pulls with a dropdown to choose the environment:

```yaml theme={null}
name: Sync Pull (Manual)
on:
  workflow_dispatch:
    inputs:
      environment:
        description: 'Environment to pull from'
        required: true
        type: choice
        options: [dev, staging, prod]
      target:
        description: 'Target to pull'
        required: true
        default: 'production'

jobs:
  pull:
    runs-on: ubuntu-latest
    permissions:
      contents: write
      pull-requests: write
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - uses: kodexa-ai/kdx-sync-action@v3
        with:
          mode: pull
          target: ${{ inputs.target }}
          environment: ${{ inputs.environment }}
          discover: true
          branch-name: sync/${{ inputs.environment }}
          pr-title: 'Sync: pull from ${{ inputs.environment }}'
          annotate-summary: true
        env:
          KODEXA_PROD_API_KEY: ${{ secrets.KODEXA_PROD_API_KEY }}
          KODEXA_STAGING_API_KEY: ${{ secrets.KODEXA_STAGING_API_KEY }}
          KODEXA_DEV_API_KEY: ${{ secrets.KODEXA_DEV_API_KEY }}
```

### Pull Mode Inputs

| Input          | Description                           | Required   | Default           |
| -------------- | ------------------------------------- | ---------- | ----------------- |
| `mode`         | Set to `pull`                         | Yes        | `deploy`          |
| `target`       | Target from sync-config.yaml          | Yes (pull) | -                 |
| `environment`  | Environment from sync-config.yaml     | Yes (pull) | -                 |
| `discover`     | Enable `--discover` for new resources | No         | `true`            |
| `skip-missing` | Skip missing server resources         | No         | `false`           |
| `branch-name`  | Branch for commits                    | No         | `sync/<env>`      |
| `pr-title`     | PR title                              | No         | `Sync from <env>` |
| `pr-base`      | PR base branch                        | No         | `main`            |

### Pull Mode Outputs

| Output              | Description               |
| ------------------- | ------------------------- |
| `pr-url`            | URL of created/updated PR |
| `changes-detected`  | `true` if files changed   |
| `resources-created` | Resources created         |
| `resources-updated` | Resources updated         |
| `resources-skipped` | Resources unchanged       |

<Note>
  Pull mode requires `permissions: contents: write` and `pull-requests: write` in your workflow file. The action uses `actions/checkout` credentials to push and the `GITHUB_TOKEN` to create PRs.
</Note>

## JSON Reports

Generate structured deployment reports for CI dashboard integration:

```bash theme={null}
kdx sync deploy --output-json ./deploy-report.json
```

The report includes timestamps, success/failure status, resource counts, and error details. Useful for:

* Slack/Teams notifications with deployment details
* Deployment tracking dashboards
* Automated rollback triggers
* Audit trails and compliance reporting

In GitHub Actions, the `kdx-sync-action` exposes the report via outputs:

```yaml theme={null}
- id: deploy
  uses: kodexa-ai/kdx-sync-action@v2
  env:
    KODEXA_PROD_API_KEY: ${{ secrets.KODEXA_PROD_API_KEY }}

- name: Upload JSON Report
  uses: actions/upload-artifact@v4
  with:
    name: deployment-report
    path: ${{ steps.deploy.outputs.json-report-path }}
```

## Example: Complete GitHub Actions Workflow

A production-ready workflow combining PR validation, multi-environment deployment, Slack notifications, and artifact upload:

```yaml theme={null}
name: Kodexa Deployment

on:
  push:
    branches: [main, staging, develop, 'feature/**']
    tags:
      - 'v*.*.*'
      - 'rc-*'
  pull_request:
    paths:
      - 'kodexa-metadata/**'
      - 'sync-config.yaml'

permissions:
  contents: read
  pull-requests: write

jobs:
  # Validate PRs with a dry run
  validate:
    if: github.event_name == 'pull_request'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - id: preview
        uses: kodexa-ai/kdx-sync-action@v2
        with:
          dry-run: true
        env:
          KODEXA_DEV_API_KEY: ${{ secrets.KODEXA_DEV_API_KEY }}

      - uses: actions/github-script@v7
        with:
          script: |
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: `## Deployment Preview\n\n**Targets**: ${{ steps.preview.outputs.targets-deployed }}\n**Create**: ${{ steps.preview.outputs.resources-created }}\n**Update**: ${{ steps.preview.outputs.resources-updated }}\n**Skip**: ${{ steps.preview.outputs.resources-skipped }}\n\nChanges validated. Safe to merge.`
            });

  # Deploy on push to branches or tags
  deploy:
    if: github.event_name == 'push'
    runs-on: ubuntu-latest
    environment: ${{ contains(github.ref, 'refs/heads/main') && 'production' || contains(github.ref, 'refs/heads/staging') && 'staging' || 'development' }}
    steps:
      - uses: actions/checkout@v4

      - id: deploy
        uses: kodexa-ai/kdx-sync-action@v2
        with:
          threads: 8
          annotate-summary: true
          slack-channel-id: ${{ secrets.SLACK_CHANNEL_ID }}
          slack-token: ${{ secrets.SLACK_BOT_TOKEN }}
        env:
          KODEXA_PROD_API_KEY: ${{ secrets.KODEXA_PROD_API_KEY }}
          KODEXA_STAGING_API_KEY: ${{ secrets.KODEXA_STAGING_API_KEY }}
          KODEXA_DEV_API_KEY: ${{ secrets.KODEXA_DEV_API_KEY }}

      - name: Upload deployment report
        uses: actions/upload-artifact@v4
        with:
          name: deployment-report
          path: ${{ steps.deploy.outputs.json-report-path }}

      - name: Summary
        run: |
          echo "## Deployment Complete" >> $GITHUB_STEP_SUMMARY
          echo "Targets: ${{ steps.deploy.outputs.targets-deployed }}" >> $GITHUB_STEP_SUMMARY
          echo "Created: ${{ steps.deploy.outputs.resources-created }}" >> $GITHUB_STEP_SUMMARY
          echo "Updated: ${{ steps.deploy.outputs.resources-updated }}" >> $GITHUB_STEP_SUMMARY
          echo "Skipped: ${{ steps.deploy.outputs.resources-skipped }}" >> $GITHUB_STEP_SUMMARY
```

## Other CI/CD Systems

The `kdx-sync-action` is GitHub-specific, but the underlying kdx CLI works in any CI/CD system. The pattern is always the same: install the binary, set environment variables for credentials, and run `kdx sync deploy`.

### GitLab CI

```yaml theme={null}
deploy:
  image: ubuntu:latest
  script:
    - curl -sL https://github.com/kodexa-ai/kdx-cli-releases/releases/latest/download/kdx_linux_x86_64.tar.gz | tar xz
    - mv kdx /usr/local/bin/
    - kdx sync deploy --confirm-all
  variables:
    KODEXA_PROD_API_KEY: $KODEXA_PROD_API_KEY
  only:
    - main
```

### Jenkins

```groovy theme={null}
pipeline {
    agent any
    environment {
        KODEXA_PROD_API_KEY = credentials('kodexa-prod-api-key')
    }
    stages {
        stage('Deploy') {
            steps {
                sh '''
                    curl -sL https://github.com/kodexa-ai/kdx-cli-releases/releases/latest/download/kdx_linux_x86_64.tar.gz | tar xz
                    chmod +x kdx
                    ./kdx sync deploy --confirm-all
                '''
            }
        }
    }
}
```

### CircleCI

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

jobs:
  deploy:
    docker:
      - image: cimg/base:current
    steps:
      - checkout
      - run:
          name: Install kdx CLI
          command: |
            curl -sL https://github.com/kodexa-ai/kdx-cli-releases/releases/latest/download/kdx_linux_x86_64.tar.gz | tar xz
            sudo mv kdx /usr/local/bin/
      - run:
          name: Deploy
          command: kdx sync deploy --confirm-all

workflows:
  deploy:
    jobs:
      - deploy:
          filters:
            branches:
              only: main
```

<Note>
  For any CI/CD system, the key requirements are:

  1. Download and install the kdx CLI binary for your platform
  2. Set the appropriate `KODEXA_*_API_KEY` environment variables
  3. Ensure `sync-config.yaml` is present in the repository
  4. Run `kdx sync deploy --confirm-all` (the `--confirm-all` flag skips interactive prompts)
</Note>

## Next Steps

<CardGroup cols={2}>
  <Card title="Sync Configuration" icon="gear" href="/guides/kdx-cli/sync/configuration">
    Configure sync-config.yaml targets and environments
  </Card>

  <Card title="Manifests" icon="file-lines" href="/guides/kdx-cli/sync/manifests">
    Define which resources to deploy with manifests
  </Card>

  <Card title="Conflict Detection" icon="code-compare" href="/guides/kdx-cli/sync/conflict-detection">
    Handle conflicts when multiple sources modify resources
  </Card>

  <Card title="GitOps with GitHub Actions" icon="github" href="/guides/deployment/gitops-github-actions">
    Full GitHub Actions reference with migration guide and security practices
  </Card>
</CardGroup>
