Ejemplo n.º 1
1
        protected override IEnumerable<Notifications.INotification> CreateNotifications(IVssRequestContext requestContext, object notificationEventArgs, int maxLines)
        {
            var repositoryService = requestContext.GetService<ITeamFoundationGitRepositoryService>();
            var identityService = requestContext.GetService<ITeamFoundationIdentityService>();
            var commonService = requestContext.GetService<CommonStructureService>();
            var locationService = requestContext.GetService<ILocationService>();

            string baseUrl = String.Format("{0}/{1}/",
                        locationService.GetAccessMapping(requestContext, "PublicAccessMapping").AccessPoint,
                        requestContext.ServiceHost.Name);

            var gitNotification = notificationEventArgs as GitNotification;

            Notifications.RepositoryNotification notification = null;

            if (gitNotification is RepositoryCreatedNotification)
            {
                var ev = notificationEventArgs as RepositoryCreatedNotification;
                var identity = identityService.ReadIdentity(requestContext, IdentitySearchFactor.Identifier, ev.Creator.Identifier);

                notification = new Notifications.RepositoryCreatedNotification();
                notification.UniqueName = identity.UniqueName;
                notification.DisplayName = identity.DisplayName;
                notification.TeamNames = GetUserTeamsByProjectUri(requestContext, gitNotification.TeamProjectUri, identity.Descriptor);
                using (ITfsGitRepository repository = repositoryService.FindRepositoryById(requestContext, gitNotification.RepositoryId))
                {
                    notification.RepoUri = repository.GetRepositoryUri();
                    notification.RepoName = repository.Name;
                }
            }
            else if (gitNotification is RepositoryRenamedNotification)
            {
                notification = new Notifications.RepositoryRenamedNotification();
                notification.RepoName = gitNotification.RepositoryName;
                using (ITfsGitRepository repository = repositoryService.FindRepositoryById(requestContext, gitNotification.RepositoryId))
                {
                    notification.RepoUri = repository.GetRepositoryUri();
                    notification.RepoName = repository.Name;
                }
                notification.TeamNames = Enumerable.Empty<string>();
            }
            else if (gitNotification is RepositoryDeletedNotification)
            {
                var repoInfo = repositoryService
                    .QueryDeletedRepositories(requestContext, gitNotification.TeamProjectUri)
                    .Single(r => r.RepositoryId == gitNotification.RepositoryId);
                var identity = identityService.ReadIdentities(requestContext, new[] { repoInfo.DeletedBy }).First();
                notification = new Notifications.RepositoryDeletedNotification();
                notification.UniqueName = identity.UniqueName;
                notification.DisplayName = identity.DisplayName;
                notification.TeamNames = GetUserTeamsByProjectUri(requestContext, gitNotification.TeamProjectUri, identity.Descriptor);
                notification.RepoName = repoInfo.Name;
            }

            notification.TeamProjectCollection = requestContext.ServiceHost.Name;
            notification.ProjectName = commonService.GetProject(requestContext, gitNotification.TeamProjectUri).Name;
            notification.ProjectUrl = baseUrl + notification.ProjectName;

            yield return notification;
        }
