What is your developer-dependent CMS actually costing you? Calculate your costs and get a full report
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:
- Pull the repository containing your Agility mappings
- Run the CLI sync command to synchronize content between instances
- 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 Settings → Instance Details in your Agility CMS dashboard.
Environment Variables
Configure these environment variables in your CI/CD platform:
| Variable | Required | Description |
|---|---|---|
AGILITY_TOKEN | Yes | Personal Access Token for authentication |
AGILITY_GUID | Yes | Source instance GUID |
AGILITY_TARGET_GUID | Yes | Target instance GUID |
AGILITY_LOCALES | No | Comma-separated locales (e.g., en-us,fr-ca) |
AGILITY_ELEMENTS | No | Elements to sync (default: all) |
AGILITY_ROOT_PATH | No | Local 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_TOKENsecret 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:
- Stop all concurrent sync operations
- Restore mappings from a known good state
- Run a fresh sync with
--update=trueto rebuild mappings
Support
- Documentation: Agility CMS Doc Site
- Community: Agility Slack
- Issues: GitHub Issues