aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrancois Kritzinger <francois@codesynthesis.com>2025-01-24 13:57:26 +0200
committerFrancois Kritzinger <francois@codesynthesis.com>2025-01-27 10:26:43 +0200
commit1ebf9597fc788102bdb6bbf5445c0c25c93b678c (patch)
tree54ec3f34c1d8079c580527f5cb52d88e4aa706fd
parentdd17caa92ef089dad70cbf6fab26ef324aa0b6be (diff)
ci-github: Update queued and building check run descriptions
-rw-r--r--mod/mod-ci-github-gq.cxx60
-rw-r--r--mod/mod-ci-github-gq.hxx29
-rw-r--r--mod/mod-ci-github.cxx107
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);