Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions .bazelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
common --enable_bzlmod
build --incompatible_strict_action_env

# BuildBuddy: `--config=bb` with BUILDBUDDY_API_KEY in the environment.
build:bb --bes_results_url=https://app.buildbuddy.io/invocation/
build:bb --bes_backend=grpcs://remote.buildbuddy.io
build:bb --remote_cache=grpcs://remote.buildbuddy.io
build:bb --remote_timeout=10m
build:bb --remote_download_minimal
build:bb --build_metadata=ROLE=CI

# Locally, the emitted projects' tests run the host's toolchains (`--config=local`).
# and the fixture's generator runs the host's Ruby.
build:local --action_env=PATH
test:local --test_env=PATH --test_env=HOME --test_env=CARGO_HOME --test_env=RUSTUP_HOME --test_env=RUSTUP_TOOLCHAIN --test_env=JAVA_HOME --test_env=GRADLE_USER_HOME

# A pull request reads the cache with a read-only key and never writes to it,
# as a fork's pull request must (it sees no secrets).
build:bb-ro --remote_cache=grpcs://remote.buildbuddy.io
build:bb-ro --remote_timeout=10m
build:bb-ro --remote_download_minimal
build:bb-ro --noremote_upload_local_results

# bazel/images/all/Dockerfile's ENV (and ruby:3.4's), declared: a remote executor has them from the image,
# a fork's local run would not, and declaring them in both keeps their action keys equal.
# Keep in step with the Dockerfile.
common:image-env --action_env=LANG=C.UTF-8 --test_env=LANG=C.UTF-8
common:image-env --action_env=GEM_HOME=/usr/local/bundle --test_env=GEM_HOME=/usr/local/bundle
common:image-env --action_env=BUNDLE_APP_CONFIG=/usr/local/bundle --test_env=BUNDLE_APP_CONFIG=/usr/local/bundle
common:image-env --action_env=BUNDLE_SILENCE_ROOT_WARNING=1 --test_env=BUNDLE_SILENCE_ROOT_WARNING=1
common:image-env --action_env=RUSTUP_HOME=/usr/local/rustup --test_env=RUSTUP_HOME=/usr/local/rustup
common:image-env --action_env=CARGO_HOME=/usr/local/cargo --test_env=CARGO_HOME=/usr/local/cargo
common:image-env --action_env=WASI_SDK_PATH=/opt/wasi-sdk --test_env=WASI_SDK_PATH=/opt/wasi-sdk
common:image-env --action_env=UV_PYTHON_INSTALL_DIR=/opt/uv-python --test_env=UV_PYTHON_INSTALL_DIR=/opt/uv-python
common:image-env --action_env=JAVA_HOME=/opt/java --test_env=JAVA_HOME=/opt/java
common:image-env --action_env=DOTNET_ROOT=/opt/dotnet --test_env=DOTNET_ROOT=/opt/dotnet
common:image-env --action_env=DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 --test_env=DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1
common:image-env --action_env=DOTNET_NOLOGO=1 --test_env=DOTNET_NOLOGO=1
common:image-env --action_env=DOTNET_CLI_TELEMETRY_OPTOUT=1 --test_env=DOTNET_CLI_TELEMETRY_OPTOUT=1

# Remote execution on BuildBuddy's Linux executors (Ubuntu 22.04 image).
build:rbe --config=bb
build:rbe --config=image-env
build:rbe --remote_executor=grpcs://remote.buildbuddy.io
build:rbe --platforms=@toolchains_buildbuddy//platforms:linux_x86_64
build:rbe --extra_execution_platforms=@toolchains_buildbuddy//platforms:linux_x86_64
build:rbe --jobs=50
# Not the client's autodetected C toolchain: its paths and flags enter every action key, so a run from another
# machine (a fork's job in the executors' image) would miss the whole cache.
build:rbe --extra_toolchains=@llvm_toolchain//:all
# A fork's pull request: the executors' platform declared, so its action keys match the cache main fills,
# but run here (`container:` is the executors' image); unsandboxed, as a container cannot nest namespaces.
build:fork --config=bb-ro
build:fork --config=image-env
build:fork --platforms=@toolchains_buildbuddy//platforms:linux_x86_64
build:fork --extra_execution_platforms=@toolchains_buildbuddy//platforms:linux_x86_64
build:fork --spawn_strategy=local
build:fork --extra_toolchains=@llvm_toolchain//:all

