CI/CD Integration Guide

This guide explains how to integrate the Agility CLI into your CI/CD pipelines to automate content synchronization between Agility CMS instances.

Overview

The typical CI/CD workflow involves:

  1. Pull the repository containing your Agility mappings
  2. Run the CLI sync command to synchronize content between instances
  3. Push the updated mappings back to the repository

Persisting mappings in a Git repository ensures that content relationships are maintained across sync operations and prevents duplicate content creation.


Prerequisites

1. Personal Access Token (PAT)

In CI/CD environments, browser-based authentication is not available. You must use a Personal Access Token (PAT) for authentication.

To obtain a PAT: Personal Access Tokens are created and managed using the management API which are documented in the "Personal Access Tokens" section of our Management API Swagger documentation found here: https://mgmt.aglty.io/index.html

2. Required Permissions

The user associated with the PAT must have one of the following roles:

  • Org Admin
  • Instance Admin
  • Manager role on both source and target instances

3. Instance GUIDs

You'll need the GUIDs for both your source and target instances:

  • Source GUID: The instance you're pulling content from
  • Target GUID: The instance you're pushing content to

Find these in SettingsInstance Details in your Agility CMS dashboard.


Environment Variables

Configure these environment variables in your CI/CD platform:

VariableRequiredDescription
AGILITY_TOKENYesPersonal Access Token for authentication
AGILITY_GUIDYesSource instance GUID
AGILITY_TARGET_GUIDYesTarget instance GUID
AGILITY_LOCALESNoComma-separated locales (e.g., en-us,fr-ca)
AGILITY_ELEMENTSNoElements to sync (default: all)
AGILITY_ROOT_PATHNoLocal directory for files (default: agility-files)

Headless Mode

When running in CI/CD, use the --headless flag to:

  • Disable interactive console output
  • Log all output to files instead
  • Prevent terminal UI elements that may cause issues in non-TTY environments
agility sync --headless --sourceGuid="$SOURCE_GUID" --targetGuid="$TARGET_GUID"

Sample Pipeline Configurations

GitHub Actions

name: Agility CMS Sync

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

env:
  AGILITY_TOKEN: ${{ secrets.AGILITY_TOKEN }}
  SOURCE_GUID: ${{ vars.AGILITY_SOURCE_GUID }}
  TARGET_GUID: ${{ vars.AGILITY_TARGET_GUID }}

jobs:
  sync:
    runs-on: ubuntu-latest
    
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
          fetch-depth: 0

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Install Agility CLI
        run: npm install -g @agility/cli

      - name: Run Agility Sync
        run: |
          agility sync \
            --headless \
            --sourceGuid="$SOURCE_GUID" \
            --targetGuid="$TARGET_GUID"

      - name: Commit and push mappings
        run: |
          git config user.name "github-actions[bot]"
          git config user.email "github-actions[bot]@users.noreply.github.com"
          
          # Add only the mappings directory
          git add agility-files/mappings/
          
          # Check if there are changes to commit
          if git diff --staged --quiet; then
            echo "No mapping changes to commit"
          else
            git commit -m "chore: update Agility CMS mappings [skip ci]"
            git push
          fi

GitHub Actions - Multi-Environment

name: Agility CMS Multi-Environment Sync

on:
  workflow_dispatch:
    inputs:
      environment:
        description: 'Target environment'
        required: true
        type: choice
        options:
          - staging
          - production

jobs:
  sync:
    runs-on: ubuntu-latest
    environment: ${{ github.event.inputs.environment }}
    
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
          fetch-depth: 0

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Install Agility CLI
        run: npm install -g @agility/cli

      - name: Run Agility Sync
        env:
          AGILITY_TOKEN: ${{ secrets.AGILITY_TOKEN }}
        run: |
          agility sync \
            --headless \
            --sourceGuid="${{ vars.AGILITY_SOURCE_GUID }}" \
            --targetGuid="${{ vars.AGILITY_TARGET_GUID }}" \
            --locales="${{ vars.AGILITY_LOCALES }}"

      - name: Commit and push mappings
        run: |
          git config user.name "github-actions[bot]"
          git config user.email "github-actions[bot]@users.noreply.github.com"
          
          git add agility-files/mappings/
          
          if git diff --staged --quiet; then
            echo "No mapping changes to commit"
          else
            git commit -m "chore: update Agility CMS mappings (${{ github.event.inputs.environment }}) [skip ci]"
            git push
          fi

