private async Task HandleChanges(
            bool allowDeletion,
            PolicyHttpClient policyClient,
            Guid projectId,
            GitRepository repository,
            List <GitBranchStats> branches,
            IEnumerable <BranchPolicies> relevantPolicies,
            IEnumerable <PolicyConfiguration> serverPolicy,
            IEnumerable <PolicyType> types)
        {
            var handledServerPolicies = new List <int>();
            var resultList            = new List <Task>();

            foreach (var currentPolicy in relevantPolicies)
            {
                // Ignore exact branches not found on the repository
                if (string.IsNullOrEmpty(currentPolicy.Branch) ||
                    currentPolicy.Branch.Contains("*") ||
                    branches.Any(x => x.Name == currentPolicy.Branch))
                {
                    this.HandleBranchChanges(policyClient, projectId, repository, serverPolicy, types, handledServerPolicies, currentPolicy, resultList);
                }
                else
                {
                    this.Logger.Debug($"Policy branch ignored, because branch does not exist on the current repository. (Repository: {repository.Name}, Branch: {currentPolicy.Branch})");
                }
            }

            this.RemoveNoMatchServerPolicies(allowDeletion, policyClient, projectId, serverPolicy, handledServerPolicies);

            await Task.WhenAll(resultList).ConfigureAwait(false);
        }
Exemplo n.º 2
0
        public GitClient(Uri baseUrl, VssCredentials credentials)
        {
            var vssConnection = new VssConnection(baseUrl, credentials);

            this.client       = vssConnection.GetClient <GitHttpClient>();
            this.policyClient = new PolicyHttpClient(baseUrl, credentials);
        }
 /// <summary>
 /// Creates a policy in Azure DevOps.
 /// </summary>
 /// <param name="policyClient">Policy client</param>
 /// <param name="types">Types</param>
 /// <param name="projectId">Team project id</param>
 /// <param name="repository">Git repository</param>
 /// <param name="currentPolicy">Branch policy</param>
 /// <param name="policy">Policy</param>
 /// <returns>Task</returns>
 protected abstract Task CreatePolicy(
     PolicyHttpClient policyClient,
     IEnumerable <PolicyType> types,
     Guid projectId,
     GitRepository repository,
     BranchPolicies currentPolicy,
     Policy policy);
 /// <summary>
 /// Logs the change.
 /// </summary>
 /// <param name="policyClient">Policy client</param>
 /// <param name="types">Types</param>
 /// <param name="projectId">Team project id</param>
 /// <param name="repository">Git repository</param>
 /// <param name="currentPolicy">Branch policy</param>
 /// <param name="policy">Policy</param>
 /// <returns>Task</returns>
 #pragma warning disable 1998
 protected override async Task CreatePolicy(
     PolicyHttpClient policyClient,
     IEnumerable <PolicyType> types,
     Guid projectId,
     GitRepository repository,
     BranchPolicies currentPolicy,
     Policy policy)
 {
     this.Logger.Info($"Policy not found in Azure DevOps, would be created. (Repository: {repository.Name}, Branch: {currentPolicy.Branch}, Type: {policy.TypeString})");
     this.Logger.Debug($"Settings is: {policy.PrepareSettingsWithScopeAndSubType(repository.Id, policy)}");
 }
        private void HandleBranchChanges(
            PolicyHttpClient policyClient,
            Guid projectId,
            GitRepository repository,
            IEnumerable <PolicyConfiguration> serverPolicies,
            IEnumerable <PolicyType> types,
            List <int> handledServerPolicies,
            BranchPolicies currentPolicy,
            List <Task> resultList)
        {
            foreach (var policy in currentPolicy.Policies)
            {
                bool hasMatch = false;

                policy.PreparePolicyType(types);

                if (policy.PolicyType == null)
                {
                    this.Logger.Warn($"Type not found. (Branch: {currentPolicy.Branch}, Type: {policy.Type})");
                }

                if (serverPolicies != null)
                {
                    foreach (var serverPolicy in serverPolicies)
                    {
                        if (policy.PolicyType.Id == serverPolicy.Type.Id && serverPolicy.DoesSubTypeMatch(policy) &&
                            ((serverPolicy.GetBranch() == null) ||     // Repository specific
                             (serverPolicy.GetBranch() == policy.Branch && serverPolicy.GetMatchKind() == policy.MatchKind)))
                        {
                            hasMatch = true;
                            handledServerPolicies.Add(serverPolicy.Id);

                            if (policy.PolicyEquals(serverPolicy))
                            {
                                this.Logger.Info($"Policy is up to date. (Repository: {repository.Name}, Branch: {currentPolicy.Branch}, Type: {policy.TypeString})");
                            }
                            else
                            {
                                resultList.Add(this.UpdatePolicy(policyClient, types, projectId, repository, currentPolicy, policy, serverPolicy));
                            }

                            break;
                        }
                    }
                }

                if (!hasMatch)
                {
                    resultList.Add(this.CreatePolicy(policyClient, types, projectId, repository, currentPolicy, policy));
                }
            }
        }
        /// <summary>
        /// Creates a policy in Azure DevOps.
        /// </summary>
        /// <param name="policyClient">Policy client</param>
        /// <param name="types">Types</param>
        /// <param name="projectId">Team project id</param>
        /// <param name="repository">Git repository</param>
        /// <param name="currentPolicy">Branch policy</param>
        /// <param name="policy">Policy</param>
        /// <returns>Task</returns>
        protected override async Task CreatePolicy(
            PolicyHttpClient policyClient,
            IEnumerable <PolicyType> types,
            Guid projectId,
            GitRepository repository,
            BranchPolicies currentPolicy,
            Policy policy)
        {
            var policyConfiguration = this.GetPolicyConfiguration(types, repository, policy);
            var result = await policyClient.CreatePolicyConfigurationAsync(policyConfiguration, projectId).ConfigureAwait(false);

            this.Logger.Debug(this.Serializer.Serialize(result));
            this.Logger.Info($"Policy created. (Repository: {repository.Name}, Branch: {currentPolicy.Branch}, Type: {policy.TypeString})");
        }
        private void RemoveNoMatchServerPolicies(bool allowDeletion, PolicyHttpClient policyClient, Guid projectId, IEnumerable <PolicyConfiguration> serverPolicy, List <int> handledServerPolicies)
        {
            if (serverPolicy != null)
            {
                var removeables = serverPolicy.Where(x => handledServerPolicies.All(htp => x.Id != htp));

                foreach (var removeable in removeables)
                {
                    if (!allowDeletion)
                    {
                        this.Logger.Info($"Existing policy not defined. Skipping removal due to allowDeletion Flag. (Repository: {removeable.GetRepositoryId()}, Branch: {removeable.GetBranch()}, Type: {removeable.Type.DisplayName})");
                        continue;
                    }

                    this.DeletePolicy(policyClient, projectId, removeable);
                }
            }
        }
