示例#1
0
        private async Task QueueBuildForStaleImages(Subscription subscription, IEnumerable <string> pathsToRebuild)
        {
            if (!pathsToRebuild.Any())
            {
                this.loggerService.WriteMessage($"All images for subscription '{subscription}' are using up-to-date base images. No rebuild necessary.");
                return;
            }

            string formattedPathsToRebuild = pathsToRebuild
                                             .Select(path => $"{ManifestFilterOptions.FormattedPathOption} '{path}'")
                                             .Aggregate((p1, p2) => $"{p1} {p2}");

            string parameters = "{\"" + subscription.PipelineTrigger.PathVariable + "\": \"" + formattedPathsToRebuild + "\"}";

            this.loggerService.WriteMessage($"Queueing build for subscription {subscription} with parameters {parameters}.");

            if (Options.IsDryRun)
            {
                return;
            }

            using (IVssConnection connection = this.connectionFactory.Create(
                       new Uri($"https://dev.azure.com/{Options.BuildOrganization}"),
                       new VssBasicCredential(String.Empty, Options.BuildPersonalAccessToken)))
                using (IProjectHttpClient projectHttpClient = connection.GetProjectHttpClient())
                    using (IBuildHttpClient client = connection.GetBuildHttpClient())
                    {
                        TeamProject project = await projectHttpClient.GetProjectAsync(Options.BuildProject);

                        Build build = new Build
                        {
                            Project = new TeamProjectReference {
                                Id = project.Id
                            },
                            Definition = new BuildDefinitionReference {
                                Id = subscription.PipelineTrigger.Id
                            },
                            SourceBranch = subscription.RepoInfo.Branch,
                            Parameters   = parameters
                        };

                        if (await HasInProgressBuildAsync(client, subscription.PipelineTrigger.Id, project.Id))
                        {
                            this.loggerService.WriteMessage(
                                $"An in-progress build was detected on the pipeline for subscription '{subscription.ToString()}'. Queueing the build will be skipped.");
                            return;
                        }

                        await client.QueueBuildAsync(build);
                    }
        }
示例#2
0
        private async Task QueueBuildForStaleImages(Subscription subscription, IEnumerable <string> pathsToRebuild)
        {
            if (!pathsToRebuild.Any())
            {
                _loggerService.WriteMessage($"All images for subscription '{subscription}' are using up-to-date base images. No rebuild necessary.");
                return;
            }

            string formattedPathsToRebuild = pathsToRebuild
                                             .Select(path => $"{ManifestFilterOptions.FormattedPathOption} '{path}'")
                                             .Aggregate((p1, p2) => $"{p1} {p2}");

            string parameters = "{\"" + subscription.PipelineTrigger.PathVariable + "\": \"" + formattedPathsToRebuild + "\"}";

            _loggerService.WriteMessage($"Queueing build for subscription {subscription} with parameters {parameters}.");

            if (Options.IsDryRun)
            {
                return;
            }

            (Uri baseUrl, VssCredentials credentials) = Options.AzdoOptions.GetConnectionDetails();

            using (IVssConnection connection = _connectionFactory.Create(baseUrl, credentials))
                using (IProjectHttpClient projectHttpClient = connection.GetProjectHttpClient())
                    using (IBuildHttpClient client = connection.GetBuildHttpClient())
                    {
                        TeamProject project = await projectHttpClient.GetProjectAsync(Options.AzdoOptions.Project);

                        Build build = new Build
                        {
                            Project = new TeamProjectReference {
                                Id = project.Id
                            },
                            Definition = new BuildDefinitionReference {
                                Id = subscription.PipelineTrigger.Id
                            },
                            SourceBranch = subscription.Manifest.Branch,
                            Parameters   = parameters
                        };

                        if (await HasInProgressBuildAsync(client, subscription.PipelineTrigger.Id, project.Id))
                        {
                            _loggerService.WriteMessage(
                                $"An in-progress build was detected on the pipeline for subscription '{subscription}'. Queueing the build will be skipped.");
                            return;
                        }

                        await client.QueueBuildAsync(build);
                    }
        }