Advanced Configuration

Selective Sync by Elements

Sync only specific content types:

agility sync \
  --headless \
  --sourceGuid="$SOURCE_GUID" \
  --targetGuid="$TARGET_GUID" \
  --elements="Models,Content,Assets"

Available elements: Models, Galleries, Assets, Containers, Content, Templates, Pages

Model-Specific Sync

Sync specific models with their dependencies:

agility sync \
  --headless \
  --sourceGuid="$SOURCE_GUID" \
  --targetGuid="$TARGET_GUID" \
  --models-with-deps="BlogPost,BlogCategory"

Locale-Specific Sync

Sync only specific locales:

agility sync \
  --headless \
  --sourceGuid="$SOURCE_GUID" \
  --targetGuid="$TARGET_GUID" \
  --locales="en-us,fr-ca"

Workflow Operations

After syncing content, you can perform workflow operations (publish, approve, etc.) on the synced items:

# Publish all synced content and pages
agility workflows \
  --headless \
  --sourceGuid="$SOURCE_GUID" \
  --targetGuid="$TARGET_GUID" \
  --operationType="publish"

Available operations: publish, unpublish, approve, decline, requestApproval

Full Sync + Publish Pipeline Example

# GitHub Actions example with sync and publish
- name: Sync and Publish Content
  run: |
    # First, sync the content
    agility sync \
      --headless \
      --sourceGuid="$SOURCE_GUID" \
      --targetGuid="$TARGET_GUID"
    
    # Then, publish the synced content
    agility workflows \
      --headless \
      --sourceGuid="$SOURCE_GUID" \
      --targetGuid="$TARGET_GUID" \
      --operationType="publish"

Best Practices

1. Store Mappings in Version Control

Always commit your agility-files/mappings/ directory to your repository. This ensures:

  • Consistency across pipeline runs
  • Rollback capability
  • Audit trail of sync operations
  • Prevention of duplicate content creation

2. Use [skip ci] in Commit Messages

Include [skip ci] in mapping commit messages to prevent infinite pipeline loops:

git commit -m "chore: update Agility CMS mappings [skip ci]"

3. Separate Environments

Use different branches or repositories for different environment mappings:

main branch       → Production sync mappings
staging branch    → Staging sync mappings
develop branch    → Development sync mappings

4. Scheduled Runs

Set up scheduled pipeline runs for regular sync operations:

# GitHub Actions cron syntax: minute hour day month weekday
schedule:
  - cron: '0 2 * * *'  # Daily at 2 AM UTC

5. Artifact Retention

Keep sync logs as artifacts for debugging:

artifacts:
  paths:
    - agility-files/logs/
  expire_in: 7 days

6. Handle Failures Gracefully

Use the exit code to handle sync failures:

agility sync --headless --sourceGuid="..." --targetGuid="..." || {
  echo "Sync failed, check logs for details"
  exit 1
}

Troubleshooting

Authentication Errors

  • Verify the PAT is valid and not expired
  • Ensure the token has sufficient permissions
  • Check that the AGILITY_TOKEN secret is properly configured

SSL Certificate Errors

In corporate environments with proxy servers, use the --insecure flag:

agility sync --headless --insecure --sourceGuid="..." --targetGuid="..."

Missing Mappings

If mappings are missing, the CLI will create new content instead of updating existing content. Always ensure:

  • The agility-files/mappings/ directory is committed to your repository
  • The pipeline checks out the full repository (not a shallow clone)

Duplicate Content

If duplicates are being created:

  1. Stop all concurrent sync operations
  2. Restore mappings from a known good state
  3. Run a fresh sync with --update=true to rebuild mappings

Support