Click here to Skip to main content
15,895,746 members
Articles / Programming Languages / XML

Generate Automated Builds for Source Code from Multiple Branches using Team Foundation Server and Team Builds

Rate me:
Please Sign up or sign in to vote.
4.83/5 (29 votes)
14 Mar 2010CPOL3 min read 64.7K   537   50  
Generate automated builds for source code from multiple branches using Team Foundation Server and Team Builds
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
//using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.Build.Client;
using Microsoft.VisualStudio.TeamFoundation.VersionControl;
using Microsoft.TeamFoundation.VersionControl.Client;
using Microsoft.TeamFoundation.VersionControl.Common;
using Microsoft.TeamFoundation.Proxy;
using System.IO;
using System.Xml;
using System.Collections;

namespace Suresh.TeamFoundation.Addins
{
    public partial class SprintSetupForm : Form
    {
        private VersionControlExplorerExt SourceControlExplorer = null;
        private string SourceServerPath = string.Empty;
        
        private TeamFoundationServer tfsServer;
        private TeamProject sourceTeamProject;
        private static VersionControlServer vcs;
        private IBuildServer buildServer;
        private TeamProject targetTeamProject;
        private IBuildAgent defaultBuildAgent;
        private static string defaultBuildAgentDisplayName = "Default";

        public SprintSetupForm(VersionControlExplorerExt vce)
        {
            SourceControlExplorer = vce;
            InitializeComponent();
        }

        private void SprintSetupForm_Load(object sender, EventArgs e)
        {
            VersionControlExplorerItem vceItem = SourceControlExplorer.SelectedItems[0];
            SourceServerPath = vceItem.SourceServerPath;
            lblSrcFolder.Text = SourceServerPath;

            tfsServer = SourceControlExplorer.Workspace.VersionControlServer.TeamFoundationServer;
            sourceTeamProject = SourceControlExplorer.Workspace.VersionControlServer.GetTeamProjectForServerPath(SourceControlExplorer.SelectedItems[0].SourceServerPath);
            targetTeamProject = sourceTeamProject;
            vcs = tfsServer.GetService(typeof(VersionControlServer)) as VersionControlServer;
            buildServer = tfsServer.GetService(typeof(IBuildServer)) as IBuildServer;

            cmbBoxBuildAgents.DropDownStyle = ComboBoxStyle.DropDownList;
            cmbBoxTargetProject.DropDownStyle = ComboBoxStyle.DropDownList;

            LoadTeamProjects();
            LoadTreeView(sourceTeamProject);
            LoadBuildAgents(sourceTeamProject);
        }

        private void LoadBuildAgents(TeamProject teamProject)
        {
            cmbBoxBuildAgents.SelectedIndexChanged -= new EventHandler(cmbBoxBuildAgents_SelectedIndexChanged);
            try
            {
                //cmbBoxBuildAgents.Items.Clear();

                IBuildAgent[] allBuildAgents = buildServer.QueryBuildAgents(teamProject.Name);
                
                List<string> allBuildAgentsSource = new List<string>();
                foreach (IBuildAgent buildagent in allBuildAgents)
                    allBuildAgentsSource.Add(buildagent.Name);
                allBuildAgentsSource.Add(defaultBuildAgentDisplayName);
                
                cmbBoxBuildAgents.DataSource = allBuildAgentsSource;
                cmbBoxBuildAgents.SelectedItem = defaultBuildAgentDisplayName;
            }
            finally
            {
                cmbBoxBuildAgents.SelectedIndexChanged += new EventHandler(cmbBoxBuildAgents_SelectedIndexChanged);
            }
        }

        private void LoadTeamProjects()
        {
            cmbBoxTargetProject.SelectedIndexChanged -= new EventHandler(cmbBoxTargetProject_SelectedIndexChanged);
            try
            {
                TeamProject[] allTeamProjects = vcs.GetAllTeamProjects(false);

                cmbBoxTargetProject.DataSource = allTeamProjects;
                cmbBoxTargetProject.DisplayMember = "Name";

                cmbBoxTargetProject.SelectedItem = sourceTeamProject.Name;
            }
            finally
            {
                cmbBoxTargetProject.SelectedIndexChanged += new EventHandler(cmbBoxTargetProject_SelectedIndexChanged);
            }
        }

