Radish alpha
r
rad:z3qg5TKmN83afz2fj9z3fQjU8vaYE
Radicle CI adapter for native CI
Radicle
Git
Make it possible to containerize the Native CI
Archived levitte opened 1 year ago

The idea is to make it possible to specify a lancher script as adapter for the CI Broker, like this:

db: $HOME/.radicle-ci/ci-broker.sqlite
report_dir: $HOME/.radicle-ci/report
default_adapter: native
adapters:
  native:
    command: $HOME/.local/bin/launch-native-ci
    env:
    sensitive_env:
filters:
  - !And
    - !Repository "rad:z3gqcJUoA1n9HaHKufZs5FCSGazv5"
    - !Branch "master"

The Native CI’s config.yaml is created by launch-native-ci.

Environment variables that can be used to configure launch-native-ci:

  • RAD_HOME

    Radicle Home. default: $HOME/.radicle

  • RADICLE_NCI_HOME

    Radicle Native CI Home. default: $HOME/.radicle-native-ci

  • RADICLE_NCI_BASE_URL

    Base URL to map the state directory to. default: file:///$HOME/.radicle-native-ci/var/radicle-nci/state

Directories and files created by launch-native-ci:

$RADICLE_NCI_HOME
  |
  +-- etc
  |    |
  |    +--- config.yaml
  |
  +-- var
       |
       +--- state
       |
       +--- logs
6 files changed +165 -23 758dde8f 752c9fbb
added .containerignore
@@ -0,0 +1 @@
+
/target
modified README.md
@@ -2,15 +2,10 @@

This is an adapter for the [Radicle CI broker], for performing CI runs
locally. This means it reads a JSON message from its stdin, and writes
-
two JSON messages to its stdout. Its configured via a configuration
-
file specified in the `RADICLE_NATIVE_CI` environment variable. There
-
is currently no logging.
+
two JSON messages to its stdout.

-
The CI run is performed locally, without any isolation. This is not
-
safe and secure, but it's simple, and easy to get working. Do not use
-
this unless you trust the repository and its dependencies.
-

-
The repository must contain a file `./radicle/native.yaml` that
+
Any repository that `radicle-native-ci` works with must contain the
+
file `.radicle/native.yaml`, or it will do nothing.  This file
specifies how CI is run for the repository. For example:

