diff --git a/entity/BUILD.bazel b/entity/BUILD.bazel index 0bb84766..6ca5d5a5 100644 --- a/entity/BUILD.bazel +++ b/entity/BUILD.bazel @@ -7,6 +7,7 @@ go_library( "batch_dependent.go", "build.go", "change_provider.go", + "queue_config.go", "request.go", "speculation_tree.go", ], @@ -16,7 +17,10 @@ go_library( go_test( name = "entity_test", - srcs = ["request_test.go"], + srcs = [ + "queue_config_test.go", + "request_test.go", + ], embed = [":entity"], deps = [ "@com_github_stretchr_testify//assert", diff --git a/entity/queue_config.go b/entity/queue_config.go new file mode 100644 index 00000000..9e042921 --- /dev/null +++ b/entity/queue_config.go @@ -0,0 +1,44 @@ +package entity + +// QueueConfig holds the configuration for a single submit queue. +// Each queue maps a VCS repository + target to a processing pipeline. +// A repository can have multiple queues, but each queue has exactly one target. +// Immutable after creation. +type QueueConfig struct { + // Name uniquely identifies this queue within the system. + // Referenced by Request.Queue. + Name string + + // VCSType identifies the version control system (e.g., "git", "svn", "perforce"). + // A queue operates on exactly one VCS. + VCSType string + + // VCSAddress identifies the repository in the version control system. + // The format is VCS-specific: + // - Git: remote URL (e.g., "git@github.com:uber/submitqueue.git") + // - Perforce: depot path (e.g., "//depot/project") + // - SVN: repository URL (e.g., "https://svn.example.com/repos/project") + VCSAddress string + + // Target is the landing target where changes are merged. + // The format is VCS-specific: + // - Git: branch ref (e.g., "main", "release/v2") + // - Perforce: stream or depot path (e.g., "//depot/main/...") + // - SVN: repository path (e.g., "trunk/") + Target string +} + +// NewQueueConfig creates a new QueueConfig with the given parameters. +func NewQueueConfig( + name string, + vcsType string, + vcsAddress string, + target string, +) QueueConfig { + return QueueConfig{ + Name: name, + VCSType: vcsType, + VCSAddress: vcsAddress, + Target: target, + } +} diff --git a/entity/queue_config_test.go b/entity/queue_config_test.go new file mode 100644 index 00000000..3e181656 --- /dev/null +++ b/entity/queue_config_test.go @@ -0,0 +1,16 @@ +package entity + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestNewQueueConfig(t *testing.T) { + cfg := NewQueueConfig("uber/submitqueue/main", "git", "git@github.com:uber/submitqueue.git", "main") + + assert.Equal(t, "uber/submitqueue/main", cfg.Name) + assert.Equal(t, "git", cfg.VCSType) + assert.Equal(t, "git@github.com:uber/submitqueue.git", cfg.VCSAddress) + assert.Equal(t, "main", cfg.Target) +} diff --git a/extension/queueconfig/BUILD.bazel b/extension/queueconfig/BUILD.bazel new file mode 100644 index 00000000..27a152fa --- /dev/null +++ b/extension/queueconfig/BUILD.bazel @@ -0,0 +1,9 @@ +load("@rules_go//go:def.bzl", "go_library") + +go_library( + name = "queueconfig", + srcs = ["queueconfig.go"], + importpath = "github.com/uber/submitqueue/extension/queueconfig", + visibility = ["//visibility:public"], + deps = ["//entity"], +) diff --git a/extension/queueconfig/README.md b/extension/queueconfig/README.md new file mode 100644 index 00000000..4c94c8c8 --- /dev/null +++ b/extension/queueconfig/README.md @@ -0,0 +1,22 @@ +# Queue Config Extension + +Vendor-agnostic interface for providing queue configurations. + +## Interfaces + +### Store + +Provides queue configurations by name. + +```go +type Store interface { + Get(ctx context.Context, name string) (entity.QueueConfig, error) + List(ctx context.Context) ([]entity.QueueConfig, error) +} +``` + +## Entities + +Queue configuration entity lives in `entity/queue_config.go`: + +- **QueueConfig** — configuration for a single submit queue (name, VCS type, VCS repo, target) diff --git a/extension/queueconfig/queueconfig.go b/extension/queueconfig/queueconfig.go new file mode 100644 index 00000000..22f33835 --- /dev/null +++ b/extension/queueconfig/queueconfig.go @@ -0,0 +1,22 @@ +package queueconfig + +import ( + "context" + "errors" + + "github.com/uber/submitqueue/entity" +) + +// ErrNotFound is returned when the requested queue configuration does not exist. +var ErrNotFound = errors.New("queue config not found") + +// Store loads and provides queue configurations. +// Implementations may read from YAML files, databases, remote services, etc. +type Store interface { + // Get returns the configuration for a named queue. + // Returns ErrNotFound if no configuration exists for the given name. + Get(ctx context.Context, name string) (entity.QueueConfig, error) + + // List returns all configured queues. + List(ctx context.Context) ([]entity.QueueConfig, error) +}