radicle-ci-broker: init at 0.21.0, radicle-native-ci: init at 0.11.1 (#436583)
This commit is contained in:
@@ -60,6 +60,10 @@
|
|||||||
|
|
||||||
- [go-httpbin](https://github.com/mccutchen/go-httpbin), a reasonably complete and well-tested golang port of httpbin, with zero dependencies outside the go stdlib. Available as [services.go-httpbin](#opt-services.go-httpbin.enable).
|
- [go-httpbin](https://github.com/mccutchen/go-httpbin), a reasonably complete and well-tested golang port of httpbin, with zero dependencies outside the go stdlib. Available as [services.go-httpbin](#opt-services.go-httpbin.enable).
|
||||||
|
|
||||||
|
- [radicle-ci-broker](https://app.radicle.xyz/nodes/seed.radicle.xyz/rad:zwTxygwuz5LDGBq255RA2CbNGrz8), runs CI for repositories in the local [Radicle](https://radicle.xyz/) node. Available as [services.radicle.ci.broker.enable](#opt-services.radicle.ci.broker.enable).
|
||||||
|
|
||||||
|
- [radicle-native-ci](https://app.radicle.xyz/nodes/seed.radicle.xyz/rad:z3qg5TKmN83afz2fj9z3fQjU8vaYE), an adapter for the [Radicle CI broker](https://app.radicle.xyz/nodes/seed.radicle.xyz/rad:zwTxygwuz5LDGBq255RA2CbNGrz8), for performing CI runs locally. Available as [services.radicle.ci.adapters.native](#opt-services.radicle.ci.adapters.native.instances).
|
||||||
|
|
||||||
- [llama-swap](https://github.com/mostlygeek/llama-swap), a light weight transparent proxy server that provides automatic model swapping to llama.cpp's server (or any server with an OpenAI compatible endpoint). Available as [](#opt-services.llama-swap.enable).
|
- [llama-swap](https://github.com/mostlygeek/llama-swap), a light weight transparent proxy server that provides automatic model swapping to llama.cpp's server (or any server with an OpenAI compatible endpoint). Available as [](#opt-services.llama-swap.enable).
|
||||||
|
|
||||||
- [tuwunel](https://matrix-construct.github.io/tuwunel/), a federated chat server implementing the Matrix protocol, forked from Conduwuit. Available as [services.matrix-tuwunel](#opt-services.matrix-tuwunel.enable).
|
- [tuwunel](https://matrix-construct.github.io/tuwunel/), a federated chat server implementing the Matrix protocol, forked from Conduwuit. Available as [services.matrix-tuwunel](#opt-services.matrix-tuwunel.enable).
|
||||||
|
|||||||
@@ -506,6 +506,8 @@
|
|||||||
./services/continuous-integration/jenkins/default.nix
|
./services/continuous-integration/jenkins/default.nix
|
||||||
./services/continuous-integration/jenkins/job-builder.nix
|
./services/continuous-integration/jenkins/job-builder.nix
|
||||||
./services/continuous-integration/jenkins/slave.nix
|
./services/continuous-integration/jenkins/slave.nix
|
||||||
|
./services/continuous-integration/radicle/adapters/native.nix
|
||||||
|
./services/continuous-integration/radicle/ci-broker.nix
|
||||||
./services/continuous-integration/woodpecker/agents.nix
|
./services/continuous-integration/woodpecker/agents.nix
|
||||||
./services/continuous-integration/woodpecker/server.nix
|
./services/continuous-integration/woodpecker/server.nix
|
||||||
./services/databases/aerospike.nix
|
./services/databases/aerospike.nix
|
||||||
|
|||||||
@@ -0,0 +1,141 @@
|
|||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.services.radicle.ci.adapters.native;
|
||||||
|
brokerCfg = config.services.radicle.ci.broker;
|
||||||
|
|
||||||
|
settingsFormat = pkgs.formats.yaml { };
|
||||||
|
|
||||||
|
enabledInstances = lib.filter (instance: instance.enable) (lib.attrValues cfg.instances);
|
||||||
|
in
|
||||||
|
|
||||||
|
{
|
||||||
|
meta.maintainers = with lib.maintainers; [ defelo ];
|
||||||
|
|
||||||
|
options.services.radicle.ci.adapters.native = {
|
||||||
|
instances = lib.mkOption {
|
||||||
|
type = lib.types.attrsOf (
|
||||||
|
lib.types.submodule (
|
||||||
|
{ config, name, ... }:
|
||||||
|
{
|
||||||
|
options = {
|
||||||
|
enable = lib.mkEnableOption "this radicle-native-ci instance" // {
|
||||||
|
default = true;
|
||||||
|
example = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
name = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = ''
|
||||||
|
Adapter name that is used in the radicle-ci-broker configuration.
|
||||||
|
Defaults to the attribute name.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
package = lib.mkPackageOption pkgs "radicle-native-ci" { };
|
||||||
|
|
||||||
|
runtimePackages = lib.mkOption {
|
||||||
|
type = lib.types.listOf lib.types.package;
|
||||||
|
description = "Packages added to the adapter's {env}`PATH`.";
|
||||||
|
defaultText = lib.literalExpression ''
|
||||||
|
with pkgs; [
|
||||||
|
bash
|
||||||
|
coreutils
|
||||||
|
curl
|
||||||
|
gawk
|
||||||
|
gitMinimal
|
||||||
|
gnused
|
||||||
|
wget
|
||||||
|
]
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
settings = lib.mkOption {
|
||||||
|
type = lib.types.submodule {
|
||||||
|
freeformType = settingsFormat.type;
|
||||||
|
|
||||||
|
options = {
|
||||||
|
state = lib.mkOption {
|
||||||
|
type = lib.types.path;
|
||||||
|
description = "Directory where per-run directories are stored.";
|
||||||
|
defaultText = lib.literalExpression ''"''${config.services.radicle.ci.broker.stateDir}/adapters/native/${config.name}"'';
|
||||||
|
};
|
||||||
|
|
||||||
|
log = lib.mkOption {
|
||||||
|
type = lib.types.path;
|
||||||
|
description = "File where radicle-native-ci should write the run log.";
|
||||||
|
defaultText = lib.literalExpression ''"''${config.services.radicle.ci.broker.logDir}/adapters/native/${config.name}.log"'';
|
||||||
|
};
|
||||||
|
|
||||||
|
base_url = lib.mkOption {
|
||||||
|
type = lib.types.nullOr lib.types.str;
|
||||||
|
description = "Base URL for build logs (mandatory for access from CI broker page).";
|
||||||
|
default = null;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
description = ''
|
||||||
|
Configuration of radicle-native-ci.
|
||||||
|
See <https://app.radicle.xyz/nodes/seed.radicle.xyz/rad:z3qg5TKmN83afz2fj9z3fQjU8vaYE#configuration> for more information.
|
||||||
|
'';
|
||||||
|
default = { };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = {
|
||||||
|
name = lib.mkDefault name;
|
||||||
|
|
||||||
|
runtimePackages = with pkgs; [
|
||||||
|
bash
|
||||||
|
coreutils
|
||||||
|
curl
|
||||||
|
gawk
|
||||||
|
gitMinimal
|
||||||
|
gnused
|
||||||
|
wget
|
||||||
|
];
|
||||||
|
|
||||||
|
settings = {
|
||||||
|
state = lib.mkDefault "${brokerCfg.stateDir}/adapters/native/${config.name}";
|
||||||
|
log = lib.mkDefault "${brokerCfg.logDir}/adapters/native/${config.name}.log";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
description = "radicle-native-ci adapter instances.";
|
||||||
|
default = { };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf (enabledInstances != [ ]) {
|
||||||
|
services.radicle.ci.broker.settings.adapters = lib.listToAttrs (
|
||||||
|
map (
|
||||||
|
instance:
|
||||||
|
lib.nameValuePair instance.name {
|
||||||
|
command = lib.getExe instance.package;
|
||||||
|
config = instance.settings;
|
||||||
|
config_env = "RADICLE_NATIVE_CI";
|
||||||
|
env.PATH = lib.makeBinPath instance.runtimePackages;
|
||||||
|
}
|
||||||
|
) enabledInstances
|
||||||
|
);
|
||||||
|
|
||||||
|
systemd.tmpfiles.settings.radicle-native-ci = lib.listToAttrs (
|
||||||
|
map (
|
||||||
|
instance:
|
||||||
|
lib.nameValuePair (builtins.dirOf instance.settings.log) {
|
||||||
|
d = {
|
||||||
|
user = config.users.users.radicle.name;
|
||||||
|
group = config.users.groups.radicle.name;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
) enabledInstances
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,256 @@
|
|||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.services.radicle.ci.broker;
|
||||||
|
|
||||||
|
settingsFormat = pkgs.formats.json { };
|
||||||
|
configFile = pkgs.runCommand "ci-broker.json" { } (
|
||||||
|
''
|
||||||
|
cp ${settingsFormat.generate "ci-broker.json" cfg.settings} $out
|
||||||
|
''
|
||||||
|
+ lib.optionalString cfg.checkConfig ''
|
||||||
|
${lib.getExe' cfg.package "cib"} --config $out config
|
||||||
|
''
|
||||||
|
);
|
||||||
|
|
||||||
|
RAD_HOME = "/var/lib/radicle";
|
||||||
|
|
||||||
|
# Convenient wrapper to run `cibtool` in the namespaces of `radicle-ci-broker.service`
|
||||||
|
cibtool-system = pkgs.writeShellScriptBin "cibtool-system" ''
|
||||||
|
set -o allexport
|
||||||
|
${lib.toShellVars {
|
||||||
|
inherit RAD_HOME;
|
||||||
|
HOME = RAD_HOME;
|
||||||
|
}}
|
||||||
|
# Note that --env is not used to preserve host's envvars like $TERM
|
||||||
|
exec ${lib.getExe' pkgs.util-linux "nsenter"} -a \
|
||||||
|
-t "$(${lib.getExe' config.systemd.package "systemctl"} show -P MainPID radicle-ci-broker.service)" \
|
||||||
|
-S "$(${lib.getExe' config.systemd.package "systemctl"} show -P UID radicle-ci-broker.service)" \
|
||||||
|
-G "$(${lib.getExe' config.systemd.package "systemctl"} show -P GID radicle-ci-broker.service)" \
|
||||||
|
${lib.getExe' cfg.package "cibtool"} --db ${lib.escapeShellArg cfg.settings.db} "$@"
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
|
||||||
|
{
|
||||||
|
meta.maintainers = with lib.maintainers; [ defelo ];
|
||||||
|
|
||||||
|
options.services.radicle.ci.broker = {
|
||||||
|
enable = lib.mkEnableOption "radicle-ci-broker";
|
||||||
|
|
||||||
|
package = lib.mkPackageOption pkgs "radicle-ci-broker" { };
|
||||||
|
|
||||||
|
stateDir = lib.mkOption {
|
||||||
|
type = lib.types.path;
|
||||||
|
description = "State directory of radicle-ci-broker.";
|
||||||
|
default = "/var/lib/radicle-ci";
|
||||||
|
};
|
||||||
|
|
||||||
|
logDir = lib.mkOption {
|
||||||
|
type = lib.types.path;
|
||||||
|
description = "Log directory of radicle-ci-broker.";
|
||||||
|
default = "/var/log/radicle-ci";
|
||||||
|
};
|
||||||
|
|
||||||
|
enableHardening = lib.mkEnableOption "systemd hardening" // {
|
||||||
|
default = true;
|
||||||
|
example = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
checkConfig =
|
||||||
|
lib.mkEnableOption "checking the {file}`ci-broker.yaml` file resulting from [](#opt-services.radicle.ci.broker.settings)"
|
||||||
|
// {
|
||||||
|
default = true;
|
||||||
|
example = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
settings = lib.mkOption {
|
||||||
|
type = lib.types.submodule {
|
||||||
|
freeformType = settingsFormat.type;
|
||||||
|
|
||||||
|
options = {
|
||||||
|
db = lib.mkOption {
|
||||||
|
type = lib.types.path;
|
||||||
|
description = "Database file path.";
|
||||||
|
defaultText = lib.literalExpression ''"''${config.services.radicle.ci.broker.stateDir}/ci-broker.db"'';
|
||||||
|
};
|
||||||
|
|
||||||
|
report_dir = lib.mkOption {
|
||||||
|
type = lib.types.nullOr lib.types.path;
|
||||||
|
description = "Directory where HTML and JSON report pages are written.";
|
||||||
|
defaultText = lib.literalExpression ''"''${config.services.radicle.ci.broker.stateDir}/reports"'';
|
||||||
|
};
|
||||||
|
|
||||||
|
adapters = lib.mkOption {
|
||||||
|
type = lib.types.attrsOf (
|
||||||
|
lib.types.submodule {
|
||||||
|
freeformType = settingsFormat.type;
|
||||||
|
|
||||||
|
options = {
|
||||||
|
command = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = "Adapter command to run.";
|
||||||
|
};
|
||||||
|
env = lib.mkOption {
|
||||||
|
type = lib.types.attrsOf settingsFormat.type;
|
||||||
|
description = "Environment variables to add when running the adapter.";
|
||||||
|
default = { };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
description = ''
|
||||||
|
CI adapters.
|
||||||
|
See also the options under [services.radicle.ci.adapters](#opt-services.radicle.ci.adapters.native.instances).
|
||||||
|
'';
|
||||||
|
default = { };
|
||||||
|
};
|
||||||
|
|
||||||
|
triggers = lib.mkOption {
|
||||||
|
type = lib.types.listOf (
|
||||||
|
lib.types.submodule {
|
||||||
|
freeformType = settingsFormat.type;
|
||||||
|
|
||||||
|
options = {
|
||||||
|
adapter = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = "Adapter name.";
|
||||||
|
};
|
||||||
|
|
||||||
|
filters = lib.mkOption {
|
||||||
|
type = lib.types.listOf settingsFormat.type;
|
||||||
|
description = "Trigger filter.";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
description = "CI triggers.";
|
||||||
|
default = [ ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
description = ''
|
||||||
|
Configuration of radicle-ci-broker.
|
||||||
|
See <https://app.radicle.xyz/nodes/seed.radicle.xyz/rad:zwTxygwuz5LDGBq255RA2CbNGrz8/tree/doc/userguide.md#configuration> for more information.
|
||||||
|
'';
|
||||||
|
default = { };
|
||||||
|
example = lib.literalExpression ''
|
||||||
|
{
|
||||||
|
adapters.native = {
|
||||||
|
command = lib.getExe pkgs.radicle-native-ci;
|
||||||
|
config = { };
|
||||||
|
config_env = "RADICLE_NATIVE_CI";
|
||||||
|
env.PATH = lib.makeBinPath (with pkgs; [ bash coreutils ]);
|
||||||
|
};
|
||||||
|
|
||||||
|
triggers = [
|
||||||
|
{
|
||||||
|
adapter = "native";
|
||||||
|
filters = [
|
||||||
|
{
|
||||||
|
And = [
|
||||||
|
{ HasFile = ".radicle/native.yaml"; }
|
||||||
|
{ Node = "z6MkgEMYod7Hxfy9qCvDv5hYHkZ4ciWmLFgfvm3Wn1b2w2FV"; }
|
||||||
|
{
|
||||||
|
Or = [
|
||||||
|
"DefaultBranch"
|
||||||
|
"PatchCreated"
|
||||||
|
"PatchUpdated"
|
||||||
|
];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
assertions = [
|
||||||
|
{
|
||||||
|
assertion = config.services.radicle.enable;
|
||||||
|
message = "radicle-ci-broker requires a local radicle node to be running.";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
services.radicle.ci.broker.settings = {
|
||||||
|
db = lib.mkDefault "${cfg.stateDir}/ci-broker.db";
|
||||||
|
report_dir = lib.mkDefault "${cfg.stateDir}/reports";
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services.radicle-ci-broker = {
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
|
||||||
|
bindsTo = [ "radicle-node.service" ];
|
||||||
|
after = [ "radicle-node.service" ];
|
||||||
|
|
||||||
|
environment = { inherit RAD_HOME; };
|
||||||
|
|
||||||
|
serviceConfig = lib.mkMerge [
|
||||||
|
{
|
||||||
|
User = config.users.users.radicle.name;
|
||||||
|
Group = config.users.groups.radicle.name;
|
||||||
|
Restart = "always";
|
||||||
|
|
||||||
|
StateDirectory = lib.mkIf (cfg.stateDir == "/var/lib/radicle-ci") "radicle-ci";
|
||||||
|
LogsDirectory = lib.mkIf (cfg.logDir == "/var/log/radicle-ci") "radicle-ci";
|
||||||
|
RuntimeDirectory = "radicle-ci-broker";
|
||||||
|
WorkingDirectory = "/run/radicle-ci-broker";
|
||||||
|
|
||||||
|
BindReadOnlyPaths = config.systemd.services.radicle-node.serviceConfig.BindReadOnlyPaths;
|
||||||
|
ReadWritePaths = [ RAD_HOME ];
|
||||||
|
|
||||||
|
ExecStart = "${lib.getExe' cfg.package "cib"} --config ${configFile} process-events";
|
||||||
|
}
|
||||||
|
|
||||||
|
(lib.mkIf cfg.enableHardening {
|
||||||
|
AmbientCapabilities = "";
|
||||||
|
CapabilityBoundingSet = [ "" ];
|
||||||
|
DevicePolicy = "closed";
|
||||||
|
LockPersonality = true;
|
||||||
|
MemoryDenyWriteExecute = true;
|
||||||
|
NoNewPrivileges = true;
|
||||||
|
PrivateDevices = true;
|
||||||
|
PrivateTmp = true;
|
||||||
|
PrivateUsers = true;
|
||||||
|
ProcSubset = "pid";
|
||||||
|
ProtectClock = true;
|
||||||
|
ProtectControlGroups = true;
|
||||||
|
ProtectHome = true;
|
||||||
|
ProtectHostname = true;
|
||||||
|
ProtectKernelLogs = true;
|
||||||
|
ProtectKernelModules = true;
|
||||||
|
ProtectKernelTunables = true;
|
||||||
|
ProtectProc = "invisible";
|
||||||
|
ProtectSystem = "strict";
|
||||||
|
RemoveIPC = true;
|
||||||
|
RestrictAddressFamilies = [ "AF_INET AF_INET6 AF_UNIX" ];
|
||||||
|
RestrictNamespaces = true;
|
||||||
|
RestrictRealtime = true;
|
||||||
|
RestrictSUIDSGID = true;
|
||||||
|
SystemCallArchitectures = "native";
|
||||||
|
SystemCallFilter = [
|
||||||
|
"@system-service"
|
||||||
|
"~@privileged"
|
||||||
|
"~@resources"
|
||||||
|
];
|
||||||
|
UMask = "0066";
|
||||||
|
})
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.tmpfiles.settings.radicle-ci-broker.${cfg.settings.report_dir}.d = {
|
||||||
|
user = config.users.users.radicle.name;
|
||||||
|
group = config.users.groups.radicle.name;
|
||||||
|
};
|
||||||
|
|
||||||
|
environment.systemPackages = [ cibtool-system ];
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1277,6 +1277,7 @@ in
|
|||||||
radarr = runTest ./radarr.nix;
|
radarr = runTest ./radarr.nix;
|
||||||
radicale = runTest ./radicale.nix;
|
radicale = runTest ./radicale.nix;
|
||||||
radicle = runTest ./radicle.nix;
|
radicle = runTest ./radicle.nix;
|
||||||
|
radicle-ci-broker = runTest ./radicle-ci-broker.nix;
|
||||||
ragnarwm = runTestOn [ "x86_64-linux" "aarch64-linux" ] ./ragnarwm.nix;
|
ragnarwm = runTestOn [ "x86_64-linux" "aarch64-linux" ] ./ragnarwm.nix;
|
||||||
rasdaemon = runTest ./rasdaemon.nix;
|
rasdaemon = runTest ./rasdaemon.nix;
|
||||||
rathole = runTest ./rathole.nix;
|
rathole = runTest ./rathole.nix;
|
||||||
|
|||||||
137
nixos/tests/radicle-ci-broker.nix
Normal file
137
nixos/tests/radicle-ci-broker.nix
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
{ lib, pkgs, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
seed-nid = "z6Mkg52RcwDrPKRzzHaYgBkHH3Gi5p4694fvPstVE9HTyMB6";
|
||||||
|
seed-ssh-keys = import ./ssh-keys.nix pkgs;
|
||||||
|
|
||||||
|
radicleConfig =
|
||||||
|
alias:
|
||||||
|
pkgs.writeText "config.json" (
|
||||||
|
builtins.toJSON {
|
||||||
|
preferredSeeds = [ "${seed-nid}@seed:8776" ];
|
||||||
|
node = { inherit alias; };
|
||||||
|
}
|
||||||
|
);
|
||||||
|
in
|
||||||
|
|
||||||
|
{
|
||||||
|
name = "radicle-ci-broker";
|
||||||
|
meta.maintainers = with lib.maintainers; [ defelo ];
|
||||||
|
|
||||||
|
nodes.seed = {
|
||||||
|
services.radicle = {
|
||||||
|
enable = true;
|
||||||
|
privateKeyFile = seed-ssh-keys.snakeOilEd25519PrivateKey;
|
||||||
|
publicKey = seed-ssh-keys.snakeOilEd25519PublicKey;
|
||||||
|
node.openFirewall = true;
|
||||||
|
settings = {
|
||||||
|
preferredSeeds = [ ];
|
||||||
|
node.alias = "seed";
|
||||||
|
};
|
||||||
|
|
||||||
|
ci = {
|
||||||
|
adapters.native.instances.native = { };
|
||||||
|
broker = {
|
||||||
|
enable = true;
|
||||||
|
settings.triggers = [
|
||||||
|
{
|
||||||
|
adapter = "native";
|
||||||
|
filters = [
|
||||||
|
{
|
||||||
|
And = [
|
||||||
|
{ HasFile = ".radicle/native.yaml"; }
|
||||||
|
"DefaultBranch"
|
||||||
|
];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
nodes.alice =
|
||||||
|
{ pkgs, ... }:
|
||||||
|
{
|
||||||
|
environment.etc."gitconfig".text = ''
|
||||||
|
[init]
|
||||||
|
defaultBranch = main
|
||||||
|
[user]
|
||||||
|
email = root@alice
|
||||||
|
name = alice
|
||||||
|
'';
|
||||||
|
|
||||||
|
environment.systemPackages = with pkgs; [
|
||||||
|
gitMinimal
|
||||||
|
radicle-node
|
||||||
|
radicle-job
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
testScript = ''
|
||||||
|
import json
|
||||||
|
import time
|
||||||
|
|
||||||
|
start_all()
|
||||||
|
|
||||||
|
seed.wait_for_unit("radicle-ci-broker.service")
|
||||||
|
|
||||||
|
alice.succeed("rad auth --alias alice --stdin </dev/null")
|
||||||
|
alice.copy_from_host("${radicleConfig "alice"}", "/root/.radicle/config.json")
|
||||||
|
alice.succeed("rad node start")
|
||||||
|
|
||||||
|
alice_nid = alice.succeed("rad self --nid").strip()
|
||||||
|
|
||||||
|
alice.succeed("mkdir /tmp/repo")
|
||||||
|
alice.succeed("git -C /tmp/repo init")
|
||||||
|
alice.succeed("mkdir /tmp/repo/.radicle")
|
||||||
|
alice.succeed("echo 'shell: echo -n it works > /run/radicle-ci-broker/result' > /tmp/repo/.radicle/native.yaml")
|
||||||
|
alice.succeed("git -C /tmp/repo add .")
|
||||||
|
alice.succeed("git -C /tmp/repo commit -m init")
|
||||||
|
|
||||||
|
alice.succeed("cd /tmp/repo && rad init --name repo --description \"\" --default-branch main --public")
|
||||||
|
rid = alice.succeed("rad inspect --rid /tmp/repo").strip()
|
||||||
|
|
||||||
|
def git_head():
|
||||||
|
return alice.succeed("git -C /tmp/repo rev-parse HEAD").strip()
|
||||||
|
|
||||||
|
def list_runs(oid):
|
||||||
|
alice.succeed(f"rad sync {rid} -f")
|
||||||
|
jobs = json.loads(alice.succeed(f"rad job --repository {rid} list"))["jobs"]
|
||||||
|
return [
|
||||||
|
{"node_id": run["node_id"], **node_run}
|
||||||
|
for job in jobs if job["oid"] == oid
|
||||||
|
for run in job["runs"] for node_run in run["runs"]
|
||||||
|
]
|
||||||
|
|
||||||
|
def run_succeeded(run):
|
||||||
|
return run["node_id"] == "${seed-nid}" and run["status"] == {"Finished": "Succeeded"}
|
||||||
|
|
||||||
|
def _retry(f):
|
||||||
|
for _ in range(10):
|
||||||
|
if out := f(): return out
|
||||||
|
time.sleep(1)
|
||||||
|
assert False
|
||||||
|
|
||||||
|
assert list_runs(head := git_head()) == []
|
||||||
|
seed.succeed(f"rad-system seed {rid}")
|
||||||
|
assert seed.wait_until_succeeds("cat /run/radicle-ci-broker/result") == "it works"
|
||||||
|
_retry(lambda: len(runs := list_runs(head)) == 1 and run_succeeded(runs[0]))
|
||||||
|
|
||||||
|
alice.succeed("echo 'shell: echo -n second commit > /run/radicle-ci-broker/result2' > /tmp/repo/.radicle/native.yaml")
|
||||||
|
alice.succeed("git -C /tmp/repo add .")
|
||||||
|
alice.succeed("git -C /tmp/repo commit -m 2")
|
||||||
|
assert list_runs(head := git_head()) == []
|
||||||
|
alice.succeed("git -C /tmp/repo push")
|
||||||
|
assert seed.wait_until_succeeds("cat /run/radicle-ci-broker/result2") == "second commit"
|
||||||
|
run = _retry(lambda: len(runs := list_runs(head)) == 1 and run_succeeded(run := runs[0]) and run)
|
||||||
|
|
||||||
|
seed.succeed("rm /run/radicle-ci-broker/result2")
|
||||||
|
seed.fail("cat /run/radicle-ci-broker/result2")
|
||||||
|
seed.succeed(f"cibtool-system trigger --repo repo --node {alice_nid} --commit main")
|
||||||
|
assert seed.wait_until_succeeds("cat /run/radicle-ci-broker/result2") == "second commit"
|
||||||
|
_retry(lambda: len(runs := sorted(list_runs(head), key=run.__ne__)) == 2
|
||||||
|
and runs[0] == run and runs[1]["run_id"] != run["run_id"] and run_succeeded(runs[1]))
|
||||||
|
'';
|
||||||
|
}
|
||||||
76
pkgs/by-name/ra/radicle-ci-broker/package.nix
Normal file
76
pkgs/by-name/ra/radicle-ci-broker/package.nix
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
{
|
||||||
|
lib,
|
||||||
|
rustPlatform,
|
||||||
|
fetchFromRadicle,
|
||||||
|
stdenv,
|
||||||
|
jq,
|
||||||
|
gitMinimal,
|
||||||
|
sqlite,
|
||||||
|
radicle-node,
|
||||||
|
versionCheckHook,
|
||||||
|
nixosTests,
|
||||||
|
}:
|
||||||
|
|
||||||
|
rustPlatform.buildRustPackage (finalAttrs: {
|
||||||
|
pname = "radicle-ci-broker";
|
||||||
|
version = "0.21.0";
|
||||||
|
|
||||||
|
src = fetchFromRadicle {
|
||||||
|
seed = "seed.radicle.xyz";
|
||||||
|
repo = "zwTxygwuz5LDGBq255RA2CbNGrz8";
|
||||||
|
node = "z6MkgEMYod7Hxfy9qCvDv5hYHkZ4ciWmLFgfvm3Wn1b2w2FV";
|
||||||
|
tag = "v${finalAttrs.version}";
|
||||||
|
hash = "sha256-c0Qo6dnR9rP4mLXODkNZp+AnhKS0tqJeh1KgzfHBRV4=";
|
||||||
|
leaveDotGit = true;
|
||||||
|
postFetch = ''
|
||||||
|
git -C $out rev-parse --short HEAD > $out/.git_head
|
||||||
|
rm -rf $out/.git
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
cargoHash = "sha256-9MkZh1hlHgLC9rGmLx5ehtLtZfhXsCqrJrCJNr1edBU=";
|
||||||
|
|
||||||
|
postPatch = ''
|
||||||
|
substituteInPlace build.rs \
|
||||||
|
--replace-fail "let hash = " "let hash = \"$(<$src/.git_head)\"; "
|
||||||
|
'';
|
||||||
|
|
||||||
|
preCheck = ''
|
||||||
|
ln -s "$PWD/target/${stdenv.hostPlatform.rust.rustcTarget}/$cargoBuildType" target/debug
|
||||||
|
'';
|
||||||
|
|
||||||
|
nativeCheckInputs = [
|
||||||
|
jq
|
||||||
|
gitMinimal
|
||||||
|
sqlite
|
||||||
|
radicle-node
|
||||||
|
];
|
||||||
|
|
||||||
|
checkFlags = [
|
||||||
|
"--skip=acceptance_criteria_for_upgrades"
|
||||||
|
"--skip=logs_adapter_stderr_output"
|
||||||
|
"--skip=process_queued_events"
|
||||||
|
"--skip=runs_adapter_with_configuration"
|
||||||
|
];
|
||||||
|
|
||||||
|
nativeInstallCheckInputs = [ versionCheckHook ];
|
||||||
|
versionCheckProgramArg = "--version";
|
||||||
|
doInstallCheck = true;
|
||||||
|
|
||||||
|
passthru = {
|
||||||
|
tests = { inherit (nixosTests) radicle-ci-broker; };
|
||||||
|
updateScript = ./update.sh;
|
||||||
|
};
|
||||||
|
|
||||||
|
meta = {
|
||||||
|
description = "Radicle CI broker";
|
||||||
|
homepage = "https://app.radicle.xyz/nodes/seed.radicle.xyz/rad:zwTxygwuz5LDGBq255RA2CbNGrz8";
|
||||||
|
changelog = "https://app.radicle.xyz/nodes/seed.radicle.xyz/rad:zwTxygwuz5LDGBq255RA2CbNGrz8/tree/NEWS.md";
|
||||||
|
license = with lib.licenses; [
|
||||||
|
mit
|
||||||
|
asl20
|
||||||
|
];
|
||||||
|
maintainers = with lib.maintainers; [ defelo ];
|
||||||
|
mainProgram = "cib";
|
||||||
|
};
|
||||||
|
})
|
||||||
18
pkgs/by-name/ra/radicle-ci-broker/update.sh
Executable file
18
pkgs/by-name/ra/radicle-ci-broker/update.sh
Executable file
@@ -0,0 +1,18 @@
|
|||||||
|
#!/usr/bin/env nix-shell
|
||||||
|
#!nix-shell -i bash -p coreutils gnused gitMinimal nix-update
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
dirname="$(dirname "${BASH_SOURCE[0]}")"
|
||||||
|
|
||||||
|
url=$(nix-instantiate --eval --raw -A radicle-ci-broker.src.url)
|
||||||
|
old_node=$(nix-instantiate --eval --raw -A radicle-ci-broker.src.node)
|
||||||
|
|
||||||
|
ref=$(git ls-remote "$url" 'refs/namespaces/*/refs/tags/v*' \
|
||||||
|
| cut -f2 | grep -Ev '\^\{\}$' | sort -t/ -k6rV | head -1)
|
||||||
|
[[ "$ref" =~ ^refs/namespaces/([^/]+)/refs/tags/v([^/]+)$ ]]
|
||||||
|
new_node="${BASH_REMATCH[1]}"
|
||||||
|
version="${BASH_REMATCH[2]}"
|
||||||
|
|
||||||
|
sed -i "s/${old_node}/${new_node}/g" "${dirname}/package.nix"
|
||||||
|
nix-update --version="$version" radicle-ci-broker
|
||||||
53
pkgs/by-name/ra/radicle-native-ci/package.nix
Normal file
53
pkgs/by-name/ra/radicle-native-ci/package.nix
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
{
|
||||||
|
lib,
|
||||||
|
rustPlatform,
|
||||||
|
fetchFromRadicle,
|
||||||
|
radicle-node,
|
||||||
|
gitMinimal,
|
||||||
|
writableTmpDirAsHomeHook,
|
||||||
|
versionCheckHook,
|
||||||
|
}:
|
||||||
|
|
||||||
|
rustPlatform.buildRustPackage (finalAttrs: {
|
||||||
|
pname = "radicle-native-ci";
|
||||||
|
version = "0.11.1";
|
||||||
|
|
||||||
|
src = fetchFromRadicle {
|
||||||
|
seed = "seed.radicle.xyz";
|
||||||
|
repo = "z3qg5TKmN83afz2fj9z3fQjU8vaYE";
|
||||||
|
node = "z6MkgEMYod7Hxfy9qCvDv5hYHkZ4ciWmLFgfvm3Wn1b2w2FV";
|
||||||
|
tag = "v${finalAttrs.version}";
|
||||||
|
hash = "sha256-OjQBq4QopT4dr1/z73fqlGLjQIjUY51/II9m2qQMW1w=";
|
||||||
|
};
|
||||||
|
|
||||||
|
cargoHash = "sha256-zyEdlAXaooEkxD4aZ1poIUX3OwXtP4nFAyOWJDdw1p8=";
|
||||||
|
|
||||||
|
preCheck = ''
|
||||||
|
git config --global user.name nixbld
|
||||||
|
git config --global user.email nixbld@example.com
|
||||||
|
'';
|
||||||
|
|
||||||
|
nativeCheckInputs = [
|
||||||
|
writableTmpDirAsHomeHook
|
||||||
|
radicle-node
|
||||||
|
gitMinimal
|
||||||
|
];
|
||||||
|
|
||||||
|
nativeInstallCheckInputs = [ versionCheckHook ];
|
||||||
|
versionCheckProgramArg = "--version";
|
||||||
|
doInstallCheck = true;
|
||||||
|
|
||||||
|
passthru.updateScript = ./update.sh;
|
||||||
|
|
||||||
|
meta = {
|
||||||
|
description = "Radicle CI adapter for native CI";
|
||||||
|
homepage = "https://app.radicle.xyz/nodes/seed.radicle.xyz/rad:z3qg5TKmN83afz2fj9z3fQjU8vaYE";
|
||||||
|
changelog = "https://app.radicle.xyz/nodes/seed.radicle.xyz/rad:z3qg5TKmN83afz2fj9z3fQjU8vaYE/tree/NEWS.md";
|
||||||
|
license = with lib.licenses; [
|
||||||
|
mit
|
||||||
|
asl20
|
||||||
|
];
|
||||||
|
maintainers = with lib.maintainers; [ defelo ];
|
||||||
|
mainProgram = "radicle-native-ci";
|
||||||
|
};
|
||||||
|
})
|
||||||
18
pkgs/by-name/ra/radicle-native-ci/update.sh
Executable file
18
pkgs/by-name/ra/radicle-native-ci/update.sh
Executable file
@@ -0,0 +1,18 @@
|
|||||||
|
#!/usr/bin/env nix-shell
|
||||||
|
#!nix-shell -i bash -p coreutils gnused gitMinimal nix-update
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
dirname="$(dirname "${BASH_SOURCE[0]}")"
|
||||||
|
|
||||||
|
url=$(nix-instantiate --eval --raw -A radicle-native-ci.src.url)
|
||||||
|
old_node=$(nix-instantiate --eval --raw -A radicle-native-ci.src.node)
|
||||||
|
|
||||||
|
ref=$(git ls-remote "$url" 'refs/namespaces/*/refs/tags/v*' \
|
||||||
|
| cut -f2 | grep -Ev '\^\{\}$' | sort -t/ -k6rV | head -1)
|
||||||
|
[[ "$ref" =~ ^refs/namespaces/([^/]+)/refs/tags/v([^/]+)$ ]]
|
||||||
|
new_node="${BASH_REMATCH[1]}"
|
||||||
|
version="${BASH_REMATCH[2]}"
|
||||||
|
|
||||||
|
sed -i "s/${old_node}/${new_node}/g" "${dirname}/package.nix"
|
||||||
|
nix-update --version="$version" radicle-native-ci
|
||||||
Reference in New Issue
Block a user