Skip to content
 
 

Repository files navigation

rules_multirun

These rules provide a simple interface for running multiple commands in parallel with a single bazel run invocation. This is especially useful for running multiple linters or formatters with a single command.

Usage

Setup the tools you want to run:

load("@rules_multirun//:defs.bzl", "command", "multirun")
load("@rules_python//python:defs.bzl", "py_binary")

sh_binary(
    name = "some_linter",
    ...
)

py_binary(
    name = "some_other_linter",
    ...
)

command(
    name = "lint-something",
    command = ":some_linter",
    arguments = ["check"], # Optional arguments passed directly to the tool
)

command(
    name = "lint-something-else",
    command = ":some_other_linter",
    environment = {"CHECK": "true"}, # Optional environment variables set when invoking the command
    data = ["..."] # Optional runtime data dependencies
)

multirun(
    name = "lint",
    commands = [
        "lint-something",
        "lint-something-else",
    ],
    jobs = 0, # Set to 0 to run in parallel, defaults to sequential
)

Run the multirun target with bazel:

$ bazel run //:lint

Usage with iBazel

Set ibazel_notify_changes on multirun to compose long-lived commands while preserving the incremental build protocol used by targets such as js_run_devserver:

load("@rules_multirun//:defs.bzl", "multirun")

multirun(
    name = "dev",
    commands = [
        ":admin_devserver",
        ":frontend_devserver",
    ],
    ibazel_notify_changes = True,
)

Run it with ibazel run //:dev. Commands tagged ibazel_notify_changes receive build notifications on stdin and remain alive across rebuilds. Commands that cannot consume the protocol can instead use affected-target restarts:

load("@rules_multirun//:defs.bzl", "command", "multirun")

command(
    name = "backend_dev",
    command = ":backend",
)

multirun(
    name = "dev",
    commands = [
        ":frontend_devserver",
        ":backend_dev",
    ],
    ibazel_notify_changes = True,
    ibazel_restart_affected_commands = True,
)

After each successful structured build event, multirun restarts only commands whose Bazel labels iBazel reports as affected. The initial build does not restart commands. If iBazel cannot completely attribute a change, multirun safely restarts every non-notification command. No path routing is configured in the BUILD file.

Set ibazel_defer_non_notification_commands when user-visible commands must not start before iBazel finishes its initial watch-discovery catch-up build:

multirun(
    name = "dev",
    commands = [
        ":frontend_devserver",
        ":backend_dev",
        ":desktop_app",
    ],
    ibazel_defer_non_notification_commands = True,
    ibazel_notify_changes = True,
    ibazel_restart_affected_commands = True,
)

Notification-capable commands start immediately. Other commands start after the first successful structured build event, so an initial live reload can finish before a desktop app or browser becomes visible. Failed initial builds keep the deferred commands stopped.

Commands that only advertise ibazel_notify_changes receive the legacy protocol. Commands that advertise ibazel_notify_changes_v1 additionally receive structured IBAZEL_EVENT messages containing changed files. Selective restarts require structured version 1 events with affected-target attribution.

See the full API docs for more info.

Usage with platform transitions

In case if the multirun rule requires a transition to other configuration than target then a new multirun-like rule can be defined as in the following example

load("@rules_multirun//:defs.bzl", "multirun_with_transition")

def _aws_deploy_platforms_impl(settings, attr):
    return {"//command_line_option:platforms": [":aws_lambda"]}

aws_deploy_transition = transition(
    implementation = _aws_deploy_platforms_impl,
    inputs = [],
    outputs = ["//command_line_option:platforms"],
)

aws_deploy = multirun_with_transition(
    aws_deploy_transition,
    "@bazel_tools//tools/allowlists/function_transition_allowlist"
)

and used in a BUILD file

aws_deploy(
    name = "staging",
    commands = [
       ...
    ]
)

Installation

Go to the releases page to grab the WORKSPACE snippet for the latest release.

Acknowledgements

This is a fork of the original multirun rules. Those rules have a dependency on golang to run, which may not be desired, these rules use a python script instead.

About

Bazel rules for running multiple commands in parallel in a single bazel invocation

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages