aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrancois Kritzinger <francois@codesynthesis.com>2024-03-07 09:49:06 +0200
committerFrancois Kritzinger <francois@codesynthesis.com>2024-04-24 15:14:54 +0200
commit7c8dec0983de14ec14bd0ae9912b072807c25335 (patch)
treeb3103af370225ca62650bee91339a4bcf06010f9
parent971155e0d79d8119c66551e58f538b845cba5bf9 (diff)
GitHub CI: add CI support
-rw-r--r--mod/mod-ci-github.cxx133
-rw-r--r--mod/mod-ci-github.hxx30
-rw-r--r--mod/mod-repository-root.cxx4
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_