docs: add initial architecture document and diagrams

Signed-off-by: Lars Wirzenius <liw@liw.fi>
This commit is contained in:
Lars Wirzenius
2023-12-06 13:17:14 +02:00
parent 2bd8b98528
commit cd86193927
8 changed files with 196 additions and 0 deletions
+119
View File
@@ -0,0 +1,119 @@
---
title: Radicle CI architecture
...
# Overview
CI support in Radicle consists of several components. For native CI
they are:
* the Radicle node
* the CI broker
* the native CI executable
These all run on the same host.
For external CI, the components are:
* the Radicle node
* the CI broker
* an executable for each supported external CI instance
* the external CI instance
The first three of these run on the same host, but the external CI
instance can run anywhere.
The child process is called "the CI adapter" in this document.
CI works like this:
* a repository known to the node changes
- a git ref is updated
- the ref can be a branch, tag, or something else, such as a Radicle
COB
- the node emits an event describing the change
* the CI broker listens to node event
- the broker subscribers to node events via the node control socket,
which is a Unix domain socket
* the CI broker filters events, based on its configuration, and the
configuration for the repository involved
* for an event that passes its filters, the CI broker spawns the
adapter process
- the adapter process is either the native CI engine, or an
integration with an external CI engine
- the CI broker uses the executable for native CI by default, but
this can be overridden by the broker configuration file, and that
can be overridden by the `.ci/config.yaml` file in the repository
the event is for
* the broker sends a request object to the adapter as a child process,
via the child's stdin, and reads any responses from the child's
stdout
- the request is JSON
- the responses are in the form of JSON Lines: a JSON object per
line serialized to not contain newline characters
## Native CI
![Sequence diagram for native CI](architecture.svg)
## External CI
![Sequence diagram for external CI](architecture.svg)
# The adapter
The adapter process reads the request to perform a CI run on a
specific commit in a repository, and responds with the id of the run,
then later with the status of the finished run.
Note: this is for the first version. This will be expanded later with
other requests and responses, as needed.
For native CI, the adapter actually is the CI engine and performs the
CI run itself. For external CI, the adapter process does whatever it
needs to do to get the external CI engine instance to perform the CI
run. If the CI engine calls back via web hook to notify of the run
finishing, the adapter process needs to receive the call and process
it.
# Request and response messages
Note: the JSON objects below are formatted on multiple lines to make
them easier to read. The actual wire format is one line per message.
The request that the broker sends looks like this:
~~~{.json .numberLines}
{
"request": "trigger",
"repo": "<RID>",
"commit": "<COMMIT>"
}
~~~
where `<RID>` is the repository ID, and `<COMMIT>` is the commit id
(the SHA checksum). The `request` fields allows us to extend this in
the future.
The first response from the adapter looks like this:
~~~{.json .numberLines}
{
"response": "triggered",
"run_id": "<RUNID>"
}
~~~
where `<RUNID>` is the id of the run that has been triggered.
The second response from the adapter looks like this:
~~~{.json .numberLines}
{
"response": "finished",
"result": "<STATUS>"
}
~~~
where `<STATUS>` is either the string `success` or `failure`. Note
that the run id is not repeated as the context makes this clear.