Ejemplo n.º 2
0
        protected override IEnumerable <INotification> CreateNotifications(IVssRequestContext requestContext, BuildCompletionNotificationEvent buildNotification, int maxLines)
        {
            BuildDetail build           = buildNotification.Build;
            var         locationService = requestContext.GetService <ILocationService>();
            var         buildService    = requestContext.GetService <TeamFoundationBuildService>();

            using (var buildReader = buildService.QueryQueuedBuildsById(requestContext, build.QueueIds, new[] { "*" }, QueryOptions.None))
            {
                var         result   = buildReader.Current <BuildQueueQueryResult>();
                QueuedBuild qb       = result.QueuedBuilds.FirstOrDefault();
                string      buildUrl = string.Format("{0}/{1}/{2}/_build#_a=summary&buildId={3}",
                                                     locationService.GetAccessMapping(requestContext, "PublicAccessMapping").AccessPoint,
                                                     requestContext.ServiceHost.Name, build.TeamProject, qb.BuildId);

                var notification = new BuildCompletionNotification()
                {
                    TeamProjectCollection = requestContext.ServiceHost.Name,
                    BuildUrl                = buildUrl,
                    ProjectName             = build.TeamProject,
                    BuildNumber             = build.BuildNumber,
                    BuildStatus             = build.Status,
                    BuildReason             = build.Reason,
                    StartTime               = build.StartTime,
                    FinishTime              = build.FinishTime,
                    RequestedForUniqueName  = qb.RequestedFor,
                    RequestedForDisplayName = qb.RequestedForDisplayName,
                    BuildDefinition         = build.Definition.Name,
                    DropLocation            = build.DropLocation,
                    TeamNames               = GetUserTeamsByProjectName(requestContext, build.TeamProject, qb.RequestedFor)
                };

                yield return(notification);
            }
        }
        protected override IEnumerable <INotification> CreateNotifications(IVssRequestContext requestContext, ReleaseCreatedServerEvent ev, int maxLines)
        {
            var projectService  = requestContext.GetService <IProjectService>();
            var identityService = requestContext.GetService <ITeamFoundationIdentityService>();

            var release = ev.Release;
            var creator = identityService.ReadIdentities(requestContext, new[] { release.CreatedBy }).First();

            string projectName = projectService.GetProjectName(requestContext, ev.ProjectId);
            var    releaseUrl  = WebAccessUrlBuilder.GetReleaseWebAccessUri(requestContext, projectName, release.Id);

            var notification = new ReleaseCreatedNotification
            {
                TeamProjectCollection = requestContext.ServiceHost.Name,
                ProjectName           = projectName,
                ReleaseDefinition     = release.ReleaseDefinitionName,
                ReleaseName           = release.Name,
                ReleaseReason         = release.Reason,
                ReleaseStatus         = release.Status,
                ReleaseUrl            = releaseUrl,
                CreatedOn             = release.CreatedOn,
                CreatedByUniqueName   = creator.UniqueName,
                CreatedByDisplayName  = creator.DisplayName,
                TeamNames             = GetUserTeamsByProjectName(requestContext, projectName, creator.Descriptor)
            };

            yield return(notification);
        }
Ejemplo n.º 4
0
        protected override IEnumerable <INotification> CreateNotifications(IVssRequestContext requestContext, PolicyViolationEvent policyViolation, int maxLines)
        {
            var commonService   = requestContext.GetService <CommonStructureService>();
            var identityService = requestContext.GetService <ITeamFoundationIdentityService>();
            var identity        = identityService.ReadIdentity(requestContext, IdentitySearchFactor.Identifier, policyViolation.Identity.Identifier);

            var notification = new PolicyViolationNotification()
            {
                TeamProjectCollection = requestContext.ServiceHost.Name,
                ProjectName           = string.Empty,
                PolicyType            = policyViolation.PolicyType,
                Message     = policyViolation.Message,
                UniqueName  = identity.UniqueName,
                DisplayName = identity.DisplayName
            };

            var push = policyViolation.OriginalEvent as PushNotification;

            if (push != null)
            {
                notification.ProjectName = commonService.GetProject(requestContext, push.TeamProjectUri).Name;
            }


            yield return(notification);
        }
Ejemplo n.º 5
0
        protected override IEnumerable <Notifications.INotification> CreateNotifications(IVssRequestContext requestContext, object notificationEventArgs, int maxLines)
        {
            var repositoryService = requestContext.GetService <ITeamFoundationGitRepositoryService>();
            var identityService   = requestContext.GetService <ITeamFoundationIdentityService>();
            var commonService     = requestContext.GetService <CommonStructureService>();
            var locationService   = requestContext.GetService <ILocationService>();

            string baseUrl = String.Format("{0}/{1}/",
                                           locationService.GetAccessMapping(requestContext, "PublicAccessMapping").AccessPoint,
                                           requestContext.ServiceHost.Name);

            var gitNotification = notificationEventArgs as GitNotification;

            Notifications.RepositoryNotification notification = null;

            if (gitNotification is RepositoryCreatedNotification)
            {
                var ev       = notificationEventArgs as RepositoryCreatedNotification;
                var identity = identityService.ReadIdentity(requestContext, IdentitySearchFactor.Identifier, ev.Creator.Identifier);

                notification             = new Notifications.RepositoryCreatedNotification();
                notification.UniqueName  = identity.UniqueName;
                notification.DisplayName = identity.DisplayName;
                notification.TeamNames   = GetUserTeamsByProjectUri(requestContext, gitNotification.TeamProjectUri, identity.Descriptor);
                using (ITfsGitRepository repository = repositoryService.FindRepositoryById(requestContext, gitNotification.RepositoryId))
                {
                    notification.RepoUri  = repository.GetRepositoryUri();
                    notification.RepoName = repository.Name;
                }
            }
            else if (gitNotification is RepositoryRenamedNotification)
            {
                notification          = new Notifications.RepositoryRenamedNotification();
                notification.RepoName = gitNotification.RepositoryName;
                using (ITfsGitRepository repository = repositoryService.FindRepositoryById(requestContext, gitNotification.RepositoryId))
                {
                    notification.RepoUri  = repository.GetRepositoryUri();
                    notification.RepoName = repository.Name;
                }
                notification.TeamNames = Enumerable.Empty <string>();
            }
            else if (gitNotification is RepositoryDeletedNotification)
            {
                var repoInfo = repositoryService
                               .QueryDeletedRepositories(requestContext, gitNotification.TeamProjectUri)
                               .Single(r => r.RepositoryId == gitNotification.RepositoryId);
                var identity = identityService.ReadIdentities(requestContext, new[] { repoInfo.DeletedBy }).First();
                notification             = new Notifications.RepositoryDeletedNotification();
                notification.UniqueName  = identity.UniqueName;
                notification.DisplayName = identity.DisplayName;
                notification.TeamNames   = GetUserTeamsByProjectUri(requestContext, gitNotification.TeamProjectUri, identity.Descriptor);
                notification.RepoName    = repoInfo.Name;
            }

            notification.TeamProjectCollection = requestContext.ServiceHost.Name;
            notification.ProjectName           = commonService.GetProject(requestContext, gitNotification.TeamProjectUri).Name;
            notification.ProjectUrl            = baseUrl + notification.ProjectName;

            yield return(notification);
        }