```yaml
@@ -20,26 +15,19 @@ shell: |

[Radicle CI broker]: https://app.radicle.xyz/nodes/radicle.liw.fi/rad:zwTxygwuz5LDGBq255RA2CbNGrz8

-
This crate also includes the program `rad-ci`, which runs the commands
-
the adapter runs when invoked by the CI broker. To use: install it on
-
your `$PATH` (using `cargo install`) and run:
-

-
```sh
-
rad ci
-
```
-

-
This will read `.radicle/native.yaml` and run the shell commands
-
specified there.
+
There are two ways to run `radicle-native-ci`:

-
(No command line arguments or options needed, nor any environment
-
variables for this.)
+
- directly, by just running the binary
+
- in a container

-
## Architecture

-
See the [documentation](doc) directory for an architecture document.
+
## Running `radicle-native-ci` directly

+
The CI run is performed locally, without any isolation. This is not
+
safe and secure, but it's simple, and easy to get working. Do not use
+
this unless you trust the repository and its dependencies.

-
## Configuration
+
### Configuration

The adapter requires the `RADICLE_NATIVE_CI` environment variable to
be set to the filename of a configuration file in YAML. For example:
@@ -57,6 +45,62 @@ The fields are:
* `log` --- required, file where native CI should write a log


+
## Running `radicle-native-ci` in a container
+

+
The CI run is performed locally, but within the isolation of a
+
container.  It also requires a container image `radicle-native-ci` to
+
be created and a script to be installed.  Both are easily done as
+
follows:
+

+
~~~console
+
$ ./containerize/install.sh --prefix=$HOME/.local
+
~~~
+

+
When this is done, use `$HOME/.local/bin/launch-native-ci` instead of
+
`radicle-native-ci` in the [Radicle CI broker] coniguration.
+

+
### Configuration
+

+
`launch-native-ci` is configured entirely with environment variables,
+
of which the main are:
+

+
-   `RAD_HOME`
+

+
    The Radicle home directory (default: `$HOME/.radicle`)
+

+
-   `RADICLE_NCI_HOME`
+

+
    The Radicle Native CI home directory, where its configuration and
+
    data are stored (default: `$HOME/.radicle-native-ci`)
+

+
-   `RADICLE_NCI_BASE_URL`
+

+
    The Base for URLs to feed back to the [Radicle CI broker].
+
    It should map to `$RADICLE_NCI_HOME/var/state`.
+

+

+
## Other programs included in this crate
+

+
This crate also includes the program `rad-ci`, which runs the commands
+
the adapter runs when invoked by the CI broker. To use: install it on
+
your `$PATH` (using `cargo install`) and run:
+

+
```sh
+
rad ci
+
```
+

+
This will read `.radicle/native.yaml` and run the shell commands
+
specified there.
+

+
(No command line arguments or options needed, nor any environment
+
variables for this.)
+

+

+
## Architecture
+

+
See the [documentation](doc) directory for an architecture document.
+

+

## Packaging

There is simple, simplistic, rudimentary, personal-use-only packaging
added containerize/Containerfile
@@ -0,0 +1,29 @@
+
# Make a build image, and build /usr/bin/radicle-native-ci
+
FROM docker.io/rust:1.80.0-bookworm as builder
+
WORKDIR /src
+
COPY . .
+

+
RUN cargo install --path . --root /usr --locked
+

+
# Make a new image, which is essentially Debian bookworm
+
# with rust tools added.  This avoids carrying around all
+
# the build artifacts, saving quite a bit of space.
+
FROM docker.io/rust:bookworm as runtime
+

+
# Include popular build tools
+
RUN apt update -y
+
RUN apt install -y build-essential cmake
+

+
# Include the Native CI adapter
+
COPY --from=builder /usr/bin/radicle-native-ci /usr/bin
+

+
# We want external volumes for the Radicle HOME and the
+
# Radicle Native CI HOME.  The Radicle HOME is expected to
+
# be read-only, while the Radicle Native CI HOME is expected
+
# to be reaad-write
+
VOLUME ["/var/radicle", "/etc/radicle-nci", "/var/radicle-nci"]
+
ENV RAD_HOME /var/radicle
+
ENV RADICLE_NATIVE_CI /etc/radicle-nci/config.yaml
+

+
# By default, just run the Native CI
+
CMD ["/usr/bin/radicle-native-ci"]
added containerize/build.sh
@@ -0,0 +1,4 @@
+
#! /bin/sh
+

+
HERE=$(dirname $0)
+
podman build -t radicle-native-ci -f $HERE/Containerfile $HERE/..
added containerize/install.sh
@@ -0,0 +1,26 @@
+
#! /bin/sh -e
+

+
PREFIX=$HOME/.local
+
BUILD=true
+
while :; do
+
    case "$1" in
+
        --no-build)
+
            BUILD=false
+
            ;;
+
        --prefix=*)
+
            PREFIX=${1#*=}
+
            ;;
+
        -*)
+
            echo >&2 "Unrecognized argument '$1'"
+
            exit 1
+
            ;;
+
        *)
+
            break
+
            ;;
+
    esac
+
    shift
+
done
+

+
HERE=$(dirname $0)
+
if $BUILD; then $HERE/build.sh; fi
+
install $HERE/launch-native-ci $PREFIX/bin
added containerize/launch-native-ci
@@ -0,0 +1,38 @@
+
#! /bin/sh
+

+
RAD_HOME=${RAD_HOME:-$HOME/.radicle}
+
RADICLE_NCI_HOME=${RADICLE_NCI_HOME:-$HOME/.radicle-native-ci}
+
RADICLE_NCI_DATA=${RADICLE_NCI_DATA:-$RADICLE_NCI_HOME/var}
+
RADICLE_NCI_CONFIG=${RADICLE_NCI_CONFIG:-$RADICLE_NCI_HOME/etc}
+
RADICLE_NCI_BASE_URL=${RADICLE_NCI_BASE_URL:-file:///$RADICLE_NCI_DATA/state}
+

+
missing=
+
for d in "$RAD_HOME" "$RADICLE_NCI_HOME"; do
+
    if ! [ -d "$d" ]; then
+
        missing="'$d'"${missing:+ ${missing}}
+
    fi
+
done
+
if [ -n "$missing" ]; then
+
    echo >&2 "Cannot launch radicle-native-ci because the following directories are missing"
+
    echo >&2 "$missing"
+
    exit 1
+
fi
+

+
mkdir -p $RADICLE_NCI_CONFIG
+
mkdir -p $RADICLE_NCI_DATA/state
+
mkdir -p $RADICLE_NCI_DATA/logs
+

+
if ! [ -f $RADICLE_NCI_CONFIG/config.yaml ]; then
+
    cat > $RADICLE_NCI_CONFIG/config.yaml <<_____
+
base_url: $RADICLE_NCI_BASE_URL
+
state: /var/radicle-nci/state
+
log: /var/radicle-nci/logs/native-ci.log
+
_____
+
fi
+

+
podman run -i \
+
       --volume "$RAD_HOME":/var/radicle:ro \
+
       --volume "$RADICLE_NCI_CONFIG":/etc/radicle-nci \
+
       --volume "$RADICLE_NCI_DATA":/var/radicle-nci \
+
       radicle-native-ci \
+
       "$@"