Esempio n. 1
0
        private async Task HandleCompletedBuild(ReleasePipelineRunnerItem item, AzureDevOpsBuild azdoBuild, CancellationToken cancellationToken)
        {
            if (azdoBuild.Result.Equals("succeeded", StringComparison.OrdinalIgnoreCase) ||
                azdoBuild.Result.Equals("partiallySucceeded", StringComparison.OrdinalIgnoreCase))
            {
                using (Logger.BeginScope(
                           $"Triggering release pipelines associated with channel {item.ChannelId} for build {item.BuildId}.",
                           item.BuildId,
                           item.ChannelId))
                {
                    await RunAssociatedReleasePipelinesAsync(item.BuildId, item.ChannelId, cancellationToken);
                }
            }
            else
            {
                int currentAttempts = item.NumberOfRetriesMade + 1;

                Logger.LogError($"Tried to trigger release pipeline for a non-succeeded build: {item.BuildId}. " +
                                $"This was attempt number {currentAttempts} of a maximum of {ReleasePipelineRunner.MaxRetriesChecksForFailedBuilds}.");

                if (currentAttempts >= ReleasePipelineRunner.MaxRetriesChecksForFailedBuilds)
                {
                    Logger.LogError($"Cancelling the checks for this build {item.BuildId}. After now retries for it won't be published.");
                }
                else
                {
                    // Build finished unsucessfully but it can still be retried and finished sucessfully.
                    EnqueueBuildStatusCheck(item, currentAttempts);
                }
            }
        }
Esempio n. 2
0
        private async void EnqueueBuildStatusCheck(ReleasePipelineRunnerItem item, int newNumberOfRetriesMade)
        {
            await Task.Delay(TimeSpan.FromMinutes(ReleasePipelineRunner.DelayBetweenBuildStatusChecksInMinutes));

            IReliableConcurrentQueue <ReleasePipelineRunnerItem> queue =
                await StateManager.GetOrAddAsync <IReliableConcurrentQueue <ReleasePipelineRunnerItem> >("queue");

            using (ITransaction tx = StateManager.CreateTransaction())
            {
                await queue.EnqueueAsync(tx, new ReleasePipelineRunnerItem
                {
                    BuildId             = item.BuildId,
                    ChannelId           = item.ChannelId,
                    NumberOfRetriesMade = newNumberOfRetriesMade
                });

                await tx.CommitAsync();
            }
        }
        public async Task <TimeSpan> RunAsync(CancellationToken cancellationToken)
        {
            IReliableConcurrentQueue <ReleasePipelineRunnerItem> queue =
                await StateManager.GetOrAddAsync <IReliableConcurrentQueue <ReleasePipelineRunnerItem> >("queue");

            try
            {
                using (ITransaction tx = StateManager.CreateTransaction())
                {
                    ConditionalValue <ReleasePipelineRunnerItem> maybeItem = await queue.TryDequeueAsync(
                        tx,
                        cancellationToken);

                    if (maybeItem.HasValue)
                    {
                        ReleasePipelineRunnerItem item = maybeItem.Value;
                        using (Logger.BeginScope(
                                   $"Triggering release pipelines associated with channel {item.ChannelId} for build {item.BuildId}.",
                                   item.BuildId,
                                   item.ChannelId))
                        {
                            await RunAssociatedReleasePipelinesAsync(item.BuildId, item.ChannelId, cancellationToken);
                        }
                    }

                    await tx.CommitAsync();
                }
            }
            catch (TaskCanceledException tcex) when(tcex.CancellationToken == cancellationToken)
            {
                return(TimeSpan.MaxValue);
            }
            catch (Exception ex)
            {
                Logger.LogError(ex, "Processing queue messages");
            }

            return(TimeSpan.FromSeconds(1));
        }
Esempio n. 4
0
        public async Task <TimeSpan> RunAsync(CancellationToken cancellationToken)
        {
            IReliableConcurrentQueue <ReleasePipelineRunnerItem> queue =
                await StateManager.GetOrAddAsync <IReliableConcurrentQueue <ReleasePipelineRunnerItem> >("queue");

            try
            {
                using (ITransaction tx = StateManager.CreateTransaction())
                {
                    ConditionalValue <ReleasePipelineRunnerItem> maybeItem = await queue.TryDequeueAsync(
                        tx,
                        cancellationToken);

                    if (maybeItem.HasValue)
                    {
                        ReleasePipelineRunnerItem item = maybeItem.Value;

                        Build build = await Context.Builds
                                      .Where(b => b.Id == item.BuildId).FirstOrDefaultAsync();

                        if (build == null)
                        {
                            Logger.LogError($"Could not find the specified BAR Build {item.BuildId} to run a release pipeline.");
                        }
                        else if (build.AzureDevOpsBuildId == null)
                        {
                            // If something uses the old API version we won't have this information available.
                            // This will also be the case if something adds an existing build (created using
                            // the old API version) to a channel
                            Logger.LogInformation($"barBuildInfo.AzureDevOpsBuildId is null for BAR Build.Id {build.Id}.");
                        }
                        else
                        {
                            AzureDevOpsClient azdoClient = await GetAzureDevOpsClientForAccount(build.AzureDevOpsAccount);

                            var azdoBuild = await azdoClient.GetBuildAsync(
                                build.AzureDevOpsAccount,
                                build.AzureDevOpsProject,
                                build.AzureDevOpsBuildId.Value);

                            if (azdoBuild.Status.Equals("completed", StringComparison.OrdinalIgnoreCase))
                            {
                                await HandleCompletedBuild(item, azdoBuild, cancellationToken);
                            }
                            else
                            {
                                Logger.LogInformation($"AzDO build {azdoBuild.BuildNumber}/{azdoBuild.Definition.Name} with BAR BuildId {build.Id} is still in progress.");

                                // Build didn't finish yet. Let's wait some time and try again.
                                EnqueueBuildStatusCheck(item, 0);
                            }
                        }
                    }

                    await tx.CommitAsync();
                }
            }
            catch (TaskCanceledException tcex) when(tcex.CancellationToken == cancellationToken)
            {
                return(TimeSpan.MaxValue);
            }
            catch (Exception ex)
            {
                Logger.LogError(ex, "Processing queue messages");
            }

            return(TimeSpan.FromMinutes(1));
        }