diff options
author | Francois Kritzinger <francois@codesynthesis.com> | 2024-03-07 09:49:06 +0200 |
---|---|---|
committer | Francois Kritzinger <francois@codesynthesis.com> | 2024-04-24 15:14:54 +0200 |
commit | 7c8dec0983de14ec14bd0ae9912b072807c25335 (patch) | |
tree | b3103af370225ca62650bee91339a4bcf06010f9 | |
parent | 971155e0d79d8119c66551e58f538b845cba5bf9 (diff) |
GitHub CI: add CI support
-rw-r--r-- | mod/mod-ci-github.cxx | 133 | ||||
-rw-r--r-- | mod/mod-ci-github.hxx | 30 | ||||
-rw-r--r-- | mod/mod-repository-root.cxx | 4 |
3 files changed, 156 insertions, 11 deletions
diff --git a/mod/mod-ci-github.cxx b/mod/mod-ci-github.cxx index 41f6790..4bf91fc 100644 --- a/mod/mod-ci-github.cxx +++ b/mod/mod-ci-github.cxx @@ -45,17 +45,41 @@ namespace brep using namespace gh; ci_github:: - ci_github (const ci_github& r) + ci_github (tenant_service_map& tsm) + : tenant_service_map_ (tsm) + { + } + + ci_github:: + ci_github (const ci_github& r, tenant_service_map& tsm) : handler (r), - options_ (r.initialized_ ? r.options_ : nullptr) + ci_start (r), + options_ (r.initialized_ ? r.options_ : nullptr), + tenant_service_map_ (tsm) { } void ci_github:: init (scanner& s) { + { + shared_ptr<tenant_service_base> ts ( + dynamic_pointer_cast<tenant_service_base> (shared_from_this ())); + + assert (ts != nullptr); // By definition. + + tenant_service_map_["ci-github"] = move (ts); + } + options_ = make_shared<options::ci_github> ( s, unknown_mode::fail, unknown_mode::fail); + + // Prepare for the CI requests handling, if configured. + // + if (options_->ci_github_app_webhook_secret_specified ()) + { + ci_start::init (make_shared<options::ci_start> (*options_)); + } } bool ci_github:: @@ -281,8 +305,10 @@ namespace brep } bool ci_github:: - handle_check_suite_request (check_suite_event cs) const + handle_check_suite_request (check_suite_event cs) { + HANDLER_DIAG; + cout << "<check_suite event>" << endl << cs << endl; installation_access_token iat ( @@ -290,9 +316,103 @@ namespace brep cout << endl << "<installation_access_token>" << endl << iat << endl; + repository_location rl (cs.repository.clone_url + '#' + + cs.check_suite.head_branch, + repository_type::git); + + optional<start_result> r (start (error, + warn, + verb_ ? &trace : nullptr, + tenant_service ("", "ci-github"), + move (rl), + vector<package> {}, + nullopt, // client_ip, + nullopt // user_agent, + )); + + if (!r) + fail << "unable to start CI"; + return true; } + function<optional<string> (const brep::tenant_service&)> brep::ci_github:: + build_queued (const tenant_service&, + const vector<build>& bs, + optional<build_state> initial_state) const + { + // return [&bs, initial_state] (const tenant_service& ts) + // { + // optional<string> r (ts.data); + + // for (const build& b: bs) + // { + // string s ((!initial_state + // ? "queued " + // : "queued " + to_string (*initial_state) + ' ') + + // b.package_name.string () + '/' + + // b.package_version.string () + '/' + + // b.target.string () + '/' + + // b.target_config_name + '/' + + // b.package_config_name + '/' + + // b.toolchain_name + '/' + + // b.toolchain_version.string ()); + + // if (r) + // { + // *r += ", "; + // *r += s; + // } + // else + // r = move (s); + // } + + // return r; + // }; + + return nullptr; + } + + function<optional<string> (const brep::tenant_service&)> brep::ci_github:: + build_building (const tenant_service&, const build& b) const + { + // return [&b] (const tenant_service& ts) + // { + // string s ("building " + + // b.package_name.string () + '/' + + // b.package_version.string () + '/' + + // b.target.string () + '/' + + // b.target_config_name + '/' + + // b.package_config_name + '/' + + // b.toolchain_name + '/' + + // b.toolchain_version.string ()); + + // return ts.data ? *ts.data + ", " + s : s; + // }; + + return nullptr; + } + + function<optional<string> (const brep::tenant_service&)> brep::ci_github:: + build_built (const tenant_service&, const build& b) const + { + // return [&b] (const tenant_service& ts) + // { + // string s ("built " + + // b.package_name.string () + '/' + + // b.package_version.string () + '/' + + // b.target.string () + '/' + + // b.target_config_name + '/' + + // b.package_config_name + '/' + + // b.toolchain_name + '/' + + // b.toolchain_version.string ()); + + // return ts.data ? *ts.data + ", " + s : s; + // }; + + return nullptr; + } + // Send a POST request to the GitHub API endpoint `ep`, parse GitHub's JSON // response into `rs` (only for 200 codes), and return the HTTP status code. // @@ -614,7 +734,7 @@ namespace brep { p.next_expect (event::begin_object); - bool nm (false), fn (false), db (false); + bool nm (false), fn (false), db (false), cu (false); // Skip unknown/uninteresting members. // @@ -628,12 +748,14 @@ namespace brep if (c (nm, "name")) name = p.next_expect_string (); else if (c (fn, "full_name")) full_name = p.next_expect_string (); else if (c (db, "default_branch")) default_branch = p.next_expect_string (); + else if (c (cu, "clone_url")) clone_url = p.next_expect_string (); else p.next_expect_value_skip (); } if (!nm) missing_member (p, "repository", "name"); if (!fn) missing_member (p, "repository", "full_name"); if (!db) missing_member (p, "repository", "default_branch"); + if (!cu) missing_member (p, "repository", "clone_url"); } ostream& @@ -641,7 +763,8 @@ namespace brep { os << "name: " << rep.name << endl << "full_name: " << rep.full_name << endl - << "default_branch: " << rep.default_branch << endl; + << "default_branch: " << rep.default_branch << endl + << "clone_url: " << rep.clone_url << endl; return os; } diff --git a/mod/mod-ci-github.hxx b/mod/mod-ci-github.hxx index 9731881..3b696d7 100644 --- a/mod/mod-ci-github.hxx +++ b/mod/mod-ci-github.hxx @@ -10,6 +10,9 @@ #include <mod/module.hxx> #include <mod/module-options.hxx> +#include <mod/ci-common.hxx> +#include <mod/tenant-service.hxx> + namespace butl { namespace json @@ -50,6 +53,7 @@ namespace brep string name; string full_name; string default_branch; + string clone_url; explicit repository (json::parser&); @@ -109,16 +113,21 @@ namespace brep operator<< (ostream&, const installation_access_token&); } - class ci_github: public handler + class ci_github: public handler, + private ci_start, + public tenant_service_build_queued, + public tenant_service_build_building, + public tenant_service_build_built { public: - ci_github () = default; + explicit + ci_github (tenant_service_map&); // Create a shallow copy (handling instance) if initialized and a deep // copy (context exemplar) otherwise. // explicit - ci_github (const ci_github&); + ci_github (const ci_github&, tenant_service_map&); virtual bool handle (request&, response&); @@ -126,6 +135,17 @@ namespace brep virtual const cli::options& cli_options () const {return options::ci_github::description ();} + virtual function<optional<string> (const tenant_service&)> + build_queued (const tenant_service&, + const vector<build>&, + optional<build_state> initial_state) const override; + + virtual function<optional<string> (const tenant_service&)> + build_building (const tenant_service&, const build&) const override; + + virtual function<optional<string> (const tenant_service&)> + build_built (const tenant_service&, const build&) const override; + private: virtual void init (cli::scanner&); @@ -133,7 +153,7 @@ namespace brep // Handle the check_suite event `requested` and `rerequested` actions. // bool - handle_check_suite_request (gh::check_suite_event) const; + handle_check_suite_request (gh::check_suite_event); string generate_jwt () const; @@ -145,6 +165,8 @@ namespace brep private: shared_ptr<options::ci_github> options_; + + tenant_service_map& tenant_service_map_; }; } diff --git a/mod/mod-repository-root.cxx b/mod/mod-repository-root.cxx index 28f642b..d44cdc5 100644 --- a/mod/mod-repository-root.cxx +++ b/mod/mod-repository-root.cxx @@ -134,7 +134,7 @@ namespace brep #else ci_ (make_shared<ci> ()), #endif - ci_github_ (make_shared<ci_github> ()), + ci_github_ (make_shared<ci_github> (*tenant_service_map_)), upload_ (make_shared<upload> ()) { } @@ -206,7 +206,7 @@ namespace brep ci_github_ ( r.initialized_ ? r.ci_github_ - : make_shared<ci_github> (*r.ci_github_)), + : make_shared<ci_github> (*r.ci_github_, *tenant_service_map_)), upload_ ( r.initialized_ ? r.upload_ |