/// <inheritdoc /> public async Task <ContinuousIntegrationStatus> GetJobStatus(PullRequest pullRequest, CancellationToken cancellationToken) { if (pullRequest == null) { throw new ArgumentNullException(nameof(pullRequest)); } logger.LogTrace("Getting job status for pull request #{0}", pullRequest.Number); var result = ContinuousIntegrationStatus.NotPresent; var tasks = new List <Task <bool> >(); var cts = new CancellationTokenSource(); var innerToken = cts.Token; using (cancellationToken.Register(() => cts.Cancel())) { await NonParallelForEachBuild(pullRequest, (state, buildNumber) => { if (state == CommitState.Failure) { result = ContinuousIntegrationStatus.Failed; return(false); } if (state == CommitState.Error) { result = ContinuousIntegrationStatus.Errored; return(false); } if (state == CommitState.Success) { //now determine if base is up to date result = ContinuousIntegrationStatus.Passed; async Task <bool> BuildIsUpToDate() { //https://developer.travis-ci.org/resource/build#Build var build = String.Join('/', BaseBuildUrl, buildNumber); var json = await requestManager.RunRequest(new Uri(build), null, GetRequestHeaders(), RequestMethod.GET, innerToken).ConfigureAwait(false); var jsonObj = JObject.Parse(json); var commitObj = (JObject)jsonObj["commit"]; var sha = (string)commitObj["sha"]; if (sha == pullRequest.MergeCommitSha) { return(true); } //so because of gender questioning memes, travis doesn't update the commit sha in the api when you restart the build //even though the correct build DID run //so now we gotta compare the creation time of the build to the creation time of the merge commit sha to make sure this plumber isn't lying to us var commit = await gitHubManager.GetCommit(pullRequest.MergeCommitSha).ConfigureAwait(false); var buildStartedAt = DateTimeOffset.Parse((string)jsonObj["started_at"], CultureInfo.InvariantCulture); return(commit.Committer.Date < buildStartedAt); }; tasks.Add(BuildIsUpToDate()); } else if (state == CommitState.Pending) { result = ContinuousIntegrationStatus.Pending; } return(true); }).ConfigureAwait(false); try { await Task.WhenAll(tasks).ConfigureAwait(false); } catch (OperationCanceledException) { cancellationToken.ThrowIfCancellationRequested(); } if (result == ContinuousIntegrationStatus.Passed && tasks.Any(x => !x.Result)) { result = ContinuousIntegrationStatus.PassedOutdated; } return(result); } }