Esempio n. 1
0
    internal static async Task <BuildTestInfoCollection> ListBuildTestInfosAsync(this DotNetQueryUtil queryUtil, BuildSearchOptionSet optionSet, bool includeAllTests = false)
    {
        TestOutcome[]? outcomes = includeAllTests
            ? null
            : new[] { TestOutcome.Failed };

        var list = new List <BuildTestInfo>();

        foreach (var build in await queryUtil.ListBuildsAsync(optionSet).ConfigureAwait(false))
        {
            try
            {
                var collection = await DotNetUtil.ListDotNetTestRunsAsync(queryUtil.Server, build, outcomes);

                var buildTestInfo = new BuildTestInfo(build, collection.SelectMany(x => x.TestCaseResults).ToList());
                list.Add(buildTestInfo);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Cannot get test info for {build.Id} {DevOpsUtil.GetBuildUri(build)}");
                Console.WriteLine(ex.Message);
            }
        }

        return(new BuildTestInfoCollection(new ReadOnlyCollection <BuildTestInfo>(list)));
    }
Esempio n. 2
0
        public void AddFlatError(Expression <Func <string> > resourceExpression, params object[] parm)
        {
            var err = new ParserError()
            {
                Message    = DotNetUtil.Msg(resourceExpression, parm),
                ErrorPoint = TextBuffer.NotValidPtr
            };

            AddError(err);
        }
Esempio n. 3
0
        public void AddException(Exception e, Expression <Func <string> > resourceExpression, params object[] parm)
        {
            string error = DotNetUtil.Msg(resourceExpression, parm);
            var    err   = new ParserError();
            string s     = _textBuffer.GetLineAndColumn(out err.Line, out err.Column);

            err.Message    = error + " " + s;
            err.ErrorPoint = _textBuffer.PointerNextChar;
            err.Ex         = e;

            AddError(err);
        }
Esempio n. 4
0
        public void AddBuildError(Expression <Func <string> > resourceExpression, CodeElement elem, params object[] parm)
        {
            string error = DotNetUtil.Msg(resourceExpression, parm);
            var    err   = new ParserError();
            string s     = string.Empty;

            if (elem != null)
            {
                err.ErrorPoint = elem.SubString.From;
                s = " " + _textBuffer.GetLineAndColumn(out err.Line, out err.Column, err.ErrorPoint);
            }
            err.Message = error + s;

            AddError(err);
        }
Esempio n. 5
0
        /// <summary>Add an error from parserElement.</summary>
        /// <param name="element"></param>
        /// <param name="errorPoint"></param>
        /// <param name="wordCount"></param>
        /// <param name="resourceExpression"></param>
        /// <param name="parm"></param>
        /// <returns>Always false.</returns>
        public bool AddSyntaxError(ParserElementBase element, int errorPoint, int wordCount, Expression <Func <string> > resourceExpression, params object[] parm)
        {
            string error = DotNetUtil.Msg(resourceExpression, parm.Insert(element.GetRule(element).Name));
            //            AddSyntaxError( element,  errorPoint,  wordCount,  error);
            var err = new ParserError();

            err.WordCount  = 0;
            err.ErrorPoint = errorPoint;
            err.Error      = error;

            string s = _textBuffer.GetLineAndColumn(out err.Line, out err.Column, errorPoint);

            err.Message = error + " " + s;

            AddError(err);
            return(false);
        }