Exemplo n.º 8
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
            .AddJsonOptions(options => options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);
            services.AddDbContext <SaludsaContext>(options =>
                                                   options.UseSqlServer(
                                                       Configuration.GetConnectionString("DefaultConnection")));

            services.AddHealthChecks()
            .AddCheck("MyDatabase", new SqlConnectionHealthCheck(Configuration.GetConnectionString("DefaultConnection")));

            services.AddTransient <TimingHandler>();

            services.Replace(ServiceDescriptor.Singleton <IHttpMessageHandlerBuilderFilter, CustomLoggingFilter>());

            services.AddHttpClient <IPaisServicio, PaisServicio>(x => x.BaseAddress = new Uri("https://restcountries.eu/"))
            .AddHttpMessageHandler <TimingHandler>()
            .SetHandlerLifetime(TimeSpan.FromSeconds(10))
            .AddPolicyHandler(PolicyHttpClient.GetRetryPolicy())
            .AddPolicyHandler(PolicyHttpClient.GetCircuitBreakerPolicy());
        }
        /// <summary>
        /// Deletes a policy in Azure DevOps.
        /// </summary>
        /// <param name="policyClient">Policy client</param>
        /// <param name="projectId">Team project id</param>
        /// <param name="policy">Policy</param>
        protected override async void DeletePolicy(PolicyHttpClient policyClient, Guid projectId, PolicyConfiguration policy)
        {
            await policyClient.DeletePolicyConfigurationAsync(projectId, policy.Id).ConfigureAwait(false);

            this.Logger.Info($"Policy removed. (Repository: {policy.GetRepositoryId()}, Branch: {policy.GetBranch()}, Type: {policy.Type.DisplayName})");
        }
