diff options
Diffstat (limited to 'mod')
-rw-r--r-- | mod/ci-common.cxx | 3 | ||||
-rw-r--r-- | mod/mod-ci-github-service-data.hxx | 32 | ||||
-rw-r--r-- | mod/mod-ci-github.cxx | 58 | ||||
-rw-r--r-- | mod/mod-ci-github.hxx | 8 | ||||
-rw-r--r-- | mod/tenant-service.hxx | 3 |
5 files changed, 86 insertions, 18 deletions
diff --git a/mod/ci-common.cxx b/mod/ci-common.cxx index 1f0ff74..caf9f40 100644 --- a/mod/ci-common.cxx +++ b/mod/ci-common.cxx @@ -541,7 +541,8 @@ namespace brep odb::core::database& db, tenant_service&& service, duration notify_interval, - duration notify_delay) const + duration notify_delay, + duplicate_tenant_mode) const { using namespace odb::core; diff --git a/mod/mod-ci-github-service-data.hxx b/mod/mod-ci-github-service-data.hxx index 5573d90..89fcaab 100644 --- a/mod/mod-ci-github-service-data.hxx +++ b/mod/mod-ci-github-service-data.hxx @@ -43,12 +43,33 @@ namespace brep } }; + // We have two kinds of service data that correspond to the following two + // scenarios (those are the only possible ones, until/unless we add support + // for merge queues): + // + // 1. Branch push (via check_suite) plus zero or more local PRs (via + // pull_request) that share the same head commit id. + // + // 2. One or more remote PRs (via pull_request) that share the same head + // commit id (from a repository in another organization). + // + // Plus, for PRs, the service data may be in the pre-check phase while we + // are in the process of requesting the test merge commit and making sure it + // can be created and is not behind base. We do all this before we actually + // create the CI tenant. + // struct service_data { // The data schema version. Note: must be first member in the object. // uint64_t version = 1; + // Kind and phase. + // + enum {local, remote /*, queue */} kind; + bool pre_check; + bool re_request; // Re-requested (rebuild). + // Check suite settings. // bool warning_success; // See gh_to_conclusion(). @@ -73,9 +94,16 @@ namespace brep // optional<string> merge_node_id; - // The commit ID the check suite or pull request (and its check runs) are + // The commit ID the branch push or pull request (and its check runs) are + // building. This will be the head commit for the branch push as well as + // local pull requests and the test merge commit for remote pull requests. + // + string check_sha; + + // The commit ID the branch push or pull request (and its check runs) are // reporting to. Note that in the case of a pull request this will be the - // head commit (`pull_request.head.sha`) as opposed to the merge commit. + // head commit (`pull_request.head.sha`) as opposed to the test merge + // commit. // string report_sha; diff --git a/mod/mod-ci-github.cxx b/mod/mod-ci-github.cxx index a8cb919..56f6d89 100644 --- a/mod/mod-ci-github.cxx +++ b/mod/mod-ci-github.cxx @@ -573,6 +573,8 @@ namespace brep error << "check suite " << nid << " (re-requested): unable to cancel"; } + // @@@ Use repo+head ad service id. + // Start CI for the check suite. // repository_location rl (cs.repository.clone_url + '#' + @@ -822,24 +824,30 @@ namespace brep return true; } - // Note: only handles pull requests (not check suites). - // function<optional<string> (const tenant_service&)> ci_github:: - build_unloaded (tenant_service&& ts, - const diag_epilogue& log_writer) const noexcept + build_unloaded_pre_check (service_data&& sd, + const diag_epilogue& log_writer) const noexcept { NOTIFICATION_DIAG (log_writer); - service_data sd; - try - { - sd = service_data (*ts.data); - } - catch (const invalid_argument& e) - { - error << "failed to parse service data: " << e; - return nullptr; - } + // Note: PR only (but both local and remove). + // + // - Ask for test merge commit. + // - If not ready, get called again. + // - If not mergeable, behind, of different head, cancel itself and ignore. + // - Otherwise, create unloaded CI tenant (with proper duplicate mode + // based on re_request) and cancel itself. + + return nullptr; + } + + function<optional<string> (const tenant_service&)> ci_github:: + build_unloaded_load (service_data&& sd, + const diag_epilogue& log_writer) const noexcept + { + // @@@ TODO: load the tenant: should be the same for both branch push and + // PR. + // // Get a new installation access token if the current one has expired. // @@ -1196,6 +1204,28 @@ namespace brep }; } + function<optional<string> (const tenant_service&)> ci_github:: + build_unloaded (tenant_service&& ts, + const diag_epilogue& log_writer) const noexcept + { + NOTIFICATION_DIAG (log_writer); + + service_data sd; + try + { + sd = service_data (*ts.data); + } + catch (const invalid_argument& e) + { + error << "failed to parse service data: " << e; + return nullptr; + } + + return sd.pre_check + ? build_unloaded_pre_check (move (sd), log_writer) + : build_unloaded_load (move (sd), log_writer) + } + // Build state change notifications (see tenant-services.hxx for // background). Mapping our state transitions to GitHub pose multiple // problems: diff --git a/mod/mod-ci-github.hxx b/mod/mod-ci-github.hxx index 489aac7..c24e0a5 100644 --- a/mod/mod-ci-github.hxx +++ b/mod/mod-ci-github.hxx @@ -46,6 +46,14 @@ namespace brep build_unloaded (tenant_service&&, const diag_epilogue& log_writer) const noexcept override; + function<optional<string> (const tenant_service&)> + build_unloaded_pre_check (service_data&&, + const diag_epilogue&) const noexcept; + + function<optional<string> (const tenant_service&)> + build_unloaded_load (service_data&&, + const diag_epilogue&) const noexcept; + virtual function<optional<string> (const tenant_service&)> build_queued (const tenant_service&, const vector<build>&, diff --git a/mod/tenant-service.hxx b/mod/tenant-service.hxx index c46cb7b..6a982ea 100644 --- a/mod/tenant-service.hxx +++ b/mod/tenant-service.hxx @@ -127,7 +127,8 @@ namespace brep // This notification is only made on unloaded CI requests created with the // ci_start::create() call and until they are loaded with ci_start::load() - // or, alternatively, abandoned with ci_start::abandon(). + // or, alternatively, abandoned with ci_start::cancel() (in which case the + // returned callback should be NULL). // // Note: make sure the implementation of this notification does not take // too long (currently 40 seconds) to avoid nested notifications. Note |