M .gitignore => .gitignore +2 -1
@@ 1,3 1,4 @@
*.json
*.pyc
-*.txt>
\ No newline at end of file
+*.txt
+local_config.py
M README.md => README.md +52 -2
@@ 1,5 1,20 @@
# trello2redmine
+From Peter:
+
+This is a copy of the [original version][og] of this script. It's essentially
+the same with some additional improvements and helpers. We ran dozens of
+projects on Trello and due to changes in both functionality and billing, we
+decided we would rather control our data versus constantly having to adapt to
+their updates.
+
+We'd already used Redmine for other projects and just decided to migrate
+everything over.
+
+[og]: https://github.com/okurz/trello2redmine
+
+Original:
+
This is a tiny tool I've written to migrate all of our issue tracking data at once. It uses Trello's JSON export feature and the JSON flavour of [Redmine's REST API](http://www.redmine.org/projects/redmine/wiki/Rest_api).
We had been using [Trello](http://trello.com) as a stop-gap solution while our internal services (including [Redmine](http://www.redmine.org)) were being set up. Hence the limited scope of support for features – it was a one-time operation, and I don't really have a vested interest in the application, but it may be of use to others.
@@ 10,6 25,15 @@ Tested with Python 2.7, but was written with Python 3 compatibility in mind.
Beyond the standard library, the script only requires [Requests](http://docs.python-requests.org/en/master/user/install/) for HTTP support.
+From Peter:
+
+You will also need a Trello API key to migrate attachments. Also, our Redmine
+install uses the [checklists plugin][cl] from RedmineUP. So if you don't have
+that plugin, just look at the commit history to see the change. You can easily
+revert my checklist changes to the original way.
+
+[cl]: https://www.redmineup.com/pages/plugins/checklists
+
## Configuration and usage
Edit [trello2redmine_config.py](trello2redmine_config.py) and fill in the details of your installation. Then just run the script.
@@ 25,11 49,36 @@ Not all features of Trello are supported. What works:
* mapping Trello lists to Redmine statuses,
* mapping Trello card labels to Redmine priorities.
+From Peter:
+
+* Checklists are now imported using the RedmineUP [checklist plugin][cl]
+* Attachments are migrated
+* Ability to specify lists who's card's should not have their attachments
+ migrated.
+* Multiple assignments are migrated (first user is assignee, rest are watchers)
+* List to redmine version support. Versions specified that are not in Redmine
+ will automatically be created.
+* Label to status mapping as well (see config file for example)
+* Set status for lists that are closed (archived)
+* General improvements to make it faster by saving json responses from Redmine
+ per project.
+* Basic recovery support by saving which cards have been successfully imported
+ and skipping those should you need to restart.
+
What doesn't:
-* multiple Trello card assignees: corresponding Redmine issue will only be assigned to the first one in Redmine,
* everything else.
+## Final comment from Peter
+
+This was done simply to move data. This is not a script I'm "proud" to share,
+even if I'm not the original author. It works great but the code is ugly,
+thrown together, hacky, violates many Python best practices and style
+guidelines, etc. Don't judge!
+
+Also huge thank you to Leszek Godlewski for the original version. It helped me
+get our data migrated much faster with the huge head start the script gave!
+
## Licensing
```
@@ 37,6 86,7 @@ What doesn't:
Version 2, December 2004
Copyright (C) 2016 Leszek Godlewski
+ Copyright (C) 2021 Peter Sanchez
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
@@ 46,4 96,4 @@ What doesn't:
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.
-```>
\ No newline at end of file
+```
A attachments/README.md => attachments/README.md +1 -0
@@ 0,0 1,1 @@
+Leave this directory. Attachments will be stored temporarily in this directory.
A json/README.md => json/README.md +2 -0
@@ 0,0 1,2 @@
+Leave this directory. Script will store project specific details about your
+Redmine install. This avoids having to query your install all the time.
M trello2redmine_config.py => trello2redmine_config.py +52 -15
@@ 4,31 4,68 @@
# All data here is exemplary, you need to fill it properly for the script to work!
# Trello configuration
-trello_board_link = 'https://trello.com/b/nSONZFOR' # As found on the board in Menu -> More -> Link to this board.
+trello_board_link = "https://trello.com/b/nSONZFOR" # As found on the board in Menu -> More -> Link to this board.
# Redmine configuration
-redmine_root_url = 'https://progress.opensuse.org'
-redmine_project_identifier = 'qam-qasle-collaboration' # As appears in the Redmine URLs.
-redmine_default_user = 'Oliver Kurz' # Trello cards which are unassigned or whose assignee does not have a mapping in username_map will be assigned to this Redmine user.
-redmine_verify_certificates = True # Whether to verify SSL certificates.
-redmine_api_key = '' # Redmine REST API key. See: http://www.redmine.org/projects/redmine/wiki/Rest_api#Authentication
+redmine_root_url = "https://your-redmine-install.com"
+redmine_project_identifier = "your-project" # As appears in the Redmine URLs.
+redmine_default_user = "Netlandish Bot" # Trello cards which are unassigned or whose assignee does not have a mapping in username_map will be assigned to this Redmine user.
+redmine_verify_certificates = True # Whether to verify SSL certificates.
+redmine_api_key = "PLACE YOUR REDMINE API KEY HERE" # Redmine REST API key. See: http://www.redmine.org/projects/redmine/wiki/Rest_api#Authentication
-# Trello card label to Redmine priority map.
+# To import attachments, you need a Trello API key and token.
+# You must create a Trello app to get the API Key. Then you need to get your token.
+# You can get the token from:
+# https://trello.com/1/authorize?key=YOUR_API_KEY&name=Your+App+Name&expiration=never&response_type=token&scope=read,write
+trello_apikey = "YOUR TRELLO API KEY"
+trello_token = "YOUR TRELLO API TOKEN"
+
+# Trello card label to Redmine tracker or status map
+# Use "Status:<status name>" if you want to translate a label to a status
label_map = {
- u'': u'Normal', # Default for no label.
+ u"": u"Normal", # Default for no label.
+ u"Feature": u"Feature", # Default for no label.
+ u"Task": u"Task", # Default for no label.
+ u"Bug": u"Bug", # Default for no label.
+ u"Blocked": u"Status:Info Needed", # Default for no label.
+ u"Info Needed": u"Status:Info Needed", # Default for no label.
}
# Trello-to-Redmine username map. Both are displayed names, *not* logins or IDs! Redmine names are resolved to user IDs behind the scenes.
username_map = {
- u'okurz': u'okurz',
- u'Foo Bar': u'Foo Bar',
- u'Nickname': u'Full Name',
+ u"Peter Sanchez": u"Peter Sanchez",
+ u"Foo Bar": u"Foo Bar",
+ u"Nickname": u"Full Name",
+ u"Jane Doe": u"Jane Doe",
}
# Trello list to Redmine status map. Redmine statuses are displayed names, *not* IDs! Statuses are resolved to IDs behind the scenes.
list_map = {
- u'TODO': u'New',
- u'DOING': u'In Progress',
- u'DONE': u'Resolved',
- u'Standing topics / status quo updates': u'Feedback',
+ u"Ideas / Backlog": u"New",
+ u"Backlog": u"New",
+ u"Next Up": u"New",
+ u"In Progress": u"In Progress",
+ u"Ready for Demo": u"Ready for Demo",
+ u"QA": u"QA Ready",
+ u"Completed": u"Resolved",
+ u"In Production": u"Resolved",
+ u"Documents": u"Not an Issue",
}
+
+# If Trello list is archived, all cards in that list should get this status
+closed_list_status = u"Resolved"
+
+# Trello list to redmine version map
+# Note: If version doesn't exist in Redmine, the script will create it.
+version_map = {
+ u"Ideas / Backlog": u"Backlog",
+ u"Backlog": u"Backlog",
+ u"Known Issues / Bugs": u"Backlog",
+ u"In Review": u"Backlog",
+ u"Next Sprint": u"Backlog",
+}
+
+# Do not import attachments from cards in these Trello lists
+no_file_import = [
+ u"Documents",
+]