diff options
Diffstat (limited to 'mod')
-rw-r--r-- | mod/mod-ci-github-gq.cxx | 84 | ||||
-rw-r--r-- | mod/mod-ci-github-gq.hxx | 33 | ||||
-rw-r--r-- | mod/mod-ci-github-service-data.hxx | 13 | ||||
-rw-r--r-- | mod/mod-ci-github.cxx | 24 |
4 files changed, 116 insertions, 38 deletions
diff --git a/mod/mod-ci-github-gq.cxx b/mod/mod-ci-github-gq.cxx index db69f0c..a4bcc3a 100644 --- a/mod/mod-ci-github-gq.cxx +++ b/mod/mod-ci-github-gq.cxx @@ -380,9 +380,12 @@ namespace brep assert (cr.state != build_state::built); // Not supported. - // Ensure details URL is non-empty if present. + // Ensure details URL and output are non-empty if present. // assert (!cr.details_url || !cr.details_url->empty ()); + assert (!cr.description || + (!cr.description->title.empty () && + !cr.description->summary.empty ())); string al ("cr" + to_string (i)); // Field alias. @@ -396,6 +399,13 @@ namespace brep os << '\n'; os << " detailsUrl: " << gq_str (*cr.details_url); } + if (cr.description) + { + os << " output: {" << '\n' + << " title: " << gq_str (cr.description->title) << '\n' + << " summary: " << gq_str (cr.description->summary) << '\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 @@ -417,9 +427,9 @@ namespace brep // Serialize a `createCheckRun` mutation for a build to GraphQL. // - // The build result argument (`br`) is required if the build_state is built - // because GitHub does not allow a check run status of completed without a - // conclusion. + // The conclusion argument (`co`) is required if the check run status is + // completed because GitHub does not allow a check run status of completed + // without a conclusion. // // The details URL argument (`du`) can be empty for queued but not for the // other states. @@ -433,12 +443,18 @@ namespace brep const optional<string>& du, // Details URL. const check_run& cr, const string& st, // Check run status. - optional<gq_built_result> br = nullopt) + const string& ti, // Output title. + const string& su, // Output summary. + optional<string> co = nullopt) // Conclusion. { // Ensure details URL is non-empty if present. // assert (!du || !du->empty ()); + // Ensure we have conclusion if the status is completed. + // + assert (st != "COMPLETED" || co); + ostringstream os; os << "mutation {" << '\n'; @@ -455,15 +471,13 @@ namespace brep os << '\n'; os << " detailsUrl: " << gq_str (*du); } - 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 @@ -485,7 +499,7 @@ namespace brep // Serialize an `updateCheckRun` mutation for one build to GraphQL. // - // The `co` (conclusion) argument is required if the build_state is built + // The `br` argument is required if the check run status is completed // because GitHub does not allow updating a check run to completed without a // conclusion. // @@ -504,6 +518,8 @@ namespace brep // assert (!du || !du->empty ()); + assert (st != "COMPLETED" || br); + ostringstream os; os << "mutation {" << '\n' @@ -586,11 +602,11 @@ namespace brep const string& hs, const optional<string>& du, 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 ()); string rq ( gq_serialize_request ( @@ -599,7 +615,8 @@ namespace brep du, cr, gh_to_status (st), - move (br)))); + move (ti), move (su), + nullopt /* conclusion */))); vector<check_run> crs {move (cr)}; crs[0].state = st; @@ -612,6 +629,35 @@ namespace brep } bool + gq_create_check_run (const basic_mark& error, + check_run& cr, + const string& iat, + const string& rid, + const string& hs, + const optional<string>& du, + gq_built_result br) + { + string rq ( + gq_serialize_request ( + gq_mutation_create_check_run (rid, + hs, + du, + cr, + gh_to_status (build_state::built), + 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; + } + + bool gq_update_check_run (const basic_mark& error, check_run& cr, const string& iat, diff --git a/mod/mod-ci-github-gq.hxx b/mod/mod-ci-github-gq.hxx index 50950d4..0d57325 100644 --- a/mod/mod-ci-github-gq.hxx +++ b/mod/mod-ci-github-gq.hxx @@ -20,7 +20,7 @@ namespace brep // // Create a new check run on GitHub for each build with the build state, - // name, and details_url taken from each check_run object. Update + // name, details_url, and output taken from each check_run object. Update // `check_runs` with the new data (node id and state_synced). Return false // and issue diagnostics if the request failed. // @@ -39,18 +39,32 @@ namespace brep const string& repository_id, const string& head_sha); - // Create a new check run on GitHub for a build. Update `cr` with the new - // data (node id, state, and state_synced). Return false and issue - // diagnostics if the request failed. + // Create a new check run on GitHub for a build in 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 (node id, 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. // - // If the details_url is absent GitHub will use the app's homepage. + // If the details_url is absent GitHub will use the app's homepage. Title + // and summary are required and cannot be empty. // - // 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_create_check_run (const basic_mark& error, + check_run& cr, + const string& installation_access_token, + const string& repository_id, + const string& head_sha, + const optional<string>& details_url, + build_state, + string title, + string summary); + + // As above but create a check run in the built state (which requires a + // conclusion). // struct gq_built_result { @@ -66,8 +80,7 @@ namespace brep const string& repository_id, const string& head_sha, const optional<string>& details_url, - build_state, - optional<gq_built_result> = nullopt); + 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. diff --git a/mod/mod-ci-github-service-data.hxx b/mod/mod-ci-github-service-data.hxx index 50bb49d..5d36696 100644 --- a/mod/mod-ci-github-service-data.hxx +++ b/mod/mod-ci-github-service-data.hxx @@ -33,10 +33,17 @@ namespace brep optional<result_status> status; // Only if state is built & synced. - // Note: never serialized (only used to pass information to the GraphQL - // functions). + // Note: these are never serialized (only used to pass information to the + // GraphQL functions). // - optional<string> details_url; + struct description_type + { + string title; + string summary; + }; + + optional<string> details_url; + optional<description_type> description; string state_string () const diff --git a/mod/mod-ci-github.cxx b/mod/mod-ci-github.cxx index 579b96b..438fcbd 100644 --- a/mod/mod-ci-github.cxx +++ b/mod/mod-ci-github.cxx @@ -579,6 +579,10 @@ namespace brep // static 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"}; + bool ci_github:: handle_branch_push (gh_push_event ps, bool warning_success) { @@ -1463,6 +1467,8 @@ namespace brep ccr.state = build_state::building; ccr.state_synced = false; + ccr.details_url = details_url (tenant_id); + ccr.description = conclusion_check_run_building_description; if (gq_create_check_runs (error, check_runs, iat->token, repo_node_id, head_sha)) @@ -1929,9 +1935,13 @@ namespace brep // Create a synthetic check run with an in-progress state. Return the // check run on success or nullopt on failure. // - auto create_synthetic_cr = [iat, + auto create_synthetic_cr = [&tenant_id, + iat, &sd, - &error] (string name) -> optional<check_run> + &error, + this] (string name, + const check_run::description_type& output) + -> optional<check_run> { check_run cr; cr.name = move (name); @@ -1943,8 +1953,9 @@ namespace brep iat->token, sd.repository_node_id, sd.report_sha, - nullopt /* details_url */, - build_state::building)) + details_url (tenant_id), + build_state::building, + output.title, output.summary)) { return cr; } @@ -2002,7 +2013,9 @@ namespace brep if (!sd.conclusion_node_id) { - if (auto cr = create_synthetic_cr (conclusion_check_run_name)) + if (auto cr = + create_synthetic_cr (conclusion_check_run_name, + conclusion_check_run_building_description)) { l3 ([&]{trace << "created check_run { " << *cr << " }";}); @@ -2847,7 +2860,6 @@ namespace brep sd.repository_node_id, sd.report_sha, details_url (b), - build_state::built, move (br))) { assert (cr.state == build_state::built); |