コード例 #1
0
        /// <summary>
        /// gets changesets for all work items of the specified state
        /// </summary>
        /// <param name="project"></param>
        /// <param name="state"></param>
        /// <param name="environment"></param>
        /// <returns></returns>
        public IEnumerable <Changeset> GetChangesetsByWorkItemState(Project project, string state, MergeEnvironment environment)
        {
            var tfs       = TfsTeamDataAccess.GetTfsTeamProjectCollection();
            var workItems = TfsTrackingDataAccess.GetTfsWorkItemsByState(tfs, project, state);

            return(workItems.SelectMany(w => GetTfsChangesetsBySource(tfs, w, environment)).ToList());
        }
コード例 #2
0
        internal static TfsWorkItem GetTfsWorkItem(int workItemId)
        {
            var tfs   = TfsTeamDataAccess.GetTfsTeamProjectCollection();
            var store = tfs.GetService <WorkItemStore>();

            return(store.GetWorkItem(workItemId));
        }
コード例 #3
0
        /// <summary>
        /// gets changesets for the specified merge environment
        /// </summary>
        /// <param name="workItem"></param>
        /// <param name="environment"></param>
        /// <returns></returns>
        public IEnumerable <Changeset> GetChangesets(IWorkItem workItem, MergeEnvironment environment)
        {
            var tfs         = TfsTeamDataAccess.GetTfsTeamProjectCollection();
            var tfsWorkItem = TfsTrackingDataAccess.GetTfsWorkItem(workItem.Id);

            return(GetTfsChangesetsBySource(tfs, tfsWorkItem, environment).ToList());
        }
コード例 #4
0
        /// <summary>
        /// commits changes for the local workspace and associates specified work items and comment
        /// </summary>
        /// <param name="workspace"></param>
        /// <param name="changes"></param>
        /// <param name="comment"></param>
        /// <param name="associatedWorkItems"></param>
        /// <returns></returns>
        private static Changeset Commit(Workspace workspace, PendingChange[] changes, string comment, IEnumerable <WorkItem> associatedWorkItems)
        {
            if (changes == null || !changes.Any())
            {
                return(null);
            }
            var tfs            = TfsTeamDataAccess.GetTfsTeamProjectCollection();
            var versionControl = tfs.GetService <VersionControlServer>();

            var associateTfsWorkItems = associatedWorkItems.Select(w => TfsTrackingDataAccess.GetTfsWorkItem(w.Id))
                                        .GroupBy(g => g.Id)
                                        .Select(w => new WorkItemCheckinInfo(w.First(), WorkItemCheckinAction.Associate)).ToArray();

            comment = string.Format("{0}: {1} {2}", string.Join(",", associateTfsWorkItems.OrderBy(o => o.WorkItem.Id).Select(a => a.WorkItem.Id.ToString(CultureInfo.InvariantCulture))), comment, ConfigurationManager.AppSettings["AutomationMessage"]);
            var changesetId = 0;

            try
            {
                changesetId = workspace.CheckIn(changes, comment, null, associateTfsWorkItems, null);
            }
            catch (GatedCheckinException gatedException)
            {
                // Gated check-in is required. Get the list of build definitions affected by the check-in
                var buildDefs = gatedException.AffectedBuildDefinitions;

                // Take first build def. I don't really have any better way to determine it.
                var buildEnum = buildDefs.GetEnumerator();
                buildEnum.MoveNext();
                var buildDef          = buildEnum.Current;
                var gatedBuildDefUri  = buildDef.Value;
                var shelvesetSpecName = gatedException.ShelvesetName;
                var shelvesetTokens   = shelvesetSpecName.Split(new[] { ';' });

                // Create a build request for the gated check-in build
                var buildServer  = tfs.GetService <IBuildServer>();
                var buildRequest = buildServer.CreateBuildRequest(gatedBuildDefUri);
                buildRequest.ShelvesetName      = shelvesetTokens[0];            // Specify the name of the existing shelveset
                buildRequest.Reason             = BuildReason.CheckInShelveset;  // Check-in the shelveset if successful
                buildRequest.GatedCheckInTicket = gatedException.CheckInTicket;  // Associate the check-in

                var build = TfsBuildDataAccess.QueueTfsBuild(buildRequest, null, true);
                if (build.Build != null)
                {
                    var firstOrDefault = build.Build.Changesets.FirstOrDefault();                     // shouldn't be null for gated check in, for pete's sake.
                    if (firstOrDefault != null)
                    {
                        changesetId = firstOrDefault.Id;
                    }
                    if (build.Build.Status == BuildStatus.Succeeded)
                    {
                        workspace.Undo(changes);
                    }
                }
            }

            var newTfsChangeset = versionControl.GetChangeset(changesetId);

            return(newTfsChangeset == null ? null : MapChangeset(newTfsChangeset));
        }