Exemplo n.º 10
0
        public async Task Check(string projectId, string repoId, int pullRequestId, Dictionary <string, string> args = null)
        {
            try
            {
                const string evaluationConfigurationType = "Build";
                string artifactId(string projectId, int pullRequestId) => $"vstfs:///CodeReview/CodeReviewId/{projectId}/{pullRequestId}";

                string buildUrl   = $"{_config.URL}/{_config.Collection}/{projectId}/_build";
                string statusName = (args != null) && args.TryGetValue("name", out string name) ? name : "CheckCodeCoverage";

                _logger.LogInformation($"[{nameof(Check)}] BEGIN {{pullRequestId:{pullRequestId}}}");

                GitHttpClient    gitClient    = _connection.GetClient <GitHttpClient>();
                PolicyHttpClient policyClient = _connection.GetClient <PolicyHttpClient>();

                // получить политики для ПР
                var evaluations = await policyClient.GetPolicyEvaluationsAsync(projectId, artifactId(projectId, pullRequestId));

                _logger.LogInformation($"[{nameof(Check)}] GetPolicyEvaluationsAsync(project:{projectId}, artifactId:{artifactId(projectId, pullRequestId)}) success: {{evaluations count:{evaluations.Count}}}");

                var policy = evaluations.FirstOrDefault(x => x.Configuration.Settings.TryGetValue("statusName", out JToken name) &&
                                                        name.ToString().Equals(statusName, StringComparison.OrdinalIgnoreCase));

                // Если у полученного PullRequest не найдена политика для правила с заданным именем, то не создаем статуса.
                if (policy == null)
                {
                    _logger.LogInformation($"[{nameof(Check)}] SKIPPED. Pullrequest({pullRequestId}) has no this policy");
                    return;
                }

                var evaluation = evaluations.FirstOrDefault(x => x.Configuration.Type.DisplayName.Equals(evaluationConfigurationType, StringComparison.OrdinalIgnoreCase));
                _logger.LogInformation($"[{nameof(Check)}] build evaluation: {JsonConvert.SerializeObject(evaluation)}");

                var    resState = GitStatusState.NotApplicable;
                string description;
                string targetUrl;

                switch (evaluation?.Status)
                {
                case PolicyEvaluationStatus.Running:
                case PolicyEvaluationStatus.Queued:
                case PolicyEvaluationStatus.Rejected:
                {
                    var buildId = evaluation.Context?.Value <int>("buildId");
                    resState    = GitStatusState.NotSet;
                    description = "Ожидаение успешной сборки";
                    targetUrl   = buildId != null ? $"{buildUrl}/results?buildId={buildId}&view=results" : null;
                    break;
                }

                case PolicyEvaluationStatus.Approved:
                {
                    var buildId = evaluation.Context.Value <int>("buildId");
                    var cover   = await GetCodeCoverageForBuild(projectId, buildId);

                    int quality = 0;
                    if (args != null && args.TryGetValue("quality", out string qualityStr) && (cover != null))
                    {
                        if (!int.TryParse(qualityStr, out quality))
                        {
                            _logger.LogWarning(message: $"[{nameof(Check)}] param \"Quality\"({qualityStr}) is not parse to int");
                        }
                        resState = (quality <= cover)
                                    ? GitStatusState.Succeeded
                                    : GitStatusState.Error;
                    }
                    else
                    {
                        resState = GitStatusState.Succeeded;
                    }

                    description = cover != null ? $"CodeCoverage = {cover:F2}%" : "CodeCoverage = (не определен)";
                    targetUrl   = $"{buildUrl}/results?buildId={buildId}&view=results";
                    break;
                }

                case PolicyEvaluationStatus.NotApplicable:
                default:
                    resState    = GitStatusState.Succeeded;
                    description = "CodeCoverage = (Build not used)";
                    targetUrl   = null;
                    break;
                }
                // New status
                var status = new GitPullRequestStatus()
                {
                    State       = resState,
                    Description = description,
                    TargetUrl   = targetUrl,
                    Context     = new GitStatusContext()
                    {
                        Name  = statusName,
                        Genre = "PullRequestCheckService"
                    }
                };
                _logger.LogInformation($"[{nameof(Check)}] created new status: " +
                                       $"{{pullRequestId:{pullRequestId}," +
                                       $"status:{{" +
                                       $"state:{status.State}," +
                                       $"description:{status.Description},context:{{name:{status.Context.Name},genre:{status.Context.Genre}}}" +
                                       $"}}" +
                                       $"}}");

                // set PR status
                var prStatus = await gitClient.CreatePullRequestStatusAsync(status, repoId, pullRequestId);

                _logger.LogInformation($"[{nameof(Check)}] CreatePullRequestStatusAsync(status:{status}, repositoryId:{repoId}, pullRequestId:{pullRequestId}) success: {JsonConvert.SerializeObject(prStatus)}");
            }
            catch (Exception e)
            {
                _logger.LogError($"Check FAILED: {e.ToString()}");
            }
            finally
            {
                _logger.LogInformation($"[{nameof(Check)}] COMPLETED");
            }
        }
 /// <summary>
 /// Deletes a policy in Azure DevOps.
 /// </summary>
 /// <param name="policyClient">Policy client</param>
 /// <param name="projectId">Team project id</param>
 /// <param name="policy">Policy</param>
 protected abstract void DeletePolicy(PolicyHttpClient policyClient, Guid projectId, PolicyConfiguration policy);
        #pragma warning restore 1998

        /// <summary>
        /// Logs the change.
        /// </summary>
        /// <param name="policyClient">Policy client</param>
        /// <param name="projectId">Team project id</param>
        /// <param name="policy">Policy</param>
        protected override void DeletePolicy(PolicyHttpClient policyClient, Guid projectId, PolicyConfiguration policy)
        {
            this.Logger.Info($"Policy not in the definition, would be removed from Azure DevOps. (Repository: {policy.GetRepositoryId()}, Branch: {policy.GetBranch()}, Type: {policy.Type.DisplayName})");
        }