        private void LoadTreeView(TeamProject teamProject)
        {
            trViewSCExplorer.Nodes.Clear();
            TreeNode tNode = trViewSCExplorer.Nodes.Add(teamProject.ServerItem);
            string path = teamProject.ServerItem;
            AddTreeNode(tNode, path);
        }

        private static void AddTreeNode(TreeNode tNode, string path)
        {
            ItemSet itemSet = vcs.GetItems(path, RecursionType.OneLevel);
            foreach (Item item in itemSet.Items)
            {
                if (!item.Equals(itemSet.Items[0]) && item.ItemType == ItemType.Folder)
                {
                    string strServerItem = item.ServerItem;
                    tNode.Nodes.Add(strServerItem.Substring(strServerItem.LastIndexOf('/') + 1));
                }
            }
        }

        private void blnCancel_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void btnCreateSprint_Click(object sender, EventArgs e)
        {
            this.Cursor = Cursors.WaitCursor;
            try
            {
                DoSprintSetup();
            }
            catch (Exception ex)
            {
                MessageBox.Show("Expcetion occurred while processing for the new sprint setup - " + ex);
            }
            finally
            {
                this.Cursor = Cursors.Default;
            }
        }

        private void DoSprintSetup()
        {
            if (IsOkToDoSprintSetup())
            {
                string targetNodePath = trViewSCExplorer.SelectedNode.FullPath + "/" + txtSprintName.Text;
                targetNodePath = targetNodePath.Replace("\\", "/");
                NewSprintFolderName = GetSpecificFolderName(targetNodePath, targetTeamProject.ServerItem);
                ExistingSprintFolderName = GetSpecificFolderName(SourceServerPath, sourceTeamProject.ServerItem);

                bool isCreateBranchSuccessful = BranchSourceCode(targetNodePath);
                bool isNewBuildDefinitionsSuccessful = CreateNewBuildDefinitionsForNewSprint(targetNodePath);
                if (isCreateBranchSuccessful && isNewBuildDefinitionsSuccessful)
                {
                    MessageBox.Show("Branch created successfully and new build definitions have been added and configured for this new setup. This form will be closed now.");
                    this.Close();
                }
            }
        }

        private void DoSprintSpecificPrerequisites()
        {
            IBuildAgent[] allBuildAgents = buildServer.QueryBuildAgents(targetTeamProject.Name);

            IBuildDefinition[] allBuildDefinitions = buildServer.QueryBuildDefinitions(targetTeamProject.Name);
            string targetFolderNodePath = trViewSCExplorer.SelectedNode.FullPath + "/" + txtSprintName.Text;
            targetFolderNodePath = targetFolderNodePath.Replace("\\", "/");
            
            List<IBuildDefinition> buildDefinitionsSpecificToSprint = new List<IBuildDefinition>();
            foreach (IBuildDefinition buildDefinition in allBuildDefinitions)
            {
                string strConfigFolder = buildDefinition.ConfigurationFolderPath;
                if ((strConfigFolder + "/").StartsWith(targetFolderNodePath + "/", StringComparison.OrdinalIgnoreCase))
                {
                    buildDefinitionsSpecificToSprint.Add(buildDefinition);
                }
            }
            
            List<IBuildDefinition> buildDefinitionsToQueue = new List<IBuildDefinition>();
            IdentifyBuildDefinitionsToQueue(buildDefinitionsToQueue, buildDefinitionsSpecificToSprint);

            QueueSelectedBuildDefnsOnSelectedBuildAgents(buildDefinitionsToQueue, allBuildAgents);
        }

        private static void IdentifyBuildDefinitionsToQueue(List<IBuildDefinition> buildDefinitionsToQueue, List<IBuildDefinition> allSpecifiedBuildDefinitions)
        {
            foreach (IBuildDefinition buildDefinition in allSpecifiedBuildDefinitions)
            {
                if (IsBuildTasksDefinition(buildDefinition))
                {
                    buildDefinitionsToQueue.Add(buildDefinition);
                }
            }

            foreach (IBuildDefinition buildDefinition in allSpecifiedBuildDefinitions)
            {
                if (IsBuildTargetsDefinition(buildDefinition))
                {
                    buildDefinitionsToQueue.Add(buildDefinition);
                }
            }
        }

