Skip to main content
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.
For GitHub Actions, the kdx-sync-action handles CLI installation, caching, and output parsing automatically: kodexa-ai/kdx-sync-action

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:
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_from_env: KODEXA_PROD_API_KEY

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

  dev:
    url: https://dev.kodexa-enterprise.com
    api_key_from_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
Use GitHub environments to add protection rules like required approvals for production deployments.

3. Create Workflow

Create .github/workflows/deploy.yml:
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

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:
InputDescriptionDefault
sync-configPath to sync-config.yamlAuto-discovered
metadata-dirMetadata directory overrideAuto-discovered
dry-runPreview only (true/false)false
kdx-versionkdx CLI version to uselatest
threadsNumber of parallel threads8
filterResource filter pattern-
branchOverride branch detection-
tagOverride with tag mapping-
slack-channel-idSlack channel ID for notifications-
slack-tokenSlack Bot Token for posting-
annotate-summaryAdd summary to GitHub jobfalse

Outputs

OutputDescription
targets-deployedNumber of targets deployed
resources-createdResources created
resources-updatedResources updated
resources-skippedResources unchanged
json-reportJSON deployment report data
json-report-pathPath to JSON report file

Using Outputs

- 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:
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

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

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:
tag_mappings:
  - pattern: "v*.*.*"
    target: production
    environment: prod

  - pattern: "v*-*"
    target: staging
    environment: staging
Release workflow:
# 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

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:
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.
# 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 Kodexa Studio 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:
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
This is especially useful when team members edit resources in the Kodexa Studio UI. The scheduled pull captures those changes and brings them back into version control automatically.

On-Demand Pull with Environment Selection

For manual pulls with a dropdown to choose the environment:
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

InputDescriptionRequiredDefault
modeSet to pullYesdeploy
targetTarget from sync-config.yamlYes (pull)-
environmentEnvironment from sync-config.yamlYes (pull)-
discoverEnable --discover for new resourcesNotrue
skip-missingSkip missing server resourcesNofalse
branch-nameBranch for commitsNosync/<env>
pr-titlePR titleNoSync from <env>
pr-basePR base branchNomain

Pull Mode Outputs

OutputDescription
pr-urlURL of created/updated PR
changes-detectedtrue if files changed
resources-createdResources created
resources-updatedResources updated
resources-skippedResources unchanged
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.

JSON Reports

Generate structured deployment reports for CI dashboard integration:
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:
- 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:
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

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

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

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
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)

Next Steps

Sync Configuration

Configure sync-config.yaml targets and environments

Manifests

Define which resources to deploy with manifests

Conflict Detection

Handle conflicts when multiple sources modify resources

GitOps with GitHub Actions

Full GitHub Actions reference with migration guide and security practices