/// <summary> /// Executes a project job, notifying the callback path when complete. /// </summary> public async Task ExecuteProjectJobAsync(ProjectJob projectJob, string operationId) { using (_logger.BeginScope( new Dictionary<string, object>() { ["OperationId"] = operationId, ["GitHubOrg"] = projectJob.GitHubOrg, ["GitHubRepo"] = projectJob.SubmissionRepo, ["CommitSha"] = projectJob.CommitSha })) { _logger.LogInformation("Starting project job."); var result = await RunJobAsync(projectJob, operationId); _logger.LogInformation( "Project job completed with {status} status and {numTestResults} test results.", result.Status.ToString() ?? "Unknown", result.TestResults?.Count ?? 0); await _notifier.NotifyAsync ( _config.ProjectJobResultHost, projectJob.CallbackPath, operationId, result ); _logger.LogInformation("Sent notification for job completion."); } }
/// <summary> /// Creates a build job for a new commit received by a push event. /// Returns the job ID for the build job. /// </summary> public async Task<string> CreateBuildJobAsync( Project project, PushEventCommit newCommit, string buildResultCallbackUrl) { var projectJob = new ProjectJob ( newCommit.Commit.BuildRequestToken, newCommit.PushEvent.Repository.Owner.Name, project.Name, newCommit.PushEvent.Repository.Name, $"{project.Name}_Template", newCommit.Commit.Sha, project.PrivateFilePaths .Select(p => p.Path) .Concat(project.ImmutableFilePaths.Select(p => p.Path)) .ToList(), project.TestClasses .Select(tc => tc.ClassName) .ToList(), buildResultCallbackUrl ); var jobId = await _jobQueueClient.EnqueueAsync<IProjectRunnerService> ( service => service.ExecuteProjectJobAsync ( projectJob, _operationIdProvider.OperationId ) ); return jobId; }
/// <summary> /// Runs the job, and returns the result. /// </summary> private async Task<ProjectJobResult> RunJobAsync(ProjectJob projectJob, string operationId) { var dockerHost = _dockerHostFactory.CreateDockerHost(c_projectRunnerId); var jobStarted = _timeProvider.UtcNow; var dockerResult = await dockerHost.RunImageInNewContainerAsync( requestContents: null, environmentVariables: new Dictionary<string, string>() { [c_githubOAuthTokenVar] = _config.GitHubOAuthToken, [c_githubOrgNameVar] = projectJob.GitHubOrg, [c_projectNameVar] = projectJob.ProjectName, [c_githubSubmissionRepoNameVar] = projectJob.SubmissionRepo, [c_githubTemplateRepoNameVar] = projectJob.TemplateRepo, [c_commitShaVar] = projectJob.CommitSha, [c_pathsToCopyVar] = string.Join(";", projectJob.CopyPaths), [c_testClassesVar] = string.Join(";", projectJob.TestClasses) }); var jobFinished = _timeProvider.UtcNow; List<TestResult> testResults = null; bool validResponse = dockerResult.Completed && dockerResult.Response != null && TryDeserializeTestResults(dockerResult.Response, out testResults); return new ProjectJobResult() { BuildRequestToken = projectJob.BuildRequestToken, Status = GetProjectJobStatus ( dockerResult.Completed, dockerResult.Response != null, validResponse ), JobStartedDate = jobStarted, JobFinishedDate = jobFinished, BuildOutput = dockerResult.Output, TestResults = testResults }; }