build --define=SPINEL_SHA=master
1 change: 1 addition & 0 deletions .bazelversion
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
9.2.0
147 changes: 147 additions & 0 deletions .github/workflows/bazel.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
name: Bazel

# Every ci.yml lane as a Bazel test, run on BuildBuddy's remote executors (#273).
# A step whose inputs match a cached run is not re-run, so a change re-tests only
# what it reaches; a pull request's results carry over to main.
on:
push:
branches: [main]
pull_request:
branches: [main]

concurrency:
group: bazel-${{ github.ref }}
# Not cancelled on main: each push's result is the record for its commit.
cancel-in-progress: ${{ github.event_name == 'pull_request' }}

permissions:
contents: read

jobs:
Comment thread
coderabbitai[bot] marked this conversation as resolved.
images:
# The remote executors' images, published to GHCR for BuildBuddy to pull.
# Not before BuildBuddy is set up: the read-only key's variable is the switch, and every job waits on this one.
if: ${{ vars.BUILDBUDDY_READONLY_API_KEY != '' }}
runs-on: ubuntu-latest
timeout-minutes: 90
permissions:
contents: read
packages: write
outputs:
ci-image: ${{ steps.ref.outputs.ci-image }}
steps:
- uses: actions/checkout@v5
- id: ref
run: echo "ci-image=$(sed -n 's|^CI_IMAGE = "docker://\(.*\)"|\1|p' bazel/images.bzl)" >> "$GITHUB_OUTPUT"
- if: github.event_name == 'push'
uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push the tags bazel/images.bzl names
if: github.event_name == 'push'
run: |
build() {
image=$(sed -n "s|^$1 = \"docker://\\(.*\\)\"|\\1|p" bazel/images.bzl)
if docker manifest inspect "$image" >/dev/null 2>&1; then echo "$image exists"; return; fi
docker build -t "$image" -f "$2" .
docker push "$image"
}
build CI_IMAGE bazel/images/all/Dockerfile
build DIND_IMAGE bazel/images/dind/Dockerfile

all-rbe:
# Every lane as Bazel tests, executed on BuildBuddy; this job only orchestrates.
# Two jobs, not one run: Spinel master moves many times a day, and its lanes would hold back the gating result.
name: all-rbe (${{ matrix.set }})
if: ${{ !(github.event_name == 'pull_request' && (github.event.pull_request.head.repo.full_name != github.repository)) }}
needs: images
runs-on: ubuntu-latest
timeout-minutes: 120
continue-on-error: ${{ matrix.set == 'advisory' }}
env:
BUILDBUDDY_API_KEY: ${{ secrets.BUILDBUDDY_ORG_API_KEY }}
BB_CONFIG: rbe
strategy:
fail-fast: false
matrix:
include:
- set: gating
filter: -advisory
- set: advisory
filter: advisory
steps:
- uses: actions/checkout@v5
- uses: bazel-contrib/setup-bazel@0.19.0
with:
bazelisk-cache: true
repository-cache: true
- name: Fixtures (real-blog, store) the source-tree suites read
# Not `bin/rh fixture` here: each run's fresh `rails new` differs in bytes, and every test reading it would miss the cache.
run: |
bazel build --config=$BB_CONFIG "--remote_header=x-buildbuddy-api-key=$BUILDBUDDY_API_KEY" --remote_download_toplevel \
//:real_blog_fixture //:store_fixture
mkdir -p fixtures/real-blog fixtures/store
tar -xf bazel-bin/real-blog-fixture.tar -C fixtures/real-blog
tar -xf bazel-bin/store-fixture.tar -C fixtures/store
- name: bazel test --config=rbe //:all (${{ matrix.set }})
run: |
set +e
bazel test --config=$BB_CONFIG "--remote_header=x-buildbuddy-api-key=$BUILDBUDDY_API_KEY" --keep_going \
--test_output=errors --jobs=80 --build_tests_only --test_tag_filters=${{ matrix.filter }} \
--define=SPINEL_SHA="$(git ls-remote https://github.com/matz/spinel refs/heads/master | cut -f1)" \
//:all 2>&1 | tee bazel-all.log
status=${PIPESTATUS[0]}
grep -E 'INFO: [0-9]+ processes|Executed [0-9]+ out of|Elapsed time' bazel-all.log >> "$GITHUB_STEP_SUMMARY"
grep -E '^//:.* (FAILED|NO STATUS|FAILED TO BUILD|TIMEOUT)' bazel-all.log >> "$GITHUB_STEP_SUMMARY" || true
exit $status

