diff options
-rw-r--r-- | mod/mod-ci-github-service-data.hxx | 4 | ||||
-rw-r--r-- | mod/mod-ci-github.cxx | 76 | ||||
-rw-r--r-- | mod/mod-ci-github.hxx | 8 |
3 files changed, 76 insertions, 12 deletions
diff --git a/mod/mod-ci-github-service-data.hxx b/mod/mod-ci-github-service-data.hxx index c4e20b3..0f8b77f 100644 --- a/mod/mod-ci-github-service-data.hxx +++ b/mod/mod-ci-github-service-data.hxx @@ -59,6 +59,10 @@ namespace brep string repository_node_id; // GitHub-internal opaque repository id. + // The commit ID the check suite (and its check runs) are associated + // with. In the case of a pull request this will be + // `pull_request.head.sha`. + // string head_sha; vector<check_run> check_runs; diff --git a/mod/mod-ci-github.cxx b/mod/mod-ci-github.cxx index b9a8271..7205e6e 100644 --- a/mod/mod-ci-github.cxx +++ b/mod/mod-ci-github.cxx @@ -338,10 +338,27 @@ namespace brep return true; } } - // else if (event == "pull_request") - // { - // return handle_pull_request (); - // } + else if (event == "pull_request") + { + gh_pull_request_event pr; + try + { + json::parser p (body.data (), body.size (), "pull_request event"); + + pr = gh_pull_request_event (p); + } + catch (const json::invalid_json_input& e) + { + string m ("malformed JSON in " + e.name + " request body"); + + error << m << ", line: " << e.line << ", column: " << e.column + << ", byte offset: " << e.position << ", error: " << e; + + throw invalid_request (400, move (m)); + } + + return handle_pull_request (move (pr), warning_success); + } else { // Log to investigate. @@ -512,14 +529,49 @@ namespace brep // Note: when a PR is merged we will get a pull_request(closed) and then a // check_suite for the base branch. // - // bool ci_github:: - // handle_pull_request (gh_pull_request_event pr) - // { - // // Fetch pull request in order to start job creating test merge - // // commit. Discard result. - // // - // // Start unloaded CI job. - // } + bool ci_github:: + handle_pull_request (gh_pull_request_event pr, bool warning_success) + { + HANDLER_DIAG; + + l3 ([&]{trace << "pull_request event { " << pr << " }";}); + + optional<string> jwt (generate_jwt (trace, error)); + if (!jwt) + throw server_error (); + + optional<gh_installation_access_token> iat ( + obtain_installation_access_token (pr.installation.id, + move (*jwt), + error)); + + if (!iat) + throw server_error (); + + l3 ([&]{trace << "installation_access_token { " << *iat << " }";}); + + string sd (service_data (warning_success, + move (iat->token), + iat->expires_at, + pr.installation.id, + move (pr.repository.node_id), + pr.pull_request.head_sha) + .json ()); + + optional<string> tid ( + create (error, warn, &trace, + *build_db_, + tenant_service (move (pr.pull_request.node_id), + "ci-github", + move (sd)), + chrono::seconds (30), + chrono::seconds (10))); + + if (!tid) + fail << "unable to create unloaded CI request"; + + return true; + } // Build state change notifications (see tenant-services.hxx for // background). Mapping our state transitions to GitHub pose multiple diff --git a/mod/mod-ci-github.hxx b/mod/mod-ci-github.hxx index 946a326..8b2676b 100644 --- a/mod/mod-ci-github.hxx +++ b/mod/mod-ci-github.hxx @@ -66,6 +66,14 @@ namespace brep bool handle_check_suite_request (gh_check_suite_event, bool warning_success); + // Handle the pull_request event `opened` and `synchronize` actions. + // + // If warning_success is true, then map result_status::warning to SUCCESS + // and to FAILURE otherwise. + // + bool + handle_pull_request (gh_pull_request_event, bool warning_success); + // Build a check run details_url for a build. // string |