/*
Example of advanced CI/CD implementation.
This file illustrate treatments doing some advanced interaction between runners, commands, and data.
*/
use cicd/runners::CicdDispatchEngine
use cicd/runners::CicdRunnerEngine
use cicd/runners::setupRunner
use cicd/runners::stopRunner
use cicd/steps::stepOn
use cicd/steps::stepOnWithInput
use process/command::|command
use process/command::|raw_commands
use process/environment::Environment
use process/environment::|environment
use std/engine/util::startup
use std/data/string_map::|map
use std/ops/option::|wrap
use work/resources::|container
use work/resources/arch::|amd64
use work/resources::|volume
use work/resources::|mount
/**
`main` treatment, used as `advanced` entrypoint as defined in `Compo.toml`.
- `api_token`: service key provided to access Mélodium work distribution API;
- `work_location`: location where dispatched runners take place (default throught API, can be set to `"compose"` for local run);
- `output_directory`: directory where output files (including logs) are wrote;
- `repository_clone_url`: URL to process Git clone;
- `repository_clone_ref`: Git reference (sha or tag) to clone.
All the other parameters are present to handle integration with CI services.
*/
treatment main(const api_token: string, const work_location: string = "api", repository_clone_url: string, repository_clone_ref: string, ci_service_token: string = "", ci_service_project: string = "", ci_service_ref: string = "", ci_service_sha: string = "", ci_service_pipeline: string = "", on_github: bool = false, on_gitlab: bool = false)
// Model used to dispatch work among Mélodium engines.
model cicd: CicdDispatchEngine(api_token=api_token, location=work_location)
{
startup()
build[cicd=cicd](repository_clone_url=repository_clone_url, repository_clone_ref=repository_clone_ref)
test[cicd=cicd]()
startup.trigger -> build.trigger,data -> test.data
startup.trigger -----------------------> test.trigger
}
/**
Build step, cloning and listing the repository root content.
*/
treatment build[cicd: CicdDispatchEngine](repository_clone_url: string, repository_clone_ref: string)
model runner: CicdRunnerEngine()
input trigger: Block<void>
output data: Stream<byte>
{
setupRunner[
dispatcher=cicd,
runner=runner,
logger=logger
](
name="build",
cpu=10,
memory=500,
storage=1000,
volumes=[|volume("build-result", 30)],
containers=[|container("ubuntu", 1000, 10, 8000, |amd64(), [|mount("build-result", "/mounted/result")], "ubuntu:noble", _)]
)
gitClone: stepOn[runner=runner](
name="git",
executor_name="ubuntu",
environment=|wrap<Environment>(|environment(|map([]), "/root", false, false)),
commands=[
|command("apt-get", ["update"]),
|command("apt-get", ["install", "-y", "git"]),
|command("git", ["config", "--global", "url.https://.insteadOf", "git://"]),
|command("git", ["clone", "--branch", repository_clone_ref, "--depth", "1", repository_clone_url, "project"])
]
)
makeList: stepOn[runner=runner](
name="list",
executor_name="ubuntu",
environment=|wrap<Environment>(|environment(|map([]), "/root/project", false, false)),
commands=|raw_commands([
"sh -c \"ls -l --almost-all | tee files-list.txt\"",
"mv files-list.txt /mounted/result/"
]),
out_filesystem="build-result",
out_file="files-list.txt"
)
stopRunner[runner=runner]()
Self.trigger -> setupRunner.trigger,ready -> gitClone.trigger,completed -> makeList.trigger,finished -> stopRunner.trigger
makeList.data -------------> Self.data
}
/**
Test step, insuring listing is not empty.
*/
treatment test[cicd: CicdDispatchEngine]()
model runner: CicdRunnerEngine()
input trigger: Block<void>
input data: Stream<byte>
output finished: Block<void>
{
setupRunner[
dispatcher=cicd,
runner=runner,
logger=logger
](
name="test",
cpu=10,
memory=500,
storage=1000,
volumes=[|volume("tested-data", 30)],
containers=[|container("alpine", 500, 10, 1000, |amd64(), [|mount("tested-data", "/mounted/data")], "alpine:3", _)]
)
makeTest: stepOnWithInput[runner=runner](
name="test",
executor_name="alpine",
in_filesystem="tested-data",
in_file="list.txt",
commands=[
|command("test", ["-s", "/mounted/data/list.txt"]),
|command("cat", ["/mounted/data/list.txt"])
]
)
stopRunner[runner=runner]()
Self.trigger -> setupRunner.trigger,ready -> makeTest.trigger
Self.data ---------------------------------> makeTest.data,finished -> stopRunner.trigger
makeTest.finished ------> Self.finished
}