aboutsummaryrefslogtreecommitdiff
path: root/mod/mod-ci-github.cxx
diff options
context:
space:
mode:
authorFrancois Kritzinger <francois@codesynthesis.com>2024-10-24 09:25:59 +0200
committerFrancois Kritzinger <francois@codesynthesis.com>2024-12-10 16:34:15 +0200
commit656b96fde2f28d4e6866180174c4e8481a358624 (patch)
tree8d2bece19568909dd0d0d89099250136e949d2ae /mod/mod-ci-github.cxx
parent630834173bba497c9f21eb0459ba5cb7264346ee (diff)
Handle check suite rebuilds (all checks) on a commit and/or PR
Diffstat (limited to 'mod/mod-ci-github.cxx')
-rw-r--r--mod/mod-ci-github.cxx83
1 files changed, 71 insertions, 12 deletions
diff --git a/mod/mod-ci-github.cxx b/mod/mod-ci-github.cxx
index 6289d8b..f7480b6 100644
--- a/mod/mod-ci-github.cxx
+++ b/mod/mod-ci-github.cxx
@@ -473,15 +473,61 @@ namespace brep
//
string sid (cs.repository.node_id + ":" + cs.check_suite.head_sha);
- // @@ Let's pass the "state" arguments explicitly in both constructors.
+ // If the user requests a rebuild of the (entire) PR, then this manifests
+ // as the check_suite rather than pull_request event. Specifically:
//
+ // - For a local PR, this event is shared with the branch push and all we
+ // need to do is restart the CI for the head commit.
+ //
+ // - For a remote PR, this event will have no gh_check_suite::head_branch.
+ // In this case we need to load the existing service data for this head
+ // commit, extract the test merge commit, and restart the CI for that.
+ //
+ string check_sha;
+ service_data::kind_type kind;
+
+ bool re_requested (cs.action == "rerequested");
+ if (re_requested && !cs.check_suite.head_branch)
+ {
+ kind = service_data::remote;
+
+ if (optional<tenant_service> ts = find (*build_db_, "ci-github", sid))
+ {
+ try
+ {
+ service_data sd (*ts->data);
+ check_sha = move (sd.check_sha); // Test merge commit.
+ }
+ catch (const invalid_argument& e)
+ {
+ fail << "failed to parse service data: " << e;
+ }
+ }
+ else
+ {
+ error << "check suite for remote pull request "
+ << cs.check_suite.node_id
+ << ": re-requested but tenant_service with id " << sid
+ << " did not exist";
+ return true;
+ }
+ }
+ else
+ {
+ // Branch push or local PR rebuild.
+ //
+ kind = service_data::local;
+ check_sha = cs.check_suite.head_sha;
+ }
+
service_data sd (warning_success,
iat->token,
iat->expires_at,
cs.installation.id,
move (cs.repository.node_id),
- move (cs.check_suite.head_sha),
- cs.action == "rerequested" /* re_request */);
+ kind, false /* pre_check */, re_requested,
+ move (check_sha),
+ move (cs.check_suite.head_sha) /* report_sha */);
// If this check suite is being re-run, replace the existing CI request if
// it exists; otherwise create a new one, doing nothing if a request
@@ -490,8 +536,9 @@ namespace brep
// Note that GitHub UI does not allow re-running the entire check suite
// until all the check runs are completed.
//
- duplicate_tenant_mode dtm (sd.re_request ? duplicate_tenant_mode::replace
- : duplicate_tenant_mode::ignore);
+ duplicate_tenant_mode dtm (re_requested
+ ? duplicate_tenant_mode::replace
+ : duplicate_tenant_mode::ignore);
// Create an unloaded CI request.
//
@@ -526,6 +573,7 @@ namespace brep
error << "check suite " << cs.check_suite.node_id
<< ": re-requested but tenant_service with id " << sid
<< " did not exist";
+ return true;
}
return true;
@@ -698,26 +746,37 @@ namespace brep
// job might actually still be relevant (in both local and remote PR
// cases).
- // @@ TMP We can already determine whether the PR is local or remote so we
- // could pass `kind` to the service_data constructor. Let's do.
+ // @@ TODO Serialize the new service_data fields!
+ //
- // @@ TODO: what happens when the entire PR build is re-requested?
+ // Distinguish between local and remote PRs by comparing the head and base
+ // repositories' paths.
+ //
+ service_data::kind_type kind (
+ pr.pull_request.head_path == pr.pull_request.base_path
+ ? service_data::local
+ : service_data::remote);
- // @@ TODO Serialize the new service_data fields!
+ // Note: for remote PRs the check_sha will be set later, in
+ // build_unloaded_pre_check(), to test merge commit id.
//
- // Note that check_sha will be set later, in build_unloaded_pre_check().
+ string check_sha (kind == service_data::local
+ ? pr.pull_request.head_sha
+ : "");
+
+ // Note that PR rebuilds (re-requested) are handled by check_suite().
//
service_data sd (warning_success,
move (iat->token),
iat->expires_at,
pr.installation.id,
move (pr.repository.node_id),
+ kind, true /* pre_check */, false /* re_request */,
+ move (check_sha),
move (pr.pull_request.head_sha) /* report_sha */,
move (pr.repository.clone_url),
pr.pull_request.number);
- assert (sd.pre_check); // @@ Get rid (once ctor changed).
-
// Create an unloaded CI request for the pre-check phase (during which we
// wait for the PR's merge commit and behindness to become available).
//