Forums

Articles
Create
cancel
Showing results for 
Search instead for 
Did you mean: 

Automating CMJ Migrations at Scale: An Open-Source Python Toolkit

Michael Salvio
April 8, 2026

Automating CMJ Migrations at Scale: An Open-Source Python Toolkit

TL;DR: After managing multiple large-scale Jira migrations using Configuration Manager for Jira (CMJ), I built a Python toolkit that automates the tedious parts—mapping validation, conflict detection, template generation, and post-migration cleanup. The code is open source on GitHub. This article shares the approach and lessons learned.

 

The Problem: CMJ Migrations at Scale

If you’ve ever done a Jira Data Center migration using CMJ, you know the pain:

  • Hundreds of objects to map: Statuses, custom fields, issue types, resolutions, link types—each needs a decision
  • Customer coordination: Someone has to review spreadsheets and make mapping decisions
  • Human error: Typos, copy-paste mistakes, and inconsistent naming can silently break a migration
  • Post-migration cleanup: CMJ creates objects that need to be deleted, but which ones are safe to remove?
  • No audit trail: What got mapped where? What was created vs. deleted?

 

For a single small project, this is manageable. For enterprise migrations with thousands of objects across multiple projects, it becomes a full-time job.

 

The Solution: An 11-Step Automated Pipeline

I built a Python toolkit that wraps around CMJ to automate the repetitive work while keeping humans in the loop for decisions that matter.

The Pipeline at a Glance

 

Phase

Steps

What Happens

Pre-Deployment

1–6

Convert data, process mappings, validate, generate CMJ templates

Customer Review

Between 3–4

Customer reviews and approves mapping decisions

CMJ Deployment

Manual

Import templates, deploy snapshot

Post-Deployment

7–11

Generate cleanup scripts, validate before/after deletion

 

Key Automation Features

The toolkit handles four categories of work that are tedious and error-prone when done manually:

  1. Intelligent Matching

The toolkit automatically matches source objects to target objects using:

  • Exact name matching
  • Fuzzy matching with confidence scores (e.g., “In Progress” → “InProgress” at 92%)
  • Type validation for custom fields (Text → Text, not Text → Number)

 

Match Results:

EXACT_MATCH: 234 objects (auto-mapped)

FUZZY_MATCH:  45 objects (suggested, needs review)

NO_MATCH:     28 objects (will be created)

 

  1. Conflict Detection

Multiple source objects mapping to the same target? The toolkit catches it before it reaches CMJ:

CONFLICTS DETECTED:

Target 'Approved' ← Sources: ['Approved', 'APPROVED', 'approved']

Target 'In Progress' ← Sources: ['In Progress', 'InProgress']

 

  1. Customer Review Validation

Before generating CMJ templates, the toolkit validates the customer-reviewed spreadsheet:

 

Check

Example Error

Leading/trailing spaces

" Status Name " → trim it

Copied suggestion text

"Status Name (85%)" → remove percentage

Invalid actions

"map" → should be "MAP"

Typos in target names

"Aproved" vs "Approved" in target

Duplicate targets

Two sources → same target (conflict)

 

  1. Safe Cleanup with JQL Validation

The generated Groovy cleanup script doesn’t blindly delete. It verifies first:

 

// Before deleting a status, verify no issues use it

def jql = "status = \"Old Status Name\""

def issueCount = countIssues(jql)

 

if (issueCount > 0) {

    println "SKIPPED: ${statusName} - ${issueCount} issues use this status"

} else {

    // Safe to delete

    statusManager.removeStatus(statusId)

}

 

Real-World Results

On a recent migration project:

 

Metric

Manual Approach

With Toolkit

Objects processed

500+

500+

Time to generate mappings

~8 hours

~10 minutes

Human errors caught

Found in UAT

Found before CMJ import

Cleanup confidence

“Hope nothing breaks”

JQL-validated, audited

 

Getting Started

The toolkit is open source and available at GitHub.

Prerequisites

  • Python 3.8+
  • CMJ installed in target Jira
  • ScriptRunner for target data export and cleanup execution
  • Access to source and target Jira REST APIs

Quick Start

 

# Clone the toolkit

git clone <repository-url>

cd cmj_template

 

# Install dependencies

pip install -r requirements.txt

 

# Validate your setup

python3 scripts/run_migration.py --validate

 

# Run interactively

python3 scripts/run_migration.py

 

The Workflow in Practice

Pre-Deployment: Data Collection (Steps 1–2)

Export data from source and target Jira instances, converting to Excel for the audit trail:

python3 run_migration.py --step 1  # Convert source data

python3 run_migration.py --step 2  # Convert target data

 

Output: Excel workbooks with all objects, IDs, and metadata—easy to review and share.

Pre-Deployment: Process & Validate (Steps 3–5)

python3 run_migration.py --step 3  # Process customer mapping

# → Customer reviews the PROCESSED.xlsx file

