# Introduction

The Radicle CI adapter for Ambient integrates the Ambient CI system to
Radicle CI. In other words, this adapter allows Radicle CI to use
Ambient to run CI for Radicle repositories.

# Data files for scenarios

The embedded files in this chapter are used by various scenarios later
in this document.

## `ambient-ci` configuration files

~~~{#ambient.yaml .file .yaml}
tmpdir: .
projects: projects.yaml
executor: ambient-execute-plan
artifacts_max_size: 1G
cache_max_size: 50G
state: state
qemu:
  cpus: 1
  memory: 1G
~~~

## Ambient adapter configuration file

~~~{#radicle-ci-ambient.yaml .file .yaml}
image: ambient.qcow2
logdir: run_logs
log: adminlog.txt
base_url: https://ci.liw.fi
~~~

~~~{#radicle-ci-ambient-trust-repo-name.yaml .file .yaml}
image: ambient.qcow2
logdir: run_logs
log: adminlog.txt
base_url: https://ci.liw.fi
trust_repository_name: true
~~~

## Script to set environment variables and running a command

This is meant to be run as `bash env.sh foo bar`, which is why it
doesn't start with a shebang.

~~~{#env.sh .file .sh}
set -euxo pipefail

export RAD_HOME="$(pwd)"
export RAD_PASSPHRASE="secret"
export RADICLE_CI_AMBIENT=radicle-ci-ambient.yaml

"$@"
~~~

## Script to create repository and set up Radicle

This creates a Git repository in `src` and sets up a Radicle node
called `xyzzy`. It also creates a trigger message as `trigger.json`,
which can be fed to the adapter via its stdin.

This is meant to be run as `bash env.sh foo bar`, which is why it
doesn't start with a shebang.

~~~{#rad-init.sh .file .sh}
set -euxo pipefail

rad auth --alias xyzzy
git init src

mkdir -p src/.radicle
cp "$1" src/.radicle/ambient.yaml

cd src

echo configuring git user
git config user.name "Ambient User"
git config user.email "ambient@example.com"

echo hello, world > greeting.txt
git add .
git commit -m initial

rad init --name abracadabra --description x --private --no-confirm
rad inspect --identity

rid="$(rad .)"
commit="$(git rev-parse HEAD)"

cat <<EOF | jq -c . > ../trigger.json
{
  "request": "trigger",
  "version": 1,
  "event_type": "push",
  "repository": {
    "id": "$rid",
    "name": "abracadabra",
    "description": "x",
    "private": true,
    "default_branch": "main",
    "delegates": [
      "did:key:z6MkgEMYod7Hxfy9qCvDv5hYHkZ4ciWmLFgfvm3Wn1b2w2FV"
    ]
  },
  "pusher": {
    "id": "did:key:z6MkgEMYod7Hxfy9qCvDv5hYHkZ4ciWmLFgfvm3Wn1b2w2FV",
    "alias": "liw"
  },
  "before": "$commit",
  "after": "$commit",
  "branch": "main",
  "commits": [
    "$commit"
  ]
}
EOF
~~~

## Script to run adapter

Due to limitations in Subplot we can't redirect adapter stdin directly
in a scenario, so we use this helper script.

This is meant to be run as `bash env.sh foo bar`, which is why it
doesn't start with a shebang.


~~~{#run.sh .file .sh}
set -euxo pipefail
sha256sum ambient.qcow2 >/dev/null
if ! radicle-ci-ambient < trigger.json; then
    code="$?"
    cat adminlog.txt 1>&2
    exit "$code"
else
    echo "=========================================================="
    pwd
    echo admin log:
    nl adminlog.txt
fi
~~~


# Acceptance criteria

## Adapter reports its version

_Want:_ The adapter can be queried for its version.

_Why:_ This is useful for diagnosing problems, and also acts as a
smoke test: if this works, we know the adapter is installed and can be
run.

~~~scenario
given an installed Ambient adapter
when I run radicle-ci-ambient --version
then stdout matches regex ^radicle-ci-ambient \d+\.\d+\.\d+@.*$
~~~

## Can run a simple project

_Want:_ The adapter can run a very simple project.

_Why:_ If this doesn't work, woe be more intricate projects.

~~~scenario
given an installed Ambient adapter
given an Ambient VM image ambient.qcow2

given file env.sh
given file rad-init.sh
given file simple.yaml
when I run bash env.sh bash rad-init.sh simple.yaml
when I run bash env.sh rad self

given file .config/ambient/config.yaml from ambient.yaml
given file radicle-ci-ambient.yaml
given file run.sh

when I run bash env.sh bash run.sh
then stdout contains ""response":"triggered""
then stdout contains ""result":"success""
then the only HTML log file in run_logs contains "hello from simple world"

then the only HTML log file in run_logs contains "&quot;request&quot;: &quot;trigger&quot;"
then the only HTML log file in run_logs contains "&quot;version&quot;: 1"

then directory state/abracadabra does not exist
~~~

~~~{#simple.yaml .file .yaml}
plan:
- action: shell
  shell: |
    printf '%s %s\n' 'hello from' 'simple world'
~~~

## Uses repository name as Ambient project name when allowed

_Want:_ The node operator can allow use of the Radicle repository name
as the Ambient project name.

_Why:_ This is helpful for using the Ambient `rsync_target_base`
configuration option.

~~~scenario
given an installed Ambient adapter
given an Ambient VM image ambient.qcow2

given file env.sh
given file rad-init.sh
given file simple.yaml
when I run bash env.sh bash rad-init.sh simple.yaml
when I run bash env.sh rad self

given file .config/ambient/config.yaml from ambient.yaml
given file radicle-ci-ambient.yaml from radicle-ci-ambient-trust-repo-name.yaml
given file run.sh
when I run bash env.sh bash run.sh
then stdout contains ""response":"triggered""
then stdout contains ""result":"success""
then the only HTML log file in run_logs contains "hello from simple world"

then the only HTML log file in run_logs contains "&quot;request&quot;: &quot;trigger&quot;"
then the only HTML log file in run_logs contains "&quot;version&quot;: 1"

when I run ls -la state
then directory state/abracadabra exists
~~~

## Give Ambient extra configuration file if needed

_Want:_ The node operator use the `radicle-ci-ambient` configuration
file to pass an extra configuration file to `ambient`.

_Why:_ This allows the node operator to configure the CI broker to
use the Ambient adapter in different ways for different CI runs. For
example, to use the `rsync` Ambient action to deliver to a different
server based on the Radicle repository.

~~~scenario
given an installed Ambient adapter
given an Ambient VM image ambient.qcow2

given file env.sh
given file rad-init.sh
given file simple.yaml
when I run bash env.sh bash rad-init.sh simple.yaml
when I run bash env.sh rad self

given file .config/ambient/config.yaml from ambient.yaml
given file radicle-ci-ambient.yaml from radicle-ci-ambient-extra.yaml
given file extra.yaml
given file run.sh
when I run bash env.sh bash run.sh
when I run find -ls
then directory extra.state/abracadabra exists
~~~

~~~{#radicle-ci-ambient-extra.yaml .file .yaml}
image: ambient.qcow2
logdir: run_logs
log: adminlog.txt
base_url: https://ci.liw.fi
extra_ambient_config: extra.yaml
trust_repository_name: true
~~~

~~~{#extra.yaml .yaml .file}
state: extra.state
~~~


## Give Ambient extra configuration values if needed

_Want:_ The node operator use the `radicle-ci-ambient` configuration
to pass in extra configuration values to `ambient`, without having to
put them into another file.

_Why:_ This is for convenience.


~~~scenario
given an installed Ambient adapter
given an Ambient VM image ambient.qcow2

given file env.sh
given file rad-init.sh
given file simple.yaml
when I run bash env.sh bash rad-init.sh simple.yaml
when I run bash env.sh rad self
given file .config/ambient/config.yaml from ambient.yaml
given file radicle-ci-ambient.yaml from radicle-ci-ambient-extra-values.yaml
given file extra.yaml
given file run.sh
when I run bash env.sh bash run.sh
then directory extra.state/abracadabra exists
~~~

~~~{#radicle-ci-ambient-extra-values.yaml .file .yaml}
image: ambient.qcow2
logdir: run_logs
log: adminlog.txt
base_url: https://ci.liw.fi
extra_ambient_config_values:
  state: extra.state
trust_repository_name: true
~~~

## Handles failing project

_Want:_ The adapter reports a failing CI run correctly.

_Why:_ We need to be sure problems are handled correctly by CI.

~~~scenario
given an installed Ambient adapter
given an Ambient VM image ambient.qcow2

given file env.sh
given file rad-init.sh
given file fail.yaml
when I run bash env.sh bash rad-init.sh fail.yaml

given file .config/ambient/config.yaml from ambient.yaml
given file radicle-ci-ambient.yaml
given file run.sh
when I run bash env.sh bash run.sh
then stdout contains ""response":"triggered""
then stdout contains ""result":"failure""
then the only HTML log file in run_logs contains "oh no"
~~~

~~~{#fail.yaml .file .yaml}
plan:
- action: shell
  shell: |
    echo oh no
    exit 1
~~~
