Skip to content

ci(bazel): source the bazel-ci container from a repo variable and run byoo first - #429

Merged
balajinvda merged 6 commits into
mainfrom
ci/bazel-shallow-checkout
Jul 27, 2026
Merged

ci(bazel): source the bazel-ci container from a repo variable and run byoo first#429
balajinvda merged 6 commits into
mainfrom
ci/bazel-shallow-checkout

Conversation

@balajinvda

@balajinvda balajinvda commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Why

Three unrelated CI fixes that were sitting on one branch, rescoped after
measurement. The original shallow-checkout change was dropped: per-step
timings showed actions/checkout is 7s of a 1972s bazel (byoo-otel-collector)
job, so shallowing it saves nothing meaningful and rows run in parallel anyway.

What remains are changes that do carry their weight.

What changed

  • Source the bazel-ci job container from the BAZEL_CI_IMAGE repository
    variable instead of a literal tag in each workflow, so the image is bumped
    in one place. Uses vars, not env: job-level container.image is
    evaluated before the workflow env context is reliably available, which
    previously made the matrix expand to zero jobs on push events. Keeps a
    literal fallback so forks and unset-variable cases still work.
  • Run the byoo-otel-collector row first. Matrix rows dispatch top-down under
    max-parallel: 8, and byoo is the longest row, so sitting at position 10 it
    spent ~4 minutes queued before starting (run created 18:58:26, job started
    19:02:22). This costs no extra runner concurrency, only dispatch order.
    max-parallel stays at 8 because the remaining rows finish well inside the
    byoo row's runtime.
  • image-push: discover services and module layout instead of hardcoding them,
    derive the push repo name correctly for hyphenated image targets, and
    surface bazel query failures instead of masking them.

Customer Release Notes

Not customer visible.

Plan Summary

Not applicable.

Usage

Set the repository variable BAZEL_CI_IMAGE before merging, otherwise the
literal fallback is used.

Testing

CI on this PR. The reorder is observable as the byoo row starting in the
first dispatch wave rather than after a slot frees.

Notes

Requires the BAZEL_CI_IMAGE repository variable to be set for the
indirection to take effect.

References

None

Related Merge Requests/Pull Requests

Builds on #444 (byoo collector genrule remote-cacheable) and #471.

Dependencies

None

@balajinvda
balajinvda requested a review from a team as a code owner July 24, 2026 18:45
@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Bazel workflows now use the BAZEL_CI_IMAGE repository variable with a 0.13.0 fallback. Checkout history is shallow for non-root and Docker-host jobs, while root jobs retain full history for PR diffing. Manual image publishing resolves Bazel module layout before selecting image targets.

Changes

Bazel CI configuration

Layer / File(s) Summary
Configurable Bazel CI image
.github/workflows/bazel.yml, .github/workflows/chart-push-manual.yml, .github/workflows/image-push-manual.yml, BAZEL.md
Workflows use BAZEL_CI_IMAGE with a ghcr.io/nvidia/nvcf/bazel-ci:0.13.0 fallback, and documentation describes updating the shared image.
Matrix checkout depth configuration
.github/workflows/bazel.yml
The root Bazel matrix row keeps full history for PR diffing, while non-root and Docker-host rows use shallow checkout.
Module-aware manual image publishing
.github/workflows/image-push-manual.yml
Manual image publishing accepts free-form service paths, resolves the Bazel module layout, and scopes oci_image_index target queries to the selected subtree.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Operator
  participant image-push-manual.yml
  participant Bazel
  Operator->>image-push-manual.yml: Provide service_path
  image-push-manual.yml->>Bazel: Resolve module layout and working directory
  image-push-manual.yml->>Bazel: Query scoped oci_image_index targets
  Bazel-->>image-push-manual.yml: Return image targets
  image-push-manual.yml-->>Operator: Build and push multi-arch images
Loading

Possibly related PRs

Suggested reviewers: kristinapathak

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title follows Conventional Commits and accurately reflects the CI/workflow changes, especially the Bazel CI container source update.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ci/bazel-shallow-checkout

Comment @coderabbitai help to get the list of available commands.

