APIs
The Agility CLI allows you to pull, push, or clone an instance from your console. This guide gives you best practices on how to integrate the Agility CLI into your CI/CD pipelines to automate content synchronization between Agility CMS instances.
This guide explains how to integrate the Agility CLI into your CI/CD pipelines to automate content synchronization between Agility CMS instances.
The typical CI/CD workflow involves:
Persisting mappings in a Git repository ensures that content relationships are maintained across sync operations and prevents duplicate content creation.
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
The user associated with the PAT must have one of the following roles:
You'll need the GUIDs for both your source and target instances:
Find these in Settings → Instance Details in your Agility CMS dashboard.
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) |
When running in CI/CD, use the --headless flag to:
agility sync --headless --sourceGuid="$SOURCE_GUID" --targetGuid="$TARGET_GUID"
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
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
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
Sync specific models with their dependencies:
agility sync \
--headless \
--sourceGuid="$SOURCE_GUID" \
--targetGuid="$TARGET_GUID" \
--models-with-deps="BlogPost,BlogCategory"
Sync only specific locales:
agility sync \
--headless \
--sourceGuid="$SOURCE_GUID" \
--targetGuid="$TARGET_GUID" \
--locales="en-us,fr-ca"
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
# 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"
Always commit your agility-files/mappings/ directory to your repository. This ensures:
[skip ci] in Commit MessagesInclude [skip ci] in mapping commit messages to prevent infinite pipeline loops:
git commit -m "chore: update Agility CMS mappings [skip ci]"
Use different branches or repositories for different environment mappings:
main branch → Production sync mappings
staging branch → Staging sync mappings
develop branch → Development sync mappings
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
Keep sync logs as artifacts for debugging:
artifacts:
paths:
- agility-files/logs/
expire_in: 7 days
Use the exit code to handle sync failures:
agility sync --headless --sourceGuid="..." --targetGuid="..." || {
echo "Sync failed, check logs for details"
exit 1
}
AGILITY_TOKEN secret is properly configuredIn corporate environments with proxy servers, use the --insecure flag:
agility sync --headless --insecure --sourceGuid="..." --targetGuid="..."
If mappings are missing, the CLI will create new content instead of updating existing content. Always ensure:
agility-files/mappings/ directory is committed to your repositoryIf duplicates are being created:
--update=true to rebuild mappings