コード例 #5
0
ファイル: TfsBuildDataAccess.cs プロジェクト: Kidsisker/Push
        public IQueuedBuild QueueBuild(IBuildRequest buildRequest)
        {
            var tfs             = TfsTeamDataAccess.GetTfsTeamProjectCollection();
            var buildServer     = tfs.GetService <IBuildServer>();
            var tfsBuildRequest = buildServer.CreateBuildRequest(buildRequest.BuildDefinitionUri);

            return(QueueTfsBuild(tfsBuildRequest, buildRequest.Quality, buildRequest.Wait));
        }
コード例 #6
0
        /// <summary>
        /// commits pending changes for the local workspace and associates specified work items and comment
        /// </summary>
        /// <param name="comment"></param>
        /// <param name="associatedWorkItems"></param>
        /// <returns></returns>
        public Changeset CommitPending(string comment, IEnumerable <WorkItem> associatedWorkItems)
        {
            var tfs            = TfsTeamDataAccess.GetTfsTeamProjectCollection();
            var versionControl = tfs.GetService <VersionControlServer>();
            var workspace      = versionControl.GetWorkspace(Workstation.Current.Name, tfs.AuthorizedIdentity.UniqueName);

            return(Commit(workspace, workspace.GetPendingChanges(), comment, associatedWorkItems));
        }
コード例 #7
0
        public MergeTask CreateMergeTask(IWorkItem parent, string taskTitle)
        {
            var tfs               = TfsTeamDataAccess.GetTfsTeamProjectCollection();
            var store             = tfs.GetService <WorkItemStore>();
            var project           = store.Projects[parent.Type.Project.Name];
            var taskType          = project.WorkItemTypes["Task"];
            var hierarchyLinkType = store.WorkItemLinkTypes[CoreLinkTypeReferenceNames.Hierarchy];

            var tfsParent = GetTfsWorkItem(parent.Id);

            if (tfsParent == null)
            {
                return(null);
            }

            var existing = (from WorkItemLink l in tfsParent.WorkItemLinks select l).ToList()
                           .Find(p => p.LinkTypeEnd.Name == "Child" && GetTfsWorkItem(p.TargetId).Title == taskTitle);

            if (existing != null)
            {
                var tfsExistingWorkItem = GetTfsWorkItem(existing.TargetId);
                return(new MergeTask(MapWorkItem(tfsExistingWorkItem))
                {
                    Parent = MapWorkItem(tfsParent)
                });
            }
            var task = new TfsWorkItem(taskType)
            {
                Title = taskTitle
            };

            task.Fields["Assigned To"].Value = "Jill LaMay";             // todo: get identity
            task.Links.Add(new WorkItemLink(hierarchyLinkType.ReverseEnd, parent.Id));

            // Check for data script and tag.
            var changesets = TfsSourceDataAccess.GetTfsChangesetsByPathName(tfs, tfsParent, "Data Scripts").ToList();             // todo: not hard code. obvs.

            if (changesets.Any())
            {
                changesets.SelectMany(s => s.Changes).GroupBy(g => g.Item.ServerItem).ToList().ForEach(f =>
                {
                    var descr  = string.Format("{0} Data Script: {1};", task.Fields["Description"].Value, f.First().Item.ServerItem);
                    task.Title = descr;                             // temp
                });
                //task.Fields["Tags"].Value = "data-script"; // todo: Not in 2012 :(
            }
            // todo: turn off save while testing
            //task.Save();

            //task.State = "Active";
            //task.Save();

            return(new MergeTask(MapWorkItem(task))
            {
                Parent = parent
            });
        }
