Пример #1
0
        private void ExecuteMigration(CommandOption token, CommandOption url, CommandOption configFile, bool forceFresh, CommandOption continueOnCritical)
        {
            ConfigJson config        = null;
            var        itemCount     = 0;
            var        revisionCount = 0;
            var        importedItems = 0;
            var        sw            = new Stopwatch();

            sw.Start();

            try
            {
                string           configFileName   = configFile.Value();
                ConfigReaderJson configReaderJson = new ConfigReaderJson(configFileName);
                config = configReaderJson.Deserialize();

                var context = MigrationContext.Init("wi-import", config.Workspace, config.LogLevel, forceFresh, continueOnCritical.Value());

                // connection settings for Azure DevOps/TFS:
                // full base url incl https, name of the project where the items will be migrated (if it doesn't exist on destination it will be created), personal access token
                var settings = new Settings(url.Value(), config.TargetProject, token.Value())
                {
                    BaseAreaPath      = config.BaseAreaPath ?? string.Empty,      // Root area path that will prefix area path of each migrated item
                    BaseIterationPath = config.BaseIterationPath ?? string.Empty, // Root iteration path that will prefix each iteration
                    IgnoreFailedLinks = config.IgnoreFailedLinks,
                    ProcessTemplate   = config.ProcessTemplate
                };

                // initialize Azure DevOps/TFS connection. Creates/fetches project, fills area and iteration caches.
                var agent = Agent.Initialize(context, settings);

                if (agent == null)
                {
                    Logger.Log(LogLevel.Critical, "Azure DevOps/TFS initialization error.");
                    return;
                }

                var executionBuilder = new ExecutionPlanBuilder(context);
                var plan             = executionBuilder.BuildExecutionPlan();

                itemCount     = plan.ReferenceQueue.AsEnumerable().Select(x => x.OriginId).Distinct().Count();
                revisionCount = plan.ReferenceQueue.Count;

                BeginSession(configFileName, config, forceFresh, agent, itemCount, revisionCount);

                while (plan.TryPop(out ExecutionPlan.ExecutionItem executionItem))
                {
                    try
                    {
                        if (!forceFresh && context.Journal.IsItemMigrated(executionItem.OriginId, executionItem.Revision.Index))
                        {
                            continue;
                        }

                        WorkItem wi = null;

                        if (executionItem.WiId > 0)
                        {
                            wi = agent.GetWorkItem(executionItem.WiId);
                        }
                        else
                        {
                            wi = agent.CreateWI(executionItem.WiType);
                        }

                        Logger.Log(LogLevel.Info, $"Processing {importedItems + 1}/{revisionCount} - wi '{wi.Id}', jira '{executionItem.OriginId}, rev {executionItem.Revision.Index}'.");

                        agent.ImportRevision(executionItem.Revision, wi);
                        importedItems++;
                    }
                    catch (AbortMigrationException)
                    {
                        Logger.Log(LogLevel.Info, "Aborting migration...");
                        break;
                    }
                    catch (Exception ex)
                    {
                        try
                        {
                            Logger.Log(ex, $"Failed to import '{executionItem.ToString()}'.");
                        }
                        catch (AbortMigrationException)
                        {
                            break;
                        }
                    }
                }
            }
            catch (CommandParsingException e)
            {
                Logger.Log(LogLevel.Error, $"Invalid command line option(s): {e}");
            }
            catch (Exception e)
            {
                Logger.Log(e, $"Unexpected migration error.");
            }
            finally
            {
                EndSession(itemCount, revisionCount, sw);
            }
        }
Пример #2
0
        private static void BeginSession(string configFile, ConfigJson config, bool force, Agent agent, int itemsCount, int revisionCount)
        {
            var toolVersion = VersionInfo.GetVersionInfo();
            var osVersion   = System.Runtime.InteropServices.RuntimeInformation.OSDescription.Trim();
            var machine     = System.Environment.MachineName;
            var user        = $"{System.Environment.UserDomainName}\\{System.Environment.UserName}";
            var hostingType = GetHostingType(agent);

            Logger.Log(LogLevel.Info, $"Import started. Importing {itemsCount} items with {revisionCount} revisions.");

            Logger.StartSession("Azure DevOps Work Item Import",
                                "wi-import-started",
                                new Dictionary <string, string>()
            {
                { "Tool version         :", toolVersion },
                { "Start time           :", DateTime.Now.ToString() },
                { "Telemetry            :", Logger.TelemetryStatus },
                { "Session id           :", Logger.SessionId },
                { "Tool user            :"******"Config               :", configFile },
                { "User                 :"******"Force                :", force ? "yes" : "no" },
                { "Log level            :", config.LogLevel },
                { "Machine              :", machine },
                { "System               :", osVersion },
                { "Azure DevOps url     :", agent.Settings.Account },
                { "Azure DevOps version :", "n/a" },
                { "Azure DevOps type    :", hostingType }
            },
                                new Dictionary <string, string>()
            {
                { "item-count", itemsCount.ToString() },
                { "revision-count", revisionCount.ToString() },
                { "system-version", "n/a" },
                { "hosting-type", hostingType }
            });
        }