        private bool CreateNewBuildDefinitionsForNewSprint(string targetNodePath)
        {
            try
            {
                IBuildDefinition[] buildDefinitionsAll = buildServer.QueryBuildDefinitions(sourceTeamProject.Name);
                List<IBuildDefinition> buildDefinitionsToDuplicate = new List<IBuildDefinition>();
                foreach (IBuildDefinition buildDefinition in buildDefinitionsAll)
                {
                    string configFolderPath = buildDefinition.ConfigurationFolderPath;
                    if ((configFolderPath + "/").StartsWith(SourceServerPath + "/", StringComparison.OrdinalIgnoreCase))
                    {
                        buildDefinitionsToDuplicate.Add(buildDefinition);
                    }
                }

                DuplicateNewBuildDefinitions(targetNodePath, buildDefinitionsToDuplicate);

                DoSprintSpecificPrerequisites();
                return true;
            }
            catch (Exception ex)
            {
                MessageBox.Show("Exception occurred while adding new build definitions and configuring them for the new sprint. - " + ex);
                return false;
            }
        }

        private void QueueSelectedBuildDefnsOnSelectedBuildAgents(List<IBuildDefinition> lstBuildDefnsToQueue, IBuildAgent[] selectedBuildAgentsArr)
        {
            foreach (IBuildDefinition buildDefinition in lstBuildDefnsToQueue)
                QueueBuildDefinitionOnSpecifiedBuildAgents(buildDefinition, selectedBuildAgentsArr);
        }

        private void QueueBuildDefinitionOnSpecifiedBuildAgents(IBuildDefinition buildDefinition, IBuildAgent[] selectedBuildAgents)
        {
            IBuildRequest buildRequest = buildDefinition.CreateBuildRequest();
            buildRequest.CommandLineArguments = "/p:prmQueueSelfOnAllOtherBuildAgents=false";
            foreach (IBuildAgent buildAgent in selectedBuildAgents)
            {
                if (buildAgent.Status == AgentStatus.Enabled)
                {
                    buildRequest.BuildAgent = buildAgent;
                    buildServer.QueueBuild(buildRequest);
                    buildAgent.Refresh();
                }
            }
        }

        private static bool IsBuildTargetsDefinition(IBuildDefinition buildDefinition)
        {
            return buildDefinition.Name.Contains(".BuildTargets.");
        }

        private static bool IsBuildTasksDefinition(IBuildDefinition buildDefinition)
        {
            return buildDefinition.Name.Contains(".BuildTasks.");
        }

        private static string ExistingSprintFolderName = string.Empty;
        private static string NewSprintFolderName = string.Empty;
        private void DuplicateNewBuildDefinitions(string targetNodePath, List<IBuildDefinition> buildDefinitionsExisting)
        {
            foreach (IBuildDefinition buildDefnExisting in buildDefinitionsExisting)
            {
                IBuildDefinition buildDefinitionNew = buildServer.CreateBuildDefinition(targetTeamProject.Name);

                UpdateBuildDefinitionNameAndDescription(buildDefinitionNew, buildDefnExisting);

                // correct the config folder path
                string selectedSourceNodePath = SourceServerPath;
                string existingConfigPath = buildDefnExisting.ConfigurationFolderPath;
                string newConfigPath = existingConfigPath.Replace(selectedSourceNodePath, targetNodePath);
                buildDefinitionNew.ConfigurationFolderPath = newConfigPath;

                // update the Build Agent
                if (defaultBuildAgent == null)
                    buildDefinitionNew.DefaultBuildAgent = buildDefnExisting.DefaultBuildAgent;
                else
                    buildDefinitionNew.DefaultBuildAgent = defaultBuildAgent;

                UpdateContinuousIntegrationDetailsOfBuildDefinition(buildDefinitionNew, buildDefnExisting);
                UpdateScheduleOfBuildDefinition(buildDefinitionNew, buildDefnExisting);
                UpdateRetentionPoliciesOfBuildDefinition(buildDefinitionNew, buildDefnExisting);

                // correct the drop location
                buildDefinitionNew.DefaultDropLocation = GetNewDefaultDropLocation(buildDefnExisting.DefaultDropLocation);

                // correct the workspace mappings
                DuplicateWorkspaceTemplate(buildDefnExisting, buildDefinitionNew, targetNodePath);

                buildDefinitionNew.Save();
            }
        }

        private static void UpdateBuildDefinitionNameAndDescription(IBuildDefinition buildDefnNew, IBuildDefinition buildDefnExisting)
        {
            // correct the build definition name

            buildDefnNew.Name = GetNewBuildDefinitionName(buildDefnExisting.Name);

            // Update description and status
            buildDefnNew.Description = buildDefnExisting.Description;
            buildDefnNew.Enabled = buildDefnExisting.Enabled;
        }