コード例 #8
0
ファイル: TfsBuildDataAccess.cs プロジェクト: Kidsisker/Push
        public IQueuedBuild QueueBuild(string project, string buildDefinition, string quality, bool wait)
        {
            var tfs          = TfsTeamDataAccess.GetTfsTeamProjectCollection();
            var buildServer  = tfs.GetService <IBuildServer>();
            var buildDef     = buildServer.GetBuildDefinition(project, buildDefinition);
            var buildRequest = buildServer.CreateBuildRequest(buildDef.Uri);

            return(QueueTfsBuild(buildRequest, quality, wait));
        }
コード例 #9
0
ファイル: TfsBuildDataAccess.cs プロジェクト: Kidsisker/Push
        public IEnumerable <IQueuedBuild> QueryQueuedBuilds()
        {
            var tfs          = TfsTeamDataAccess.GetTfsTeamProjectCollection();
            var buildServer  = tfs.GetService <IBuildServer>();
            var spec         = buildServer.CreateBuildQueueSpec("*", "*");
            var buildResults = buildServer.QueryQueuedBuilds(spec);

            return(buildResults.QueuedBuilds.Select(MapQueuedBuild).ToList());
        }
コード例 #10
0
ファイル: TfsBuildDataAccess.cs プロジェクト: Kidsisker/Push
        public IEnumerable <IBuildDetail> QueryBuilds()
        {
            var tfs         = TfsTeamDataAccess.GetTfsTeamProjectCollection();
            var buildServer = tfs.GetService <IBuildServer>();
            var spec        = buildServer.CreateBuildDetailSpec("*", "*");

            spec.MinFinishTime = DateTime.Today.AddDays(-7);
            spec.MaxFinishTime = DateTime.Today.AddDays(1);
            spec.RequestedFor  = tfs.AuthorizedIdentity.UniqueName;
            var buildResults = buildServer.QueryBuilds(spec);

            return(buildResults.Builds.Select(MapBuild).ToList());
        }
コード例 #11
0
        /// <summary>
        /// commits pending changes for a changeset that have been merged to the specified target and associates specified work items and comment
        /// </summary>
        /// <param name="changeset"></param>
        /// <param name="environment"></param>
        /// <param name="comment"></param>
        /// <returns></returns>
        public Changeset CommitChangeset(Changeset changeset, MergeEnvironment environment, string comment)
        {
            var tfs            = TfsTeamDataAccess.GetTfsTeamProjectCollection();
            var versionControl = tfs.GetService <VersionControlServer>();
            var workspace      = versionControl.GetWorkspace(Workstation.Current.Name, tfs.AuthorizedIdentity.UniqueName);
            var tfsChangeset   = versionControl.GetChangeset(changeset.Id);
            var changes        = (from change in tfsChangeset.Changes select change).ToList();
            var relationship   = GetMergeRelationship(changeset, environment);
            var pending        = workspace.GetPendingChanges(changes
                                                             .Select(m => new ItemSpec(m.Item.ServerItem.ToLower()
                                                                                       .Replace(string.Format("/{0}/", changeset.Branch.Name.ToLower()), string.Format("/{0}/", relationship.Target.Name)), RecursionType.None)).ToArray(), false, int.MaxValue, null, true).ToList();
            var pendingChangesetChanges = pending.ToArray();

            //.Where(p => p.IsMerge && p.MergeSources.Any(source => changes.Any(change => string.Compare(change.Item.ServerItem, source.ServerItem, StringComparison.OrdinalIgnoreCase) == 0))).ToArray();

            return(Commit(workspace, pendingChangesetChanges, comment, changeset.WorkItems));
        }
