Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
343fd79
feat(extension): add BuildManager extension for CI/CD integration
djuloori27 Feb 24, 2026
6ca9bc9
refactor(extension): simplify BuildManager interface and remove unuse…
djuloori27 Feb 25, 2026
936177c
refactor(extension): redesign BuildManager.Schedule to accept changes…
djuloori27 Feb 25, 2026
bfb2ba5
feat(extension): enhance BuildManager interface and add BuildStatusAc…
djuloori27 Feb 25, 2026
a10c7f9
docs(extension): update BuildManager README with latest interface cha…
djuloori27 Feb 25, 2026
025cf2a
refactor(extension): simplify BuildStatus enum and error contract
djuloori27 Feb 25, 2026
bf095ca
feat(extension): add metadata to Poll method and reorder BuildAction …
djuloori27 Feb 25, 2026
3da9f04
refactor(extension): remove ErrProviderUnavailable from errors.go
djuloori27 Feb 25, 2026
d009f94
refactor(entity): rename BuildStatusPassed to BuildStatusSucceeded
djuloori27 Feb 25, 2026
fc385f0
refactor(extension): rename parameter from id to buildID in Poll and …
djuloori27 Feb 26, 2026
539423f
refactor(entity): rename BuildAction to ChangeAction
djuloori27 Feb 26, 2026
4998f0b
refactor(entity): introduce BuildMetadata type for Poll return value
djuloori27 Feb 26, 2026
0bf45a8
docs(build): update README to reference BuildMetadata type
djuloori27 Feb 26, 2026
9e13403
refactor(build): refine BuildManager interface and documentation
djuloori27 Feb 26, 2026
58cebbe
docs(build): improve ChangeActionValidate comment clarity
djuloori27 Feb 26, 2026
9b862dc
docs(build): simplify BuildStatusCancelled comment
djuloori27 Feb 26, 2026
34d58d9
docs(build): remove context timeout explanation from Close method
djuloori27 Feb 26, 2026
1f9d780
refactor(build): remove context parameter from Close method
djuloori27 Feb 26, 2026
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
51 changes: 36 additions & 15 deletions entity/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,34 +7,28 @@ const (
// BuildStatusUnknown is the unreachable state. It is set by default when the structure is initialized. It should never be seen in the system.
BuildStatusUnknown BuildStatus = ""

// BuildStatusQueued indicates the build has been scheduled but not yet started.
BuildStatusQueued BuildStatus = "queued"
// BuildStatusAccepted indicates the build has been accepted by the CI provider.
BuildStatusAccepted BuildStatus = "accepted"

// BuildStatusRunning indicates the build is currently executing.
BuildStatusRunning BuildStatus = "running"

// BuildStatusPassed indicates the build completed successfully.
// BuildStatusSucceeded indicates the build completed successfully.
// This is a terminal state.
BuildStatusPassed BuildStatus = "passed"
BuildStatusSucceeded BuildStatus = "succeeded"

// BuildStatusFailed indicates the build completed with failures.
// This is a terminal state.
BuildStatusFailed BuildStatus = "failed"

// BuildStatusCancelled indicates the build was cancelled before completion.
// BuildStatusCancelled indicates the build was cancelled by SubmitQueue.
// This is a terminal state.
// Note: If the build system cancels a build for external reasons (e.g., timeout, resource limits),
// this should be reported as BuildStatusFailed, not BuildStatusCancelled.
BuildStatusCancelled BuildStatus = "cancelled"

// BuildStatusBlocked indicates the build is waiting for manual approval or unblocking.
// Some CI systems (like BuildKite) support manual approval steps.
BuildStatusBlocked BuildStatus = "blocked"
)

