public static bool IsForceRequired(this PushNotification pushNotification, TeamFoundationRequestContext requestContext, TfsGitRepository repository) { foreach (var refUpdateResult in pushNotification.RefUpdateResults.Where(r => r.Succeeded)) { // Don't bother with new or deleted refs if (refUpdateResult.OldObjectId.IsEmpty || refUpdateResult.NewObjectId.IsEmpty) { continue; } TfsGitObject gitObject = repository.LookupObject(requestContext, refUpdateResult.NewObjectId); if (gitObject.ObjectType != GitObjectType.Commit) { continue; } TfsGitCommit gitCommit = (TfsGitCommit)gitObject; if (!gitCommit.IsDescendantOf(requestContext, refUpdateResult.OldObjectId)) { return(true); } } return(false); }
protected override IEnumerable <INotification> CreateNotifications(IVssRequestContext requestContext, PushNotification pushNotification, int maxLines) { var repositoryService = requestContext.GetService <ITeamFoundationGitRepositoryService>(); var commonService = requestContext.GetService <CommonStructureService>(); var commitService = requestContext.GetService <ITeamFoundationGitCommitService>(); var identityService = requestContext.GetService <TeamFoundationIdentityService>(); var identity = identityService.ReadIdentity(requestContext, IdentitySearchFactor.Identifier, pushNotification.Pusher.Identifier); var teamNames = GetUserTeamsByProjectUri(requestContext, pushNotification.TeamProjectUri, pushNotification.Pusher); using (ITfsGitRepository repository = repositoryService.FindRepositoryById(requestContext, pushNotification.RepositoryId)) { var pushRow = new PushRow() { UniqueName = pushNotification.AuthenticatedUserName, DisplayName = identity.DisplayName, RepoName = pushNotification.RepositoryName, RepoUri = repository.GetRepositoryUri(), ProjectName = commonService.GetProject(requestContext, pushNotification.TeamProjectUri).Name, IsForcePush = Settings.IdentifyForcePush && pushNotification.IsForceRequired(requestContext, repository) }; var notification = new GitPushNotification(requestContext.ServiceHost.Name, pushRow.ProjectName, pushRow.RepoName, pushNotification.AuthenticatedUserName, teamNames, pushNotification.RefUpdateResults.Where(r => r.Succeeded).Select(r => new GitRef(r))); notification.Add(pushRow); notification.TotalLineCount++; var refLookup = new Dictionary <Sha1Id, List <GitRef> >(); var deletedRefs = new List <GitRef>(); var oldCommits = new HashSet <TfsGitCommit>(new TfsGitObjectEqualityComparer()); var unknowns = new List <TfsGitRefUpdateResult>(); // Associate refs (branch, lightweight and annotated tag) with corresponding commit foreach (var refUpdateResult in pushNotification.RefUpdateResults.Where(r => r.Succeeded)) { var newObjectId = refUpdateResult.NewObjectId; TfsGitCommit commit = null; if (newObjectId.IsEmpty) { deletedRefs.Add(new GitRef(refUpdateResult)); continue; } TfsGitObject gitObject = repository.LookupObject(newObjectId); if (gitObject.ObjectType == WebApi.GitObjectType.Commit) { commit = gitObject as TfsGitCommit; } else if (gitObject.ObjectType == WebApi.GitObjectType.Tag) { var tag = (TfsGitTag)gitObject; commit = tag.TryResolveToCommit(); } if (commit != null) { List <GitRef> refs; if (!refLookup.TryGetValue(commit.ObjectId, out refs)) { refs = new List <GitRef>(); refLookup.Add(commit.ObjectId, refs); } refs.Add(new GitRef(refUpdateResult)); if (!pushNotification.IncludedCommits.Contains(commit.ObjectId)) { oldCommits.Add(commit); } } else { unknowns.Add(refUpdateResult); } } notification.TotalLineCount += pushNotification.IncludedCommits.Count() + oldCommits.Count + unknowns.Count; // Add new commits with refs var pushCommits = pushNotification.IncludedCommits.Select(commitId => (TfsGitCommit)repository.LookupObject(commitId)).OrderByDescending(c => c.GetCommitter().Time); foreach (var commit in pushCommits.TakeWhile(c => notification.Count < maxLines)) { notification.Add(CreateCommitRow(requestContext, commitService, repository, commit, CommitRowType.Commit, pushNotification, refLookup)); } // Add updated refs to old commits foreach (TfsGitCommit gitCommit in oldCommits.OrderByDescending(c => c.GetCommitter().Time).TakeWhile(c => notification.Count < maxLines)) { notification.Add(CreateCommitRow(requestContext, commitService, repository, gitCommit, CommitRowType.RefUpdate, pushNotification, refLookup)); } // Add deleted refs if any if (deletedRefs.Any() && notification.Count < maxLines) { notification.Add(new DeleteRow() { Refs = deletedRefs }); } // Add "unknown" refs foreach (var refUpdateResult in unknowns.TakeWhile(c => notification.Count < maxLines)) { var newObjectId = refUpdateResult.NewObjectId; TfsGitObject gitObject = repository.LookupObject(newObjectId); notification.Add(new RefUpdateRow() { NewObjectId = newObjectId, ObjectType = gitObject.ObjectType, Refs = new[] { new GitRef(refUpdateResult) } }); } yield return(notification); } }
protected override IEnumerable <INotification> CreateNotifications(TeamFoundationRequestContext requestContext, PushNotification pushNotification, int maxLines) { var repositoryService = requestContext.GetService <TeamFoundationGitRepositoryService>(); var commonService = requestContext.GetService <CommonStructureService>(); var commitService = requestContext.GetService <TeamFoundationGitCommitService>(); var identityService = requestContext.GetService <TeamFoundationIdentityService>(); var identity = identityService.ReadIdentity(requestContext, IdentitySearchFactor.Identifier, pushNotification.Pusher.Identifier); var teamNames = GetUserTeamsByProjectUri(requestContext, pushNotification.TeamProjectUri, pushNotification.Pusher); using (TfsGitRepository repository = repositoryService.FindRepositoryById(requestContext, pushNotification.RepositoryId)) { var pushRow = new PushRow() { UniqueName = pushNotification.AuthenticatedUserName, DisplayName = identity.DisplayName, RepoName = pushNotification.RepositoryName, RepoUri = repository.GetRepositoryUri(requestContext), ProjectName = commonService.GetProject(requestContext, pushNotification.TeamProjectUri).Name, IsForcePush = settings.IdentifyForcePush ? pushNotification.IsForceRequired(requestContext, repository) : false }; var notification = new GitPushNotification(requestContext.ServiceHost.Name, pushRow.ProjectName, pushRow.RepoName, teamNames); notification.Add(pushRow); notification.TotalLineCount++; var refNames = new Dictionary <byte[], List <string> >(new ByteArrayComparer()); var oldCommits = new HashSet <byte[]>(new ByteArrayComparer()); var unknowns = new List <RefUpdateResultGroup>(); // Associate refs (branch, lightweight and annotated tag) with corresponding commit var refUpdateResultGroups = pushNotification.RefUpdateResults .Where(r => r.Succeeded) .GroupBy(r => r.NewObjectId, (key, items) => new RefUpdateResultGroup(key, items), new ByteArrayComparer()); foreach (var refUpdateResultGroup in refUpdateResultGroups) { byte[] newObjectId = refUpdateResultGroup.NewObjectId; byte[] commitId = null; if (newObjectId.IsZero()) { commitId = newObjectId; } else { TfsGitObject gitObject = repository.LookupObject(requestContext, newObjectId); if (gitObject.ObjectType == TfsGitObjectType.Commit) { commitId = newObjectId; } else if (gitObject.ObjectType == TfsGitObjectType.Tag) { var tag = (TfsGitTag)gitObject; var commit = tag.TryResolveToCommit(requestContext); if (commit != null) { commitId = commit.ObjectId; } } } if (commitId != null) { List <string> names; if (!refNames.TryGetValue(commitId, out names)) { names = new List <string>(); refNames.Add(commitId, names); } names.AddRange(RefsToStrings(refUpdateResultGroup.RefUpdateResults)); if (commitId.IsZero() || !pushNotification.IncludedCommits.Any(r => r.SequenceEqual(commitId))) { oldCommits.Add(commitId); } } else { unknowns.Add(refUpdateResultGroup); } } notification.TotalLineCount += pushNotification.IncludedCommits.Count() + oldCommits.Count + unknowns.Count; // Add new commits with refs foreach (byte[] commitId in pushNotification.IncludedCommits.TakeWhile(c => notification.Count < maxLines)) { TfsGitCommit gitCommit = (TfsGitCommit)repository.LookupObject(requestContext, commitId); notification.Add(CreateCommitRow(requestContext, commitService, gitCommit, CommitRowType.Commit, pushNotification, refNames)); } // Add updated refs to old commits foreach (byte[] commitId in oldCommits.TakeWhile(c => notification.Count < maxLines)) { if (commitId.IsZero()) { notification.Add(new DeleteRow() { RefNames = refNames[commitId] }); } else { TfsGitCommit gitCommit = (TfsGitCommit)repository.LookupObject(requestContext, commitId); notification.Add(CreateCommitRow(requestContext, commitService, gitCommit, CommitRowType.RefUpdate, pushNotification, refNames)); } } // Add "unknown" refs foreach (var refUpdateResultGroup in unknowns.TakeWhile(c => notification.Count < maxLines)) { byte[] newObjectId = refUpdateResultGroup.NewObjectId; TfsGitObject gitObject = repository.LookupObject(requestContext, newObjectId); notification.Add(new RefUpdateRow() { NewObjectId = newObjectId, ObjectType = gitObject.ObjectType, RefNames = RefsToStrings(refUpdateResultGroup.RefUpdateResults) }); } yield return(notification); } }
public EventNotificationStatus ProcessEvent(TeamFoundationRequestContext requestContext, NotificationType notificationType, object notificationEventArgs, out int statusCode, out string statusMessage, out Microsoft.TeamFoundation.Common.ExceptionPropertyCollection properties) { statusCode = 0; statusMessage = string.Empty; properties = null; try { if (notificationType == NotificationType.Notification && notificationEventArgs is PushNotification) { Stopwatch timer = new Stopwatch(); timer.Start(); PushNotification pushNotification = notificationEventArgs as PushNotification; var repositoryService = requestContext.GetService <TeamFoundationGitRepositoryService>(); var commonService = requestContext.GetService <CommonStructureService>(); using (TfsGitRepository repository = repositoryService.FindRepositoryById(requestContext, pushNotification.RepositoryId)) { string repoName = pushNotification.RepositoryName; string projectName = commonService.GetProject(requestContext, pushNotification.TeamProjectUri).Name; string userName = pushNotification.AuthenticatedUserName.Replace(DOMAIN_PREFIX, ""); var lines = new List <string>(); string pushText = pushNotification.IsForceRequired(requestContext, repository) ? "FORCE push" : "push"; lines.Add(String.Format("{0} by {1} to {2}/{3}", pushText, userName, projectName, repoName)); var refNames = new Dictionary <byte[], List <string> >(new ByteArrayComparer()); var oldCommits = new HashSet <byte[]>(new ByteArrayComparer()); var unknowns = new List <RefUpdateResultGroup>(); // Associate refs (branch, ligtweight and annotated tag) with corresponding commit var refUpdateResultGroups = pushNotification.RefUpdateResults .Where(r => r.Succeeded) .GroupBy(r => r.NewObjectId, (key, items) => new RefUpdateResultGroup(key, items), new ByteArrayComparer()); foreach (var refUpdateResultGroup in refUpdateResultGroups) { byte[] newObjectId = refUpdateResultGroup.NewObjectId; byte[] commitId = null; if (newObjectId.IsZero()) { commitId = newObjectId; } else { TfsGitObject gitObject = repository.LookupObject(requestContext, newObjectId); if (gitObject.ObjectType == TfsGitObjectType.Commit) { commitId = newObjectId; } else if (gitObject.ObjectType == TfsGitObjectType.Tag) { var tag = (TfsGitTag)gitObject; var commit = tag.TryResolveToCommit(requestContext); if (commit != null) { commitId = commit.ObjectId; } } } if (commitId != null) { List <string> names; if (!refNames.TryGetValue(commitId, out names)) { names = new List <string>(); refNames.Add(commitId, names); } names.AddRange(RefsToStrings(refUpdateResultGroup.RefUpdateResults)); if (commitId.IsZero() || !pushNotification.IncludedCommits.Any(r => r.SequenceEqual(commitId))) { oldCommits.Add(commitId); } } else { unknowns.Add(refUpdateResultGroup); } } // Display new commits with refs foreach (byte[] commitId in pushNotification.IncludedCommits) { TfsGitCommit gitCommit = (TfsGitCommit)repository.LookupObject(requestContext, commitId); string line = CommitToString(requestContext, gitCommit, "commit", pushNotification, refNames); lines.Add(line); } // Display updated refs to old commits foreach (byte[] commitId in oldCommits) { string line = null; if (commitId.IsZero()) { line = String.Format("{0} deleted", String.Join("", refNames[commitId])); } else { TfsGitCommit gitCommit = (TfsGitCommit)repository.LookupObject(requestContext, commitId); line = CommitToString(requestContext, gitCommit, "->", pushNotification, refNames); } lines.Add(line); } // Display "unknown" refs foreach (var refUpdateResultGroup in unknowns) { byte[] newObjectId = refUpdateResultGroup.NewObjectId; TfsGitObject gitObject = repository.LookupObject(requestContext, newObjectId); string line = String.Format("{0} -> {1} {2}", RefsToString(refUpdateResultGroup.RefUpdateResults), gitObject.ObjectType, newObjectId.ToHexString()); lines.Add(line); } //Log(lines); List <string> sendLines = lines; if (lines.Count > MAX_LINES) { sendLines = lines.Take(MAX_LINES).ToList(); sendLines.Add(String.Format("{0} more line(s) suppressed.", lines.Count - MAX_LINES)); } Task.Run(() => SendToBot(sendLines)); } timer.Stop(); //Log("Time spent in ProcessEvent: " + timer.Elapsed); } } catch (Exception ex) { Log(ex.Message); Log(ex.StackTrace); } return(EventNotificationStatus.ActionPermitted); }