Migrate Checklists from Jira Cloud to Cloud

This instruction describes how to migrate Checklists created by Smart Checklist add-on from one Jira Cloud instance to another Cloud instance. It’s based on Atlassian’s recommended method - Copy Jira data.

 

There are two methods of migrating checklist data from Jira Cloud to Cloud:

 

☝🏼NOTE: It is required to have Checklists and Smart Checklist Progress Custom Fields to be set on source Cloud instance. Only data from the custom fields will be migrated.

These checklist data will not be migrated:

  • custom statuses

  • templates

Instructions

Preconditions

  • Source cloud instance - Smart Checklist app is installed, Custom Fields are created: Checklists, Smart Checklist Progress.

  • Destination cloud instance - Smart Checklist app is installed, Custom Fields are not created.

  • Source cloud instance have projects with checklist data.

Copy Jira data flow

All below steps are taken from https://support.atlassian.com/organization-administration/docs/copy-jira-data/

Step 1 To start copying data

  1. Go to admin.atlassian.com. Select your organization if you have more than one.

  2. Select Settings > Data management > Copy product data.

  3. Select Create copy plan.

  4. On the How it works page, select Next.

  5. From the Select a product page, select Jira.

Step 2 Choose source and destination instances

  1. Select the source and destination instances.

  2. Name your plan. If you create multiple plans, you’ll be able to track the progress of a plan by this name.

  3. Click Next.

Step 3 Select the project to copy

  1. Select the projects to migrate and click Next.

Step 4 Select data

  1. In the users and groups section, choose your option to copy users and groups.

  2. In the Group memberships section, select whether to copy users and groups separately or together.

  3. In the Customers and Organizations section, select whether to all customers and organizations or only customers related to the selected projects.

  4. In the boards and filters section, select whether to cross-project boards and filters associated with selected projects, all or none.

  5. Click Next.

Step 5 Validate data

  1. Run checks to identify potential problems or unwanted settings. At this step, we create and save the plan, and it’ll appear on the dashboard.

  2. Click Next.

Step 6 Review data

  1. Review the data you selected on the Review your selections page.

  2. Click Copy data.

Post actions

Monitor the progress by keeping track of the status of a plan. Wait until your migration is complete.

  1. Go to the destination cloud instance.

  2. Follow this link to add Checklists custom field to the Issue screen for the migrated projects.

    1. Navigate to Settings → Settings → Issues → Custom fields → Find ‘Checklists' or custom field.

    2. Click on the 3-dots menu → Associate to Screens.

    3. Select screens related to your migrated projects.

    4. Click Update.

  3. Open any issue from the project with checklist data.

  4. Verify Checklists field is not empty and contains data.

    image-20240808-093410.png

  5. Navigate to Apps → Manage your apps → Smart Checklist of Smart Checklist app → Global Settings tab.

  6. Run the ‘Synchronize checklist storages’ to copy data from Jira custom fields to the SC database.

    image-20240808-093449.png

  7. Wait once it is completed and open any issue with checklist data

 

 

FAQ about Smart Checklist add-on migration in Copy Jira data

1. What data from Smart Checklist for Jira. Pro addon will be migrated from Cloud to Cloud?

Unfortunately, app data migration is not supported in the Copy Jira data process based on Jira documentation. Check here what data is copied - https://support.atlassian.com/organization-administration/docs/what-product-data-is-copied/

Only custom field values are copied. Make sure the Smart Checklist app is installed on both Cloud instances to migrate checklist data.

Please see detailed information in the table below:

Data type

Migration support

Source Cloud

Destination Cloud

Data type

Migration support

Source Cloud

Destination Cloud

Checklist items with different markup:

  • raw text

  • simple items

  • items with details

  • bold, italic, emphasized text

  • numbered lists

  • unnumbered lists

  • images

  • links to external sources

  • links to Jira (same project or different, but also migrated project)

supported

 

Checklist data will be migrated from Checklists custom field

Default statuses

not supported

 

Will be present once Smart Checklist app is installed on destination instance

Custom statuses

not supported

 

Need to be created manually before migration

Templates

not supported

 

 

2. How to migrate templates?

You can import templates to the Issues, and thus their content will be migrated. After the migration, you will need to save the corresponding checklists as templates again.

3. I have custom fields “Checklists” and “Smart Checklist Progress” created on the destination Cloud, what can I do?

In this case, after migration, you will have duplicated custom fields:

Smart Checklist Addon on Cloud uses “Checklists” and “Smart Checklist Progress” custom fields to sync data in, so after migration you need to synchronize data from custom field to addon database. This should be done to synchronize data to the addon database (and make it visible in the addon).

There are several ways to deal with duplicates:

  • the main option is to synchronize data from the 'Checklists (migrated)' field

  • an alternative way is to copy data from the migrated field (usually Checklists (migrated)) to the original Checklists field using third-party apps

