Add docs about how to update multitool's lockfile (#31)

We've added a companion CLI called (creatively) `multitool`, that
supports updating GitHub release based artifacts. In practice this is
most of the artifacts we end up working with, and adding support for
other, limited artifact sources seems tractable.

In an ideal world, we'll ultimately teach Renovate how to run updates to
our lockfile. However, looking at [Renovate's support for
Bazel](https://github.com/renovatebot/renovate/blob/d6d1e57763ffefa04767a4d01b028b1d39f27188/lib/modules/manager/bazel/index.ts#L17-L22)
artifact updates: Renovate will update GitHub releases, GitHub tags, Go
datasources, and docker datasources. This is relatively limited, and our
read is that GitHub releases covers the bulk of the artifacts one
expects to encounter.

Additionally, we'd like to make it easy to add new tools and more
generally to manage the lockfile, and plan to add `add`, `remove`, and
`lint` commands to our CLI down the road. We think that'll be useful
even if we had full Renovate support.

In addition to describing that the CLI exists, this PR includes sample
GitHub Actions to use within one's repo. Publicly, one can see the
download-and-execute example in
[rules_uv](https://github.com/theoremlp/rules_uv/blob/main/.github/workflows/periodic-update-multitool.yml).

Partial solution to #28.
2 files changed
tree: 241c355c447d897adeb5fd6c3e62caf27635f354
  1. .bcr/
  2. .github/
  3. docs/
  4. examples/
  5. multitool/
  6. .bazelignore
  7. .bazelrc
  8. .bazelversion
  9. .gitattributes
  10. .gitignore
  11. BUILD.bazel
  12. LICENSE
  13. lockfile.schema.json
  14. MODULE.bazel
  15. readme.md
  16. WORKSPACE.bazel
readme.md

rules_multitool

An ergonomic approach to defining a single tool target that resolves to a matching os and CPU architecture variant of the tool.

Usage

For a quickstart, see the module example or workspace example.

Define a lockfile that references the tools to load:

{
  "$schema": "https://raw.githubusercontent.com/theoremlp/rules_multitool/main/lockfile.schema.json",
  "tool-name": {
    "binaries": [
      {
        "kind": "file",
        "url": "https://...",
        "sha256": "sha256 of the file",
        "os": "linux|macos",
        "cpu": "x86_64|arm64"
      }
    ]
  }
}

The lockfile supports the following binary kinds:

  • file: the URL refers to a file to download

    • sha256: the sha256 of the downloaded file
  • archive: the URL referes to an archive to download, specify additional options:

    • file: executable file within the archive
    • sha256: the sha256 of the downloaded archive
  • pkg: the URL refers to a MacOS pkg archive to download, specify additional options:

    • file: executable file within the archive
    • sha256: the sha256 of the downloaded pkg archive

Bazel Module Usage

Once your lockfile is defined, load the ruleset in your MODULE.bazel and create a hub that refers to your lockfile:

bazel_dep(name = "rules_multitool", version = "0.0.0")

multitool = use_extension("@rules_multitool//multitool:extension.bzl", "multitool")
multitool.hub(lockfile = "//:multitool.lock.json")
use_repo(multitool, "multitool")

Tools may then be accessed using @multitool//tools/tool-name.

Workspace Usage

Instructions for using with WORKSPACE may be found in release notes.

Running tools in the current working directory

When running @multitool//tools/tool-name, Bazel will execute the tool at the root of the runfiles tree due to https://github.com/bazelbuild/bazel/issues/3325.

To run a tool in the current working directory, use the convenience target @multitool//tools/tool-name:cwd.

A common pattern we recommend to further simplify invoking tools for repository users it to:

  1. Create a tools/ directory
  2. Create an executable shell script tools/_run_multitool.sh with the following code:
    #!/usr/bin/env bash
    bazel run "@multitool//tools/$( basename $0 ):cwd" -- "$@"
    
  3. Create symlinks of tools/tool-name to tools/_run_multitool.sh

Keeping Tools Up-to-Date

We provide a companion CLI multitool to help manage multitool lockfiles. The CLI supports basic updating of artifacts that come from GitHub releases, and may be extended in the future to support other common release channels.

See our docs on configuring a GitHub Action to check for updates and open PRs periodically.