// IsTerminal returns true if the build state represents a final state (passed, failed, or cancelled).
// IsTerminal returns true if the build state represents a final state (succeeded, failed, or cancelled).
// Terminal states indicate the build has finished and will not change state again.
// Note: BuildStatusBlocked is NOT terminal as blocked builds can be unblocked and continue execution.
func (s BuildStatus) IsTerminal() bool {
return s == BuildStatusPassed || s == BuildStatusFailed || s == BuildStatusCancelled
return s == BuildStatusSucceeded || s == BuildStatusFailed || s == BuildStatusCancelled
}


Expand All @@ -61,3 +55,30 @@ type Build struct {
// Status represents the state of the build lifecycle this build is in.
Status BuildStatus
}

// ChangeAction defines the action to perform on a change submitted to the build system.
type ChangeAction string

const (
// ChangeActionUnknown is the sentinel value for uninitialized actions.
ChangeActionUnknown ChangeAction = ""
// ChangeActionApply applies the change to the target branch.
ChangeActionApply ChangeAction = "apply"
// ChangeActionValidate applies the change first, and then validates the change by running respective validation/test suites.
ChangeActionValidate ChangeAction = "validate"
)

// BuildChange represents a code change to be processed by the build system.
// This is used by BuildManager to specify what changes to build and what action to perform.
type BuildChange struct {
// Change is the code change to process.
// This references the same Change entity used in Request, containing the source provider
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

at this moment Change is just a list of URLs and provider is encoded into schema part of it

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

isn't line number 76 good enough?

// and list of change IDs (e.g., PR numbers, diff IDs).
Change Change
// Action specifies what operation to perform on this change.
Action ChangeAction
}

// BuildMetadata contains additional metadata about a build returned by the build system.
// The specific keys and values are implementation-defined.
type BuildMetadata map[string]string
60 changes: 47 additions & 13 deletions entity/build_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ func TestBuildStatus_IsTerminal(t *testing.T) {
expected bool
}{
{
name: "passed is terminal",
status: BuildStatusPassed,
name: "succeeded is terminal",
status: BuildStatusSucceeded,
expected: true,
},
{
Expand All @@ -28,30 +28,64 @@ func TestBuildStatus_IsTerminal(t *testing.T) {
expected: true,
},
{
name: "queued is not terminal",
status: BuildStatusQueued,
name: "accepted is not terminal",
status: BuildStatusAccepted,
expected: false,
},
{
name: "running is not terminal",
status: BuildStatusRunning,
name: "unknown is not terminal",
status: BuildStatusUnknown,
expected: false,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equal(t, tt.expected, tt.status.IsTerminal())
})
}
}

func TestBuildChange_Creation(t *testing.T) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

change detector

tests := []struct {
name string
change BuildChange
wantID string
wantAction ChangeAction
}{
{
name: "blocked is not terminal",
status: BuildStatusBlocked,
expected: false,
name: "apply action",
change: BuildChange{
ChangeID: "PR-42",
Action: ChangeActionApply,
},
wantID: "PR-42",
wantAction: ChangeActionApply,
},
{
name: "unknown is not terminal",
status: BuildStatusUnknown,
expected: false,
name: "validate action",
change: BuildChange{
ChangeID: "D12345",
Action: ChangeActionValidate,
},
wantID: "D12345",
wantAction: ChangeActionValidate,
},
{
name: "unknown action",
change: BuildChange{
ChangeID: "123",
Action: ChangeActionUnknown,
},
wantID: "123",
wantAction: ChangeActionUnknown,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equal(t, tt.expected, tt.status.IsTerminal())
assert.Equal(t, tt.wantID, tt.change.ChangeID)
assert.Equal(t, tt.wantAction, tt.change.Action)
})
}
}
14 changes: 14 additions & 0 deletions extension/build/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
load("@rules_go//go:def.bzl", "go_library")

go_library(
name = "build",
srcs = [
"build_manager.go",
"errors.go",
],
importpath = "github.com/uber/submitqueue/extension/build",
visibility = ["//visibility:public"],
deps = [
"//entity",
],
)
Loading
Loading