Esempio n. 6
0
        internal static async Task <List <Build> > ListBuildsAsync(this DotNetQueryUtil queryUtil, BuildSearchOptionSet optionSet)
        {
            if (optionSet.BuildIds.Count > 0 && optionSet.Definitions.Count > 0)
            {
                OptionFailure("Cannot specify builds and definitions", optionSet);
                throw CreateBadOptionException();
            }

            var searchCount = optionSet.SearchCount ?? BuildSearchOptionSet.DefaultSearchCount;
            var repository  = optionSet.Repository;
            var branch      = optionSet.Branch;
            var before      = optionSet.Before;
            var after       = optionSet.After;

            if (branch is object && !branch.StartsWith("refs"))
            {
                branch = $"refs/heads/{branch}";
            }

            var builds = new List <Build>();

            if (optionSet.BuildIds.Count > 0)
            {
                if (optionSet.Repository is object)
                {
                    OptionFailure("Cannot specify builds and repository", optionSet);
                    throw CreateBadOptionException();
                }

                if (optionSet.Branch is object)
                {
                    OptionFailure("Cannot specify builds and branch", optionSet);
                    throw CreateBadOptionException();
                }

                if (optionSet.SearchCount is object)
                {
                    OptionFailure("Cannot specify builds and count", optionSet);
                    throw CreateBadOptionException();
                }

                foreach (var buildInfo in optionSet.BuildIds)
                {
                    if (!TryGetBuildId(optionSet, buildInfo, out var buildProject, out var buildId))
                    {
                        OptionFailure($"Cannot convert {buildInfo} to build id", optionSet);
                        throw CreateBadOptionException();
                    }

                    var build = await queryUtil.Server.GetBuildAsync(buildProject, buildId).ConfigureAwait(false);

                    builds.Add(build);
                }
            }
            else
            {
                var(project, definitions) = GetProjectAndDefinitions();
                var collection = await queryUtil.ListBuildsAsync(
                    searchCount,
                    project,
                    definitions : definitions,
                    repositoryId : repository,
                    branch : branch,
                    includePullRequests : optionSet.IncludePullRequests,
                    before : optionSet.Before,
                    after : optionSet.After);

                builds.AddRange(collection);
            }

            // Exclude out the builds that are complicating results
            foreach (var excludedBuildId in optionSet.ExcludedBuildIds)
            {
                builds = builds.Where(x => x.Id != excludedBuildId).ToList();
            }

            return(builds);

            (string Project, int[] Definitions) GetProjectAndDefinitions()
            {
                if (optionSet.Definitions.Count == 0)
                {
                    return(optionSet.Project ?? DotNetUtil.DefaultAzureProject, Array.Empty <int>());
                }

                string?project = null;
                var    list    = new List <int>();

                foreach (var definition in optionSet.Definitions)
                {
                    if (!DotNetUtil.TryGetDefinitionId(definition, out var definitionProject, out var definitionId))
                    {
                        OptionFailureDefinition(definition, optionSet);
                        throw CreateBadOptionException();
                    }

                    if (definitionProject is object)
                    {
                        if (project is null)
                        {
                            project = definitionProject;
                        }
                        else if (!StringComparer.OrdinalIgnoreCase.Equals(definitionProject, project))
                        {
                            throw new InvalidOperationException($"Conflicting project names {project} and {definitionProject}");
                        }
                    }

                    list.Add(definitionId);
                }

                project ??= DotNetUtil.DefaultAzureProject;
                return(project, list.ToArray());
            }
Esempio n. 7
0
        public async Task <string> GetStatusIssueTextAsync(IGitHubClient gitHubClient)
        {
            var header = new StringBuilder();
            var body   = new StringBuilder();
            var footer = new StringBuilder();

            header.AppendLine("## Overview");
            header.AppendLine("Please use these queries to discover issues");

            await BuildOne("Blocking CI", "blocking-clean-ci", DotNetUtil.GetDefinitionKeyFromFriendlyName("runtime")).ConfigureAwait(false);
            await BuildOne("Blocking Official Build", "blocking-official-build", DotNetUtil.GetDefinitionKeyFromFriendlyName("runtime-official")).ConfigureAwait(false);
            await BuildOne("Blocking CI Optional", "blocking-clean-ci-optional", DotNetUtil.GetDefinitionKeyFromFriendlyName("runtime"));
            await BuildOne("Blocking Outerloop", "blocking-outerloop", null);

            // Blank line to move past the table
            header.AppendLine("");
            BuildFooter();

            return(header.ToString() + body.ToString() + footer.ToString());

            void BuildFooter()
            {
                footer.AppendLine(@"## Goals

1. A minimum 95% passing rate for the `runtime` pipeline

## Resources

1. [runtime pipeline analytics](https://dnceng.visualstudio.com/public/_build?definitionId=686&view=ms.vss-pipelineanalytics-web.new-build-definition-pipeline-analytics-view-cardmetrics)");
            }

            async Task BuildOne(string title, string label, DefinitionKey?definitionKey)
            {
                header.AppendLine($"- [{title}](https://github.com/dotnet/runtime/issues?q=is%3Aopen+is%3Aissue+label%3A{label})");

                body.AppendLine($"## {title}");
                body.AppendLine("|Status|Issue|Build Count|");
                body.AppendLine("|---|---|---|");

                var query = (await DoSearchAsync(gitHubClient, label).ConfigureAwait(false))
                            .OrderByDescending(x => x.Count);

                foreach (var(issue, count) in query)
                {
                    var emoji = issue.Labels.Any(x => x.Name == "intermittent")
                        ? ":warning:"
                        : ":fire:";
                    var titleLimit = 75;
                    var issueText  = issue.Title.Length >= titleLimit
                        ? issue.Title.Substring(0, titleLimit - 5) + " ..."
                        : issue.Title;

                    var issueEntry = $"[{issueText}]({issue.HtmlUrl})";
                    var countStr   = count.HasValue ? count.ToString() : "N/A";

                    body.AppendLine($"|{emoji}|{issueEntry}|{countStr}|");
                }
            }

            async Task <List <(Octokit.Issue Issue, int?Count)> > DoSearchAsync(IGitHubClient gitHubClient, string label)
            {
                var request = new SearchIssuesRequest()
                {
                    Labels = new [] { label },
                    State  = ItemState.Open,
                    Type   = IssueTypeQualifier.Issue,
                    Repos  = { { "dotnet", "runtime" } },
                };
                var result = await gitHubClient.Search.SearchIssues(request).ConfigureAwait(false);

                var list = new List <(Octokit.Issue Issue, int?Count)>();

                foreach (var issue in result.Items)
                {
                    var count = await GetImpactedBuildsCountAsync(issue.GetIssueKey()).ConfigureAwait(false);

                    list.Add((issue, count));
                }
                return(list);
            }

            async Task <int?> GetImpactedBuildsCountAsync(GitHubIssueKey issueKey)
            {
                var modelTrackingIssue = await TriageContextUtil
                                         .GetModelTrackingIssuesQuery(issueKey)
                                         .FirstOrDefaultAsync()
                                         .ConfigureAwait(false);

                if (modelTrackingIssue is null)
                {
                    return(null);
                }

                var count = await Context
                            .ModelTrackingIssueResults
                            .Where(x => x.IsPresent && x.ModelTrackingIssueId == modelTrackingIssue.Id)
                            .CountAsync()
                            .ConfigureAwait(false);

                return(count);;
            }
        }
Esempio n. 8
0
        public static string BuildMsg(int line, int col, Expression <Func <string> > resourceExpression, params object[] parm)
        {
            string pos = (line > 0) ? " " + string.Format(MessageRes.LineAndCol, line, col) : string.Empty;

            return(DotNetUtil.Msg(resourceExpression, parm) + pos);
        }
Esempio n. 9
0
 /// <summary>Raise PropertyChanged when a property is changed.</summary>
 /// <param name="exp">Lambda expression. Feks ()=>PropertyName.</param>
 protected void RaisePropertyChanged(Expression <Func <object> > exp)
 {
     RaisePropertyChanged(DotNetUtil.GetMemberName(exp));
 }
Esempio n. 10
0
        public async Task UpdateStatusIssue()
        {
            var header = new StringBuilder();
            var body   = new StringBuilder();
            var footer = new StringBuilder();

            header.AppendLine("## Overview");
            header.AppendLine("Please use this queries to discover issues");

            await BuildOne("Blocking CI", "blocking-clean-ci", DotNetUtil.GetBuildDefinitionKeyFromFriendlyName("runtime"));
            await BuildOne("Blocking Official Build", "blocking-official-build", DotNetUtil.GetBuildDefinitionKeyFromFriendlyName("runtime-official"));
            await BuildOne("Blocking CI Optional", "blocking-clean-ci-optional", DotNetUtil.GetBuildDefinitionKeyFromFriendlyName("runtime"));
            await BuildOne("Blocking Outerloop", "blocking-outerloop", null);

            // Blank line to move past the table
            header.AppendLine("");
            BuildFooter();

            await UpdateIssue();

            void BuildFooter()
            {
                footer.AppendLine(@"## Goals

1. A minimum 95% passing rate for the `runtime` pipeline

## Resources

1. [runtime pipeline analytics](https://dnceng.visualstudio.com/public/_build?definitionId=686&view=ms.vss-pipelineanalytics-web.new-build-definition-pipeline-analytics-view-cardmetrics)");
            }

            async Task BuildOne(string title, string label, BuildDefinitionKey?definitionKey)
            {
                header.AppendLine($"- [{title}](https://github.com/dotnet/runtime/issues?q=is%3Aopen+is%3Aissue+label%3A{label})");

                body.AppendLine($"## {title}");
                body.AppendLine("|Status|Issue|Build Count|");
                body.AppendLine("|---|---|---|");

                var query = (await DoSearch(label))
                            .Select(x =>
                {
                    var issueKey = x.GetIssueKey();
                    var count    = definitionKey.HasValue
                                ? GetImpactedBuildsCount(issueKey, definitionKey.Value)
                                : null;

                    return(x, Count: count);
                })
                            .OrderByDescending(x => x.Count);

                foreach (var(issue, count) in query)
                {
                    var emoji = issue.Labels.Any(x => x.Name == "intermittent")
                        ? ":warning:"
                        : ":fire:";
                    var titleLimit = 75;
                    var issueText  = issue.Title.Length >= titleLimit
                        ? issue.Title.Substring(0, titleLimit - 5) + " ..."
                        : issue.Title;

                    var issueEntry = $"[{issueText}]({issue.HtmlUrl})";
                    var countStr   = count.HasValue ? count.ToString() : "N/A";

                    body.AppendLine($"|{emoji}|{issueEntry}|{countStr}|");
                }
            }

            async Task <List <Octokit.Issue> > DoSearch(string label)
            {
                var request = new SearchIssuesRequest()
                {
                    Labels = new [] { label },
                    State  = ItemState.Open,
                    Type   = IssueTypeQualifier.Issue,
                    Repos  = { { "dotnet", "runtime" } },
                };
                var result = await GitHubClient.Search.SearchIssues(request);

                return(result.Items.ToList());
            }

            async Task UpdateIssue()
            {
                var issueKey    = new GitHubIssueKey("dotnet", "runtime", 702);
                var issueClient = GitHubClient.Issue;
                var issue       = await issueClient.Get(issueKey.Organization, issueKey.Repository, issueKey.Number);

                var updateIssue = issue.ToUpdate();

                updateIssue.Body = header.ToString() + body.ToString() + footer.ToString();
                await GitHubClient.Issue.Update(issueKey.Organization, issueKey.Repository, issueKey.Number, updateIssue);
            }

            int?GetImpactedBuildsCount(GitHubIssueKey issueKey, BuildDefinitionKey definitionKey)
            {
                if (!TriageContextUtil.TryGetTimelineQuery(issueKey, out var timelineQuery))
                {
                    return(null);
                }

                // TODO: need to be able to filter to the repo the build ran against
                var count = Context.ModelTimelineItems
                            .Include(x => x.ModelBuild)
                            .ThenInclude(x => x.ModelBuildDefinition)
                            .Where(x =>
                                   x.ModelTimelineQueryId == timelineQuery.Id &&
                                   x.ModelBuild.ModelBuildDefinition.AzureOrganization == definitionKey.Organization &&
                                   x.ModelBuild.ModelBuildDefinition.AzureProject == definitionKey.Project &&
                                   x.ModelBuild.ModelBuildDefinition.DefinitionId == definitionKey.Id)
                            .Count();

                return(count);;
            }
        }