Ejemplo n.º 6
0
        public Task NotifyAsync(IVssRequestContext requestContext, INotification notification, BotElement bot, EventRuleElement matchingRule)
        {
            if (!notification.TargetUserNames.Any())
            {
                return(Task.FromResult(0));
            }

            var    config             = TfsNotificationRelaySection.Instance;
            string host               = bot.GetSetting("host", "127.0.0.1");
            int    port               = bot.GetIntSetting("port", 25);
            string fromAddress        = bot.GetSetting("fromAddress");
            string fromName           = bot.GetSetting("fromName");
            string subjectTextId      = bot.GetSetting("subjectTextId", "plaintext");
            bool   isHtml             = bot.GetSetting("isHtml") == "true";
            var    subjectTextElement = config.Texts.FirstOrDefault(t => t.Id == subjectTextId) ?? bot.Text;
            string subject            = notification.ToMessage(bot, subjectTextElement, s => s).First();

            var client = new SmtpClient(host, port);

            var message = new MailMessage();

            message.From            = new MailAddress(fromAddress, fromName, Encoding.UTF8);
            message.SubjectEncoding = Encoding.UTF8;
            message.Subject         = subject;
            message.IsBodyHtml      = isHtml;
            message.BodyEncoding    = Encoding.UTF8;
            message.Body            = string.Join(isHtml ? "<br/>": "\n", notification.ToMessage(bot, s => s));

            var identityService = requestContext.GetService <ITeamFoundationIdentityService>();

            foreach (var username in notification.TargetUserNames)
            {
                var identity = identityService.ReadIdentity(requestContext, IdentitySearchFactor.AccountName, username);
                var email    = identityService.GetPreferredEmailAddress(requestContext, identity.TeamFoundationId);
                if (string.IsNullOrEmpty(email))
                {
                    string errmsg = $"TfsNotificationRelay.Smtp.SmtpNotifier: User {username} doesn't have an email address.";
                    TeamFoundationApplicationCore.Log(requestContext, errmsg, 0, EventLogEntryType.Warning);
                }
                else
                {
                    message.To.Add(email);
                }
            }

            if (message.To.Any())
            {
                requestContext.Trace(0, TraceLevel.Info, Constants.TraceArea, "SmtpNotifier",
                                     string.Format("Sending {0} email notification to: {1}.", notification.GetType(), string.Join(", ", message.To.Select(m => m.Address))));

                return(client.SendMailAsync(message));
            }
            else
            {
                requestContext.Trace(0, TraceLevel.Warning, Constants.TraceArea, "SmtpNotifier",
                                     string.Format("No recipients to send {0} email notification to.", notification.GetType()));

                return(Task.FromResult(0));
            }
        }
Ejemplo n.º 7
0
            internal Mailer(IVssRequestContext requestContext)
            {
                this.Enabled = false;
                try
                {
                    TeamFoundationRegistryService service = requestContext.GetService <TeamFoundationRegistryService>();
                    Microsoft.TeamFoundation.Framework.Server.RegistryEntryCollection registryEntryCollection = service.ReadEntriesFallThru(requestContext, FrameworkServerConstants.NotificationRootPath + "/*");
                    if (registryEntryCollection["EmailEnabled"].GetValue <bool>(true))
                    {
                        this.SmtpServer  = registryEntryCollection["SmtpServer"].GetValue(string.Empty);
                        this.SmtpPort    = registryEntryCollection["SmtpPort"].GetValue <int>(-1);
                        this.EnableSsl   = registryEntryCollection["SmtpEnableSsl"].GetValue <bool>(false);
                        this.FromAddress = null;

                        string value = registryEntryCollection["EmailNotificationFromAddress"].GetValue(string.Empty);
                        if (!string.IsNullOrEmpty(value) && !string.IsNullOrEmpty(this.SmtpServer))
                        {
                            this.FromAddress = new MailAddress(value);
                            this.Enabled     = true;
                        }
                    }
                }
                catch (System.Exception ex)
                {
                    System.Diagnostics.Debug.WriteLine($"SendMail failed: {ex.Message}");
                }
            }
