Simple .NET app to migrate issues between Redmine hosts

Added by Aleksey Oriekhov about 5 years ago

Hi all,

I've created a simple .NET console application to migrate issues between different Redmine hosts.
It can be useful if you don't have access to database and/or not able to export your data in raw format.

Actually, Redmine can export part of the data, but it can't export journal notes, which are often contain important information about the issue.
So, I've decided to create own script which will copy journal comments as well. Note, that only text of journal comment is copied, all other information omitted.

See the code below. To compile it, you will need to use Redmine .NET API library
Also, the next links could be useful:


using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Redmine.Net.Api;
using Redmine.Net.Api.Types;

namespace RedmineIssuesMigrationTool
    class Program
        static void Main(string[] args)
            const string sourceHost = "http://localhost:8080/redmine";
            const string sourceApiKey = "your_hash_here";
            //const string sourceProject = "your-project-name";

            const string targetHost = "";
            const string targetApiKey = "your_target_hash_here";
            // project id on target host, can be received by calling manager.GetTotalObjectList<Project>(listParams);
            const int targetProjectId = 9999; 

            var sourceManager = new RedmineManager(sourceHost, sourceApiKey);
            var targetManager = new RedmineManager(targetHost, targetApiKey);

            var listParams = new NameValueCollection
                //{ "project_id", sourceProject},
                { "status_id", "open" } // open, closed or *
            var issueParams = new NameValueCollection
                { "include", "journals"}

            // warning. this code is not fast, especially if you have lots of issues!
            IList<Issue> issuesList = sourceManager.GetTotalObjectList<Issue>(listParams);

            foreach (var issue in issuesList)
                Console.WriteLine("#{0}: {1}", issue.Id, issue.Subject);

                // get additional info about issue
                var issueDetails = sourceManager.GetObject<Issue>(issue.Id.ToString(CultureInfo.InvariantCulture), issueParams);

                //Create a issue on target host
                var newIssue = new Issue();
                newIssue.Project = new IdentifiableName() {Id = targetProjectId};
                newIssue.Tracker = issueDetails.Tracker; // valid only if basic trackers used, e.g. bug, feature, support... for custom you have to map each tracker
                newIssue.Status = issueDetails.Status; // same as above, if no custom statuses, it's OK

                //newIssue.Priority = new IdentifiableName() { Id = issueDetails.Priority.Id };
                newIssue.Priority = issueDetails.Priority; // same as above

                newIssue.Subject = issueDetails.Subject;
                newIssue.Description = issueDetails.Description;

                //newIssue.Category = issueDetails.Category; // to use categories you have to implement mapping: source category -> target category
                //newIssue.AssignedTo = new IdentifiableName() { Id = 999 };

                var createdIssue = targetManager.CreateObject(newIssue);

                // not sure if journal is already sorted or not, sort it anyway
                var sortedList = issueDetails.Journals.OrderBy(journal => journal.CreatedOn);
                // migrate journal notes
                foreach (var journal in sortedList)
                    // skip empty comments
                    if (!string.IsNullOrEmpty(journal.Notes))
                        Console.WriteLine("@{0}: {1}", journal.CreatedOn, journal.Notes);

                        createdIssue.Notes = journal.Notes;
                        targetManager.UpdateObject(createdIssue.Id.ToString(CultureInfo.InvariantCulture), createdIssue);

Replies (5)

RE: Simple .NET app to migrate issues between Redmine hosts - Added by Alex ferguson about 1 year ago

In reality, Redmine can trade some portion of the information, yet it can't send out diary notes, which regularly contain critical data about the issue. Can Someone Do My Essay In this way, I've chosen to make possess content which will duplicate diary remarks also. Note, that exclusive content of diary remark is replicated,

RE: Simple .NET app to migrate issues between Redmine hosts - Added by Arabella Alice 4 months ago

Definitely, Redmine facilitating administration encourages you a considerable measure in your ventures and [url=]purchase essay online[/url] organizations. It was checked on in a blog I had perused previously.

RE: Simple .NET app to migrate issues between Redmine hosts - Added by Doris J. Titsworth Doris J. Titsworth 4 months ago

It was an awesome script which I noticed here today. I have tried it before for my review blogs. Generally we have taken the essay blog experts help in creating new alternative toolkit and now we are using that toolkit only for our company project works.

RE: Simple .NET app to migrate issues between Redmine hosts - Added by Jasmine Freeman 3 months ago

As a general rule, Redmine can exchange some segment of the data, yet it can't convey journal notes, which routinely contain basic information about the issue. Would someone be able to Law Essay Help in UK along these lines, I've made have content which will copy journal comments too? Note, that select substance of journal comment is duplicated,

RE: Simple .NET app to migrate issues between Redmine hosts - Added by Carolina Emory about 1 month ago

Designed for the console and show screen, a support application is driven by console and framework occasions created by system associations and items. manufactured home parks