        private static string GetNewBuildDefinitionName(string existingBuildDefintionName)
        {
            if (existingBuildDefintionName.StartsWith(ExistingSprintFolderName, StringComparison.OrdinalIgnoreCase))
                existingBuildDefintionName = existingBuildDefintionName.Substring(ExistingSprintFolderName.Length + 1);
            return NewSprintFolderName + "." + existingBuildDefintionName;
        }

        public static string GetSpecificFolderName(string sourceControlPath, string teamProjectServerItem)
        {
            string finalFolderName = string.Empty;
            string sourceControlPathWithoutTeamProjectName = sourceControlPath.Replace(teamProjectServerItem, "");
            string[] diffFolderNames = sourceControlPathWithoutTeamProjectName.Split(new string[]{"/"}, StringSplitOptions.RemoveEmptyEntries);
            foreach (string folderName in diffFolderNames)
                finalFolderName = finalFolderName + "." + folderName;

            if (finalFolderName.StartsWith(".", StringComparison.OrdinalIgnoreCase))
                finalFolderName = finalFolderName.Substring(1);

            return finalFolderName;
        }

        private static void UpdateContinuousIntegrationDetailsOfBuildDefinition(IBuildDefinition buildDefnNew, IBuildDefinition buildDefnExisting)
        {
            buildDefnNew.ContinuousIntegrationType = buildDefnExisting.ContinuousIntegrationType;
            buildDefnNew.ContinuousIntegrationQuietPeriod = buildDefnExisting.ContinuousIntegrationQuietPeriod;
        }

        private static void UpdateScheduleOfBuildDefinition(IBuildDefinition buildDefnNew, IBuildDefinition buildDefnExisting)
        {
            buildDefnNew.Schedules.Clear();
            foreach (ISchedule schedule in buildDefnExisting.Schedules)
                buildDefnNew.Schedules.Add(schedule);
        }

        private static void UpdateRetentionPoliciesOfBuildDefinition(IBuildDefinition buildDefnNew, IBuildDefinition buildDefnExisting)
        {
            buildDefnNew.RetentionPolicies.Clear();
            foreach (string keyName in Enum.GetNames(typeof(BuildStatus)))
            {
                BuildStatus keyBuildStatus = (BuildStatus)Enum.Parse(typeof(BuildStatus), keyName);
                if (buildDefnExisting.RetentionPolicies.ContainsKey(keyBuildStatus))
                {
                    IRetentionPolicy valueRetentionPolicy;
                    bool isValueExists = buildDefnExisting.RetentionPolicies.TryGetValue(keyBuildStatus, out valueRetentionPolicy);
                    if (isValueExists)
                        buildDefnNew.RetentionPolicies.Add(keyBuildStatus, valueRetentionPolicy);
                }
            }
        }

        private string GetNewDefaultDropLocation(string buildDefinitionExistingDropLocation)
        {
            string defaultDropFolderPathExisting = ExistingSprintFolderName;
            string rootFolderName = NewSprintFolderName;
            string dropFolderNew = buildDefinitionExistingDropLocation.Replace("\\" + defaultDropFolderPathExisting + "\\", "\\" + rootFolderName + "\\");
            dropFolderNew = dropFolderNew.Replace("\\" + sourceTeamProject.Name + "\\", "\\" + targetTeamProject.Name + "\\");
            if (!Directory.Exists(dropFolderNew))
                Directory.CreateDirectory(dropFolderNew);
            return dropFolderNew;
        }

