public override void Run() { WorkItemStore store = Driver.TeamFoundationServer.GetService(typeof(WorkItemStore)) as WorkItemStore; ILinking linking = Driver.TeamFoundationServer.GetService(typeof(ILinking)) as ILinking; int changeSet = 1; // Get URI for changeset ArtifactId changeSetId = new ArtifactId(); changeSetId.Tool = "VersionControl"; changeSetId.ArtifactType = "ChangeSet"; changeSetId.ToolSpecificId = changeSet.ToString(); string changeSetUri = LinkingUtilities.EncodeUri(changeSetId); // Get referencing artifacts for given changeset Artifact[] artifacts = linking.GetReferencingArtifacts(new string[] { changeSetUri }, null); foreach (Artifact artifact in artifacts) { Console.WriteLine(artifact.ToString()); ArtifactId artifactId = LinkingUtilities.DecodeUri(artifact.Uri); if (String.Equals(artifactId.Tool, "WorkItemTracking", StringComparison.OrdinalIgnoreCase)) { WorkItem wi = store.GetWorkItem(Convert.ToInt32(artifactId.ToolSpecificId)); Console.WriteLine(wi); } } }
public void OpenBuildSecurityDialog(string projectName, string projectUri) { var projectInfo = new ProjectInfo(projectUri, projectName, ProjectState.WellFormed); var artifactId = LinkingUtilities.DecodeUri(projectUri); _teamFoundationBuild.Value.BuildExplorerWrapper.OpenBuildSecurityDialog(projectInfo, projectInfo.Name, artifactId.ToolSpecificId); }
public void OpenBuildDefinitionSecurityDialog(string projectName, string projectUri, string definitionName, string definitionUri) { var projectInfo = new ProjectInfo(projectUri, projectName, ProjectState.WellFormed); var projectArtifactId = LinkingUtilities.DecodeUri(projectUri); var definitionArtifactId = LinkingUtilities.DecodeUri(definitionUri); var securityToken = string.Concat(projectArtifactId.ToolSpecificId, BuildSecurity.NamespaceSeparator, definitionArtifactId.ToolSpecificId); _teamFoundationBuild.Value.BuildExplorerWrapper.OpenBuildSecurityDialog(projectInfo, definitionName, securityToken); }
/// <summary> /// gets ts changesets for a particular path (branch) and workitem /// </summary> /// <param name="tfs"></param> /// <param name="workItem"></param> /// <param name="pathName"></param> internal static IEnumerable <TfsChangeset> GetTfsChangesetsByPathName(TfsTeamProjectCollection tfs, TfsWorkItem workItem, string pathName) { var versionControl = tfs.GetService <VersionControlServer>(); return((from extLink in workItem.Links.OfType <ExternalLink>() let artifact = LinkingUtilities.DecodeUri(extLink.LinkedArtifactUri) where String.Equals(artifact.ArtifactType, "Changeset", StringComparison.Ordinal) select versionControl.ArtifactProvider.GetChangeset(new Uri(extLink.LinkedArtifactUri))) .Where(w => w.Changes.Any(a => a.Item.ServerItem.IndexOf(string.Format("/{0}/", pathName), StringComparison.OrdinalIgnoreCase) > 0)).ToList()); }
private Details.Changeset MapChangeset(ExternalLink link, bool?isAdded) { ArtifactId artifactId = LinkingUtilities.DecodeUri(link.LinkedArtifactUri); var id = int.Parse(artifactId.ToolSpecificId); return(new Details.Changeset { Id = id, IsAdded = isAdded, Uri = new Uri(link.LinkedArtifactUri), Comment = link.Comment }); }
private IEnumerable <IChangeset> GetAssociatedChangesets(VersionControlServer vcs, WorkItem workItem) { if (workItem != null) { return(workItem.Links.OfType <ExternalLink>() .Where(x => String.Equals(LinkingUtilities.DecodeUri(x.LinkedArtifactUri).ArtifactType, "Changeset", StringComparison.Ordinal)) .Select(x => vcs.ArtifactProvider.GetChangeset(new Uri(x.LinkedArtifactUri))) .Select(_ChangesetFactory.Create) .OrderBy(x => x) .AsReadOnly()); } return(Enumerable.Empty <IChangeset>()); }
private void AddChangesets(SortedList <int, object> changesetIds, WorkItem workItem) { foreach (Link link in workItem.Links) { ExternalLink extLink = link as ExternalLink; if (extLink != null) { ArtifactId artifact = LinkingUtilities.DecodeUri(extLink.LinkedArtifactUri); if (String.Equals(artifact.ArtifactType, "Changeset", StringComparison.Ordinal)) { changesetIds[Convert.ToInt32(artifact.ToolSpecificId)] = "don't care"; } } } }
private List <Tuple <Link, Changeset> > GetLinkAndChangesetPairs(int workitemID, string source) { var query = string.Format("SELECT * FROM WorkItems WHERE [System.Id] = {0}", workitemID); var workItems = _workitemStore.Query(query); // _workitemStore.GetWorkItem() throws exception if not found. This is fail safe. if (workItems.Count == 0) { _log.Info("No workitems found with given inputs!!"); return(null); } _log.InfoFormat("Workitem {0} found", workitemID); var versionControl = _collection.GetService <VersionControlServer>(); var linkAndChangesetTuples = new List <Tuple <Link, Changeset> >(); foreach (var link in workItems[0].Links) { var extLink = link as ExternalLink; if (extLink == null) { continue; } // Ensure link has a type of 'Changeset' var artifact = LinkingUtilities.DecodeUri(extLink.LinkedArtifactUri); if (String.Equals(artifact.ArtifactType, "Changeset", StringComparison.Ordinal) == false) { continue; } // Ensure changeset is related to given source branch var changeset = versionControl.ArtifactProvider.GetChangeset(new Uri(extLink.LinkedArtifactUri)); if (changeset.Changes[0].Item.ServerItem.StartsWith(source) == false) { continue; } // Ensure changeset is related to this user if (changeset.Committer != _sourceControl.AuthorizedUser) { continue; } linkAndChangesetTuples.Add(new Tuple <Link, Changeset>(link as Link, changeset)); } return(linkAndChangesetTuples); }
/// <summary> /// Initializes a new instance of the <see cref="TeamProjectInfo"/> class. /// </summary> /// <param name="teamProjectCollection">The Team Project Collection that this Team Project is part of.</param> /// <param name="name">The name of this Team Project.</param> /// <param name="uri">The URI of this Team Project.</param> /// <param name="logger">The logger.</param> public TeamProjectInfo(TeamProjectCollectionInfo teamProjectCollection, string name, Uri uri, ILogger logger) { this.TeamProjectCollection = teamProjectCollection; this.Name = name; this.Uri = uri; if (this.Uri != null) { try { var artifactId = LinkingUtilities.DecodeUri(this.Uri.ToString()); this.Guid = new Guid(artifactId.ToolSpecificId); } catch (Exception exc) { if (logger != null) { logger.Log("Could not determine the GUID from Uri \"{0}\" for Team Project \"{1}\"".FormatCurrent(uri, this.Name), exc, TraceEventType.Warning); } } } }
public IList <WorkItem> GetAssociateItems(int changeset) { var result = new List <WorkItem>(); // Создал объект для получения URL var setId = new ArtifactId { Tool = ToolNames.VersionControl, ArtifactType = WorkItemTypes.ChangeSet, ToolSpecificId = changeset.ToString() }; // По этому URL буду искать линкованные элементы var uri = LinkingUtilities.EncodeUri(setId); // Нашел связи var linked = _linking.GetReferencingArtifacts(new[] { uri }); Trace.WriteLine($"{nameof(TfsApi)}.{nameof(GetAssociateItems)}: Founded {linked.Length} links"); foreach (var artifact in linked) { // Распарсил url var artifactId = LinkingUtilities.DecodeUri(artifact.Uri); // Какая-то хитрая проверка if (string.Equals(artifactId.Tool, ToolNames.WorkItemTracking, StringComparison.OrdinalIgnoreCase)) { // Нашёл элемент var item = _itemStore.GetWorkItem(Convert.ToInt32(artifactId.ToolSpecificId)); // Добавил result.Add(item); } } Trace.WriteLineIf(result.Any(), $"{nameof(TfsApi)}.{nameof(GetAssociateItems)}: Changeset {changeset} linked with items: {string.Join(", ", result.Select(x => x.Id))}"); return(result); }
public void ExpandVariables_ExpandBuildIdVariableWhenExecuteInvoked() { // arrange var target = new ExpandVariables(); var parameters = new Dictionary <string, object> { { "Inputs", new[] { "$(BuildId)" } }, { "IncludeBuildVariables", true } }; var buildDetail = GetMockedIBuildDetail(); var invoker = new WorkflowInvoker(target); invoker.Extensions.Add(buildDetail.Object); // act var actual = invoker.Invoke(parameters); // assert Assert.AreEqual(1, ((IEnumerable <string>)actual["Result"]).Count(), "Expected only one output parameter."); Assert.AreEqual(LinkingUtilities.DecodeUri(buildDetail.Object.Uri.ToString()).ToolSpecificId, ((IEnumerable <string>)actual["Result"]).ElementAt(0)); }
static SecurityManager() { permissionGroupFactories = new[] { new PermissionGroupFactory(PermissionScope.TeamProject, FrameworkSecurity.TeamProjectNamespaceId, "Team Project", new [] { "ADMINISTER_BUILD", "START_BUILD", "EDIT_BUILD_STATUS", "UPDATE_BUILD" }, (tpc, tfsVersion, teamProjectName, teamProjectUri) => new[] { PermissionNamespaces.Project + teamProjectUri }), new PermissionGroupFactory(PermissionScope.Tagging, FrameworkSecurity.TaggingNamespaceId, "Tagging", (tpc, tfsVersion, teamProjectName, teamProjectUri) => new[] { "/" + LinkingUtilities.DecodeUri(teamProjectUri).ToolSpecificId }), new PermissionGroupFactory(PermissionScope.WorkItemAreas, AuthorizationSecurityConstants.CommonStructureNodeSecurityGuid, "Areas", (tpc, tfsVersion, teamProjectName, teamProjectUri) => { var css = tpc.GetService <ICommonStructureService>(); var projectStructures = css.ListStructures(teamProjectUri); var rootArea = projectStructures.SingleOrDefault(n => n.StructureType == StructureType.ProjectModelHierarchy); if (rootArea == null) { throw new InvalidOperationException("The root area could not be retrieved"); } return(new[] { rootArea.Uri }); }), new PermissionGroupFactory(PermissionScope.WorkItemIterations, AuthorizationSecurityConstants.IterationNodeSecurityGuid, "Iterations", (tpc, tfsVersion, teamProjectName, teamProjectUri) => { var css = tpc.GetService <ICommonStructureService>(); var projectStructures = css.ListStructures(teamProjectUri); var rootIteration = projectStructures.SingleOrDefault(n => n.StructureType == StructureType.ProjectLifecycle); if (rootIteration == null) { throw new InvalidOperationException("The root iteration could not be retrieved"); } return(new[] { rootIteration.Uri }); }), new PermissionGroupFactory(PermissionScope.WorkItemQueryFolders, QueryItemSecurityConstants.NamespaceGuid, "Queries", new [] { "FullControl" }, (tpc, tfsVersion, teamProjectName, teamProjectUri) => { var store = tpc.GetService <WorkItemStore>(); var project = store.Projects[teamProjectName]; foreach (var item in project.QueryHierarchy) { if (!item.IsPersonal && item is QueryFolder) { var teamProjectGuid = LinkingUtilities.DecodeUri(teamProjectUri).ToolSpecificId; return(new[] { "$/{0}/{1}".FormatInvariant(teamProjectGuid, item.Id.ToString()) }); } } throw new InvalidOperationException("The shared queries folder could not be retrieved"); }), new PermissionGroupFactory(PermissionScope.TeamBuild, BuildSecurity.BuildNamespaceId, "Team Build", (tpc, tfsVersion, teamProjectName, teamProjectUri) => new[] { LinkingUtilities.DecodeUri(teamProjectUri).ToolSpecificId }), new PermissionGroupFactory(PermissionScope.SourceControl, SecurityConstants.RepositorySecurityNamespaceGuid, "TFVC", (tpc, tfsVersion, teamProjectName, teamProjectUri) => { var vcs = tpc.GetService <VersionControlServer>(); var teamProject = vcs.TryGetTeamProject(teamProjectName); return(teamProject == null ? null: new[] { vcs.GetTeamProject(teamProjectName).ServerItem }); }), new PermissionGroupFactory(PermissionScope.GitRepositories, GitConstants.GitSecurityNamespaceId, "Git", (tpc, tfsVersion, teamProjectName, teamProjectUri) => { // For pre-TFS 2013.5 this is "repositories/<guid>", otherwise it's "repoV2/<guid>". // Since we don't know the exact update level, we return both in case of doubt. // Retrieving permissions from a non-existant token returns an empty ACL, and setting // permissions on a non-existant token doesn't seem to cause side effects (it's stored // in the database but otherwise ignored). var teamProjectGuid = LinkingUtilities.DecodeUri(teamProjectUri).ToolSpecificId; var tokens = new List <string>(2); if (tfsVersion >= TfsMajorVersion.V12) { if (tfsVersion < TfsMajorVersion.V14) { tokens.Add("repositories/" + teamProjectGuid); } tokens.Add("repoV2/" + teamProjectGuid); } return(tokens); }), }; }
protected override IEnumerable <INotification> CreateNotifications(TeamFoundationRequestContext requestContext, DiscussionsNotification args, int maxLines) { var locationService = requestContext.GetService <ILocationService>(); var linkingService = requestContext.GetService <TeamFoundationLinkingService>(); var hyperlinkService = requestContext.GetService <TswaServerHyperlinkService>(); var identityService = requestContext.GetService <ITeamFoundationIdentityService>(); var commonService = requestContext.GetService <ICommonStructureService>(); var discussionService = requestContext.GetService <ITeamFoundationDiscussionService>(); var notifications = new List <INotification>(); foreach (var thread in args.Threads) { if (thread.Comments == null) { continue; // e.g. when a comment is deleted } var artifactId = LinkingUtilities.DecodeUri(thread.ArtifactUri); int discussionId = thread.DiscussionId <= 0 ? thread.Comments[0].DiscussionId : thread.DiscussionId; if (artifactId.ArtifactType.Equals("Commit", StringComparison.OrdinalIgnoreCase)) { var repositoryService = requestContext.GetService <TeamFoundationGitRepositoryService>(); var commitService = requestContext.GetService <TeamFoundationGitCommitService>(); Guid projectGuid; Guid repositoryId; Sha1Id commitId; GitCommitArtifactId.Decode(artifactId, out projectGuid, out repositoryId, out commitId); using (TfsGitRepository repository = repositoryService.FindRepositoryById(requestContext, repositoryId)) { var project = commonService.GetProject(requestContext, projectGuid); var repoUri = repository.GetRepositoryUri(requestContext); var commitUri = repoUri + "/commit/" + commitId.ToHexString(); string itemPath; if (thread.Properties.TryGetValue <string>("Microsoft.TeamFoundation.Discussion.ItemPath", out itemPath)) { commitUri += string.Format("#path={0}&discussionId={1}&_a=contents", Uri.EscapeDataString(itemPath), discussionId); } var commitManifest = commitService.GetCommitManifest(requestContext, repository, commitId); var pusher = identityService.ReadIdentities(requestContext, new[] { commitManifest.PusherId }).FirstOrDefault(); foreach (var comment in thread.Comments) { var commenter = identityService.ReadIdentities(requestContext, new[] { comment.Author }).First(); var notification = new Notifications.CommitCommentNotification() { TeamProjectCollection = requestContext.ServiceHost.Name, PusherUniqueName = pusher?.UniqueName, UniqueName = commenter.UniqueName, DisplayName = comment.AuthorDisplayName, ProjectName = project.Name, RepoUri = repoUri, RepoName = repository.Name, CommitId = commitId, CommitUri = commitUri, Comment = TextHelper.Truncate(comment.Content, Settings.DiscussionCommentMaxLength), TeamNames = GetUserTeamsByProjectUri(requestContext, project.Uri, commenter.Descriptor), }; notifications.Add(notification); } } } else if (artifactId.ArtifactType.Equals("CodeReviewId", StringComparison.OrdinalIgnoreCase)) { Guid projectGuid; int pullRequestId; LegacyCodeReviewArtifactId.Decode(artifactId, out projectGuid, out pullRequestId); var pullRequestService = requestContext.GetService <ITeamFoundationGitPullRequestService>(); var pullRequest = pullRequestService.GetPullRequestDetails(requestContext, pullRequestId); var repositoryService = requestContext.GetService <TeamFoundationGitRepositoryService>(); using (TfsGitRepository repository = repositoryService.FindRepositoryById(requestContext, pullRequest.RepositoryId)) { var project = commonService.GetProject(requestContext, projectGuid); string repoUri = repository.GetRepositoryUri(requestContext); var creator = identityService.ReadIdentities(requestContext, new[] { pullRequest.Creator }).FirstOrDefault(); foreach (var comment in thread.Comments) { var commenter = identityService.ReadIdentities(requestContext, new[] { comment.Author }).First(); var notification = new Notifications.PullRequestCommentNotification() { TeamProjectCollection = requestContext.ServiceHost.Name, CreatorUniqueName = creator?.UniqueName, UniqueName = commenter.UniqueName, DisplayName = commenter.DisplayName, ProjectName = project.Name, RepoUri = repoUri, RepoName = repository.Name, PrId = pullRequest.PullRequestId, PrUrl = $"{repoUri}/pullrequest/{pullRequest.PullRequestId}#view=discussion", PrTitle = pullRequest.Title, TeamNames = GetUserTeamsByProjectUri(requestContext, project.Uri, commenter.Descriptor), SourceBranch = new GitRef(pullRequest.SourceBranchName), TargetBranch = new GitRef(pullRequest.TargetBranchName), Comment = TextHelper.Truncate(comment.Content, Settings.DiscussionCommentMaxLength) }; notifications.Add(notification); } } } else if (artifactId.ArtifactType.Equals("Changeset", StringComparison.OrdinalIgnoreCase)) { var versionControlService = requestContext.GetService <TeamFoundationVersionControlService>(); var uri = new VersionControlIntegrationUri(thread.ArtifactUri); var changesetId = int.Parse(uri.ArtifactName); var reader = versionControlService.QueryChangeset(requestContext, changesetId, true, false, false); var changeset = reader.Current <Changeset>(); var changesetUrl = hyperlinkService.GetChangesetDetailsUrl(changesetId).AbsoluteUri; string baseUrl = String.Format("{0}/{1}/", locationService.GetAccessMapping(requestContext, "PublicAccessMapping").AccessPoint, requestContext.ServiceHost.Name); string itemPath = string.Empty; string projectName = string.Empty; const string projectNamePattern = @"^\$\/([^\/]*)\/"; if (thread.Properties != null && thread.Properties.TryGetValue <string>("Microsoft.TeamFoundation.Discussion.ItemPath", out itemPath)) { changesetUrl += string.Format("#path={0}&discussionId={1}&_a=contents", Uri.EscapeDataString(itemPath), discussionId); Match match = Regex.Match(itemPath, projectNamePattern); if (match.Success) { projectName = match.Groups[1].Value; } } else { // This assumes changeset doesn't span multiple projects. var serverItem = changeset.Changes.FirstOrDefault()?.Item.ServerItem; if (serverItem != null) { Match match = Regex.Match(serverItem, projectNamePattern); if (match.Success) { projectName = match.Groups[1].Value; } } } var commiter = identityService.ReadIdentity(requestContext, IdentitySearchFactor.AccountName, changeset.Committer); foreach (var comment in thread.Comments) { var commenter = identityService.ReadIdentities(requestContext, new[] { comment.Author }).First(); var notification = new Notifications.ChangesetCommentNotification() { TeamProjectCollection = requestContext.ServiceHost.Name, CreatorUniqueName = commiter?.UniqueName, UniqueName = commenter.UniqueName, DisplayName = commenter.DisplayName, ProjectUrl = baseUrl + projectName, ProjectName = projectName, ChangesetId = changesetId, ChangesetUrl = changesetUrl, TeamNames = GetUserTeamsByProjectName(requestContext, projectName, commenter.Descriptor), SourcePath = itemPath, Comment = TextHelper.Truncate(comment.Content, Settings.DiscussionCommentMaxLength) }; notifications.Add(notification); } } } return(notifications); }
/// <summary> /// Executes the logic for this workflow activity /// </summary> /// <returns> /// The activity result. /// </returns> protected override IEnumerable <string> InternalExecute() { // get inputs var inputs = this.Inputs.Get(this.ActivityContext); if (inputs == null || !inputs.Any()) { this.LogBuildWarning("No variable expanded, input strings is null or empty."); return(inputs); } // get variables (copy userVariables to put them inside a case insensitive dictionary) var userVariables = this.Variables.Get(this.ActivityContext) != null ? new Dictionary <string, string>(this.Variables.Get(this.ActivityContext), StringComparer.OrdinalIgnoreCase) : default(Dictionary <string, string>); var buildVariables = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase); if (this.IncludeBuildVariables.Get(this.ActivityContext)) { var buildAgent = this.ActivityContext.GetExtension <IBuildAgent>(); var buildDetail = this.ActivityContext.GetExtension <IBuildDetail>(); buildVariables["BuildNumber"] = buildDetail.BuildNumber; buildVariables["BuildId"] = LinkingUtilities.DecodeUri(buildDetail.Uri.ToString()).ToolSpecificId; buildVariables["BuildDefinitionName"] = buildDetail.BuildDefinition.Name; buildVariables["BuildDefinitionId"] = buildDetail.BuildDefinition.Id; buildVariables["TeamProject"] = buildDetail.BuildDefinition.TeamProject; buildVariables["DropLocation"] = buildDetail.DropLocation; buildVariables["BuildAgent"] = buildAgent != null ? buildAgent.Name : string.Empty; buildVariables["BuildAgentName"] = buildAgent != null ? buildAgent.Name : string.Empty; // Same as BuildAgent but more consistent with TFS naming convention buildVariables["BuildAgentId"] = buildAgent != null?LinkingUtilities.DecodeUri(buildAgent.Uri.AbsoluteUri).ToolSpecificId : string.Empty; buildVariables["BuildControllerName"] = buildAgent != null ? buildAgent.Controller.Name : string.Empty; buildVariables["BuildControllerId"] = buildAgent != null?LinkingUtilities.DecodeUri(buildAgent.Controller.Uri.AbsoluteUri).ToolSpecificId : string.Empty; buildVariables["BuildControllerCustomAssemblyPath"] = buildAgent != null ? buildAgent.Controller.CustomAssemblyPath : string.Empty; } var envVariables = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase); if (this.IncludeEnvironmentVariables.Get(this.ActivityContext)) { foreach (var entry in Environment.GetEnvironmentVariables().Cast <DictionaryEntry>()) { envVariables[entry.Key.ToString()] = entry.Value.ToString(); } } // find and replace variables var outputs = new List <string>(); foreach (var input in inputs) { var output = new StringBuilder(input); if (input != null) { var matches = variableRegex.Matches(input); for (var i = matches.Count - 1; i >= 0; --i) { if (matches[i].Success) { var value = default(string); if ((userVariables != null && userVariables.TryGetValue(matches[i].Groups[1].Value, out value)) || buildVariables.TryGetValue(matches[i].Groups[1].Value, out value) || envVariables.TryGetValue(matches[i].Groups[1].Value, out value)) { output.Replace(matches[i].Value, value, matches[i].Index, matches[i].Length); this.LogBuildMessage("Expanded variable " + matches[i].Value + " to '" + value + "'."); } } } } outputs.Add(output.ToString()); } return(outputs); }
/// <summary> /// Retrieves changesets associated with a work item /// </summary> /// <param name="wi">The work item to retrieve changesets for</param> /// <param name="stub">The work item stub to add them to</param> private void GetChangesets(WorkItem wi, WorkItemStub stub) { //Loop through all of the links in the work item. Note that this is the links //not the work item links so this includes things like hyperlinks, versioned items //and changeset links for (int i = 0; i < wi.Links.Count; i++) { //Determine if this is an external link which is an indication of a changeset link if (wi.Links[i].BaseType == BaseLinkType.ExternalLink) { int cs_id; ExternalLink ex = (ExternalLink)wi.Links[i]; //We have a valid changeset link type if (ex.ArtifactLinkType.Equals(_wis.RegisteredLinkTypes[ArtifactLinkIds.Changeset])) { //Get the ID of the changeset ArtifactId artifact = LinkingUtilities.DecodeUri(ex.LinkedArtifactUri); cs_id = Convert.ToInt32(artifact.ToolSpecificId); //It is a changeset, validate that we haven't processed it already ChangesetStub c = stub.Changesets.Find( delegate(ChangesetStub s) { return(s.ID == cs_id); } ); //It wasn't found, process it if (c == null) { //It is a changeset so get the specific changeset Changeset cs = _vcs.GetChangeset(cs_id); ChangesetStub csStub = new ChangesetStub(); csStub.ID = cs_id; //Loop through the files in the changeset which is represented by the Changes for (int j = 0; j < cs.Changes.Count(); j++) { //Add the files to the changeset stub FileChangeInfo fc = new FileChangeInfo(); fc.ChangeType = cs.Changes[j].ChangeType.ToString(); fc.FullPath = cs.Changes[j].Item.ServerItem; csStub.Files.Add(fc); //Check to see if we have added this file to the master list, //if we haven't, add it if (!_allFiles.Contains(fc.FileName)) { _allFiles.Add(fc.FileName); } } stub.Changesets.Add(csStub); //Loop through the files in the changeset which is represented by the Changes for (int j = 0; j < cs.Changes.Count(); j++) { ChangesetFilesToWorkItems(cs.Changes[j].Item.ServerItem); } } } } } }
private static bool IsChangesetLink(ExternalLink link) { var artifact = LinkingUtilities.DecodeUri(link.LinkedArtifactUri); return(String.Equals(artifact.ArtifactType, "Changeset", StringComparison.Ordinal)); }