Orcs! ===== __This is a work-in-progress!__ Tool for building and deploying microservices within a monorepo. * [Usage](#usage) * [Terms](#terms) * [Configuration files](#configuration-files) ## Usage ### Initialization commands * `orcs init {project}`: Create a new project * `orcs init {project} -t {template}`: Create a new project * `orcs new service {service}`: Create a new service * `orcs new service {service} -t {template}`: Create a new service * `orcs new recipe {recipe}`: Create a new recipe ### Run commands * `orcs run all`: Run all services in all stages * `orcs run {stage}`: Run all services for a specific stage * `orcs run all {service}`: Run all stages for a specific service * `orcs run {stage} {service}`: Run a specific stage for a specific service ### Parameter store commands * `orcs get {parameter}`: Retrieve a parameter value * `orcs get-file {parameter} {filename}`: Retrieve an artifact file * `orcs set {parameter} {value}`: Set a parameter value * `orcs set-file {parameter} {filename}`: Store an artifact file ## Terms ### Actions The __actions__ are the list of commands to perform for a specific service and stage. Stages also support _check actions_, which are meant to be fast and return an error if the stage should be run again for that particular service. ### Parameter A __parameter__ is a value provided by a service as a result of its actions. Parameters could be simple values, such as an API endpoint URL, or files such as zipped libraries, etc. ### Project A __project__ represent a repository containing multiple services, recipes, etc. ### Recipe A __recipe__ is a series of default __actions__ that can be used by services. For example, if many services use the same programming language, you may want to create a recipe for linting, building, testing services that use that language. ### Service A __service__ represent either a microservice or a shared library used by other microservices. Services can have dependencies between each other, and those dependencies may vary based on the stage. For example, it might be possible to build two microservices at the same time, but one needs to wait until the other one is updated. ### Stage A __stage__ is a step within the entire workflow of the project. A simple workflow typically consists of two stages: _build_ and _deploy_. Within a service, a stage will consists of a series of actions to take to perform the desired action related to that stage. For example, building a library or deploying a microservice. Stages can depend on each other, thus allowing complex workflows. Stages can also be skipped during a complete run, for example if this is a clean up stage. ## Configuration files ### Project file A __project file__ is the `orcs.toml` file at the root of the project and is comprised of three main sections: global, envs and stages. * The __global__ section defines parameters that can be used across all stages and environments. * The __envs__ section defines parameters that can only be used within the environment itself. * The __stages__ section defines stages, dependencies between stages, parameter values to use within the stage and what environments it support (which can be none). ```toml [global.params] # Global parameters accessible in all services and stages project = "my-project" ################## # Environments # ################## # This section contains environment-specific parameters. # These may override values from the global parameters. [envs.dev] params.is-prod = "false" [envs.prod] params.is-prod = "true" ################## # Stages # ################## [stages.build] # Leaving the section empty will create a stage but let all internal properties # empty. This means no dependencies, parameters or environments. [stages.deploy] # Stages may depend on other stages depends_on = ["build"] # Stages may also have parameter values within the project file. # Stage parameters will override environment parameters. params.target = "linux" # If a stage supports environments, it should refer to the list of environments # it supports. Not all stages have to support all environments envs = ["dev", "prod"] ``` ### Service file A __service file__ is an `orcs.toml` file in a given service folder containing all the instructions and metadata about a service. ```toml # An optional description about what the service does # This can contain multiple lines. description = """API to returns a string backwards ## Usage ...""" # List of maintainers for that service maintainers = [ "John Doe " ] # An optional page where people can find more information about the service. homepage = "https://wiki.company.example/my-service" # List of recipes used by that service. # Recipes will be resolved in order, with the first recipe to set actions for a # stage taking over. recipes = [ "python" ] ################## # Stages # ################## # Stages contains the instruction to run a specific stage for that service. # Stages can also list which services they depend on. This will ensure that the # dependencies are run first, and also grant access to the parameters/artifacts # provided by those dependencies. [stages.build] depends_on = [] # Actions # You can provide a list of actions either with an array of strings or with a # multi-line string. actions = [ "echo Hello from $ORCS_SERVICE", # You can use 'orcs set' and 'orcs get' within a list of actions to set and # retrieve parameter values. "orcs set my-parameter:value" ] # Check # Checks are meant to run fast and tell if the stage/service should be run # prior to another, dependent stage/service combo. # # If you try to run a stage for a dependency of this service and this returns # a non-zero (aka false) value, the run will fail. # # If you run this stage/service combo and wants to skip the actions, you should # rely on checking this in the actions section instead. # # By default, this is set to "false". check = "false" [stages.deploy] depends_on = [] # Actions # An explicit 'false' value (without quotes) will disable the actions entirely # and prevent recipes from overwiting these values. # If you want a recipe to overwrite this, you can set it to an empty value # (either empty string or empty array). actions = false # Check check = "false" ``` ### Recipe file __Recipe files__ are TOML files in the `rcp` folder of the project and only support stages sections. Within these sections, you can define default actions and checks for common use-cases. Only _actions_ and _check_ are supported within recipe files. ```toml [stages.build] actions = [ "echo Hello from a recipe" ] check = [ "echo Check if the stage needs to be built" ] [stages.deploy] actions = [ "echo Hello from a recipe" ] ```