From 292af29b264ad498e878be4fdb0a35e432dc0acc Mon Sep 17 00:00:00 2001 From: Jason Schroeder Date: Mon, 13 Oct 2025 15:04:47 -0700 Subject: [PATCH 1/8] fix: set workerName, instanceName for worker profile and pipeline change requests --- view/worker.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/view/worker.go b/view/worker.go index 689b118..d2d37a6 100644 --- a/view/worker.go +++ b/view/worker.go @@ -554,12 +554,18 @@ func pausedStyle(p bool) ui.Style { func (v *worker) Update() { conn := v.a.GetWorkerConn(v.w, v.a.CA) workerProfile := bfpb.NewWorkerProfileClient(conn) - profile, err := workerProfile.GetWorkerProfile(context.Background(), &bfpb.WorkerProfileRequest{}) + profile, err := workerProfile.GetWorkerProfile(context.Background(), &bfpb.WorkerProfileRequest{ + InstanceName: "shard", + WorkerName: v.w, + }) if err == nil { v.profile = profile } c := bfpb.NewWorkerControlClient(conn) - r, err := c.PipelineChange(context.Background(), &bfpb.WorkerPipelineChangeRequest{}) + r, err := c.PipelineChange(context.Background(), &bfpb.WorkerPipelineChangeRequest{ + InstanceName: "shard", + WorkerName: v.w, + }) if err != nil { panic(err) } From 25e8d984cb6c60acfda6c7ddd816e7cb61ceb4a7 Mon Sep 17 00:00:00 2001 From: George Gensure Date: Wed, 26 Nov 2025 09:31:43 -0500 Subject: [PATCH 2/8] Prevent concurrent app.Ops read/write --- view/operation_list.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/view/operation_list.go b/view/operation_list.go index 3d544e2..dd0b623 100644 --- a/view/operation_list.go +++ b/view/operation_list.go @@ -370,6 +370,8 @@ func (v *operationList) Update() { if v.opcache.Contains(op.Name) { continue } + // avoid concurrent v.a.Ops map read/write + v.a.Mutex.Lock() if o, ok := v.a.Ops[op.Name]; !ok || o == nil { m := op.Metadata if m == nil { @@ -378,6 +380,7 @@ func (v *operationList) Update() { go getExecution(v.a, op.Name, v.a.Conn, &wg) } } + v.a.Mutex.Unlock() } wg.Wait() v.opNames = make([]string, 0) From bca7ef5d842ccef380b2154e2466a5cedfeb34a3 Mon Sep 17 00:00:00 2001 From: Jason Schroeder Date: Thu, 16 Oct 2025 16:57:25 -0700 Subject: [PATCH 3/8] fix(crasher): avoid crashing when ExecutionOperationMetadata is not parsable --- client/operation.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/client/operation.go b/client/operation.go index 29ef8be..15ef41c 100644 --- a/client/operation.go +++ b/client/operation.go @@ -30,7 +30,10 @@ func ExecuteOperationMetadata(op *longrunning.Operation) (*reapi.ExecuteOperatio } return qm.ExecuteOperationMetadata, nil } - return nil, errors.New("Unexpected metadata: " + proto.MarshalTextString(op)) + // Gracefully handle unexpected or unknown metadata types by returning an + // empty ExecuteOperationMetadata instead of an error to avoid crashing + // callers that expect a non-nil metadata instance. + return &reapi.ExecuteOperationMetadata{}, nil } func RequestMetadata(o *longrunning.Operation) *reapi.RequestMetadata { From 515378bd5f955c3940f611b13abb7df738595cf5 Mon Sep 17 00:00:00 2001 From: Jason Schroeder Date: Mon, 23 Mar 2026 13:39:22 -0700 Subject: [PATCH 4/8] chore(deps): bump buildfarm to v2.16.0 Bumping dependency --- MODULE.bazel.lock | 15 ++++----------- extensions.bzl | 6 +++--- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index 2dbff73..1c87cff 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -242,7 +242,7 @@ "moduleExtensions": { "//:extensions.bzl%build_deps": { "general": { - "bzlTransitiveDigest": "yzPfL9UwdpPYFRKWTv5Ol84AkkFQRm/y91nJeUagJz4=", + "bzlTransitiveDigest": "4McQAVUuB28g6/K1krYOhheuC9nBITj+74GIhJvArC0=", "usagesDigest": "N1be+WNYxoeG1JN4CaIE1KMt+fq1c0PjhQ9M3tOJvU0=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, @@ -252,19 +252,12 @@ "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", "attributes": { "build_file": "@@//:BUILD.buildfarm", - "sha256": "cf47ea9674bde436cfafdcfc772be0fb5998482185c0e339ee4170370f025cf8", - "strip_prefix": "buildfarm-6be2f5e33ca9e3a0c7a2be253d52a53c3df4eddc/src/main/protobuf/build/buildfarm/v1test/", + "sha256": "575c657a565c4e986ba10b55c6e652c6ec7a68c2222b4951a9362dc0e53e3d2d", + "strip_prefix": "buildfarm-2.16.0/src/main/protobuf/build/buildfarm/v1test/", "urls": [ - "https://github.com/buildfarm/buildfarm/archive/6be2f5e33ca9e3a0c7a2be253d52a53c3df4eddc.zip" + "https://github.com/buildfarm/buildfarm/archive/refs/tags/2.16.0.zip" ] } - }, - "local_buildfarm": { - "repoRuleId": "@@bazel_tools//tools/build_defs/repo:local.bzl%new_local_repository", - "attributes": { - "build_file": "@@//:BUILD.buildfarm", - "path": "../buildfarm/src/main/protobuf/build/buildfarm/v1test" - } } }, "recordedRepoMappingEntries": [ diff --git a/extensions.bzl b/extensions.bzl index 7577ead..bdc928a 100644 --- a/extensions.bzl +++ b/extensions.bzl @@ -4,10 +4,10 @@ def _buildfarm_extension_impl(_ctx): http_archive( name = "buildfarm", build_file = "@//:BUILD.buildfarm", - sha256 = "cf47ea9674bde436cfafdcfc772be0fb5998482185c0e339ee4170370f025cf8", - strip_prefix = "buildfarm-6be2f5e33ca9e3a0c7a2be253d52a53c3df4eddc/src/main/protobuf/build/buildfarm/v1test/", + sha256 = "575c657a565c4e986ba10b55c6e652c6ec7a68c2222b4951a9362dc0e53e3d2d", + strip_prefix = "buildfarm-2.16.0/src/main/protobuf/build/buildfarm/v1test/", urls = [ - "https://github.com/buildfarm/buildfarm/archive/6be2f5e33ca9e3a0c7a2be253d52a53c3df4eddc.zip", + "https://github.com/buildfarm/buildfarm/archive/refs/tags/2.16.0.zip", ], ) From 81697eea0471dd017aab68a5c5128ca2c2413a18 Mon Sep 17 00:00:00 2001 From: Jason Schroeder Date: Thu, 9 Oct 2025 16:03:41 -0700 Subject: [PATCH 5/8] Contributor guide and pre-commit configuration (optional) --- .pre-commit-config.yaml | 9 +++++++ CONTRIBUTING.md | 53 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 .pre-commit-config.yaml create mode 100644 CONTRIBUTING.md diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..c6f1f89 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,9 @@ +repos: + - repo: local + hooks: + - id: gofmt-bazel + name: Format Go code via Bazel (rules_go) + entry: bazel run @io_bazel_rules_go//go -- fmt ./... + language: system + pass_filenames: false + types: [go] diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..18faa08 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,53 @@ +## Contributing + +Thank you for helping improve `bf-client`! This guide outlines the basics for making high‑quality contributions that are easy to review and maintain. + +### Prerequisites +- Go 1.23 (see `go.mod`) +- Bazel (build/test) +- Git + +### Getting started +1. Fork the repo and create a feature branch from the default branch. +2. Make small, focused commits with clear messages. +3. Open a pull request early for feedback; keep PRs scoped and reviewable. + +### Build and test +- Bazel (preferred): + - Build: `bazel build //...` + - Test: `bazel test //...` +- Native Go (if helpful locally): + - `go build ./...` + - `go test ./...` + +All PRs should pass tests and build cleanly. + +### Formatting and static checks +- Always run formatting before committing: + - `go fmt ./...` + - Optionally also: `gofmt -s -w .` +- Prefer to run basic static checks locally: + - `go vet ./...` + +CI may reject PRs that aren’t formatted. If you’re unsure, re‑run `go fmt ./...`. + + +### Pre-commit (optional but encouraged) +Use `pre-commit` to auto‑format and vet changes locally. + +Then run: +```bash +pre-commit install +``` + +### Commit and PR checklist +- [ ] Code compiles and tests pass (`bazel test //...`) +- [ ] Public APIs and non‑obvious logic documented +- [ ] PR description explains the why and the what + +### Communication +- Prefer small, iterative PRs; include context and tradeoffs. +- Be kind and constructive in reviews; propose changes with rationale. + +Thanks for contributing! + From 18b461c002424bc2b1a0a8b5d0e17c6b849284ab Mon Sep 17 00:00:00 2001 From: Jason Schroeder Date: Mon, 13 Oct 2025 13:01:24 -0700 Subject: [PATCH 6/8] build: remove non-existent target There is no `test.go` --- BUILD | 9 --------- 1 file changed, 9 deletions(-) diff --git a/BUILD b/BUILD index f5da7f3..3027457 100644 --- a/BUILD +++ b/BUILD @@ -22,12 +22,3 @@ go_binary( embed = [":go_default_library"], visibility = ["//visibility:public"], ) - -go_binary( - name = "test", - srcs = ["test.go"], - deps = [ - "@com_github_golang_protobuf//proto:go_default_library", - "@remoteapis//build/bazel/remote/execution/v2:go_default_library", - ], -) From b1f2d10b08fe3a9cd54d3f02b08a3d8458e13216 Mon Sep 17 00:00:00 2001 From: Jason Schroeder Date: Mon, 13 Oct 2025 13:02:17 -0700 Subject: [PATCH 7/8] ci: build everything --- .github/workflows/pr-build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pr-build.yml b/.github/workflows/pr-build.yml index 51d660c..e333d47 100644 --- a/.github/workflows/pr-build.yml +++ b/.github/workflows/pr-build.yml @@ -40,7 +40,7 @@ jobs: fi - name: Build - run: bazel build //:client + run: bazel build //... # Template for future matrix builds # matrix-build: From 19ecd4da069e9e0de3e8a0389adbf6ea07516396 Mon Sep 17 00:00:00 2001 From: Jason Schroeder Date: Tue, 24 Mar 2026 14:53:35 -0700 Subject: [PATCH 8/8] refactor: use App.Instance instead of hard-coded "shard" instance name Co-Authored-By: Claude Opus 4.6 --- view/operation_list.go | 2 +- view/queue.go | 2 +- view/worker.go | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/view/operation_list.go b/view/operation_list.go index dd0b623..af863d1 100644 --- a/view/operation_list.go +++ b/view/operation_list.go @@ -61,7 +61,7 @@ func NewOperationList(a *client.App, mode int, v View) *operationList { start := time.Now() a.Fetches++ status, err := c.Status(context.Background(), &bfpb.BackplaneStatusRequest{ - InstanceName: "shard", + InstanceName: a.Instance, }) a.LastReapiLatency = time.Since(start) if err != nil { diff --git a/view/queue.go b/view/queue.go index b6231d2..8877368 100644 --- a/view/queue.go +++ b/view/queue.go @@ -271,7 +271,7 @@ func (v *Queue) Update() { } start := time.Now() st, err := c.Status(context.Background(), &bfpb.BackplaneStatusRequest{ - InstanceName: "shard", + InstanceName: v.a.Instance, }) v.a.LastReapiLatency = time.Since(start) if err == nil { diff --git a/view/worker.go b/view/worker.go index d2d37a6..c05ce29 100644 --- a/view/worker.go +++ b/view/worker.go @@ -555,7 +555,7 @@ func (v *worker) Update() { conn := v.a.GetWorkerConn(v.w, v.a.CA) workerProfile := bfpb.NewWorkerProfileClient(conn) profile, err := workerProfile.GetWorkerProfile(context.Background(), &bfpb.WorkerProfileRequest{ - InstanceName: "shard", + InstanceName: v.a.Instance, WorkerName: v.w, }) if err == nil { @@ -563,7 +563,7 @@ func (v *worker) Update() { } c := bfpb.NewWorkerControlClient(conn) r, err := c.PipelineChange(context.Background(), &bfpb.WorkerPipelineChangeRequest{ - InstanceName: "shard", + InstanceName: v.a.Instance, WorkerName: v.w, }) if err != nil {