[presubmit] Always install into local dir

Installing the package locally makes it easier to swap
in preleases for testing.

Bug: 390427892
Change-Id: I1487a3fbf8b568207050bd9b71a375f6f16b4bfe
Reviewed-on: https://fuchsia-review.googlesource.com/c/rsclient/+/1372782
Reviewed-by: Aaron Wood <aaronwood@google.com>
Fuchsia-Auto-Submit: David Fang <fangism@google.com>
Commit-Queue: David Fang <fangism@google.com>
1 file changed
tree: 3e52a484e1e3264a8edbf9a4c7124436d4786922
  1. cmd/
  2. internal/
  3. scripts/
  4. tools/
  5. .bazelversion
  6. .gitignore
  7. AUTHORS
  8. BUILD.bazel
  9. cipd.yaml.template
  10. CONTRIBUTING.md
  11. GEMINI.md
  12. go.mod
  13. go.sum
  14. LICENSE
  15. MODULE.bazel
  16. OWNERS
  17. PATENTS
  18. README.md
  19. version.bzl
README.md

ResultStore Client Tools

The rsclient repository contains tools that support the use of ResultStore services and API.

rsproxy acts as a bridge between build tools and the ResultStore service.

The first supported build tool is Fuchsia's fork of ninja.

Developing from source

Prerequisites

rsclient builds with Bazel using rules_go.

rsclient is supported for Linux, and is yet untested on other platforms.

Setup

Commit Hook

Before working with the code base, we recommend installing the precommit hook once per git clone with:

./scripts/install_precommit.sh

This runs a variety of checks and automatic regeneration steps for you before committing local changes.

Prebuilts

Download prerequisite tools (like bazel, clang, ninja) by running:

./scripts/infra/bootstrap_prebuilts.sh

This will install tools and bazel build files under prebuilt/. This will also create a convenient ./bazel symlink.

Workflow

A typical build-and-test development cycle is conveniently captured in the following script:

./scripts/infra/presubmit.sh

Building and Testing

To build and test everything, use typical bazel commands:

$ ./bazel build ...
$ ./bazel test ...

Package

To create a package at bazel-bin/rsclient.tar:

$ ./bazel build //:artifacts_tar

User documentation

rsproxy

rsproxy acts as bridge between a local build tool and a ResultStore service, primarily the uploading subset of its API. It connects to a ResultStore service using its API and gRPC calls. It receives ResultStore UploadRequests through a named fifo, and performs some minor transformations such batching before uploading them to the service.

rsproxy can also upload files to a CAS service, separate from the ResultStore service. This is useful for relaying logs and useful artifacts from the build tool.

rsproxy-wrap.sh

rsproxy-wrap.sh is a convenient wrapper script that starts and stops rsproxy around an arbitrary command (typically a build tool) and returns that command's exit status. The wrapper starts rsproxy in the background, and sets up a named pipe (FIFO) for the wrapped command to send data to rsproxy.

rsproxy-wrap.sh is included as part of the built package.

Usage

/path/to/rsproxy-wrap.sh [wrapper_options...] [--rsproxy_options rsproxy_options...] -- command_to_wrap...
  • --rsproxy <path>: (Required) The path to the rsproxy binary.
  • --log-dir <path>: A directory to store logs and other artifacts from the rsproxy process. If not provided, a temporary directory will be created.
  • --async-shutdown: If set, the wrapper script will not wait for rsproxy to shut down before exiting.

rsproxy options can be passed after --rsproxy_options, and before the -- that precedes the wrapped command.

Communication

The wrapper script creates a named pipe (FIFO) and exports its path to the wrapped command via the RSPROXY_FIFO environment variable. The wrapped command is expected to write ResultStore UploadRequests to this pipe.

The first UploadRequest coming from the build tool must be CreateInvocation request, after which any number of generic UploadRequests may follow. Sending FinalizeInvocation will mark the end of the stream of requests and trigger a shutdown of rsproxy. If the pipe is closed before FinalizeInvocation is seen, it will be assumed that the build was interrupted and rsproxy will update the invocation as such before sending its own FinalizeInvocation.

Integration with Ninja

The rs-ninja.sh script is the build tool's counterpart to rsproxy-wrap.sh. It acts as a wrapper around the ninja command, automatically providing the necessary flags for ResultStore integration.

When rs-ninja.sh is run within the environment set up by rsproxy-wrap.sh, it does the following:

  1. It takes the path to the named pipe from the RSPROXY_FIFO environment variable (set by rsproxy-wrap.sh).
  2. It injects the --resultstore_output=<pipe_path> flag into the ninja command.
  3. It generates a unique invocation ID and passes it to ninja via the NINJA_BUILD_ID environment variable. This requires the uuidgen tool to be available in your PATH.

rs-ninja.sh expects the first argument to be the ninja executable.

Here is an example of how to use them together:

/path/to/rsproxy-wrap.sh \
  --rsproxy /path/to/rsproxy \
  --rsproxy_options \
  --cfg rsproxy.cfg \
  -- \
  /path/to/rs-ninja.sh \
  /path/to/ninja -C build_output_dir ...

If any other wrapper scripts are involved between rsproxy-wrap.sh and rs-ninja.sh, they need to preserve the RSPROXY_FIFO environment variable and preserve exit statuses of wrapped commands.

Versioning

Not yet applicable.

Releases

Not yet applicable.