diff options
Diffstat (limited to 'mod')
-rw-r--r-- | mod/mod-ci-github-gq.cxx | 176 | ||||
-rw-r--r-- | mod/mod-ci-github-gq.hxx | 19 | ||||
-rw-r--r-- | mod/mod-ci-github.cxx | 92 |
3 files changed, 5 insertions, 282 deletions
diff --git a/mod/mod-ci-github-gq.cxx b/mod/mod-ci-github-gq.cxx index cbf2b00..e2d68a9 100644 --- a/mod/mod-ci-github-gq.cxx +++ b/mod/mod-ci-github-gq.cxx @@ -446,182 +446,6 @@ namespace brep return r; } - pair<optional<gh_check_run>, bool> - gq_fetch_check_run (const string& iat, - const string& check_suite_id, - const string& cr_name, - const basic_mark& error) noexcept - { - try - { - // Example request: - // - // query { - // node(id: "CS_kwDOLc8CoM8AAAAFQPQYEw") { - // ... on CheckSuite { - // checkRuns(last: 100, filterBy: {checkName: "linux_debian_..."}) { - // totalCount, - // edges { - // node { - // id, name, status - // } - // } - // } - // } - // } - // } - // - // This request does the following: - // - // - Look up the check suite by node ID ("direct node lookup"). This - // returns a Node (GraphQL interface). - // - // - Get to the concrete CheckSuite type by using a GraphQL "inline - // fragment" (`... on CheckSuite`). - // - // - Get the check suite's check runs - // - Filter by the sought name - // - Return only two check runs, just enough to be able to tell - // whether there are more than one check runs with this name (which - // is an error). - // - // - Return the id, name, and status fields from the matching check run - // objects. - // - string rq; - { - ostringstream os; - - os << "query {" << '\n'; - - os << "node(id: " << gq_str (check_suite_id) << ") {" << '\n' - << " ... on CheckSuite {" << '\n' - << " checkRuns(last: 2," << '\n' - << " filterBy: {" << '\n' - << "checkName: " << gq_str (cr_name) << '\n' - << " })" << '\n' - // Specify the selection set (fields to be returned). Note that - // edges and node are mandatory. - // - << " {" << '\n' - << " totalCount," << '\n' - << " edges {" << '\n' - << " node {" << '\n' - << " id, name, status" << '\n' - << " }" << '\n' - << " }" << '\n' - << " }" << '\n' - << " }" << '\n' - << "}" << '\n'; - - os << "}" << '\n'; - - rq = os.str (); - } - - // Example response (the part we need to parse here, at least): - // - // { - // "node": { - // "checkRuns": { - // "totalCount": 1, - // "edges": [ - // { - // "node": { - // "id": "CR_kwDOLc8CoM8AAAAFgeoweg", - // "name": "linux_debian_...", - // "status": "IN_PROGRESS" - // } - // } - // ] - // } - // } - // } - // - struct resp - { - optional<gh_check_run> cr; - size_t cr_count = 0; - - resp (json::parser& p) - { - using event = json::event; - - gq_parse_response (p, [this] (json::parser& p) - { - p.next_expect (event::begin_object); - p.next_expect_member_object ("node"); - p.next_expect_member_object ("checkRuns"); - - cr_count = p.next_expect_member_number<size_t> ("totalCount"); - - p.next_expect_member_array ("edges"); - - for (size_t i (0); i != cr_count; ++i) - { - p.next_expect (event::begin_object); - p.next_expect_name ("node"); - gh_check_run cr (p); - p.next_expect (event::end_object); - - if (i == 0) - this->cr = move (cr); - } - - p.next_expect (event::end_array); // edges - p.next_expect (event::end_object); // checkRuns - p.next_expect (event::end_object); // node - p.next_expect (event::end_object); - }); - } - - resp () = default; - } rs; - - uint16_t sc (github_post (rs, - "graphql", - strings {"Authorization: Bearer " + iat}, - gq_serialize_request (rq))); - - if (sc == 200) - { - if (rs.cr_count <= 1) - return {rs.cr, true}; - else - { - error << "unexpected number of check runs (" << rs.cr_count - << ") in response"; - } - } - else - error << "failed to get check run by name: error HTTP " - << "response status " << sc; - } - catch (const json::invalid_json_input& e) - { - // Note: e.name is the GitHub API endpoint. - // - error << "malformed JSON in response from " << e.name - << ", line: " << e.line << ", column: " << e.column - << ", byte offset: " << e.position << ", error: " << e; - } - catch (const invalid_argument& e) - { - error << "malformed header(s) in response: " << e; - } - catch (const system_error& e) - { - error << "unable to get check run by name (errno=" << e.code () - << "): " << e.what (); - } - catch (const std::exception& e) - { - error << "unable to get check run by name: " << e.what (); - } - - return {nullopt, false}; - } - // GraphQL serialization functions. // // The GraphQL spec: diff --git a/mod/mod-ci-github-gq.hxx b/mod/mod-ci-github-gq.hxx index 2966670..87ba49b 100644 --- a/mod/mod-ci-github-gq.hxx +++ b/mod/mod-ci-github-gq.hxx @@ -62,25 +62,6 @@ namespace brep const string& node_id, build_state, const basic_mark& error); - - // Fetch from GitHub the check run with the specified name (hints-shortened - // build ID). - // - // Return the check run or nullopt if no such check run exists. - // - // In case of error diagnostics will be issued and false returned in second. - // - // Note that the existence of more than one check run with the same name is - // considered an error and reported as such. The API docs imply that there - // can be more than one check run with the same name in a check suite, but - // the observed behavior is that creating a check run destroys the existent - // one, leaving only the new one with a different node ID. - // - pair<optional<gh_check_run>, bool> - gq_fetch_check_run (const string& installation_access_token, - const string& check_suite_id, - const string& cr_name, - const basic_mark& error) noexcept; } #endif // MOD_MOD_CI_GITHUB_GQ_HXX diff --git a/mod/mod-ci-github.cxx b/mod/mod-ci-github.cxx index 27797f6..9d31210 100644 --- a/mod/mod-ci-github.cxx +++ b/mod/mod-ci-github.cxx @@ -754,96 +754,14 @@ namespace brep // No state has been persisted, or one or both of the other // notifications were unable to create the check run on GitHub. // - // It's also possible that another notification has since created the - // check run on GitHub but its lambda just hasn't run yet. - // // Thus the check run may or may not exist on GitHub. // - // Because creation destroys check runs with the same name (see - // comments at top of function) we have to check whether the check run - // exists on GitHub before we can do anything. - // - // Destructive creation would be catastrophic if, for example, our - // "new" building check run replaced the existing built one because it - // would look exactly like a transition from built back to building in - // the GitHub UI. And then the built lambda could run after our - // building lambda, creating an opportunity for the real node ID to be - // overwritten with the old one. - // - cr.build_id = move (bid); - - // Fetch the check run by name from GitHub. + // Do nothing because build_queued() may currently be creating the + // check run in which case doing so here would result in a duplicate + // check run. The queued->building transition will be lost but that's + // acceptable as long as the check run ends up in the built state. // - pair<optional<gh_check_run>, bool> pr ( - gq_fetch_check_run (iat->token, - ts.id, - gh_check_run_name (b, &hs), - error)); - - if (pr.second) // No errors. - { - if (!pr.first) // Check run does not exist on GitHub. - { - // Assume the most probable cases: build_queued() failed to create - // the check run or build_building() is running before - // build_queued(), so creating with building state is - // correct. (The least likely being that build_built() ran before - // this, in which case we should create with the built state.) - // - // @@ TODO Create with whatever the failed state was if we decide - // to store it. - // - if (gq_create_check_run (cr, - iat->token, - sd.repository_id, sd.head_sha, - b, - build_state::queued, - hs, - error)) - { - l3 ([&]{trace << "created check_run { " << cr << " }";}); - } - } - else // Check run exists on GitHub. - { - if (pr.first->status == gh_to_status (build_state::queued)) - { - if (scr != nullptr) - { - cr = move (*scr); - cr.state = nullopt; - } - - if (gq_update_check_run (cr, - iat->token, - sd.repository_id, - pr.first->node_id, - build_state::building, - error)) - { - l3 ([&]{trace << "updated check_run { " << cr << " }";}); - } - } - else - { - // Do nothing because the GitHub state is already built so the - // lambda returned by build_built() will update the database to - // built. - // - return nullptr; - } - } - } - else // Error communicating with GitHub. - { - // Can't tell whether the check run exists GitHub. Make the final - // decision on whether or not to store nullopt in node_id and state - // based on what's in the database when the lambda runs - // (build_built() and its lambda could run in the meantime). - // - // @@ TODO Store build_state::building if we start storing failed - // state. - } + return nullptr; } } |