Implementing Changelog Generation from Architect Flow Version Diffs
What This Guide Covers
You are implementing an automated system to track and document changes in Genesys Cloud Architect flows. In large contact centers, IVR logic evolves rapidly across multiple developers. Manual changelogs are often incomplete or inaccurate. By programmatically diffing exported Architect flow configurations (YAML or JSON) between versions, you can generate a readable changelog that highlights modified prompts, updated Data Action inputs, changed routing targets, and new decision logic. This guide demonstrates how to use the Architect Scripting API and standard diffing tools to build a CI/CD-integrated documentation pipeline.
Prerequisites, Roles & Licensing
- Genesys Cloud: CX 1, 2, or 3.
- Permissions:
Architect > Flow > ViewArchitect > Flow > Export
- Tooling:
- Python 3.9+ or Node.js.
archy(Genesys Cloud Architect CLI) or the Architect Scripting SDK.jsondiffpatchor a similar object-diffing library.
The Implementation Deep-Dive
1. Architect Flow Versioning Strategy
Architect flows do not have a built-in “diff” view in the UI. To see what changed between version 15 and version 16, you must export both and compare them.
Exporting via Archy:
# Export the current version of the flow
archy export --flowName "Customer_Service_Main" --flowType "inboundcall" --exportType "yaml" --outputFile ./flows/current_v16.yaml
# Export the previous version (requires temporary revert or fetching from Git history)
# Best practice: Store every published version in a Git repository.
2. Normalizing Flow Exports
Architect exports contain transient metadata (timestamps, user IDs, internal IDs) that change even if the logic stays the same. Before diffing, you must normalize the files.
import yaml
import json
def normalize_flow(flow_dict):
"""Recursively removes transient metadata from Architect flow dict."""
keys_to_remove = ['id', 'dateModified', 'modifiedBy', 'version', 'dateCreated']
if isinstance(flow_dict, dict):
return {k: normalize_flow(v) for k, v in flow_dict.items() if k not in keys_to_remove}
elif isinstance(flow_dict, list):
return [normalize_flow(item) for item in flow_dict]
else:
return flow_dict
# Usage
with open('current_v16.yaml', 'r') as f:
v16 = yaml.safe_load(f)
normalized_v16 = normalize_flow(v16)
3. Generating the Semantic Diff
Instead of a line-by-line text diff, use a semantic object diff to identify specific Architect actions.
from dictdiffer import diff
def generate_architect_changelog(old_flow, new_flow):
changelog = []
changes = diff(old_flow, new_flow)
for action, path, data in changes:
path_str = " -> ".join(map(str, path))
if action == 'change':
old_val, new_val = data
changelog.append(f"MODIFIED: {path_str} changed from '{old_val}' to '{new_val}'")
elif action == 'add':
changelog.append(f"ADDED: New element at {path_str}: {data}")
elif action == 'remove':
changelog.append(f"REMOVED: Element at {path_str}")
return changelog
4. Categorizing Changes (Human-Readable)
A raw diff is still hard to read. Map the paths to Architect concepts:
| Path Prefix | Category |
|---|---|
settings.prompts |
Prompt Updates |
menus |
IVR Menu Structure |
tasks |
Business Logic / Flow |
tasks.actions[?(@.type == 'dataAction')] |
Integration Changes |
Refined Logic:
def humanize_path(path_list):
if 'tasks' in path_list:
task_name = path_list[path_list.index('tasks') + 1]
return f"Task '{task_name}'"
if 'prompts' in path_list:
return "Audio Prompts"
return "Global Settings"
5. Automation via GitHub Actions
Run this check every time a flow is committed to the repository to automatically generate a PR comment with the changelog.
name: Architect Flow Diff
on: [pull_request]
jobs:
diff_flow:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Generate Changelog
run: |
python scripts/flow_differ.py --old HEAD~1 --new HEAD > changelog.txt
- name: Comment PR
uses: thollander/actions-comment-pull-request@v2
with:
filePath: changelog.txt
Validation, Edge Cases & Troubleshooting
Edge Case 1: Large Flows (Memory Limit)
Very complex flows (1000+ nodes) can cause recursion depth errors in some diff libraries.
Solution: Use iterative diffing or increase the recursion limit. Focus only on the tasks and menus keys to reduce processing overhead.
Edge Case 2: Expression Change Detection
If an expression like ToDuration("PT1H") is changed to ToDuration("PT2H"), a simple string diff might miss the semantic intent.
Solution: Use regex or an expression parser if you need to detect specific variable changes within Architect expressions.
Edge Case 3: Re-ordered Actions
If a developer swaps the order of two “Play Audio” steps, a list diff might report it as one removal and one addition.
Solution: Use a diffing library that supports “best match” or “LCS” (Longest Common Subsequence) to detect re-ordering without flooding the changelog.