Radicle CI adapter implementation

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:

{
  "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.

{"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:

{"response":"finished","result":"success"}

Failure:

{"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.

#!/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.)