fork:
# A fork's pull request sees no secrets, and a read-only key cannot upload remote execution's inputs:
# it reads the cache main fills, and runs the misses here, in the executors' image.
name: fork (${{ matrix.set }})
if: ${{ github.event_name == 'pull_request' && (github.event.pull_request.head.repo.full_name != github.repository) }}
needs: images
runs-on: ubuntu-latest
container: ${{ needs.images.outputs.ci-image }}
timeout-minutes: 180
continue-on-error: ${{ matrix.set == 'advisory' }}
strategy:
fail-fast: false
matrix:
include:
- set: gating
filter: -advisory,-rbe-only
- set: advisory
filter: advisory,-rbe-only
env:
BUILDBUDDY_API_KEY: ${{ vars.BUILDBUDDY_READONLY_API_KEY }}
defaults:
run:
shell: bash
steps:
- uses: actions/checkout@v5
- name: Bazelisk
# Not setup-bazel: inside a job container the bazel it installs is not on PATH.
run: |
curl -fsSL https://github.com/bazelbuild/bazelisk/releases/download/v1.27.0/bazelisk-linux-amd64 -o /usr/local/bin/bazel
chmod +x /usr/local/bin/bazel
- name: Fixtures (real-blog, store) the source-tree suites read
run: |
bazel build --config=fork "--remote_header=x-buildbuddy-api-key=$BUILDBUDDY_API_KEY" --remote_download_toplevel \
//:real_blog_fixture //:store_fixture
mkdir -p fixtures/real-blog fixtures/store
tar -xf bazel-bin/real-blog-fixture.tar -C fixtures/real-blog
tar -xf bazel-bin/store-fixture.tar -C fixtures/store
- name: bazel test --config=fork //:all (${{ matrix.set }})
run: |
set +e
bazel test --config=fork "--remote_header=x-buildbuddy-api-key=$BUILDBUDDY_API_KEY" --keep_going \
--test_output=errors --build_tests_only --test_tag_filters=${{ matrix.filter }} \
--define=SPINEL_SHA="$(git ls-remote https://github.com/matz/spinel refs/heads/master | cut -f1)" \
//:all 2>&1 | tee bazel-all.log
status=${PIPESTATUS[0]}
grep -E 'INFO: [0-9]+ processes|Executed [0-9]+ out of|Elapsed time' bazel-all.log >> "$GITHUB_STEP_SUMMARY"
grep -E '^//:.* (FAILED|NO STATUS|FAILED TO BUILD|TIMEOUT)' bazel-all.log >> "$GITHUB_STEP_SUMMARY" || true
exit $status
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,6 @@
/*-srv.err
/bench/probes/
/scratchpad/

# Bazel output trees
/bazel-*
10 changes: 10 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,16 @@ defect even if the build is green.
The ~5 `continue-on-error: true` jobs track upstream Spinel and other moving
toolchains on purpose — **red there is a signal to read, not a regression to
shim away.** Don't add workarounds just to make an advisory job green.
- **CI also runs on Bazel + BuildBuddy** (`.github/workflows/bazel.yml`,
`BUILD.bazel`). Every ci.yml lane is a Bazel test, cached by its inputs, so
a change re-tests only what it reaches; ci.yml's `continue-on-error` lanes
carry the `advisory` tag. A pull request from a fork cannot see secrets: it
reads the cache read-only and runs the rest on Actions, so a wide change can
take tens of minutes, where a push to `main` or a branch in this repository
runs remotely in minutes. Cargo stays the source of truth. Bazel needs an
edit for a new crate with a build script, a new lane, or a tool in
`bazel/images/all/Dockerfile` (bump its tag in `bazel/images.bzl`, and keep
`.bazelrc`'s `image-env` in step with its `ENV`).

## The actual goal

Expand Down
Loading
Loading