Ejemplo n.º 8
0
 private static IVssRequestContext CreateServicingContext(IVssDeploymentServiceHost deploymentServiceHost, Guid instanceId)
 {
     using (IVssRequestContext requestContext = deploymentServiceHost.CreateSystemContext(true))
     {
         TeamFoundationHostManagementService host = requestContext.GetService <TeamFoundationHostManagementService>();
         return(host.BeginRequest(requestContext, instanceId, RequestContextType.ServicingContext));
     }
 }
Ejemplo n.º 9
0
        public Task NotifyAsync(IVssRequestContext requestContext, INotification notification, BotElement bot, EventRuleElement matchingRule)
        {
            if (!notification.TargetUserNames.Any())
                return Task.FromResult(0);

            var config = TfsNotificationRelaySection.Instance;
            string host = bot.GetSetting("host", "127.0.0.1");
            int port = bot.GetIntSetting("port", 25);
            string fromAddress = bot.GetSetting("fromAddress");
            string fromName = bot.GetSetting("fromName");
            string subjectTextId = bot.GetSetting("subjectTextId", "plaintext");
            bool isHtml = bot.GetSetting("isHtml") == "true";
            var subjectTextElement = config.Texts.FirstOrDefault(t => t.Id == subjectTextId) ?? bot.Text;
            string subject = notification.ToMessage(bot, subjectTextElement, s => s).First();

            var client = new SmtpClient(host, port);

            var message = new MailMessage();
            message.From = new MailAddress(fromAddress, fromName, Encoding.UTF8);
            message.SubjectEncoding = Encoding.UTF8;
            message.Subject = subject;
            message.IsBodyHtml = isHtml;
            message.BodyEncoding = Encoding.UTF8;
            message.Body = string.Join(isHtml ? "<br/>": "\n", notification.ToMessage(bot, s => s));

            var identityService = requestContext.GetService<ITeamFoundationIdentityService>();

            foreach (var username in notification.TargetUserNames)
            {
                var identity = identityService.ReadIdentity(requestContext, IdentitySearchFactor.AccountName, username);
                var email = identityService.GetPreferredEmailAddress(requestContext, identity.TeamFoundationId);
                if (string.IsNullOrEmpty(email))
                {
                    string errmsg = $"TfsNotificationRelay.Smtp.SmtpNotifier: User {username} doesn't have an email address.";
                    TeamFoundationApplicationCore.Log(requestContext, errmsg, 0, EventLogEntryType.Warning);
                }
                else
                {
                    message.To.Add(email);
                }
            }

            if (message.To.Any())
            {
                requestContext.Trace(0, TraceLevel.Info, Constants.TraceArea, "SmtpNotifier",
                    string.Format("Sending {0} email notification to: {1}.", notification.GetType(), string.Join(", ", message.To.Select(m => m.Address))));

                return client.SendMailAsync(message);
            }
            else
            {
                requestContext.Trace(0, TraceLevel.Warning, Constants.TraceArea, "SmtpNotifier",
                    string.Format("No recipients to send {0} email notification to.", notification.GetType()));

                return Task.FromResult(0);
            }
        }
