# Radicle CI Broker
## Requirements
- You've created a radicle identity for the "CI" node
- You have the radicle-node and radicle-httpd running
## Process
- 1. Deploy Concourse
- 2. Deploy CI Broker
- 3. Write a Concourse pipeline
- 4. Open a Patch to add the pipeline
- 5. Watch Build Updates as Patch comments
## 1. Deploy Concourse
Basically following the official [quick start guide]()
```yaml=
version: '3'
services:
concourse-db:
image: postgres
environment:
POSTGRES_DB: concourse
POSTGRES_PASSWORD: concourse_pass
POSTGRES_USER: concourse_user
PGDATA: /database
concourse:
image: concourse/concourse
command: quickstart
privileged: true
depends_on: [concourse-db]
ports: ["8080:8080"]
environment:
CONCOURSE_POSTGRES_HOST: concourse-db
CONCOURSE_POSTGRES_USER: concourse_user
CONCOURSE_POSTGRES_PASSWORD: concourse_pass
CONCOURSE_POSTGRES_DATABASE: concourse
CONCOURSE_EXTERNAL_URL: http://localhost:8080
CONCOURSE_ADD_LOCAL_USER: test:test
CONCOURSE_MAIN_TEAM_LOCAL_USER: test
# instead of relying on the default "detect"
CONCOURSE_WORKER_BAGGAGECLAIM_DRIVER: overlay
CONCOURSE_CLIENT_SECRET: Y29uY291cnNlLXdlYgo=
CONCOURSE_TSA_CLIENT_SECRET: Y29uY291cnNlLXdvcmtlcgo=
CONCOURSE_X_FRAME_OPTIONS: allow
CONCOURSE_CONTENT_SECURITY_POLICY: "*"
CONCOURSE_CLUSTER_NAME: tutorial
CONCOURSE_WORKER_CONTAINERD_DNS_SERVER: "8.8.8.8"
# For ARM-based machine, change the Concourse runtime to "houdini"
CONCOURSE_WORKER_RUNTIME: "containerd"
```
## 2. Deploy Radicle CI Broker
Add an extra container to your docker-compose deployment:
```yaml=
radicle-ci-broker:
image: quay.io/gsaslis/radicle-ci
# mount your RAD_HOME as a volume
volumes:
- /home/radicle/.radicle:/root/.radicle
# for SSH agent forwarding
- type: bind
source: ${SSH_AUTH_SOCK}
target: /run/host-services/ssh-auth.sock
# pass in environment variables configuring which Concourse Instance and Radicle HTTPD the broker will connect to
environment:
CONCOURSE_URL: {{ concourse_domain }}
CONCOURSE_USER: {{ concourse_user }}
CONCOURSE_PASS: {{ concourse_password }}
RADICLE_API_URL: https://radicle.yorgos.net.gr # to know where the repo can be cloned from
SSH_AUTH_SOCK: /run/host-services/ssh-auth.sock # for SSH agent forwarding
```
Start Concourse and CI broker:
```yaml=
docker-compose up -d
```
## 3. Write a Concourse pipeline
With those in place, you are now ready to add a Concourse pipeline, **in the special file**: `.concourse/config.yaml` in your repo.
```yaml=
jobs:
- name: pipeline-configure
plan:
- task: get-code
config:
outputs:
- name: repo
platform: linux
image_resource:
type: registry-image
source:
repository: alpine/git
run:
user: root
entrypoint: ""
path: /bin/sh
args:
- -c
- |
git clone ((repo_url)) repo
cd repo
git fetch origin ((patch_revision_id))
git fetch origin ((patch_head))
git checkout FETCH_HEAD
ls -al .concourse
- task: test-all
config:
platform: linux
image_resource:
type: registry-image
source:
repository: quay.io/gsaslis/rust-git-builder # built from https://github.com/gsaslis/rust-git-builder/blob/main/Dockerfile
tag: latest
inputs:
- name: repo
outputs:
- name: output.txt
run:
dir: repo
path: /bin/bash
args:
- -c
- |
git --version
. "$HOME/.cargo/env"
cargo --version
# run tests
RUST_BACKTRACE=1 cargo test --all | tee output.txt
```
## 4. Open a Patch to add the pipeline
```bash=
git add .concourse/config.yaml
git commit -m 'adds pipeline'
git push rad -o patch.message="Add Concourse Pipeline" HEAD:refs/patches
rad sync
```
## 5. Watch Build Updates as Patch comments (for now - Check COBs later)
The moment the broker triggers the concourse pipeline, it adds a comment to the patch:
### Build started
Here's a screenshot of a patch with a comment added by the CI node (comment content still work-in-progress):

### Build Completed
Once the job has completed, another comment confirms this:

### Concourse Job View
This is an example of where the link would lead to:

## 6. Which projects does the CI node run jobs for ?
Any project it tracks.
The Radicle CI Broker subscribes to node events and is specifically interested in `radicle::node::Event::RefsFetched` events.
Right now, it looks for `RefUpdate::Updated` and `RefUpdate::Updated` references related to patches.