コード例 #12
0
ファイル: TfsBuildDataAccess.cs プロジェクト: Kidsisker/Push
        internal static IQueuedBuild QueueTfsBuild(Microsoft.TeamFoundation.Build.Client.IBuildRequest buildRequest, string quality, bool wait)
        {
            var tfs = TfsTeamDataAccess.GetTfsTeamProjectCollection();
            // Create a build request for the gated check-in build
            var buildServer = tfs.GetService <IBuildServer>();

            //Queue the build request
            var queuedBuild = buildServer.QueueBuild(buildRequest);

            if (wait)
            {
                // Wait for the build to complete.
                while (!queuedBuild.Build.BuildFinished)
                {
                    // Get the latest status of the build, and pause to yield CPU
                    queuedBuild.Refresh(QueryOptions.Process);
                    System.Threading.Thread.Sleep(1000);
                }
            }
            if (queuedBuild.Build == null)
            {
                return(MapQueuedBuild(queuedBuild));
            }

            if (queuedBuild.Build.Status == Microsoft.TeamFoundation.Build.Client.BuildStatus.Succeeded)
            {
                queuedBuild.Build.RefreshAllDetails();

                if (!string.IsNullOrEmpty(quality))
                {
                    queuedBuild.Build.Quality = quality;                     //todo: implement Release data access
                    queuedBuild.Build.Save();
                }
            }
            var changesetSummaries = InformationNodeConverters.GetAssociatedChangesets(queuedBuild.Build);
            var build = MapQueuedBuild(queuedBuild);

            build.Build.Changesets = changesetSummaries.Select(c => new Changeset
            {
                Id = c.ChangesetId
            });

            return(build);
        }
コード例 #13
0
        /// <summary>
        /// get merge candidates for a project and environment
        /// </summary>
        /// <param name="project"></param>
        /// <param name="environment"></param>
        /// <returns></returns>
        public IEnumerable <Changeset> GetMergeCandidates(Project project, MergeEnvironment environment)
        {
            var tfs            = TfsTeamDataAccess.GetTfsTeamProjectCollection();
            var projects       = TfsTeamDataAccess.GetTfsProjects().ToList();
            var versionControl = tfs.GetService <VersionControlServer>();

            var mergeCandidates = new List <Changeset>();

            projects.ForEach(tfsProject => environment.Relationships.ToList().ForEach(relationship =>
            {
                var projectName = !tfsProject.ServerItem.EndsWith("/") ? tfsProject.ServerItem + "/" : tfsProject.Name;
                var sourcePath  = string.Format("{0}{1}/", projectName, relationship.Source.Name);
                var targetPath  = string.Format("{0}{1}/", projectName, relationship.Target.Name);
                try
                {
                    var candidates = versionControl.GetMergeCandidates(sourcePath, targetPath, RecursionType.Full).ToList();
                    candidates.ForEach(candidate =>
                    {
                        var workItems =
                            candidate.Changeset.WorkItems.Where(
                                workItem =>
                                workItem.State != "Active" &&
                                workItem.State != "In Review" &&
                                workItem.Type != workItem.Project.WorkItemTypes["Task"] &&                                                         // ignore changesets associated with task. Will create another audit that checks for changesets ONLY associated to task.
                                string.Compare(project.Name, workItem.Project.Name, StringComparison.OrdinalIgnoreCase) == 0);
                        if (workItems.Any())
                        {
                            mergeCandidates.Add(MapChangeset(candidate.Changeset, relationship.Source));
                        }
                    });
                }
                catch (Exception e)
                {
                }
            }));

            return(mergeCandidates);
        }
コード例 #14
0
        public IEnumerable <MergeTask> GetWorkItemsWithMigrationScripts(Project project, string state)
        {
            var tfs = TfsTeamDataAccess.GetTfsTeamProjectCollection();

            var tasks     = new List <MergeTask>();
            var workItems = GetWorkItemsByState(project, state);

            workItems.ToList().ForEach(workItem =>
            {
                var tfsWorkItem = GetTfsWorkItem(workItem.Id);
                // Check for data script and tag.
                var changesets = TfsSourceDataAccess.GetTfsChangesetsByPathName(tfs, tfsWorkItem, "Data Scripts").ToList();                         // todo: not hard code. obvs.
                if (changesets.Any())
                {
                    tasks.AddRange(changesets.SelectMany(s => s.Changes).GroupBy(g => g.Item.ServerItem).Select(change => new MergeTask
                    {
                        Title  = string.Format("Execute Data Script: {0};", change.First().Item.ServerItem),
                        Parent = workItem
                    }));
                }
            });
            return(tasks);
        }
コード例 #15
0
        public IEnumerable <WorkItem> GetWorkItemsByState(Project project, string state)
        {
            var tfs = TfsTeamDataAccess.GetTfsTeamProjectCollection();

            return(GetTfsWorkItemsByState(tfs, project, state).Select(MapWorkItem));
        }