Ejemplo n.º 10
0
        protected override IEnumerable <Notifications.INotification> CreateNotifications(IVssRequestContext requestContext, ReviewerVoteNotification ev, int maxLines)
        {
            var repositoryService = requestContext.GetService <ITeamFoundationGitRepositoryService>();
            var identityService   = requestContext.GetService <ITeamFoundationIdentityService>();
            var commonService     = requestContext.GetService <ICommonStructureService>();

            var identity = identityService.ReadIdentity(requestContext, IdentitySearchFactor.Identifier, ev.Reviewer.Descriptor.Identifier);

            using (ITfsGitRepository repository = repositoryService.FindRepositoryById(requestContext, ev.RepositoryId))
            {
                var pullRequestService = requestContext.GetService <ITeamFoundationGitPullRequestService>();
                TfsGitPullRequest pullRequest;
                if (pullRequestService.TryGetPullRequestDetails(requestContext, repository, ev.PullRequestId, out pullRequest))
                {
                    string repoUri      = repository.GetRepositoryUri();
                    var    creator      = identityService.ReadIdentities(requestContext, new[] { pullRequest.Creator }).First();
                    var    reviewers    = identityService.ReadIdentities(requestContext, pullRequest.Reviewers.Select(r => r.Reviewer).ToArray());
                    var    notification = new Notifications.PullRequestReviewerVoteNotification()
                    {
                        TeamProjectCollection = requestContext.ServiceHost.Name,
                        CreatorUniqueName     = creator.UniqueName,
                        Vote              = ev.ReviewerVote,
                        UniqueName        = identity.UniqueName,
                        DisplayName       = identity.DisplayName,
                        ProjectName       = commonService.GetProject(requestContext, ev.TeamProjectUri).Name,
                        RepoUri           = repoUri,
                        RepoName          = ev.RepositoryName,
                        PrId              = pullRequest.PullRequestId,
                        PrUrl             = $"{repoUri}/pullrequest/{ev.PullRequestId}#view=discussion",
                        PrTitle           = pullRequest.Title,
                        TeamNames         = GetUserTeamsByProjectUri(requestContext, ev.TeamProjectUri, ev.Reviewer.Descriptor),
                        SourceBranch      = new Notifications.GitRef(pullRequest.SourceBranchName),
                        TargetBranch      = new Notifications.GitRef(pullRequest.TargetBranchName),
                        ReviewerUserNames = reviewers.Select(r => r.UniqueName)
                    };
                    yield return(notification);
                }
                else
                {
                    throw new TfsNotificationRelayException("Unable to get pull request " + ev.PullRequestId);
                }
            }
        }
Ejemplo n.º 11
0
        protected override PolicyEvaluationResult Evaluate(IVssRequestContext requestContext, PushNotification notificationEventArgs)
        {
            var commonService = requestContext.GetService <ICommonStructureService>();
            var push          = (PushNotification)notificationEventArgs;
            var projectName   = commonService.GetProject(requestContext, push.TeamProjectUri).Name;

            if (projectName == "TestCompany")
            {
                return(new PolicyEvaluationResult(true));
            }

            return(EvaluateInternal(requestContext, notificationEventArgs));
        }
Ejemplo n.º 12
0
        protected override IEnumerable <INotification> CreateNotifications(IVssRequestContext requestContext, TFVC.CheckinNotification checkin, int maxLines)
        {
            var locationService = requestContext.GetService <ILocationService>();

            string baseUrl = String.Format("{0}/{1}/",
                                           locationService.GetAccessMapping(requestContext, "PublicAccessMapping").AccessPoint,
                                           requestContext.ServiceHost.Name);

            var teamNames = new HashSet <string>();
            var projects  = new Dictionary <string, string>();

            var submittedItems = checkin.GetSubmittedItems(requestContext).ToList();

            const string pattern = @"^\$\/([^\/]*)\/";

            foreach (string item in submittedItems)
            {
                Match match = Regex.Match(item, pattern);
                if (match.Success)
                {
                    string projectName = match.Groups[1].Value;
                    if (projects.ContainsKey(projectName))
                    {
                        continue;
                    }

                    string projectUrl = baseUrl + projectName;
                    projects.Add(projectName, projectUrl);

                    foreach (var team in GetUserTeamsByProjectName(requestContext, projectName, checkin.ChangesetOwner.Descriptor))
                    {
                        teamNames.Add(team);
                    }
                }
            }

            var notification = new CheckinNotification()
            {
                TeamProjectCollection = requestContext.ServiceHost.Name,
                UniqueName            = checkin.ChangesetOwner.UniqueName,
                DisplayName           = checkin.ChangesetOwner.DisplayName,
                ChangesetUrl          = $"{baseUrl}_versionControl/changeset/{checkin.Changeset}",
                ChangesetId           = checkin.Changeset,
                Projects       = projects,
                Comment        = TextHelper.Truncate(checkin.Comment, Settings.CommentMaxLength, true),
                TeamNames      = teamNames,
                SubmittedItems = submittedItems
            };

            yield return(notification);
        }
        public EventNotificationStatus ProcessEvent(
            IVssRequestContext requestContext,
            NotificationType notificationType,
            object notificationEventArgs,
            out int statusCode,
            out string statusMessage,
            out ExceptionPropertyCollection properties)
        {
            statusCode    = 0;
            statusMessage = string.Empty;
            properties    = null;

            if (notificationType == NotificationType.DecisionPoint && notificationEventArgs is PushNotification)
            {
                var pushNotification = notificationEventArgs as PushNotification;

                var repositoryService = requestContext.GetService <ITeamFoundationGitRepositoryService>();

                using (var gitRepository = repositoryService.FindRepositoryById(
                           requestContext,
                           pushNotification.RepositoryId))
                {
                    // TODO: gitRepository.Name should probably equal "Estream". Company wide TFS instance!
                    // TODO: Also, this name should not be hard coded and should be a collection.

                    foreach (var item in pushNotification.IncludedCommits)
                    {
                        var gitCommit = (TfsGitCommit)gitRepository.LookupObject(item);

                        var comment = gitCommit.GetComment(requestContext);

                        if (!CommitRules.IsCommitAcceptable(comment))
                        {
                            statusMessage =
                                $"Non-merge commits must contain links to TFS (i.e. #12345) [Repository Name: {gitRepository.Name}].";
                            return(EventNotificationStatus.ActionDenied);
                        }
                    }
                }
            }

            return(EventNotificationStatus.ActionApproved);
        }