python3 run_migration.py --step 4  # Validate reviewed file

python3 run_migration.py --step 5  # Filter for CMJ template

 

The validation step is critical. It catches mistakes before they become CMJ import failures.

Pre-Deployment: Generate CMJ Templates (Step 6)

python3 run_migration.py --step 6  # Generate CMJ XML templates

 

Output: Two CMJ template files ready for import:

  • global_cmj_template.cmj — Statuses, Resolutions, Link Types, and Issue Types
  • custom_field_cmj_template.cmj — Custom Fields (imported separately due to size)

 

These templates are generated directly from the validated mapping spreadsheet, ensuring every MAP operation has been reviewed and approved before it touches CMJ. No more manual XML editing or copy-paste errors.

CMJ Deployment

Import both templates into CMJ and deploy your snapshot. This step remains manual—the toolkit hands off cleanly-formatted, validated input so the CMJ deployment itself is straightforward.

Post-Deployment Cleanup (Steps 7–11)

After CMJ deployment, export the new target state and generate the cleanup script:

python3 run_migration.py --step 7   # Convert post-import data

python3 run_migration.py --step 8   # Generate cleanup report

python3 run_migration.py --step 9   # Generate Groovy cleanup script

python3 run_migration.py --step 10  # Validate dryrun output

python3 run_migration.py --step 11  # Validate liverun output

 

The two-phase validation (dryrun then liverun) ensures nothing gets deleted that shouldn’t be.

 

Lessons Learned

  1. Validate Early, Validate Often

The #1 cause of CMJ failures in our experience: bad input data. A typo in a target name, an extra space, a copied suggestion with “(85%)” still attached. Catching these before CMJ import saves hours of debugging.

  1. Protect What Existed Before

Objects that existed in the target before migration should never be deleted. The toolkit tracks pre-import state and protects those objects during cleanup.

  1. Trust but Verify (JQL Checks)

Even after careful planning, always verify with JQL before deleting:

  • status = "StatusName" → Any issues using this status?
  • "FieldName" is not EMPTY → Any issues with data in this field?
  • issuetype = "TypeName" → Any issues of this type?
  1. Keep the Human in the Loop

Automation handles the tedious work. Humans make the decisions:

  • Should this source status map to “Done” or “Closed”?
  • Is this fuzzy match correct, or should we create a new object?
  • Which of these conflicting mappings wins?

 

None of This Works Without the Right Customer

Tools like this don’t get built—or validated—in a vacuum. A critical ingredient in making this toolkit production-ready was having a customer who was genuinely invested in getting it right.

Ryan Stroup dedicated real time and attention to this effort: reviewing mapping spreadsheets, testing the pipeline against his projects’ actual data, surfacing edge cases that only appear in production environments, and validating that every requirement was met before sign-off. That kind of engaged partnership is what separates a toolkit that works in theory from one you can trust on a live migration.

If you’re planning to adopt this approach, I’d strongly encourage the same model: identify a customer stakeholder who will roll up their sleeves and test alongside you. The automation handles the tedious work—but a willing, thorough collaborator on the customer side is what gives you confidence the output is actually correct.

 

Built with AI: A Claude Code Story

Full disclosure: this toolkit was built collaboratively with Claude Code, Anthropic’s AI-powered CLI assistant.

What started as a few helper scripts evolved into a comprehensive 11-step pipeline through iterative development with AI assistance. Claude Code helped with:

  • Rapid prototyping — Describing what I needed and getting working code in minutes
  • Edge case handling — “What if the customer copies the suggestion text with the percentage?” became a validation rule
  • Refactoring at scale — Restructuring the entire pipeline from 8 steps to 11 steps with proper validation
  • Documentation — Generating consistent docstrings, README updates, and yes, even this article draft

 

The experience reinforced something important: AI doesn’t replace domain expertise—it amplifies it. I knew what CMJ migrations needed; Claude Code helped me build it faster and with fewer bugs than I could have alone.

If you’re on the fence about using AI tools for Jira administration work, I’d encourage you to try it. The combination of your Jira knowledge and AI’s coding assistance is genuinely powerful.

 

Conclusion

CMJ is a powerful tool, but it’s only as good as the data you feed it. This toolkit fills the gap between “we have a mapping spreadsheet” and “CMJ templates are ready to import” with:

  • Automated matching and validation
  • Conflict detection before it’s too late
  • Production-ready CMJ XML templates
  • Safe, audited post-migration cleanup with JQL validation
  • Excel audit trails for everything

 

Whether you’re migrating one project or fifty, having a repeatable, validated process makes all the difference.

 

The code is on GitHub. If you run into issues or have improvements, feel free to open an issue or PR.

 

Questions or feedback? Drop a comment below or reach out directly. I’m always interested in hearing how others are tackling Jira migrations—and whether you’re using AI to help.

0 comments

Comment

Log in or Sign up to comment
TAGS
AUG Leaders

Atlassian Community Events