        private void DuplicateWorkspaceTemplate(IBuildDefinition buildDefinitionExisting, IBuildDefinition buildDefinitionNew, string targetNodePath)
        {
            foreach (IWorkspaceMapping workspaceMappingExisting in buildDefinitionExisting.Workspace.Mappings)
            {
                if ((workspaceMappingExisting.ServerItem + "/").StartsWith(SourceServerPath + "/", StringComparison.OrdinalIgnoreCase))
                {
                    string workspaceServerItemNew = workspaceMappingExisting.ServerItem.Replace(SourceServerPath, targetNodePath);

                    string workspaceLocalItemNew = String.Empty;
                    string workspaceLocalItemExisting = workspaceMappingExisting.LocalItem;
                    if (!String.IsNullOrEmpty(workspaceLocalItemExisting))
                    {
                        string strToMatch = sourceTeamProject.Name + "\\";
                        int lastIndex = workspaceLocalItemExisting.LastIndexOf(strToMatch, StringComparison.OrdinalIgnoreCase);
                        if (lastIndex > 0 && lastIndex + strToMatch.Length > 0)
                        {
                            workspaceLocalItemExisting = workspaceLocalItemExisting.Substring(lastIndex + strToMatch.Length);
                            workspaceLocalItemExisting = "$(SourceDir)\\" + workspaceLocalItemExisting;
                        }
                        string sourceLocalItemExisting = SourceServerPath.Replace(sourceTeamProject.ServerItem, "$(SourceDir)");
                        sourceLocalItemExisting = sourceLocalItemExisting.Replace("/", "\\");
                        string targetLocalItem = targetNodePath.Replace(targetTeamProject.ServerItem, "$(SourceDir)");
                        workspaceLocalItemNew = workspaceLocalItemExisting.Replace(sourceLocalItemExisting, targetLocalItem);
                    }
                    buildDefinitionNew.Workspace.AddMapping(workspaceServerItemNew, workspaceLocalItemNew, workspaceMappingExisting.MappingType, workspaceMappingExisting.Depth);
                }
                else
                {
                    buildDefinitionNew.Workspace.AddMapping(workspaceMappingExisting.ServerItem, workspaceMappingExisting.LocalItem, workspaceMappingExisting.MappingType, workspaceMappingExisting.Depth);
                }
            }
        }

        private bool IsOkToDoSprintSetup()
        {
            bool isOkToProceedWithSprintSetup = false;
            if (String.IsNullOrEmpty(txtSprintName.Text))
            {
                MessageBox.Show("Please enter sprint name");
                txtSprintName.Focus();
                return isOkToProceedWithSprintSetup;
            }

            if (trViewSCExplorer.SelectedNode == null)
            {
                MessageBox.Show("Please select target folder.");
                return isOkToProceedWithSprintSetup;
            }

            string targetNodePath = Path.Combine(trViewSCExplorer.SelectedNode.FullPath, txtSprintName.Text);
            if (vcs.ServerItemExists(targetNodePath, ItemType.Folder))
            {
                MessageBox.Show("Please change the sprint name or the target folder. This folder already exist.");
                return isOkToProceedWithSprintSetup;
            }

            return true;
        }

        private bool BranchSourceCode(string targetNodePath)
        {
            bool isFolderAlreadyMapped = EnsureTeamProjectIsMapped(SourceControlExplorer.Workspace, targetNodePath, targetTeamProject.ServerItem);

            VersionSpec vspec = new DateVersionSpec(DateTime.Now);
            vcs.CreateBranch(SourceServerPath, targetNodePath, vspec);
            
            MakeSprintSpecificChanges(targetNodePath);

            if (!isFolderAlreadyMapped)
                DeleteTemporaryWorkspace(SourceControlExplorer.Workspace, targetTeamProject.ServerItem);

            return true;
        }

        private static string localFolderToMap = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "Project_360");
        public static bool EnsureTeamProjectIsMapped(Workspace workspace, string nodePath, string teamProjectServerItem)
        {
            bool isFolderAlreadyMapped = true;
            if (!workspace.IsServerPathMapped(nodePath))
            {
                try
                {
                    isFolderAlreadyMapped = false;
                    if (!Directory.Exists(localFolderToMap))
                        Directory.CreateDirectory(localFolderToMap);
                    workspace.Map(teamProjectServerItem, localFolderToMap);
                }
                catch (MissingMethodException) { }
            }

            return isFolderAlreadyMapped;
        }

        public static void DeleteTemporaryWorkspace(Workspace workspace, string teamProjectServerItem)
        {
            if (workspace.IsServerPathMapped(teamProjectServerItem))
            {
                string localFolderMappedWithTeamProject = workspace.GetLocalItemForServerItem(teamProjectServerItem);
                try
                {
                    workspace.DeleteMapping(new WorkingFolder(teamProjectServerItem, localFolderMappedWithTeamProject));
                }
                catch (MissingMethodException) { }

                if (Directory.Exists(localFolderMappedWithTeamProject))
                {
                    string[] allFilePaths = Directory.GetFiles(localFolderMappedWithTeamProject, "*.*", SearchOption.AllDirectories);
                    foreach (string filePath in allFilePaths)
                        (new FileInfo(filePath)).Attributes = FileAttributes.Normal;
                    Directory.Delete(localFolderMappedWithTeamProject, true);
                }
            }
        }