Ejemplo n.º 14
0
        protected override IEnumerable <INotification> CreateNotifications(IVssRequestContext requestContext, ProjectCreatedEvent ev, int maxLines)
        {
            var locationService = requestContext.GetService <ILocationService>();

            string projectUrl = String.Format("{0}/{1}/{2}",
                                              locationService.GetAccessMapping(requestContext, "PublicAccessMapping").AccessPoint,
                                              requestContext.ServiceHost.Name,
                                              ev.Name);

            if (!ProjectsNames.ContainsKey(ev.Uri))
            {
                ProjectsNames.Add(ev.Uri, ev.Name);
            }

            yield return(new ProjectCreatedNotification()
            {
                TeamProjectCollection = requestContext.ServiceHost.Name, ProjectUrl = projectUrl, ProjectName = ev.Name
            });
        }
Ejemplo n.º 15
0
        private static void ProvisionProjectFeatures(IVssRequestContext context, Microsoft.TeamFoundation.WorkItemTracking.Client.Project project, StreamWriter logFile)
        {
            // Get the Feature provisioning service ("Configure Features")
            var projectFeatureProvisioningService = context.GetService <ProjectFeatureProvisioningService>();

            if (!projectFeatureProvisioningService.GetFeatures(context, project.Uri.ToString()).Where(f => (f.State == ProjectFeatureState.NotConfigured && !f.IsHidden)).Any())
            {
                // When the team project is already fully or partially configured, report it
                Console.WriteLine("\t{0}: Project is up to date.", project.Name);
                logFile.WriteLine(">>> Team Project is now already up to date");
            }
            else
            {
                // Find valid process templates
                var projectFeatureProvisioningDetails = projectFeatureProvisioningService.ValidateProcessTemplates(context, project.Uri.ToString());

                var validProcessTemplateDetails = projectFeatureProvisioningDetails.Where(d => d.IsValid);

                switch (validProcessTemplateDetails.Count())
                {
                case 0:
                    Console.WriteLine("\t{0}: No valid process templates found.", project.Name);
                    logFile.WriteLine(">>> No valid process templates found, the team project cannot be configured/upgraded automatically to adopt the latest features.");
                    break;

                case 1:
                    var projectFeatureProvisioningDetail = projectFeatureProvisioningDetails.ElementAt(0);
                    Console.WriteLine(">>> Upgrading Team Project with template " + projectFeatureProvisioningDetail.ProcessTemplateDescriptorName);
                    logFile.WriteLine(">>> Upgrading Team Project with template " + projectFeatureProvisioningDetail.ProcessTemplateDescriptorName);
                    ProvisionProject(context, project, projectFeatureProvisioningService, projectFeatureProvisioningDetail);
                    break;

                default:
                    // Try to upgrade using the recommended process template
                    var newRecommendedTemplate = validProcessTemplateDetails.FirstOrDefault(ptd => ptd.IsRecommended);
                    Console.WriteLine(">>> Multiple valid process templates found. Upgrading Team Project with recommended template " + newRecommendedTemplate.ProcessTemplateDescriptorName);
                    logFile.WriteLine(">>> Multiple valid process templates found. Upgrading Team Project with recommended template " + newRecommendedTemplate.ProcessTemplateDescriptorName);
                    ProvisionProject(context, project, projectFeatureProvisioningService, newRecommendedTemplate);
                    break;
                }
            }
        }