コード例 #16
0
        /// <summary>
        /// merges a changeset for the specified environment
        /// </summary>
        /// <param name="changeset"></param>
        /// <param name="environment"></param>
        /// <returns></returns>
        public MergeStatus MergeChangeset(Changeset changeset, MergeEnvironment environment)
        {
            var tfs            = TfsTeamDataAccess.GetTfsTeamProjectCollection();
            var versionControl = tfs.GetService <VersionControlServer>();
            var workspace      = versionControl.GetWorkspace(Workstation.Current.Name, tfs.AuthorizedIdentity.UniqueName);
            var tfsChangeset   = versionControl.GetChangeset(changeset.Id);
            var statusList     = new List <MergeStatus>();

            tfsChangeset.Changes.ToList().ForEach(change =>
            {
                var sourcePath        = change.Item.ServerItem.Substring(0, change.Item.ServerItem.LastIndexOf("/", StringComparison.Ordinal));
                sourcePath            = !sourcePath.EndsWith("/") ? sourcePath + "/" : sourcePath;
                var mergeRelationship = GetMergeRelationship(changeset, environment);
                if (mergeRelationship == null)
                {
                    statusList.Add(new MergeStatus
                    {
                        NumFailures = 1,
                        Message     = string.Format("There are no merge relationships configured for {0}", changeset.Branch.Name)
                    });
                    return;
                }
                var targetPath = sourcePath.ToLower().Replace(string.Format("/{0}/", changeset.Branch.Name.ToLower()), string.Format("/{0}/", mergeRelationship.Target.Name));

                if (string.Compare(sourcePath, targetPath, StringComparison.OrdinalIgnoreCase) == 0)                         // this happens with feature branches. They will get picked up on next "changeset".
                {
                    return;
                }

                // Get Latest first
                string[] itemsSpec = { targetPath };
                workspace.Get(itemsSpec, VersionSpec.Latest, RecursionType.Full, GetOptions.Overwrite);

                // Get ready to Merge.
                MergeStatus status;
                var verSpec = new ChangesetVersionSpec(tfsChangeset.ChangesetId);
                try
                {
                    status = MapMergeStatus(workspace.Merge(sourcePath, targetPath, verSpec, verSpec, LockLevel.None, RecursionType.Full, MergeOptions.None));
                }
                catch (Exception e)
                {
                    status = new MergeStatus
                    {
                        NumFailures = 1,
                        Message     = e.Message
                    };
                }
                var conflicts = workspace.QueryConflicts(new[] { targetPath }, true);
                conflicts.ToList().ForEach(conflict =>
                {
                    workspace.MergeContent(conflict, false);
                    if (conflict.ContentMergeSummary.TotalConflicting > 0)
                    {
                        return;
                    }
                    // Conflict was resolved. Does not require a human!
                    conflict.Resolution = Resolution.AcceptMerge;
                    // If the conflict is successfully resolved, the IsResolved property is set to true.
                    // If resolving this conflict caused other conflicts to be deleted besides the current conflict, the list of other deleted conflicts appears in resolvedConflicts.
                    Conflict[] resolvedConflicts;
                    workspace.ResolveConflict(conflict, out resolvedConflicts);
                    if (!conflict.IsResolved)
                    {
                        return;
                    }

                    var totalResolved           = resolvedConflicts.Count();
                    status.NumResolvedConflicts = status.NumResolvedConflicts + 1 + totalResolved;
                    status.NumConflicts         = status.NumConflicts - 1 - totalResolved;
                });
                statusList.Add(status);
            });
            return(new MergeStatus             // create summary of all merges for this changeset
            {
                HaveResolvableWarnings = statusList.Any(s => s.HaveResolvableWarnings),
                NoActionNeeded = statusList.All(s => s.NoActionNeeded),
                NumBytes = statusList.Sum(s => s.NumBytes),
                NumConflicts = statusList.Sum(s => s.NumConflicts),
                NumFailures = statusList.Sum(s => s.NumFailures),
                NumFiles = statusList.Sum(s => s.NumFiles),
                NumOperations = statusList.Sum(s => s.NumOperations),
                NumResolvedConflicts = statusList.Sum(s => s.NumResolvedConflicts),
                NumUpdated = statusList.Sum(s => s.NumUpdated),
                NumWarnings = statusList.Sum(s => s.NumWarnings)
            });
        }