        private void trViewSCExplorer_AfterExpand(object sender, TreeViewEventArgs e)
        {
            ExpandChildNodes(e.Node);
        }

        private static void ExpandChildNodes(TreeNode parentNode)
        {
            foreach (TreeNode node in parentNode.Nodes)
                AddTreeNode(node, node.FullPath);
        }

        private void trViewSCExplorer_BeforeExpand(object sender, TreeViewCancelEventArgs e)
        {
        }

        private void trViewSCExplorer_BeforeCollapse(object sender, TreeViewCancelEventArgs e)
        {
            CollapseTreeviewChildNodes(e.Node);
        }

        private static void CollapseTreeviewChildNodes(TreeNode parentNode)
        {
            foreach (TreeNode node in parentNode.Nodes)
            {
                node.Collapse();
                node.Nodes.Clear();
            }
        }

        public static List<string> DownloadTeambuildfilesOnLocalMachine(Workspace workspace, string targetFolderPath)
        {
            string localTargetFolderPath = workspace.GetLocalItemForServerItem(targetFolderPath);
            string teambuildTypesPath = Path.Combine(localTargetFolderPath, "TeamBuildTypes");
            try
            {
                workspace.Get(new string[] { teambuildTypesPath }, VersionSpec.Latest, RecursionType.Full, GetOptions.GetAll | GetOptions.Overwrite);
            }
            catch (MissingMethodException) { }

            string[] teambuildTargetFilePaths = Directory.GetFiles(teambuildTypesPath, "*.targets", SearchOption.AllDirectories);
            string[] teambuildProjFilePaths = Directory.GetFiles(teambuildTypesPath, "*.proj", SearchOption.AllDirectories);

            List<string> teambuildFilePaths = new List<string>();
            teambuildFilePaths.AddRange(teambuildTargetFilePaths);
            teambuildFilePaths.AddRange(teambuildProjFilePaths);

            return teambuildFilePaths;
        }

        public static XmlDocument LoadRawXmlDocument(string strFilePath)
        {
            XmlDocument rawXmlDocument = new XmlDocument();
            rawXmlDocument.Load(strFilePath);

            return rawXmlDocument;
        }