Synchronize data with the 'Checklists (migrated)' field

  1. Navigate to Apps → Manage your apps → Smart Checklist of Smart Checklist app → Global Settings tab.

  2. Click ‘Synchronize’ button and select the 'Checklists (migrated)' field to copy data from Jira custom fields to the SC database.

  3. This process runs in the background and may take some time before all the data finishes synchronizing.

  4. Once it is completed go to the Settings → Issues → Custom fields → Find ‘Checklists (migrated)' field

  5. Click on the 3-dots menu and select Move to trash

  6. Confirm the operation and repeat it for 'Smart Checklist progress (migrated)’ field

  7. Go to the Trashed tab under the Custom fields and delete those fields from there too.

An alternative way to copy data from the migrated field (usually Checklists (migrated)) to the original Checklists field using third-party apps

This can be done, for example, using the Scriptrunner addon script or any other automation tools.

Below is an example of a Scriptrunner script that copies data from one field to another, and additionally it transfers data from the Checklists field to the addon database.

  1. Navigate to SCRIPTRUNNER (addon should be previously installed) → Select 'Script Console'

  2. In the console field copy and paste the following code:

// Define a JQL query for the issues on which you want to copy custom field values def query = 'project = NTP' // Here you can specify the names of the fields you want to copy from and into def sourceFieldName = 'Checklists (migrated)' def targetFieldName = 'Checklists' // We retrieve a list of all fields in this JIRA instance def fields = get("/rest/api/2/field") .asObject(List) assert fields.status == 200 List<Map> allFields = fields.body // Now we lookup the field IDs Map sourceField = allFields.find { it.name == sourceFieldName } Map targetField = allFields.find { it.name == targetFieldName } assert sourceField : "No field found with name '${sourceFieldName}'" assert targetField : "No field found with name '${targetFieldName}'" // Search for the issues we want to update def searchReq = get("/rest/api/2/search") .queryString("jql", query) .queryString("startAt", 0) .queryString("maxResults", 100) // If we search for too many issues we'll reach the 30s script timeout .queryString("fields", "${sourceField.key},${targetField.key}") .queryString("expand", "names,schema") .asObject(Map) assert searchReq.status == 200 Map searchResult = searchReq.body // A useful helper method def sanitiseValue(fieldValue) { // If we strip ids and self links out, we can set options by their values if (fieldValue instanceof Map) { fieldValue.remove('id') fieldValue.remove('self') } if (fieldValue instanceof List || fieldValue.class?.isArray()) { fieldValue.each { sanitiseValue(it) } } } // Each field type stores its value in a different way, we allow some conversion between types here def getValue(sourceValue, String sourceType, String targetType) { if (sourceType == targetType) { return sourceValue } if (sourceType == 'option' && targetType == 'array') { return [sourceValue] } if (sourceType == 'option' && targetType == 'string') { return (sourceValue as Map).value } if (sourceType == 'array' && (targetType == 'option' || targetType == 'user')) { return (sourceValue as List)[0] } if (sourceType == 'array' && targetType == 'string') { return (sourceValue as List<Map>).collect { it.value }.join(',') } if (sourceType == 'string' && targetType == 'option') { return [value: sourceValue] } if (sourceType == 'string' && targetType == 'array') { return [[value:sourceValue]] } if (sourceType == 'user' && targetType == 'array') { return [sourceValue] } sourceValue } String sourceType = (sourceField.schema as Map).type String targetType = (targetField.schema as Map).type def count = 0 def errors = '' // Now we iterate through the search results searchResult.issues.each { Map issue -> def issueFields = issue.fields as Map def sourceFieldValue = issueFields[sourceField.key] if (sourceFieldValue) { // If there is a field value in the source field we try and convert it into a format that // the target field will understand sanitiseValue(sourceFieldValue) def updateDoc = [fields: [ (targetField.key): getValue(sourceFieldValue, sourceType, targetType) ]] // Now we make the change, ignoring whether the field exists on the edit screen def resp = put("/rest/api/2/issue/${issue.key}") .header("Content-Type", "application/json") .body(updateDoc) .asObject(Map) if (resp.status > 299) { logger.error("Failed to update ${issue.key}: ${resp.statusText} - ${resp.body}") def errorMessages = (resp.body as Map).errorMessages as List<String> errors += "\nERROR: ${issue.key}: ${errorMessages?.join(',')}" } else { count++ } } } logger.info("Updated '${targetFieldName}' on ${count} issues") errors
  1. In the script set project, sourceFieldName and targetFieldName, in our case:

def query = ‘project = NTP' - here instead of NTP should be your project key
def sourceFieldName = ‘Checklists (migrated)' - the name of the duplicated field, usually 'Checklists (migrated)’
def targetFieldName = 'Checklists' - here should be the 'Checklists’ field

  1. Run the script.

  2. Delete the duplicated field

4. I don’t see migrated data in the Jira issues, what can I do?

If, after the data is copied to the Checklists field, the Smart Checklist addon does not display the checklist, you will need to run Synchronize checklist storages additionally.

 

 


📫 Don’t hesitate to get in touch with us for any questions or feature requests!