Ejemplo n.º 16
0
        protected override PolicyEvaluationResult EvaluateInternal(IVssRequestContext requestContext, PushNotification push)
        {
            var repositoryService = requestContext.GetService <ITeamFoundationGitRepositoryService>();

            var newBranches = push.RefUpdateResults.Where(r => r.OldObjectId == Sha1Id.Empty && r.Name.StartsWith(Constants.BranchPrefix));
            var branch      = newBranches.SingleOrDefault(b => b.Name == Constants.BranchPrefix + "master");

            if (branch != null)
            {
                using (ITfsGitRepository repository = repositoryService.FindRepositoryById(requestContext, push.RepositoryId))
                {
                    TfsGitCommit commit = (TfsGitCommit)repository.LookupObject(branch.NewObjectId);
                    if (commit != null)
                    {
                        var tree        = commit.GetTree();
                        var treeEntries = tree.GetTreeEntries();
                        if (treeEntries.Any())
                        {
                            bool includesGitignore     = false;
                            bool includesGitattributes = false;
                            foreach (var entry in treeEntries)
                            {
                                if (entry.ObjectType == GitObjectType.Blob && entry.Name.Equals(".gitignore", StringComparison.OrdinalIgnoreCase))
                                {
                                    includesGitignore = true;
                                }

                                if (entry.ObjectType == GitObjectType.Blob && entry.Name.Equals(".gitattributes", StringComparison.OrdinalIgnoreCase))
                                {
                                    using (var reader = new StreamReader(entry.Object.GetContent()))
                                    {
                                        var gitattributesContents = reader.ReadToEnd();
                                        // Make sure .gitattributes file has a '* text=auto' line for eol normalization
                                        if (!Regex.IsMatch(gitattributesContents, @"^\*\s+text=auto\s*$", RegexOptions.Multiline))
                                        {
                                            Logger.Log("pushNotification:", push);
                                            var statusMessage = $".gitattributes is missing '* text=auto'. See {Settings.DocsBaseUrl}/guidelines/scm/git-conventions/#mandatory-files.";
                                            Logger.Log(statusMessage);
                                            return(new PolicyEvaluationResult(false, push.Pusher, statusMessage));
                                        }

                                        includesGitattributes = true;
                                    }
                                }
                            }

                            if (!includesGitignore || !includesGitattributes)
                            {
                                Logger.Log("pushNotification:", push);
                                var statusMessage = $"Mandatory files missing. See {Settings.DocsBaseUrl}/guidelines/scm/git-conventions/#mandatory-files.";
                                Logger.Log(statusMessage);
                                return(new PolicyEvaluationResult(false, push.Pusher, statusMessage));
                            }
                        }
                        else
                        {
                            Logger.Log("Commit without tree entries: " + branch.NewObjectId);
                        }
                    }
                    else
                    {
                        Logger.Log("Unable to find commit " + branch.NewObjectId);
                    }
                }
            }

            return(new PolicyEvaluationResult(true));
        }
Ejemplo n.º 17
0
        protected override IEnumerable <INotification> CreateNotifications(IVssRequestContext 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 <ITeamFoundationGitRepositoryService>();
                    var commitService     = requestContext.GetService <ITeamFoundationGitCommitService>();

                    Guid   projectId;
                    Guid   repositoryId;
                    Sha1Id commitId;
                    GitCommitArtifactId.Decode(artifactId, out projectId, out repositoryId, out commitId);

                    using (ITfsGitRepository repository = repositoryService.FindRepositoryById(requestContext, repositoryId))
                    {
                        var    project   = commonService.GetProject(requestContext, projectId);
                        var    repoUri   = repository.GetRepositoryUri();
                        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 pushData       = commitService.GetPushDataForPushIds(requestContext, repository.RepoId.RepoId, new[] { commitManifest.PushId }).FirstOrDefault();
                        var pusher         = identityService.ReadIdentities(requestContext, new[] { pushData.PusherId }).FirstOrDefault();

                        foreach (var comment in thread.Comments)
                        {
                            var commenter = identityService.ReadIdentities(requestContext, new[] { Guid.Parse(comment.Author.Id) }).First();

                            var notification = new Notifications.CommitCommentNotification()
                            {
                                TeamProjectCollection = requestContext.ServiceHost.Name,
                                PusherUniqueName      = pusher?.UniqueName,
                                UniqueName            = commenter.UniqueName,
                                DisplayName           = comment.Author.DisplayName,
                                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);
                        }
                    }
                }
                if (artifactId.Tool.Equals("CodeReview", StringComparison.OrdinalIgnoreCase))
                {
                    var pullRequestService = requestContext.GetService <ITeamFoundationGitPullRequestService>();
                    var repositoryService  = requestContext.GetService <ITeamFoundationGitRepositoryService>();

                    Guid projectId;
                    int  pullRequestId = PullRequestArtifactHelper.GetPullRequestId(requestContext, thread.ArtifactUri, out projectId);

                    var pullRequest = pullRequestService.GetPullRequestDetails(requestContext, pullRequestId);

                    using (ITfsGitRepository repository = repositoryService.FindRepositoryById(requestContext, pullRequest.RepositoryId))
                    {
                        var    project = commonService.GetProject(requestContext, projectId);
                        string repoUri = repository.GetRepositoryUri();
                        var    creator = identityService.ReadIdentities(requestContext, new[] { pullRequest.Creator }).FirstOrDefault();

                        foreach (var comment in thread.Comments)
                        {
                            var commenter = identityService.ReadIdentities(requestContext, new[] { Guid.Parse(comment.Author.Id) }).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[] { Guid.Parse(comment.Author.Id) }).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);
        }
