diff options
author | Francois Kritzinger <francois@codesynthesis.com> | 2025-01-24 13:57:26 +0200 |
---|---|---|
committer | Francois Kritzinger <francois@codesynthesis.com> | 2025-01-27 10:26:43 +0200 |
commit | 1ebf9597fc788102bdb6bbf5445c0c25c93b678c (patch) | |
tree | 54ec3f34c1d8079c580527f5cb52d88e4aa706fd | |
parent | dd17caa92ef089dad70cbf6fab26ef324aa0b6be (diff) |
ci-github: Update queued and building check run descriptions
-rw-r--r-- | mod/mod-ci-github-gq.cxx | 60 | ||||
-rw-r--r-- | mod/mod-ci-github-gq.hxx | 29 | ||||
-rw-r--r-- | mod/mod-ci-github.cxx | 107 |
3 files changed, 129 insertions, 67 deletions
diff --git a/mod/mod-ci-github-gq.cxx b/mod/mod-ci-github-gq.cxx index 37d944c..7abd709 100644 --- a/mod/mod-ci-github-gq.cxx +++ b/mod/mod-ci-github-gq.cxx @@ -511,9 +511,13 @@ namespace brep const string& ni, // Node ID. const string& st, // Check run status. optional<timestamp> sa, // Started at. - optional<gq_built_result> br) + const string& ti, // Output title. + const string& su, // Output summary. + optional<string> co = nullopt) // Conclusion. { - assert (st != "COMPLETED" || br); + // Ensure we have conclusion if the status is completed. + // + assert (st != "COMPLETED" || co); ostringstream os; @@ -538,15 +542,13 @@ namespace brep ": " + e.what ()); } } - if (br) - { - os << '\n'; - os << " conclusion: " << gq_enum (br->conclusion) << '\n' - << " output: {" << '\n' - << " title: " << gq_str (br->title) << '\n' - << " summary: " << gq_str (br->summary) << '\n' - << " }"; - } + os << '\n'; + if (co) + os << " conclusion: " << gq_enum (*co) << '\n'; + os << " output: {" << '\n' + << " title: " << gq_str (ti) << '\n' + << " summary: " << gq_str (su) << '\n' + << " }"; os << "})" << '\n' // Specify the selection set (fields to be returned). Note that we // rename `id` to `node_id` (using a field alias) for consistency with @@ -654,11 +656,11 @@ namespace brep const string& rid, const string& nid, build_state st, - optional<gq_built_result> br) + string ti, string su) { - // Must have a result if state is built. + // State cannot be built without a conclusion. // - assert (st != build_state::built || br); + assert (st != build_state::built && !ti.empty () && !su.empty ()); // Set `startedAt` to current time if updating to building. // @@ -673,7 +675,8 @@ namespace brep nid, gh_to_status (st), sa, - move (br)))); + move (ti), move (su), + nullopt /* conclusion */))); vector<check_run> crs {move (cr)}; crs[0].state = st; @@ -685,6 +688,33 @@ namespace brep return r; } + bool + gq_update_check_run (const basic_mark& error, + check_run& cr, + const string& iat, + const string& rid, + const string& nid, + gq_built_result br) + { + string rq ( + gq_serialize_request ( + gq_mutation_update_check_run (rid, + nid, + gh_to_status (build_state::built), + nullopt /* startedAt */, + move (br.title), move (br.summary), + move (br.conclusion)))); + + vector<check_run> crs {move (cr)}; + crs[0].state = build_state::built; + + bool r (gq_mutate_check_runs (error, crs, iat, move (rq))); + + cr = move (crs[0]); + + return r; + } + // Serialize a GraphQL query that fetches a pull request from GitHub. // // Throw invalid_argument if the node id is not a valid GraphQL string. diff --git a/mod/mod-ci-github-gq.hxx b/mod/mod-ci-github-gq.hxx index 0fc3817..19c4924 100644 --- a/mod/mod-ci-github-gq.hxx +++ b/mod/mod-ci-github-gq.hxx @@ -82,28 +82,41 @@ namespace brep const optional<string>& details_url, gq_built_result); - // Update a check run on GitHub. Update `cr` with the new data (state and - // state_synced). Return false and issue diagnostics if the request failed. + // Update a check run on GitHub to the queued or building state. Note that + // the state cannot be built because in that case a conclusion is required. + // + // Update `cr` with the new data (state and state_synced). Return false and + // issue diagnostics if the request failed. // // Throw invalid_argument if the passed data is invalid, missing, or // inconsistent. // + // Title and summary are required and cannot be empty. + // + bool + gq_update_check_run (const basic_mark& error, + check_run& cr, + const string& installation_access_token, + const string& repository_id, + const string& node_id, + build_state, + string title, + string summary); + + // As above but update a check run to the built state (which requires a + // conclusion). + // // Note that GitHub allows any state transitions except from built (but // built to built is allowed). The latter case is signalled by setting the // check_run state_synced member to false and the state member to built. // - // The gq_built_result is required if the build_state is built because - // GitHub does not allow a check run status of `completed` without at least - // a conclusion. - // bool gq_update_check_run (const basic_mark& error, check_run& cr, const string& installation_access_token, const string& repository_id, const string& node_id, - build_state, - optional<gq_built_result> = nullopt); + gq_built_result); // Fetch pre-check information for a pull request from GitHub. This // information is used to decide whether or not to CI the PR and is diff --git a/mod/mod-ci-github.cxx b/mod/mod-ci-github.cxx index b995256..c2596c7 100644 --- a/mod/mod-ci-github.cxx +++ b/mod/mod-ci-github.cxx @@ -577,11 +577,51 @@ namespace brep // Let's capitalize the synthetic conclusion check run name to make it // easier to distinguish from the regular ones. // - static string conclusion_check_run_name ("CONCLUSION"); + static const string conclusion_check_run_name ("CONCLUSION"); - static check_run::description_type conclusion_check_run_building_description { - "\U000026AA IN PROGRESS", // "Medium white" circle. - "Waiting for all builds to complete"}; + // Yellow circle. + // + static const string conclusion_building_title ("\U0001F7E1 IN PROGRESS"); + static const string conclusion_building_summary ( + "Waiting for all the builds to complete."); + + // "Medium white" circle. + // + static const string check_run_queued_title ("\U000026AA QUEUED"); + static const string check_run_queued_summary ( + "Waiting for the build to start."); + + // Yellow circle. + // + static const string check_run_building_title ("\U0001F7E1 BUILDING"); + static const string check_run_building_summary ( + "Waiting for the build to complete."); + + // Return the colored circle corresponding to a result_status. + // + // Note: the rest of the title is produced by to_string(result_status). + // + static string + circle (result_status rs) + { + switch (rs) + { + case result_status::success: return "\U0001F7E2"; // Green circle. + case result_status::warning: return "\U0001F7E0"; // Orange circle. + case result_status::error: + case result_status::abort: + case result_status::abnormal: return "\U0001F534"; // Red circle. + + // Valid values we should never encounter. + // + case result_status::skip: + case result_status::interrupt: + throw invalid_argument ("unexpected result_status value: " + + to_string (rs)); + } + + return ""; // Should never reach. + } bool ci_github:: handle_branch_push (gh_push_event ps, bool warning_success) @@ -1115,30 +1155,6 @@ namespace brep return true; } - // Return the colored circle corresponding to a result_status. - // - static string - circle (result_status rs) - { - switch (rs) - { - case result_status::success: return "\U0001F7E2"; // Green circle. - case result_status::warning: return "\U0001F7E0"; // Orange circle. - case result_status::error: - case result_status::abort: - case result_status::abnormal: return "\U0001F534"; // Red circle. - - // Valid values we should never encounter. - // - case result_status::skip: - case result_status::interrupt: - throw invalid_argument ("unexpected result_status value: " + - to_string (rs)); - } - - return ""; // Should never reach. - } - // Make a check run summary from a CI start_result. // static string @@ -1329,7 +1345,7 @@ namespace brep if (gq_update_check_run (error, bcr, iat->token, repo_node_id, cr.check_run.node_id, - build_state::built, br)) + br)) { l3 ([&]{trace << "updated check_run { " << bcr << " }";}); } @@ -1342,7 +1358,7 @@ namespace brep if (gq_update_check_run (error, ccr, iat->token, repo_node_id, *sd.conclusion_node_id, - build_state::built, move (br))) + move (br))) { l3 ([&]{trace << "updated conclusion check_run { " << ccr << " }";}); } @@ -1390,7 +1406,7 @@ namespace brep // if (gq_update_check_run (error, ccr, iat->token, repo_node_id, *sd.conclusion_node_id, - build_state::built, move (br))) + move (br))) { l3 ([&]{trace << "updated conclusion check_run { " << ccr << " }";}); } @@ -1467,11 +1483,13 @@ namespace brep bcr.state = build_state::queued; bcr.state_synced = false; bcr.details_url = cr.check_run.details_url; + bcr.description = {check_run_queued_title, check_run_queued_summary}; ccr.state = build_state::building; ccr.state_synced = false; ccr.details_url = details_url (tenant_id); - ccr.description = conclusion_check_run_building_description; + ccr.description = {conclusion_building_title, + conclusion_building_summary}; if (gq_create_check_runs (error, check_runs, iat->token, repo_node_id, head_sha)) @@ -1622,7 +1640,7 @@ namespace brep // if (gq_update_check_run (error, bcr, iat->token, repo_node_id, *bcr.node_id, - build_state::built, br)) + br)) { l3 ([&]{trace << "updated check_run { " << bcr << " }";}); } @@ -1638,7 +1656,7 @@ namespace brep // if (gq_update_check_run (error, ccr, iat->token, repo_node_id, *ccr.node_id, - build_state::built, move (br))) + move (br))) { l3 ([&]{trace << "updated conclusion check_run { " << ccr << " }";}); } @@ -1941,7 +1959,8 @@ namespace brep &sd, &error, this] (string name, - const check_run::description_type& output) + const string& title, + const string& summary) -> optional<check_run> { check_run cr; @@ -1956,7 +1975,7 @@ namespace brep sd.report_sha, details_url (tenant_id), build_state::building, - output.title, output.summary)) + title, summary)) { return cr; } @@ -1991,7 +2010,6 @@ namespace brep iat->token, sd.repository_node_id, node_id, - build_state::built, move (br))) { assert (cr.state == build_state::built); @@ -2013,9 +2031,9 @@ namespace brep if (!sd.conclusion_node_id) { - if (auto cr = - create_synthetic_cr (conclusion_check_run_name, - conclusion_check_run_building_description)) + if (auto cr = create_synthetic_cr (conclusion_check_run_name, + conclusion_building_title, + conclusion_building_summary)) { l3 ([&]{trace << "created check_run { " << *cr << " }";}); @@ -2317,7 +2335,8 @@ namespace brep false /* state_synced */, nullopt /* status */, details_url (b), - nullopt /* description */}); + check_run::description_type {check_run_queued_title, + check_run_queued_summary}}); } } @@ -2521,7 +2540,9 @@ namespace brep iat->token, sd.repository_node_id, *cr->node_id, - build_state::building)) + build_state::building, + check_run_building_title, + check_run_building_summary)) { // Do nothing further if the state was already built on GitHub (note // that this is based on the above-mentioned special GitHub semantics @@ -2808,7 +2829,6 @@ namespace brep iat->token, sd.repository_node_id, *cr.node_id, - build_state::built, move (br))) { assert (cr.state == build_state::built); @@ -3089,7 +3109,6 @@ namespace brep iat->token, sd.repository_node_id, *sd.conclusion_node_id, - build_state::built, move (br))) { assert (cr.state == build_state::built); |