Build Pipeline

An elixir development tool for running commands with maximum possible concurrency, designed to speed up CI / CD build piplines by running mulitple independent build steps at once.

Commands will only be executed if the commands that it dependsOn have run successfully first.

If commands don't depend on anything, or if all of their dependent commands have already run successfully, then they'll be run together concurrently.

Installation and Getting Up and Running

Dependencies

Installation

This package can be installed by adding build_pipeline to your list of dependencies in mix.exs:

def deps do
  [
    {:build_pipeline, "~> 0.3.0"}
  ]
end

Then, From the root of your projects' directory (where your mix.exs file is) run:

mix build_pipeline.init

Run this as first-time setup -

This will generate some directories and a default config.json file, like so:

build_pipeline
├── config.json
└── scripts

Next, edit your config.json file, adding the desired build steps.<br> config.json must be only a list, containing buildSteps.

Build steps are defined as in the example below.

[
  {
    "buildStepName": "find_todos",
    "commandType": "script",
    "command": "find_todos",
    "dependsOn": []
  },
  {
    "buildStepName": "deps.get",
    "commandType": "shellCommand",
    "command": "mix deps.get",
    "dependsOn": []
  },
  {
    "buildStepName": "compile",
    "commandType": "shellCommand",
    "command": "mix compile --force --warnings-as-errors",
    "dependsOn": [
      "deps.get"
    ],
    "envVars": [
      {
        "name": "MIX_ENV",
        "value": "test"
      }
    ]
  },
  {
    "buildStepName": "loadconfig",
    "commandType": "shellCommand",
    "command": "mix loadconfig config/prod.exs",
    "dependsOn": []
  },
  {
    "buildStepName": "test",
    "commandType": "shellCommand",
    "command": "mix test --color",
    "dependsOn": [
      "compile"
    ]
  },
  {
    "buildStepName": "esciptBuild",
    "commandType": "shellCommand",
    "command": "mix escript.build",
    "dependsOn": [
      "test"
    ],
    "envVars": [
      {
        "name": "MIX_ENV",
        "value": "prod"
      }
    ]
  }
]

The above example is what is used to build build_pipeline itself. Note that there is a bash script in the scripts folder which returns a non-zero exit code if "TODO" is found anywhere in the codebase (except for in the README of course :) because that wouldn't work).

Also note: If A depends on B which depends on C, then you only need to define A with the dependsOn of [B], and B with the dependsOn of [C]. Saying that A dependsOn [B, C] is redundant. Just define A with dependsOn = [B].

Once your config.json and any supporting scripts in scripts are in place, you're good to go, and you can run

mix build_pipeline.run

And you're away!

By default, output from successful commands are silenced, and command output is only displayed by the first command that fails (returns a non 0 exit code). In the event of a command failing, subsequent dependent commands and commands in progress are gracefully not started or terminated respectively.

mix build_pipeline.run - Options