Skip to content

Commit 1a474a1

Browse files
committed
feat(stovepipe): define the repair executor extension
Summary: Add RepairExecutor.Submit accepting the existing OpenIssue directly. Define queue-scoped factory resolution and submission acceptance/error semantics, with generated mocks and Bazel targets. Extensions can resolve additional context through dependencies injected at construction. Extract this independently landable contract from the broader design in #893 so provider adapters can implement it before the controller is enabled. Revert Plan: Revert this commit.
1 parent 210f9d1 commit 1a474a1

6 files changed

Lines changed: 175 additions & 0 deletions

File tree

‎Makefile‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -629,6 +629,7 @@ GO_GENERATE_PACKAGES := \
629629
./stovepipe/core/requestlog/... \
630630
./stovepipe/extension/buildissue/... \
631631
./stovepipe/extension/buildrunner/... \
632+
./stovepipe/extension/fixer/... \
632633
./stovepipe/extension/projectstatus/... \
633634
./stovepipe/extension/queueconfig/... \
634635
./stovepipe/extension/sourcecontrol/... \
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 = ["fixer.go"],
6+
importpath = "github.com/uber/submitqueue/stovepipe/extension/fixer",
7+
visibility = ["//visibility:public"],
8+
deps = ["//stovepipe/entity:go_default_library"],
9+
)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Repair execution
2+
3+
[`RepairExecutor`](fixer.go) submits a repair attempt for an existing [`OpenIssue`](../../entity/open_issue.go). It can invoke an in-process implementation or wrap an external provider. The executor receives the issue directly and can retrieve additional build or failure details through storage dependencies injected at construction.
4+
5+
`OpenIssue.FirstSeenBuildID` identifies the build where this continuous opening of the condition was first observed. Task and unit identifiers retain their existing issue semantics, including an empty unit for a task-wide issue. A provider that cannot repair a given issue returns an error.
6+
7+
`Submit` returns promptly after the provider accepts the attempt, with a nonempty, opaque attempt ID and a nil error. The ID identifies the submitted work; acceptance does not establish that the issue recovered. Build observations remain the source of recovery information.
8+
9+
Each call may start an attempt. The caller owns first-failure selection and duplicate suppression. An error, including a timeout or cancellation, can occur after the provider accepted the work, so it must not cause an automatic resubmission. Implementations return plain dependency errors and must support concurrent calls.
10+
11+
`Factory.For` resolves an executor bound to `Config.QueueName`. Service wiring owns provider selection and injects credentials, clients, and queue mappings into concrete implementations. Generated mocks are available in [`mock`](mock/fixer_mock.go).

‎stovepipe/extension/fixer/fixer.go‎

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
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 fixer defines repair submission for a validation issue.
16+
package fixer
17+
18+
//go:generate mockgen -source=fixer.go -destination=mock/fixer_mock.go -package=mock
19+
20+
import (
21+
"context"
22+
23+
"github.com/uber/submitqueue/stovepipe/entity"
24+
)
25+
26+
// RepairExecutor submits repair attempts within a configured queue.
27+
// Implementations must be concurrency-safe and return promptly after submission.
28+
type RepairExecutor interface {
29+
// Submit returns a nonempty, opaque provider attempt ID on acceptance, not recovery.
30+
// Repeated calls may start additional attempts. A plain error can follow acceptance,
31+
// including on context cancellation; callers must not automatically repeat Submit.
32+
Submit(context.Context, entity.OpenIssue) (string, error)
33+
}
34+
35+
// Config identifies the queue whose repair executor is requested.
36+
type Config struct {
37+
// QueueName identifies the validation queue.
38+
QueueName string
39+
}
40+
41+
// Factory resolves queue-bound executors; routing belongs to service wiring.
42+
type Factory interface {
43+
For(Config) (RepairExecutor, error)
44+
}
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 = ["fixer_mock.go"],
6+
importpath = "github.com/uber/submitqueue/stovepipe/extension/fixer/mock",
7+
visibility = ["//visibility:public"],
8+
deps = [
9+
"//stovepipe/entity:go_default_library",
10+
"//stovepipe/extension/fixer:go_default_library",
11+
"@org_uber_go_mock//gomock:go_default_library",
12+
],
13+
)

‎stovepipe/extension/fixer/mock/fixer_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)