Ejemplo n.º 18
0
        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(IVssRequestContext requestContext, WorkItemChangedEvent ev, int maxLines)
        {
            var notifications = new List <INotification>();

            var identityService = requestContext.GetService <TeamFoundationIdentityService>();
            var identity        = identityService.ReadIdentity(requestContext, IdentitySearchFactor.Identifier, ev.ChangerSid);

            if (ev.CoreFields == null)
            {
                throw new TfsNotificationRelayException("ev.CoreFields is null");
            }
            if (ev.CoreFields.StringFields == null)
            {
                throw new TfsNotificationRelayException("ev.CoreFields.StringFields is null");
            }
            if (ev.CoreFields.IntegerFields == null)
            {
                throw new TfsNotificationRelayException("ev.CoreFields.IntegerFields is null");
            }

            var typeField = ev.CoreFields.StringFields.SingleOrDefault(f => f.ReferenceName == "System.WorkItemType");

            if (typeField == null)
            {
                throw new TfsNotificationRelayException("missing System.WorkItemType");
            }
            string type = typeField.NewValue;

            var idField = ev.CoreFields.IntegerFields.Single(f => f.ReferenceName == "System.Id");

            if (idField == null)
            {
                throw new TfsNotificationRelayException("missing System.Id");
            }
            int id = idField.NewValue;

            var    assignedToString     = ev.CoreFields.StringFields.GetFieldValue("System.AssignedTo", f => f.NewValue);
            string assignedToUniqueName = null;
            string assignedTo           = null;

            if (!string.IsNullOrEmpty(assignedToString))
            {
                UserField assignedToField = null;
                if (UserField.TryParse(assignedToString, out assignedToField) && assignedToField.Identifier != Guid.Empty)
                {
                    assignedTo = assignedToField.DisplayName;
                    var assignedToIdentity = identityService.ReadIdentities(requestContext, new[] { assignedToField.Identifier }).First();
                    assignedToUniqueName = assignedToIdentity.UniqueName;
                }
            }

            var teamNames = GetUserTeamsByProjectUri(requestContext, ev.ProjectNodeId, identity.Descriptor).ToList();

            var comment = ev.TextFields?.FirstOrDefault(f => f.ReferenceName == "System.History" && !string.IsNullOrEmpty(f.Value));

            if (comment != null)
            {
                var commentNotification = new WorkItemCommentNotification()
                {
                    TeamProjectCollection = requestContext.ServiceHost.Name,
                    UniqueName            = identity.UniqueName,
                    DisplayName           = identity.DisplayName,
                    WiUrl                = ev.DisplayUrl,
                    WiType               = type,
                    WiId                 = id,
                    WiTitle              = ev.WorkItemTitle,
                    ProjectName          = ev.PortfolioProject,
                    AreaPath             = ev.AreaPath,
                    AssignedTo           = assignedTo,
                    AssignedToUniqueName = assignedToUniqueName,
                    CommentHtml          = comment.Value,
                    Comment              = TextHelper.HtmlToText(comment.Value),
                    TeamNames            = teamNames
                };

                notifications.Add(commentNotification);
            }

            var changeNotification = new WorkItemChangedNotification()
            {
                TeamProjectCollection = requestContext.ServiceHost.Name,
                IsNew                = ev.ChangeType == ChangeTypes.New,
                UniqueName           = identity.UniqueName,
                DisplayName          = identity.DisplayName,
                WiUrl                = ev.DisplayUrl,
                WiType               = type,
                WiId                 = id,
                WiTitle              = ev.WorkItemTitle,
                ProjectName          = ev.PortfolioProject,
                AreaPath             = ev.AreaPath,
                IsStateChanged       = ev.ChangedFields?.StringFields?.Any(f => f.ReferenceName == "System.State") ?? false,
                IsAssignmentChanged  = ev.ChangedFields?.StringFields?.Any(f => f.ReferenceName == "System.AssignedTo") ?? false,
                State                = ev.CoreFields.StringFields.GetFieldValue("System.State", f => f.NewValue),
                AssignedTo           = assignedTo,
                AssignedToUniqueName = assignedToUniqueName,
                CoreFields           = ev.CoreFields,
                ChangedFields        = ev.ChangedFields,
                TeamNames            = teamNames
            };

            notifications.Add(changeNotification);

            return(notifications);
        }