by 96bcaa76-0f27-45e7-9aa3-65c535e53a05

Radicle: Distributed Git Forge

radicle

Radicle is a decentralized git forge. It is still very new as you can see from what I had to do to get it running but I am hopeful it could eventually replace github at least for me. my node is here radicle I am still working on the best way to house artifacts, but the ci is running and running with devbox support so easy to have standard reproducable environments.

configs

.radicle/config.json

{
  "publicExplorer": "https://app.radicle.xyz/nodes/$host/$rid$path",
  "preferredSeeds": [
    "z6MkrLMMsiPWUcNPHcRajuMi9mDfYckSoJyPwwnknocNYPm7@seed.radicle.garden:8776",
    "z6Mkmqogy2qEM2ummccUthFEaaHvyYmYBYh3dbe9W4ebScxo@ash.radicle.garden:8776"
  ],
  "web": {
    "pinned": {
      "repositories": [
"rad:z2ixRGetGtwFtRyXjRgu5fH573wyy",
"rad:z3N1dSXzVuiJVeJyBG17KRxgySnGs", 
"rad:zwTxygwuz5LDGBq255RA2CbNGrz8",
"rad:z4V1sjrXqjvFdnCUbxPFqd5p4DtH5",
"rad:z3gqcJUoA1n9HaHKufZs5FCSGazv5", 
"rad:z3qg5TKmN83afz2fj9z3fQjU8vaYE" 
      ]
    }
  },
  "cli": {
    "hints": true
  },
  "node": {
    "alias": "rad.rldn.net",
    "listen": ["0.0.0.0:8776"],
    "externalAddresses": [
      "rad.rldn.net:8776"
    ],
    "peers": {
      "type": "dynamic"
    },
    "connect": [],
    "network": "main",
    "log": "INFO",
    "relay": "auto",
    "limits": {
      "routingMaxSize": 1000,
      "routingMaxAge": 604800,
      "gossipMaxAge": 1209600,
      "fetchConcurrency": 1,
      "maxOpenFiles": 4096,
      "rate": {
        "inbound": {
          "fillRate": 5.0,
          "capacity": 1024
        },
        "outbound": {
          "fillRate": 10.0,
          "capacity": 2048
        }
      },
      "connection": {
        "inbound": 128,
        "outbound": 16
      }
    },
    "workers": 8,
    "seedingPolicy": {
      "default": "block"
    }
  }
}

radicle-cib.yaml

default_adapter: native
db: /mnt/drive_1/state/radicle/ci-broker.sqlite
report_dir: /mnt/drive_1/state/radicle/reports
adapters:
  native:
    command: radicle-native-ci
    env:
      RADICLE_NATIVE_CI: /mnt/drive_1/state/radicle/radicle-native.yaml
    sensitive_env:
      some_secret: some_secret_value_that_is_not_logged
filters:
  - !And
    - !Repository "rad:z2ixRGetGtwFtRyXjRgu5fH573wyy"
    - !Or
      - !Branch "main"
      - !AnyPatchRef

radicle-native.yaml

state: /mnt/drive_1/state/radicle/reports/http
log: /mnt/drive_1/state/radicle/native-ci.log
base_url: https://radci.rldn.net/http

package setup

radicle-ci-broker.nix

{ fetchgit
, rustPlatform
, stdenv
, lib
}: rustPlatform.buildRustPackage rec {
  pname = "radicle-ci-broker";
  version = "0.8.0";
  src = fetchgit {
    url = "https://radapi.rldn.net/zwTxygwuz5LDGBq255RA2CbNGrz8.git";
    rev = "cdc4af1462af48fa61ec96da1e549cfb8c537028";
    hash = "sha256-+CXxljESm/thCQPcG7k5/l5SnLtgMKRHSkKPr4XNnWc=";
  };
  cargoHash = "sha256-k8aHeouZ9PaYZZkRccEIBpp9YCESp5FuU48Qdgtnyx0=";
 doCheck = false;
  meta = {
    description = "Radicle CI Broker";
    longDescription = ''
      Radicle is an open source, peer-to-peer code collaboration stack built on Git.
      This is a CI broker for that stack.
    '';
    homepage = "https://radicle.xyz";
    license = with lib.licenses; [ asl20 mit ];
    platforms = lib.platforms.unix;
    maintainers = with lib.maintainers; [ mog ];
    mainProgram = "cib";
  };
}

radicle-native-ci.nix

{ fetchgit
, rustPlatform
, stdenv
, lib
}: rustPlatform.buildRustPackage rec {
  pname = "radicle-native-ci";
  version = "0.3.0";
  src = fetchgit {
    url = "https://radapi.rldn.net/z3qg5TKmN83afz2fj9z3fQjU8vaYE.git";
    rev = "6b0b32bb7546f1efe7e8fef995a14593aac6a605";
    hash = "sha256-KJD+0r5XJFbpK8/a0g/OmPIqCWjOqVuoC2YWKHTXNw4=";
#lib.fakeHash;
  };
  cargoHash =  "sha256-y75yHms8KerrPEAXo9ha4zeqZRjeTCYiXHJdA3jGgDg=";
#lib.fakeHash;
  doCheck = false;
    
  meta = {
    description = "Radicle Native CI";
    longDescription = ''
      Radicle is an open source, peer-to-peer code collaboration stack built on Git.
      This is the runner for the broker
    '';
    homepage = "https://radicle.xyz";
    license = with lib.licenses; [ asl20 mit ];
    platforms = lib.platforms.unix;
    maintainers = with lib.maintainers; [ mog ];
    mainProgram = "cib";
  };
}

radicle service


systemd.services.mog_radicle = {
  enable = true;
  after = [ "network.target" ];
  wantedBy = [ "default.target" ];
  description = "Mog radicle";
  path = [ pkgs.unstable.radicle-httpd
           pkgs.unstable.radicle-node
           (pkgs.unstable.callPackage ../pkgs/radicle-ci-broker.nix { })
           (pkgs.unstable.callPackage ../pkgs/radicle-native-ci.nix { })
           pkgs.bash
           pkgs.git
           pkgs.nix
           pkgs.devbox
         ];
  serviceConfig = {
      Type = "simple";
      User = "mog";
      Restart = "always";
      RestartSec = "3"; # Added
      ExecStart = ''/home/mog/code/dotfiles/nixos/services/radicle.sh'';
  };
};

radicle bash script

#!/usr/bin/env bash
rad node start
radicle-httpd --listen 127.0.0.1:8675 &
cib --config /mnt/drive_1/state/radicle/radicle-cib.yaml process-events

caddy config

    virtualHosts."radapi.rldn.net" = {
      useACMEHost = "rldn.net";
      extraConfig = ''
       reverse_proxy http://127.0.0.1:8675
    '';
    };

    virtualHosts."rad.rldn.net" = {
      useACMEHost = "rldn.net";
      extraConfig = ''
        root * /mnt/drive_1/state/radicle-explorer/build
	try_files {path} /index.html
        file_server
    '';
    };

    virtualHosts."radci.rldn.net" = {
      useACMEHost = "rldn.net";
      extraConfig = ''
        root * /mnt/drive_1/state/radicle/reports
	try_files {path} /index.html
        file_server
    '';
    };