diff --git a/stovepipe/core/filter/filter.go b/stovepipe/core/filter/filter.go new file mode 100644 index 00000000..356f6d56 --- /dev/null +++ b/stovepipe/core/filter/filter.go @@ -0,0 +1,41 @@ +// Copyright (c) 2025 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package filter implements a filter for commit events. +package filter + +import ( + "strings" + + "github.com/uber/submitqueue/stovepipe/entity" +) + +// Config controls which VCS URIs are watched. +// WatchedURIPrefixes is a list of URI prefixes to match against ChangeInfo.URI. +// Example: "git://github.com/uber/go-code/refs/heads/main" +// watches all commits on the main branch of uber/go-code. +type Config struct { + WatchedURIPrefixes []string +} + +// ShouldProcess returns true if the commit event's URI matches +// any of the configured watched prefixes. +func ShouldProcess(cfg Config, event entity.ChangeInfo) bool { + for _, prefix := range cfg.WatchedURIPrefixes { + if strings.HasPrefix(event.URI, prefix) { + return true + } + } + return false +} diff --git a/stovepipe/entity/entity.go b/stovepipe/entity/entity.go index 15ac8680..80c625df 100644 --- a/stovepipe/entity/entity.go +++ b/stovepipe/entity/entity.go @@ -4,7 +4,7 @@ // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // -// http://www.apache.org/licenses/LICENSE-2.0 +// http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, @@ -12,5 +12,38 @@ // See the License for the specific language governing permissions and // limitations under the License. -// Package entity holds Stovepipe-specific domain types (distinct from shared repo entity/). +// Package entity holds Stovepipe-specific domain entities. package entity + +// ChangeInfo represents a new change detected on a VCS remote. +// It is intentionally VCS-agnostic: the URI scheme carries the +// provider identity, mirroring the github:// scheme used in +// SubmitQueue's ChangeInfo. +// +// URI format: "git://///" +// Example: "git://github.com/uber/go-code/refs/heads/main/c3a4d5e6f789..." +// +// Fields are immutable after construction. +type ChangeInfo struct { + // URI is the canonical VCS identifier for this change. + // Scheme is "git://"; path encodes host, repo, ref, and new revision. + // This mirrors the ChangeInfo.URI pattern used in SubmitQueue. + URI string `json:"uri"` + + // PreviousURI is the URI of the prior revision on the same ref, if known. + // Empty string if unavailable. + // Example: "git://github.com/uber/go-code/refs/heads/main/aabbccdd..." + PreviousURI string `json:"previous_uri,omitempty"` + + // Author is the identity of the person who authored the change. + Author Author `json:"author"` +} + +// Author identifies the person who authored a change. +// Mirrors SubmitQueue's Author to keep the two domains consistent. +type Author struct { + // Name is the display name of the author. + Name string `json:"name"` + // Email is the email address of the author. + Email string `json:"email,omitempty"` +} diff --git a/stovepipe/extension/changeingester/logging.go b/stovepipe/extension/changeingester/logging.go new file mode 100644 index 00000000..e3c50e57 --- /dev/null +++ b/stovepipe/extension/changeingester/logging.go @@ -0,0 +1,46 @@ +// Copyright (c) 2025 Uber Technologies, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package changeingester provides ChangeIngester implementations. +package changeingester + +import ( + "context" + + "github.com/uber/submitqueue/stovepipe/entity" + "github.com/uber/submitqueue/stovepipe/extension" + "go.uber.org/zap" +) + +// LoggingHandler is a stub ChangeHandler that logs received changes. +// Replace with real persistence logic once DB schema is ready. +type LoggingHandler struct { + logger *zap.Logger +} + +// New constructs a new LoggingHandler. +// The return type enforces interface compliance at compile time. +func New(logger *zap.Logger) extension.ChangeHandler { + return LoggingHandler{logger: logger} +} + +func (h LoggingHandler) IngestChange(ctx context.Context, info entity.ChangeInfo) error { + h.logger.Info("ingested change", + zap.String("uri", info.URI), + zap.String("previous_uri", info.PreviousURI), + zap.String("author", info.Author.Name), + zap.String("author_email", info.Author.Email), + ) + return nil +} diff --git a/stovepipe/extension/extension.go b/stovepipe/extension/extension.go index 92d4bcea..5a891faf 100644 --- a/stovepipe/extension/extension.go +++ b/stovepipe/extension/extension.go @@ -14,3 +14,21 @@ // Package extension holds Stovepipe-specific extension implementations. package extension + +import ( + "context" + + "github.com/uber/submitqueue/stovepipe/entity" +) + +// ChangeIngester subscribes to change events from a VCS source +// and dispatches them for processing. The source and VCS are +// implementation details left to the injected backend. +type ChangeIngester interface { + Start(ctx context.Context) error +} + +// ChangeHandler processes a single change received from the ingester. +type ChangeHandler interface { + IngestChange(ctx context.Context, info entity.ChangeInfo) error +}