Skip to content

Commit 3c505ea

Browse files
authored
feat(stovepipe): Add build issue detection contract (#898)
## Summary **What**: - Define provider-neutral discovery of confirmed validation issues identified by a logical task and optional unit. **Why**: - Support deduplicated accumulation of open issues as validation progresses. ## Test Plan - [x] Verify the new contract and generated test doubles compile. ## Revert Plan - Revert this PR. It introduces no runtime wiring, schema changes, or persisted data. ## Issue Links - [CODEM-607](https://linear.app/uber/issue/CODEM-607/build-analysis)
1 parent dc1db41 commit 3c505ea

8 files changed

Lines changed: 203 additions & 0 deletions

File tree

‎Makefile‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -627,6 +627,7 @@ GO_GENERATE_PACKAGES := \
627627
./runway/extension/merger/... \
628628
./stovepipe/controller/... \
629629
./stovepipe/core/requestlog/... \
630+
./stovepipe/extension/buildissue/... \
630631
./stovepipe/extension/buildrunner/... \
631632
./stovepipe/extension/projectstatus/... \
632633
./stovepipe/extension/queueconfig/... \

‎stovepipe/entity/BUILD.bazel‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ go_library(
44
name = "go_default_library",
55
srcs = [
66
"build.go",
7+
"build_issue.go",
78
"ingest.go",
89
"list.go",
910
"project_status.go",

‎stovepipe/entity/build_issue.go‎

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Copyright (c) 2026 Uber Technologies, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package entity
16+
17+
// BuildIssue identifies a validation failure by task and optional unit.
18+
type BuildIssue struct {
19+
// TaskID identifies the logical validation task, stable across builds and retries.
20+
TaskID string `json:"task_id"`
21+
// UnitID identifies the failed unit within the task; empty for a task-wide issue.
22+
// Repeated observations of the same condition use the same TaskID and UnitID.
23+
UnitID string `json:"unit_id"`
24+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
load("@rules_go//go:def.bzl", "go_library")
2+
3+
go_library(
4+
name = "go_default_library",
5+
srcs = ["buildissue.go"],
6+
importpath = "github.com/uber/submitqueue/stovepipe/extension/buildissue",
7+
visibility = ["//visibility:public"],
8+
deps = ["//stovepipe/entity:go_default_library"],
9+
)
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Build issue detection
2+
3+
`Detector` discovers confirmed validation issues from a build. It returns failure observations, not a complete view of build state.
4+
5+
Issue values are defined in the [domain model](../../entity/build_issue.go). A validation task is a logical validation operation. A validation unit is an identifiable piece of work within a task.
6+
7+
Within a validation queue, TaskID and UnitID together identify the validation condition. Repeated observations of the same condition use the same pair across builds. UnitID is empty for a task-wide issue.
8+
9+
Each detection returns issues discoverable at that time and may repeat earlier observations. Detection does not mark issues as handled. An issue's absence from a detection result does not mean it is resolved.
10+
11+
Detectors must support concurrent calls. Dependency failures return plain errors; issue results returned with an error must not be used.
12+
13+
`Factory` resolves the detector for a validation queue.
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// Copyright (c) 2026 Uber Technologies, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
// Package buildissue defines confirmed-issue discovery for active or
16+
// completed builds, independently of build status polling.
17+
package buildissue
18+
19+
//go:generate mockgen -source=buildissue.go -destination=mock/buildissue_mock.go -package=mock
20+
21+
import (
22+
"context"
23+
24+
"github.com/uber/submitqueue/stovepipe/entity"
25+
)
26+
27+
// Detector discovers confirmed issues without waiting for build completion.
28+
// Implementations own confirmation and retry rules and must be concurrency-safe.
29+
// Detection does not mark issues as handled.
30+
// An issue's absence from a detection result does not mean it is resolved.
31+
// Return plain dependency errors; issue results returned with an error must not be used.
32+
type Detector interface {
33+
Detect(ctx context.Context, buildID entity.BuildID) ([]entity.BuildIssue, error)
34+
}
35+
36+
// Config identifies the queue whose issue detector is requested.
37+
type Config struct {
38+
// QueueName identifies the queue.
39+
QueueName string
40+
}
41+
42+
// Factory resolves a queue's detector; implementations and routing belong to host wiring.
43+
type Factory interface {
44+
For(cfg Config) (Detector, error)
45+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
load("@rules_go//go:def.bzl", "go_library")
2+
3+
go_library(
4+
name = "go_default_library",
5+
srcs = ["buildissue_mock.go"],
6+
importpath = "github.com/uber/submitqueue/stovepipe/extension/buildissue/mock",
7+
visibility = ["//visibility:public"],
8+
deps = [
9+
"//stovepipe/entity:go_default_library",
10+
"//stovepipe/extension/buildissue:go_default_library",
11+
"@org_uber_go_mock//gomock:go_default_library",
12+
],
13+
)

‎stovepipe/extension/buildissue/mock/buildissue_mock.go‎

Lines changed: 97 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)