        private void UpdateTeambuildFiles(Workspace workspace, List<string> teambuildFiles, string targetFolderPath)
        {
            foreach (string teambuildFilePath in teambuildFiles)
            {
                XmlDocument rawXmlDocument = LoadRawXmlDocument(teambuildFilePath);
                XmlNamespaceManager nsmngr = new XmlNamespaceManager(rawXmlDocument.NameTable);
                nsmngr.AddNamespace("pr", "http://schemas.microsoft.com/developer/msbuild/2003");

                bool isRequiredToSaveDocument = false;

                XmlNodeList xmlBranchFolderNodeList = rawXmlDocument.SelectNodes("pr:Project/pr:PropertyGroup/pr:BranchFolder", nsmngr);
                string newBranchFolderPath = targetFolderPath.Replace(targetTeamProject.ServerItem + "/", "");
                newBranchFolderPath = newBranchFolderPath.Replace(@"/", @"\");
                foreach (XmlNode xmlBranchFolderNode in xmlBranchFolderNodeList)
                {
                    xmlBranchFolderNode.InnerText = newBranchFolderPath;
                    isRequiredToSaveDocument = true;
                }

                XmlNodeList xmlBranchRootNodeList = rawXmlDocument.SelectNodes("pr:Project/pr:PropertyGroup/pr:BranchRoot", nsmngr);
                foreach (XmlNode xmlBranchRootNode in xmlBranchRootNodeList)
                {
                    xmlBranchRootNode.InnerText = targetFolderPath;
                    isRequiredToSaveDocument = true;
                }

                if (IsUpdateSetupRequired())
                {
                    XmlNode executeUpdateSetupTaskNode = rawXmlDocument.SelectSingleNode("pr:Project/pr:PropertyGroup/pr:ExecuteUpdateSetupTask", nsmngr);
                    if (executeUpdateSetupTaskNode != null)
                        executeUpdateSetupTaskNode.InnerText = "true";
                }

                XmlNodeList xmlNodeListGeneral = rawXmlDocument.SelectNodes("pr:Project/pr:PropertyGroup", nsmngr);
                foreach (XmlNode xmlNodeGeneral in xmlNodeListGeneral)
                {
                    foreach (XmlNode xNode in xmlNodeGeneral.ChildNodes)
                    {
                        if (IsNodeContainsBuildDefinitionToQueue(xNode.Name))
                        {
                            xNode.InnerText = GetNewBuildDefinitionName(xNode.InnerText);
                            isRequiredToSaveDocument = true;
                        }
                    }
                }

                if (isRequiredToSaveDocument)
                {
                    CheckoutAndSaveXmlDocument(workspace, teambuildFilePath, rawXmlDocument);
                }
            }
        }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        private bool IsUpdateSetupRequired()
        {
            return true; ;
        }

        private void MakeSprintSpecificChanges(string targetFolderPath)
        {
            Workspace workspace = SourceControlExplorer.Workspace;
            targetFolderPath = targetFolderPath.Replace("\\", "/");
            List<string> teambuildFiles = DownloadTeambuildfilesOnLocalMachine(workspace, targetFolderPath);

            UpdateTeambuildFiles(workspace, teambuildFiles, targetFolderPath);

            CheckinTeambuildfilesFromLocalMachine(workspace, targetFolderPath);
        }

        private static bool IsNodeContainsBuildDefinitionToQueue(string nodeName)
        {
            return nodeName.EndsWith("BuildToQueue", StringComparison.OrdinalIgnoreCase);
        }

        private static void CheckoutAndSaveXmlDocument(Workspace workspace, string filePath, XmlDocument rawXmlDocument)
        {
            try
            {
                workspace.PendEdit(filePath);
            }
            catch (MissingMethodException) { }
            rawXmlDocument.Save(filePath);
        }

        private static void CheckinTeambuildfilesFromLocalMachine(Workspace workspace, string targetFolderPath)
        {
            PendingChange[] pendingChanges = workspace.GetPendingChanges(targetFolderPath, RecursionType.Full);
            if (pendingChanges.Length > 0)
            {
                PolicyOverrideInfo policyOverrideInfo = new PolicyOverrideInfo("Modified by Teambuild Addins to support sprint branching.", null);
                try
                {
                    workspace.CheckIn(pendingChanges, "Modified by Teambuild Addins to support sprint branching.", null, null, policyOverrideInfo);
                }
                catch (MissingMethodException) { }
            }
        }

        private void txtSprintName_TextChanged(object sender, EventArgs e)
        {
        }

        private void trViewSCExplorer_AfterSelect(object sender, TreeViewEventArgs e)
        {
            UpdateTargetFolderLabel(e.Node);
        }

        private void UpdateTargetFolderLabel(TreeNode node)
        {
            lblTargetFolder.Text = node.FullPath;
        }

        private void cmbBoxTargetProject_SelectedIndexChanged(object sender, EventArgs e)
        {
            UpdateTreeView();
        }

        private void UpdateTreeView()
        {
            if (cmbBoxTargetProject.SelectedValue as TeamProject != null)
                targetTeamProject = cmbBoxTargetProject.SelectedValue as TeamProject;

            LoadTreeView(targetTeamProject);
            LoadBuildAgents(targetTeamProject);
        }

        private void cmbBoxBuildAgents_SelectedIndexChanged(object sender, EventArgs e)
        {
            UpdateDefaultBuildAgent();
        }

        private void UpdateDefaultBuildAgent()
        {
            if (!cmbBoxBuildAgents.SelectedItem.ToString().Equals(defaultBuildAgentDisplayName, StringComparison.OrdinalIgnoreCase))
            {
                string buildAgentName = cmbBoxBuildAgents.SelectedItem as string;

                IBuildAgentSpec buildAgentSpec = buildServer.CreateBuildAgentSpec(targetTeamProject.Name, buildAgentName);
                IBuildAgentQueryResult buildAgentQueryResults = buildServer.QueryBuildAgents(buildAgentSpec);
                if (buildAgentQueryResults != null && buildAgentQueryResults.Agents != null)
                    defaultBuildAgent = buildAgentQueryResults.Agents[0];
            }
            else
                defaultBuildAgent = null;
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Web Developer PROTEANS SOFTWARE SOLUTIONS LTD.(www.proteans.com)
India India
I am currently working in an outsourced software product development company, PROTEANS SOFTWARE SOLUTIONS LTD.(www.proteans.com) as a Module Lead.

Comments and Discussions