示例#3
0
        private async Task QueueBuildForStaleImages(Subscription subscription, IEnumerable <string> pathsToRebuild)
        {
            if (!pathsToRebuild.Any())
            {
                _loggerService.WriteMessage($"All images for subscription '{subscription}' are using up-to-date base images. No rebuild necessary.");
                return;
            }

            string formattedPathsToRebuild = pathsToRebuild
                                             .Select(path => $"{CliHelper.FormatAlias(ManifestFilterOptionsBuilder.PathOptionName)} '{path}'")
                                             .Aggregate((p1, p2) => $"{p1} {p2}");

            string parameters = "{\"" + subscription.PipelineTrigger.PathVariable + "\": \"" + formattedPathsToRebuild + "\"}";

            _loggerService.WriteMessage($"Queueing build for subscription {subscription} with parameters {parameters}.");

            if (Options.IsDryRun)
            {
                return;
            }

            WebApi.Build?        queuedBuild        = null;
            Exception?           exception          = null;
            IEnumerable <string>?inProgressBuilds   = null;
            IEnumerable <string>?recentFailedBuilds = null;

            try
            {
                (Uri baseUrl, VssCredentials credentials) = Options.AzdoOptions.GetConnectionDetails();

                using (IVssConnection connection = _connectionFactory.Create(baseUrl, credentials))
                    using (IProjectHttpClient projectHttpClient = connection.GetProjectHttpClient())
                        using (IBuildHttpClient client = connection.GetBuildHttpClient())
                        {
                            TeamProject project = await projectHttpClient.GetProjectAsync(Options.AzdoOptions.Project);

                            WebApi.Build build = new()
                            {
                                Project = new TeamProjectReference {
                                    Id = project.Id
                                },
                                Definition = new WebApi.BuildDefinitionReference {
                                    Id = subscription.PipelineTrigger.Id
                                },
                                SourceBranch = subscription.Manifest.Branch,
                                Parameters   = parameters
                            };

                            inProgressBuilds = await GetInProgressBuildsAsync(client, subscription.PipelineTrigger.Id, project.Id);

                            if (!inProgressBuilds.Any())
                            {
                                (bool shouldDisallowBuild, IEnumerable <string> recentFailedBuildsLocal) =
                                    await ShouldDisallowBuildDueToRecentFailuresAsync(client, subscription.PipelineTrigger.Id, project.Id);

                                recentFailedBuilds = recentFailedBuildsLocal;
                                if (shouldDisallowBuild)
                                {
                                    _loggerService.WriteMessage(
                                        PipelineHelper.FormatErrorCommand("Unable to queue build due to too many recent build failures."));
                                }
                                else
                                {
                                    queuedBuild = await client.QueueBuildAsync(build);

                                    await client.AddBuildTagAsync(project.Id, queuedBuild.Id, AzdoTags.AutoBuilder);
                                }
                            }
                        }
            }
            catch (Exception ex)
            {
                exception = ex;
                throw;
            }
            finally
            {
                await LogAndNotifyResultsAsync(
                    subscription, pathsToRebuild, queuedBuild, exception, inProgressBuilds, recentFailedBuilds);
            }
        }
        public override async Task ExecuteAsync()
        {
            StringBuilder notificationMarkdown           = new();
            string        buildUrl                       = string.Empty;
            Dictionary <string, TaskResult?> taskResults = Options.TaskNames
                                                           .ToDictionary(name => name, name => (TaskResult?)null);
            Dictionary <string, string> buildParameters = new();
            BuildResult overallResult = BuildResult.Succeeded;
            BuildReason buildReason   = BuildReason.None;
            string?     correlatedQueueNotificationUrl = null;

            if (!Options.IsDryRun)
            {
                (Uri baseUrl, VssCredentials credentials) = Options.AzdoOptions.GetConnectionDetails();
                using (IVssConnection connection = _connectionFactory.Create(baseUrl, credentials))
                    using (IProjectHttpClient projectHttpClient = connection.GetProjectHttpClient())
                        using (IBuildHttpClient buildClient = connection.GetBuildHttpClient())
                        {
                            TeamProject project = await projectHttpClient.GetProjectAsync(Options.AzdoOptions.Project);

                            TeamFoundation.Build.WebApi.Build build = await buildClient.GetBuildAsync(project.Id, Options.BuildId);

                            buildUrl    = build.GetWebLink();
                            buildReason = build.Reason;

                            // Get the build's queue-time parameters
                            if (build.Parameters is not null)
                            {
                                JObject parametersJson = JsonConvert.DeserializeObject <JObject>(build.Parameters);
                                foreach (KeyValuePair <string, JToken?> pair in parametersJson)
                                {
                                    buildParameters.Add(pair.Key, pair.Value?.ToString() ?? string.Empty);
                                }
                            }

                            overallResult = await GetBuildTaskResultsAsync(taskResults, buildClient, project);

                            correlatedQueueNotificationUrl = await GetCorrelatedQueueNotificationUrlAsync();
                        }
            }

            notificationMarkdown.AppendLine($"# Publish Results");
            notificationMarkdown.AppendLine();

            WriteSummaryMarkdown(notificationMarkdown, buildUrl, overallResult, buildReason, correlatedQueueNotificationUrl);
            notificationMarkdown.AppendLine();

            WriteTaskStatusesMarkdown(taskResults, notificationMarkdown);
            notificationMarkdown.AppendLine();

            WriteBuildParameters(buildParameters, notificationMarkdown);
            notificationMarkdown.AppendLine();

            WriteImagesMarkdown(notificationMarkdown);

            await _notificationService.PostAsync(
                $"Publish Result - {Options.SourceRepo}/{Options.SourceBranch}",
                notificationMarkdown.ToString(),
                new string[]
            {
                NotificationLabels.Publish,
                NotificationLabels.GetRepoLocationLabel(Options.SourceRepo, Options.SourceBranch)
            }.AppendIf(NotificationLabels.Failure, () => overallResult == BuildResult.Failed),
                Options.GitOptions.GetRepoUrl().ToString(),
                Options.GitOptions.AuthToken,
                Options.IsDryRun);
        }