@balajinvda
balajinvda force-pushed the ci/bazel-shallow-checkout branch from 0692055 to e8c0c0a Compare July 24, 2026 20:41
@balajinvda
balajinvda requested a review from a team as a code owner July 24, 2026 20:41

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@BAZEL.md`:
- Around line 432-433: Update the Bazel toolchain documentation near the “Every
workflow” statement to limit the claim to containerized Bazel jobs, reflecting
that the bazel-docker job runs on ubuntu-latest and installs Bazelisk
independently.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 6b66742f-fd7a-4400-b982-a40a67a725c8

📥 Commits

Reviewing files that changed from the base of the PR and between 0692055 and e8c0c0a.

📒 Files selected for processing (4)
  • .github/workflows/bazel.yml
  • .github/workflows/chart-push-manual.yml
  • .github/workflows/image-push-manual.yml
  • BAZEL.md

Comment thread BAZEL.md
@balajinvda
balajinvda force-pushed the ci/bazel-shallow-checkout branch from e8c0c0a to 7f6df99 Compare July 25, 2026 02:58

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/image-push-manual.yml:
- Line 149: Update the query handling around the indexes population so the bazel
query invoked by the workflow preserves and propagates failures instead of
hiding them behind mapfile process substitution. Run bazel query directly before
reading its output, while retaining the existing parsing and empty-result
behavior for successful queries.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 6445b402-fe05-4c65-b70b-58f305cda000

📥 Commits

Reviewing files that changed from the base of the PR and between e8c0c0a and 7f6df99.

📒 Files selected for processing (4)
  • .github/workflows/bazel.yml
  • .github/workflows/chart-push-manual.yml
  • .github/workflows/image-push-manual.yml
  • BAZEL.md
🚧 Files skipped from review as they are similar to previous changes (3)
  • .github/workflows/chart-push-manual.yml
  • .github/workflows/bazel.yml
  • BAZEL.md

Comment thread .github/workflows/image-push-manual.yml Outdated
@balajinvda

balajinvda commented Jul 27, 2026

Copy link
Copy Markdown
Contributor Author

Correction: reopening. Rescoping this PR to the BAZEL_CI_IMAGE repository-variable change and dropping the shallow-checkout change.

Measurement showed the shallow checkout does not deliver a meaningful speedup. Per-step timings from a representative bazel (byoo-otel-collector) job (run 30296173803):

Step Duration
bazel build 1839s
actions/checkout@v4 7s
bazel test //... 11s
Total job 1972s

Checkout is 7s of a 1972s job, so shallowing it saves a few seconds per row and nothing in wall-clock terms, since rows run in parallel. The cost is entirely in the build step.

The BAZEL_CI_IMAGE change is worthwhile independently: it moves the bazel-ci image tag to a repository variable so it is bumped in one place instead of being edited in every workflow that runs in that container.

@balajinvda balajinvda closed this Jul 27, 2026
@balajinvda balajinvda reopened this Jul 27, 2026
balajinvda and others added 5 commits July 27, 2026 13:08
The bazel-ci image was hardcoded in four places and had already drifted to
three different versions: bazel.yml on 0.13.0, image-push-manual.yml and
chart-push-manual.yml on 0.8.0, and BAZEL.md documenting 0.12.0. The release
path building shipping images on a different toolchain than CI validates with
is a correctness problem, not just untidiness.

Source the container from the BAZEL_CI_IMAGE repository variable so the image
is bumped in one place. Each workflow keeps the current pin as a || fallback so
CI still runs when the variable is unavailable, for example on a fork.

It must be vars, not env: GitHub Actions evaluates job-level container.image
before the workflow-level env: context is reliably available, which is why the
previous note told maintainers to keep the tag literal. The vars context does
not have that ordering problem, so the value can now be centralized.

Co-authored-by: Balaji Ganesan <bganesan@nvidia.com>
(cherry picked from commit 881a51e)
…ding

The manual image-push workflow carried a hardcoded choice list of 11 service
paths, so every new service needed a workflow edit before its image could be
pushed for pre-merge testing. cloud-tasks, for example, was not selectable.

GitHub Actions cannot populate a choice input dynamically, so drop the list:
service_path is a free-form path, and the workflow discovers what to build.

It also assumed every subtree is its own Bazel module: it ran bazel from
inside the subtree and queried //... . That is false for services in the
repo-root module (the Java services), where the query finds nothing. The
workflow now derives the layout from whether the subtree owns a MODULE.bazel,
querying from the subtree with //... or from the root with a path-scoped
pattern. Both were verified against a standalone module (grpc-proxy resolves
//:image_index) and a root-module service (cloud-tasks resolves
//src/control-plane-services/cloud-tasks/nvct-service:nvct-service-oss-image_index).

An unknown path now fails with the list of subtrees owning a Bazel module,
which replaces the discoverability the dropdown provided.

Co-authored-by: Balaji Ganesan <bganesan@nvidia.com>
(cherry picked from commit 7f6df99)
The repo-name rule only stripped an _image suffix, so a target using hyphens
fell through to the default branch and got both the service prefix and the
suffix left on. byoo-otel-collector-image became
byoo-otel-collector-byoo-otel-collector-image, and cloud-tasks would have
pushed nvct-service-oss as cloud-tasks-nvct-service-oss-image.

The tree uses the separator to mean two different things:
  image              the service's sole image; repo is the service
  <component>_image  a sub-component; repo is <service>-<component>
  <image-name>-image the target already carries the full image name; use it
                     as-is without the service prefix

Add the hyphenated case. Verified against every image target in the tree: the
11 services currently selectable are unchanged, and byoo-otel-collector (2
targets) and cloud-tasks are corrected. byoo was latent because it is not in
the old hardcoded list; making the input free-form would have exposed it.

Co-authored-by: Balaji Ganesan <bganesan@nvidia.com>
(cherry picked from commit 7d4fcc4)
The target discovery used mapfile with process substitution, so only stdout
reached mapfile and the query's exit status was discarded. A failing query (a
BUILD error, an unloadable package, a bad scope) produced an empty array and
was then misreported as "no oci_image_index targets under <path>", pointing
the operator at the wrong problem.

Run the query directly, check its status, and build the array explicitly. The
array is built in a loop rather than from a here-string because a here-string
of empty output yields one empty element instead of an empty array, which would
defeat the existing no-targets check.

Verified all four cases: failing query surfaces the error, empty result gives 0
targets, single and multiple results parse correctly.

Co-authored-by: Balaji Ganesan <bganesan@nvidia.com>
(cherry picked from commit 054f2c1)
Matrix rows are dispatched top-down and capped by max-parallel: 8, so a
long row placed late waits for a free slot before it starts. The byoo
collector sat at row 10 and spent about four minutes queued before doing
any work (run created 18:58:26, job started 19:02:22).

It is the longest row in the matrix, so it now leads and starts in the
first wave. This costs no additional runner concurrency; it only changes
dispatch order. max-parallel stays at 8 because the remaining rows finish
well inside the byoo row's runtime, so raising it would not move the
run's wall clock.

Co-authored-by: Balaji Ganesan <bganesan@nvidia.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@balajinvda
balajinvda force-pushed the ci/bazel-shallow-checkout branch from 054f2c1 to 2771184 Compare July 27, 2026 20:13
@balajinvda balajinvda changed the title ci(bazel): shallow checkout for non-root matrix rows ci(bazel): source the bazel-ci container from a repo variable and run byoo first Jul 27, 2026
The byoo collector genrule produces a 271 MB binary that never reached
the remote cache. Bazel reported it per run:

  WARNING: Remote Cache: Error while uploading artifact with digest
  '71dfa2b5.../283998957'

so the genrule stayed a local action on every job. The build summary
showed the cost directly: "383 processes: 316 remote cache hit, 59
internal, 3 local" -- everything cached except the collector, rebuilt in
all three of its configurations each run.

The cause is a client/server mismatch, not a size ceiling. The cache
tolerates large slow uploads on purpose: nginx sets grpc_read_timeout and
grpc_send_timeout to 600s ("bb-storage itself tolerates 10 minute
streams, so do not be the bottleneck"), client_max_body_size to 1 GB, and
bb-storage sets maximumMessageSizeBytes to 1 GB against ~1.68 GB blocks.
271 MB clears all of those. The Bazel client, though, was left at
--remote_timeout=120, which requires sustaining ~2.4 MB/s from a
GitHub-hosted runner to us-west-2 for a single blob, three times per job.

Raise the client to 600s so it matches what the server already allows.

This only bounds how long a client waits, so it cannot break a healthy
build. It does mean a genuinely unreachable cache takes longer to give
up, but nginx keeps grpc_connect_timeout at 30s, so connection failures
still surface quickly; the longer budget applies to in-flight streams.
The cacheless-retry fallback remains the backstop.

Co-authored-by: Balaji Ganesan <bganesan@nvidia.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@balajinvda
balajinvda enabled auto-merge July 27, 2026 20:34
@balajinvda
balajinvda added this pull request to the merge queue Jul 27, 2026
Merged via the queue into main with commit 0e1dc27 Jul 27, 2026
38 checks passed
@balajinvda
balajinvda deleted the ci/bazel-shallow-checkout branch July 27, 2026 21:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants