| + |
# Implementing a CI adapter
|
| + |
|
| + |
A CI adapter reads a line from its stdin of JSON containing the "trigger
|
| + |
message". This tells the adapter which repository and commit to run CI on.
|
| + |
There's also some other data there, in case it's useful.
|
| + |
|
| + |
A trigger message, formatted for readability, might look like this:
|
| + |
|
| + |
~~~json
|
| + |
{
|
| + |
"request": "trigger",
|
| + |
"version": 1,
|
| + |
"event_type": "push",
|
| + |
"repository": {
|
| + |
"id": "rad:z3uBEubocQ9kJANPvMAo6z5ZhhaFh",
|
| + |
"name": "pathdedup",
|
| + |
"description": "De-duplicate $PATH",
|
| + |
"private": false,
|
| + |
"default_branch": "main",
|
| + |
"delegates": [
|
| + |
"did:key:z6MkgEMYod7Hxfy9qCvDv5hYHkZ4ciWmLFgfvm3Wn1b2w2FV"
|
| + |
]
|
| + |
},
|
| + |
"pusher": {
|
| + |
"id": "did:key:z6MkgEMYod7Hxfy9qCvDv5hYHkZ4ciWmLFgfvm3Wn1b2w2FV",
|
| + |
"alias": "liw"
|
| + |
},
|
| + |
"before": "b40598e76a43f3a9c171f8422fc6fd1e2a94f87f",
|
| + |
"after": "b40598e76a43f3a9c171f8422fc6fd1e2a94f87f",
|
| + |
"branch": "main",
|
| + |
"commits": [
|
| + |
"b40598e76a43f3a9c171f8422fc6fd1e2a94f87f"
|
| + |
]
|
| + |
}
|
| + |
~~~
|
| + |
|
| + |
The adapter outputs two lines of JSON. First is the "triggered" message, which
|
| + |
it outputs when CI has started to run and the run ID is known.
|
| + |
|
| + |
~~~json
|
| + |
{"response":"triggered","run_id":{"id":"AI-wonderland"}}
|
| + |
~~~
|
| + |
|
| + |
The second one is output once the CI run has finished and the adapter knows if the
|
| + |
run succeded or failed. Success message:
|
| + |
|
| + |
~~~json
|
| + |
{"response":"finished","result":"success"}
|
| + |
~~~
|
| + |
|
| + |
Failure:
|
| + |
|
| + |
~~~json
|
| + |
{"response":"finished","result":"failure"}
|
| + |
~~~
|
| + |
|
| + |
The adapter must not output anything else to its stdout.
|
| + |
|
| + |
The adapter can output log messages or other things to its stderr. These are
|
| + |
captured and logged by the CI broker.
|
| + |
|
| + |
## Example adapter
|
| + |
|
| + |
As a silly example of an adapter, the following shell scripts implements
|
| + |
CI using advanced artificial intelligence technology. The threshold can be
|
| + |
adjusted based on how much the repository owner pays for the service.
|
| + |
|
| + |
~~~sh
|
| + |
#!/bin/bash
|
| + |
|
| + |
set -euo pipefail
|
| + |
|
| + |
THRESHOLD=15000
|
| + |
|
| + |
# Read the trigger message into a file where we can query it repeatedly.
|
| + |
tmp="$(mktemp -d)"
|
| + |
trap 'rm -rf "$tmp"' EXIT
|
| + |
cd "$tmp"
|
| + |
cat > "trigger.json"
|
| + |
repoid="$(jq -r .repository.id trigger.json)"
|
| + |
commit="$(jq -r .after trigger.json)"
|
| + |
name="$(jq -r .repository.name trigger.json)"
|
| + |
|
| + |
# Check out the repository
|
| + |
chronic rad checkout "$repoid"
|
| + |
cd "$name"
|
| + |
git checkout -q "$commit"
|
| + |
|
| + |
# Send response to say we start CI run.
|
| + |
echo '{"response":"triggered","run_id":{"id":"AI-wonderland"}}'
|
| + |
|
| + |
# Decide if we succeed or fail.
|
| + |
echo "Trying hard to figure out if run will succeed or fail" 2>&1
|
| + |
if [ "$RANDOM" -gt "$THRESHOLD" ]; then
|
| + |
echo '{"response":"finished","result":"success"}'
|
| + |
else
|
| + |
echo '{"response":"finished","result":"failure"}'
|
| + |
fi
|
| + |
~~~
|
| + |
|
| + |
While this is a bit of a joke, if you change the `echo "Trying..."` line with
|
| + |
something that actually does useful work, this is basically a production ready
|
| + |
adapter.
|
| + |
|
| + |
(Except you should rewrite it something more sensible than shell for procution
|
| + |
use.)
|