Example #1
0
        /// <summary>
        /// Update the table storage to contain the result of the specified build.
        /// </summary>
        private async Task <BuildResultEntity> GetBuildFailureEntity(BuildId id)
        {
            var buildInfo = await _client.GetBuildInfoAsync(id);

            var jobKind = await _client.GetJobKindAsync(id.JobId);

            PullRequestInfo prInfo = null;

            if (JobUtil.IsPullRequestJobName(id.JobId.Name))
            {
                try
                {
                    prInfo = await _client.GetPullRequestInfoAsync(id);
                }
                catch (Exception ex)
                {
                    // TODO: Flow builds don't have the PR directly in the triggered jobs.  Have to walk
                    // back up to the parent job.  For now swallow this error so we don't trigger false
                    // positives in the error detection.
                    _textWriter.WriteLine($"Error pulling PR info for {id}: {ex.Message}");
                }
            }

            BuildResultClassification classification;

            switch (buildInfo.State)
            {
            case BuildState.Succeeded:
                classification = BuildResultClassification.Succeeded;
                break;

            case BuildState.Aborted:
                classification = BuildResultClassification.Aborted;
                break;

            case BuildState.Failed:
                classification = await PopulateFailedBuildResult(buildInfo, jobKind, prInfo);

                break;

            case BuildState.Running:
                classification = BuildResultClassification.Unknown;
                break;

            default:
                throw new Exception($"Invalid enum: {buildInfo.State} for {id.JobName} - {id.Number}");
            }

            return(new BuildResultEntity(
                       buildInfo.Id,
                       buildInfo.Date,
                       buildInfo.Duration,
                       jobKind: jobKind,
                       machineName: buildInfo.MachineName,
                       classification: classification,
                       prInfo: prInfo));
        }
Example #2
0
        private static async Task QueueBuildAsync(IQueueJenkinsBuildArgs args, CancellationToken cancellationToken)
        {
            args.LogInformation($"Queueing build for job \"{args.JobName}\"{IfHasValue(args.BranchName, $" on branch \"{args.BranchName}\"")}...");

            var client = new JenkinsClient(args.UserName, args.Password, args.ServerUrl, args.CsrfProtectionEnabled, args, cancellationToken);

            var queueItem = await client.TriggerBuildAsync(args.JobName, args.BranchName, args.AdditionalParameters).ConfigureAwait(false);

            args.LogInformation($"Jenkins build queued successfully.");
            args.LogDebug($"Queue item number: {queueItem}");

            if (!args.WaitForStart && !args.WaitForCompletion)
            {
                args.LogDebug("The operation is not configured to wait for the build to start.");
                return;
            }

            string buildNumber;
            string lastReason = null;

            while (true)
            {
                await Task.Delay(2 * 1000, cancellationToken).ConfigureAwait(false);

                var info = await client.GetQueuedBuildInfoAsync(queueItem).ConfigureAwait(false);

                if (!string.IsNullOrEmpty(info.BuildNumber))
                {
                    buildNumber             = info.BuildNumber;
                    args.JenkinsBuildNumber = buildNumber;
                    args.LogInformation($"Build number is {buildNumber}.");
                    break;
                }

                if (!string.Equals(lastReason, info.WaitReason))
                {
                    args.LogDebug($"Waiting for build to start... ({info.WaitReason})");
                    lastReason = info.WaitReason;
                }

                args.SetProgress(new OperationProgress(null, info.WaitReason));
            }

            if (args.WaitForCompletion)
            {
                args.LogInformation($"Waiting for build {buildNumber} to complete...");

                JenkinsBuild build;
                int          attempts = 5;
                while (true)
                {
                    await Task.Delay(2 * 1000, cancellationToken).ConfigureAwait(false);

                    build = await client.GetBuildInfoAsync(args.JobName, args.BranchName, buildNumber).ConfigureAwait(false);

                    if (build == null)
                    {
                        args.LogDebug("Build information was not returned.");
                        if (attempts > 0)
                        {
                            args.LogDebug($"Reloading build data ({attempts} attempts remaining)...");
                            attempts--;
                            continue;
                        }
                        break;
                    }

                    // reset retry counter
                    attempts = 5;

                    if (!build.Building)
                    {
                        args.LogDebug("Build has finished building.");
                        args.SetProgress(new OperationProgress(100));
                        break;
                    }

                    args.SetProgress(ComputeProgress(build));
                }

                if (string.Equals("success", build?.Result, StringComparison.OrdinalIgnoreCase))
                {
                    args.LogDebug("Build status returned: success");
                }
                else
                {
                    args.LogError("Build not not report success; result was: " + (build?.Result ?? "<not returned>"));
                }
            }
            else
            {
                args.LogDebug("The operation is not configured to wait for build completion.");
            }
        }