diff --git a/buf/registry/module/v1/commit.proto b/buf/registry/module/v1/commit.proto new file mode 100644 index 0000000..ca6f071 --- /dev/null +++ b/buf/registry/module/v1/commit.proto @@ -0,0 +1,75 @@ +// Copyright 2023-2024 Buf 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. + +syntax = "proto3"; + +package buf.registry.module.v1; + +import "buf/registry/module/v1/digest.proto"; +import "buf/registry/priv/extension/v1beta1/extension.proto"; +import "buf/validate/validate.proto"; +import "google/protobuf/timestamp.proto"; + +option go_package = "buf.build/gen/go/bufbuild/registry/protocolbuffers/go/buf/registry/module/v1"; + +// A commit on a specific Module. +// +// Commits are immutable. +// +// Many Commits may be associated with one Digest. +// +// Note that the Digest returned on a Commit depends on the requested DigestType in the +// RPC that returned the Commit. +message Commit { + option (buf.registry.priv.extension.v1beta1.message).response_only = true; + + // The id of the Commit. + string id = 1 [ + (buf.validate.field).required = true, + (buf.validate.field).string.uuid = true + ]; + // The time the Commit was pushed to the BSR. + // + // Commits are immutable, so there is no corresponding update_time. + google.protobuf.Timestamp create_time = 2 [(buf.validate.field).required = true]; + // The id of the User or Organization that owns the Module that the Commit is associated with. + string owner_id = 3 [ + (buf.validate.field).required = true, + (buf.validate.field).string.uuid = true + ]; + // The id of the Module that the Commit is associated with. + string module_id = 4 [ + (buf.validate.field).required = true, + (buf.validate.field).string.uuid = true + ]; + // The Digest of the Commit's contents. + // + // Note that individual RPCs may request a specific DigestType, and a Digest of + // this DigestType will be returned as part of this Commit. This may affect your + // caching of returned Commit messages if you require different DigestTypes. + Digest digest = 5 [(buf.validate.field).required = true]; + // The id of the User that created this Commit on the BSR. + // + // May be empty if the User is no longer available. + string created_by_user_id = 6 [(buf.validate.field).string.uuid = true]; + // The URL of the source control commit that is associated with the Commit. + // + // BSR users can navigate to this link to find source control information that is relevant to this Commit + // (e.g. commit description, PR discussion, authors, approvers, etc.). + string source_control_url = 7 [ + (buf.validate.field).string.uri = true, + (buf.validate.field).string.max_len = 255, + (buf.validate.field).ignore = IGNORE_IF_UNPOPULATED + ]; +} diff --git a/buf/registry/module/v1/commit_service.proto b/buf/registry/module/v1/commit_service.proto new file mode 100644 index 0000000..490fe95 --- /dev/null +++ b/buf/registry/module/v1/commit_service.proto @@ -0,0 +1,51 @@ +// Copyright 2023-2024 Buf 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. + +syntax = "proto3"; + +package buf.registry.module.v1; + +import "buf/registry/module/v1/commit.proto"; +import "buf/registry/module/v1/resource.proto"; +import "buf/validate/validate.proto"; + +option go_package = "buf.build/gen/go/bufbuild/registry/protocolbuffers/go/buf/registry/module/v1"; + +// Operate on Commits. +service CommitService { + // Get Commits. + rpc GetCommits(GetCommitsRequest) returns (GetCommitsResponse) { + option idempotency_level = NO_SIDE_EFFECTS; + } +} + +message GetCommitsRequest { + // References to request a Commit for. + // + // See the documentation on ResourceRef for resource resolution details. + // + // Resolution is as follows: + // - If a Module is referenced, the Commit of the default Label is returned. + // - If a Label is referenced, the Commit of this Label is returned. + // - If a Commit is referenced, this Commit is returned. + repeated ResourceRef resource_refs = 1 [ + (buf.validate.field).repeated.min_items = 1, + (buf.validate.field).repeated.max_items = 250 + ]; +} + +message GetCommitsResponse { + // The found Commits in the same order as requested. + repeated Commit commits = 1 [(buf.validate.field).repeated.min_items = 1]; +} diff --git a/buf/registry/legacy/federation/v1beta1/doc.proto b/buf/registry/module/v1/digest.proto similarity index 50% rename from buf/registry/legacy/federation/v1beta1/doc.proto rename to buf/registry/module/v1/digest.proto index d831af6..d31c6b1 100644 --- a/buf/registry/legacy/federation/v1beta1/doc.proto +++ b/buf/registry/module/v1/digest.proto @@ -14,9 +14,29 @@ syntax = "proto3"; -// This package is only needed due to a legacy federation feature that only remains -// enabled on the clusters of a few of Buf's customers. If you are not one of -// these customers, you should not use this package. -package buf.registry.legacy.federation.v1beta1; +package buf.registry.module.v1; -option go_package = "buf.build/gen/go/bufbuild/registry/protocolbuffers/go/buf/registry/legacy/federation/v1beta1"; +import "buf/validate/validate.proto"; + +option go_package = "buf.build/gen/go/bufbuild/registry/protocolbuffers/go/buf/registry/module/v1"; + +// A digest of a Commit's content. +// +// A digest represents all content for a single Commit, including its .proto files, documentation +// files, license files, and the digests of its dependencies. +message Digest { + // The type of the Digest. + DigestType type = 1 [ + (buf.validate.field).required = true, + (buf.validate.field).enum.defined_only = true + ]; + // The value of the Digest. + bytes value = 2 [(buf.validate.field).required = true]; +} + +// The type of Digest. +enum DigestType { + DIGEST_TYPE_UNSPECIFIED = 0; + // The b5 digest function. + DIGEST_TYPE_B5 = 1; +} diff --git a/buf/registry/module/v1/download_service.proto b/buf/registry/module/v1/download_service.proto new file mode 100644 index 0000000..76d044f --- /dev/null +++ b/buf/registry/module/v1/download_service.proto @@ -0,0 +1,110 @@ +// Copyright 2023-2024 Buf 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. + +syntax = "proto3"; + +package buf.registry.module.v1; + +import "buf/registry/module/v1/commit.proto"; +import "buf/registry/module/v1/file.proto"; +import "buf/registry/module/v1/resource.proto"; +import "buf/validate/validate.proto"; + +option go_package = "buf.build/gen/go/bufbuild/registry/protocolbuffers/go/buf/registry/module/v1"; + +// Download contents. +service DownloadService { + // Download the contents of multiple Modules, Labels, or Commits. + // + // Content consists of the .proto files, license files, and documentation files. + rpc Download(DownloadRequest) returns (DownloadResponse) { + option idempotency_level = NO_SIDE_EFFECTS; + } +} + +message DownloadRequest { + // A request for content for a single reference. + message Value { + // The reference to get content for. + // + // See the documentation on ResourceRef for resource resolution details. + // + // Once the resource is resolved, the following content is returned: + // - If a Module is referenced, the content of the Commit of the default Label is returned. + // - If a Label is referenced, the content of the Commit of this Label is returned. + // - If a Commit is referenced, the content for this Commit is returned. + ResourceRef resource_ref = 1 [(buf.validate.field).required = true]; + // Specific file types to request. + // + // If not set, all file types are returned. + repeated FileType file_types = 2 [(buf.validate.field).repeated.items.enum.defined_only = true]; + // Specific file paths to retrieve. + // + // May be directories. For example, path "foo/bar" will result in files "foo/bar/baz.proto", + // "foo/bar/LICENSE" being downloaded. + // + // If empty, all file paths for the given reference are retrieved. + // + // If no paths match, an empty Files list will be returned, however the call may still + // be successful if paths_allow_not_exist is set (the dependency list may still be on + // the response). If a directory "foo/bar" is specified but this directory has no files, + // this is considered to be a non-match. + // + // This field also interacts with file_types - if file_types is set, a path only matches + // if it is also of the file type, and if there are no matching paths for the given FileTypes, + // an error is returned unless paths_not_allow_exist is set. + // + // The path must be relative, and cannot contain any "." or ".." components + // The separator "/" must be used. + repeated string paths = 3 [(buf.validate.field).repeated.items = { + string: { + max_len: 4096 + not_contains: "\\" + pattern: "^([^/.][^/]?|[^/][^/.]|[^/]{3,})(/([^/.][^/]?|[^/][^/.]|[^/]{3,}))*$" + } + }]; + // Whether to allow file paths not to exist within the given module. + // + // For example, one may want to retrieve the file paths "buf.md" and "README.md", + // but only expect one to actually exist. + // + // If false, it is an error to specify non-existent file paths. + bool paths_allow_not_exist = 4; + } + // The references to get contents for. + repeated Value values = 1 [ + (buf.validate.field).repeated.min_items = 1, + (buf.validate.field).repeated.max_items = 250 + ]; +} + +message DownloadResponse { + // Content for a single Commit. + message Content { + // The Commit associated with the Content. + // + // The Commit associated with this ID will be present in the commits field. + // + // The Commit will use the DigestType specified in the request value. + Commit commit = 1 [(buf.validate.field).required = true]; + // The Files of the content. + // + // This will consist of the .proto files, license files, and documentation files. + // + // If no paths match and paths_allow_not_exist is set, this may be empty. + repeated File files = 2; + } + // The Contents of the references in the same order as requested. + repeated Content contents = 1 [(buf.validate.field).repeated.min_items = 1]; +} diff --git a/buf/registry/module/v1/file.proto b/buf/registry/module/v1/file.proto new file mode 100644 index 0000000..ff710d8 --- /dev/null +++ b/buf/registry/module/v1/file.proto @@ -0,0 +1,59 @@ +// Copyright 2023-2024 Buf 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. + +syntax = "proto3"; + +package buf.registry.module.v1; + +import "buf/validate/validate.proto"; + +option go_package = "buf.build/gen/go/bufbuild/registry/protocolbuffers/go/buf/registry/module/v1"; + +// A file that can be read or written to from disk. +// +// A File includes a path and associated content. +// Files are purposefully simple, and do not include attributes such as permissions. +message File { + // The path of the File. + // + // The path must be relative, and cannot contain any "." or ".." components. + // The separator "/" must be used. + string path = 1 [ + (buf.validate.field).required = true, + (buf.validate.field).string = { + max_len: 4096, + not_contains: "\\", + pattern: "^([^/.][^/]?|[^/][^/.]|[^/]{3,})(/([^/.][^/]?|[^/][^/.]|[^/]{3,}))*$" + } + ]; + // The content of the File. + // + // May be empty. + bytes content = 2; +} + +// A specific file type. +enum FileType { + FILE_TYPE_UNSPECIFIED = 0; + // A .proto file. + FILE_TYPE_PROTO = 1; + // A documentation file. + // + // Documentation files are always named README.md, README.markdown, or buf.md. + FILE_TYPE_DOC = 2; + // A license file. + // + // License files are always named LICENSE. + FILE_TYPE_LICENSE = 3; +} diff --git a/buf/registry/legacy/federation/v1beta1/graph.proto b/buf/registry/module/v1/graph.proto similarity index 66% rename from buf/registry/legacy/federation/v1beta1/graph.proto rename to buf/registry/module/v1/graph.proto index 96ddd8d..5e90c8d 100644 --- a/buf/registry/legacy/federation/v1beta1/graph.proto +++ b/buf/registry/module/v1/graph.proto @@ -14,30 +14,18 @@ syntax = "proto3"; -package buf.registry.legacy.federation.v1beta1; +package buf.registry.module.v1; -import "buf/registry/module/v1beta1/commit.proto"; +import "buf/registry/module/v1/commit.proto"; import "buf/registry/priv/extension/v1beta1/extension.proto"; import "buf/validate/validate.proto"; -option go_package = "buf.build/gen/go/bufbuild/registry/protocolbuffers/go/buf/registry/legacy/federation/v1beta1"; +option go_package = "buf.build/gen/go/bufbuild/registry/protocolbuffers/go/buf/registry/module/v1"; -// A dependency graph that allows for federation. -// -// See the package documentation for more details. You should likely use buf.registry.module.v1beta1 -// and not this package. +// A dependency graph. message Graph { option (buf.registry.priv.extension.v1beta1.message).response_only = true; - // A Commit in the dependency graph. - // - // This wraps the top-level Commit. - message Commit { - // The top-level Commit. - buf.registry.module.v1beta1.Commit commit = 1 [(buf.validate.field).required = true]; - // The registry hostname of the Commit. - string registry = 2 [(buf.validate.field).required = true]; - } // A node in the dependency graph. message Node { // The commit of the node. @@ -45,8 +33,6 @@ message Graph { (buf.validate.field).required = true, (buf.validate.field).string.uuid = true ]; - // The registry hostname of the Node. - string registry = 2 [(buf.validate.field).required = true]; } // An edge in the dependency graph. message Edge { diff --git a/buf/registry/legacy/federation/v1beta1/graph_service.proto b/buf/registry/module/v1/graph_service.proto similarity index 64% rename from buf/registry/legacy/federation/v1beta1/graph_service.proto rename to buf/registry/module/v1/graph_service.proto index f6a7430..da85e41 100644 --- a/buf/registry/legacy/federation/v1beta1/graph_service.proto +++ b/buf/registry/module/v1/graph_service.proto @@ -14,19 +14,15 @@ syntax = "proto3"; -package buf.registry.legacy.federation.v1beta1; +package buf.registry.module.v1; -import "buf/registry/legacy/federation/v1beta1/graph.proto"; -import "buf/registry/legacy/federation/v1beta1/resource.proto"; -import "buf/registry/module/v1beta1/digest.proto"; +import "buf/registry/module/v1/graph.proto"; +import "buf/registry/module/v1/resource.proto"; import "buf/validate/validate.proto"; -option go_package = "buf.build/gen/go/bufbuild/registry/protocolbuffers/go/buf/registry/legacy/federation/v1beta1"; +option go_package = "buf.build/gen/go/bufbuild/registry/protocolbuffers/go/buf/registry/module/v1"; // Get dependency graphs. -// -// See the package documentation for more details. You should likely use buf.registry.module.v1beta1 -// and not this package. service GraphService { // Get a dependency graph that includes the given Commits. // @@ -34,16 +30,11 @@ service GraphService { // graph, along with their dependencies. // // A dependency graph is a directed acyclic graph. - // - // See the package documentation for more details. You should likely use buf.registry.module.v1beta1 - // and not this package. rpc GetGraph(GetGraphRequest) returns (GetGraphResponse) { option idempotency_level = NO_SIDE_EFFECTS; } } -// See the package documentation for more details. You should likely use buf.registry.module.v1beta1 -// and not this package. message GetGraphRequest { // The references to resolve to Commits to include in the graph. // @@ -60,17 +51,8 @@ message GetGraphRequest { (buf.validate.field).repeated.min_items = 1, (buf.validate.field).repeated.max_items = 250 ]; - // The DigestType to return for Commit nodes. - // - // If this DigestType is not available, an error is returned. - // Note that certain DigestTypes may be deprecated over time. - // - // If not set, the latest DigestType is used. - buf.registry.module.v1beta1.DigestType digest_type = 2 [(buf.validate.field).enum.defined_only = true]; } -// See the package documentation for more details. You should likely use buf.registry.module.v1beta1 -// and not this package. message GetGraphResponse { // The Graph calculated for the Commits. Graph graph = 1 [(buf.validate.field).required = true]; diff --git a/buf/registry/module/v1/label.proto b/buf/registry/module/v1/label.proto new file mode 100644 index 0000000..1d9b306 --- /dev/null +++ b/buf/registry/module/v1/label.proto @@ -0,0 +1,166 @@ +// Copyright 2023-2024 Buf 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. + +syntax = "proto3"; + +package buf.registry.module.v1; + +import "buf/registry/priv/extension/v1beta1/extension.proto"; +import "buf/validate/validate.proto"; +import "google/protobuf/timestamp.proto"; + +option go_package = "buf.build/gen/go/bufbuild/registry/protocolbuffers/go/buf/registry/module/v1"; + +// A label on a specific Module. +// +// Many Labels can be associated with one Commit. +message Label { + option (buf.registry.priv.extension.v1beta1.message).response_only = true; + + // The id of the Label. + string id = 1 [ + (buf.validate.field).required = true, + (buf.validate.field).string.uuid = true + ]; + // The time the Label was created on the BSR. + google.protobuf.Timestamp create_time = 2 [(buf.validate.field).required = true]; + // The last time the Label was updated on the BSR. + google.protobuf.Timestamp update_time = 3 [(buf.validate.field).required = true]; + // Whether or not the Label was archived. + // + // If a Label is archived, the API considers it to not exist and will not return archived + // Labels, except when calling LabelService.GetLabels. + bool archived = 4; + // The name of the Label. + // + // Unique within a given Module. + string name = 5 [ + (buf.validate.field).required = true, + (buf.validate.field).string.max_len = 250 + ]; + // The id of the User or Organization that owns the Module that the Label is associated with. + string owner_id = 6 [ + (buf.validate.field).required = true, + (buf.validate.field).string.uuid = true + ]; + // The id of the Module that the Label is associated with. + string module_id = 7 [ + (buf.validate.field).required = true, + (buf.validate.field).string.uuid = true + ]; + // The id of the Commit currently associated with the Label. + // + // If policy checks are enabled, this will point to the most recent Commit that passed or was approved. + // To get the history of the Commits that have been associated with a Label, use ListLabelHistory. + string commit_id = 8 [ + (buf.validate.field).required = true, + (buf.validate.field).string.uuid = true + ]; + // The id of the User that last updated this Label on the BSR. + string updated_by_user_id = 9 [ + (buf.validate.field).required = true, + (buf.validate.field).string.uuid = true + ]; + // The CommitCheckState for the Commit the Label points to. + // + // The CommitCheckStatus will always be disabled, passed, or approved, since Labels will + // never point to pending or rejected Commits. + // + // TODO: Add custom CEL validation to validate the status field is one of DISABLED, PASSED, APPROVED. + CommitCheckState commit_check_state = 10 [(buf.validate.field).required = true]; +} + +// The state of a Commit's policy checks for a particular Label. +// +// Policy checks are an enterprise-only feature - contact us to learn more! +message CommitCheckState { + // The status of the policy check. + CommitCheckStatus status = 1 [ + (buf.validate.field).enum.defined_only = true, + (buf.validate.field).required = true + ]; + // The time the policy check state was last updated. + // + // If the status is disabled, this will be equal to the Commit create_time. + google.protobuf.Timestamp update_time = 3 [(buf.validate.field).required = true]; +} + +// A check status for a Commit. +// +// Policy checks are an enterprise-only feature - contact us to learn more! +enum CommitCheckStatus { + COMMIT_CHECK_STATUS_UNSPECIFIED = 0; + // Policy checks were not enabled when the Commit was created. + COMMIT_CHECK_STATUS_DISABLED = 1; + // The Commit did not fail any policy checks and therefore did not need review. + COMMIT_CHECK_STATUS_PASSED = 2; + // The Commit has not yet been reviewed after failing policy checks and is pending. + COMMIT_CHECK_STATUS_PENDING = 3; + // The Commit was reviewed after failing policy checks and was rejected. + COMMIT_CHECK_STATUS_REJECTED = 4; + // The Commit was reviewed after failing policy checks and was approved. + COMMIT_CHECK_STATUS_APPROVED = 5; +} + +// LabelRef is a reference to a Label, either an id or a fully-qualified name. +// +// This is used in requests. +message LabelRef { + option (buf.registry.priv.extension.v1beta1.message).request_only = true; + + // The fully-qualified name of a Label within a BSR instance. + // + // A Name uniquely identifies a Label. + // This is used for requests when a caller only has the label name and not the ID. + message Name { + // The name of the owner of the Module that contains the Label, either a User or Organization. + string owner = 1 [ + (buf.validate.field).required = true, + (buf.validate.field).string.max_len = 32 + ]; + // The name of the Module that contains the Label, either a User or Organization. + string module = 2 [(buf.validate.field).string = { + min_len: 2, + max_len: 100 + }]; + // The Label name. + string label = 3 [ + (buf.validate.field).required = true, + (buf.validate.field).string.max_len = 250 + ]; + } + + oneof value { + option (buf.validate.oneof).required = true; + // The id of the Label. + string id = 1 [(buf.validate.field).string.uuid = true]; + // The fully-qualified name of the Label. + Name name = 2; + } +} + +// A reference to a Label scoped to a Module, either an id or a name. +// +// This is used in requests. +message ScopedLabelRef { + option (buf.registry.priv.extension.v1beta1.message).request_only = true; + + oneof value { + option (buf.validate.oneof).required = true; + // The id of the Label. + string id = 1 [(buf.validate.field).string.uuid = true]; + // The name of the Label. + string name = 2; + } +} diff --git a/buf/registry/module/v1/label_service.proto b/buf/registry/module/v1/label_service.proto new file mode 100644 index 0000000..c5a6aaf --- /dev/null +++ b/buf/registry/module/v1/label_service.proto @@ -0,0 +1,213 @@ +// Copyright 2023-2024 Buf 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. + +syntax = "proto3"; + +package buf.registry.module.v1; + +import "buf/registry/module/v1/commit.proto"; +import "buf/registry/module/v1/label.proto"; +import "buf/registry/module/v1/resource.proto"; +import "buf/validate/validate.proto"; + +option go_package = "buf.build/gen/go/bufbuild/registry/protocolbuffers/go/buf/registry/module/v1"; + +// Operate on Labels. +service LabelService { + // Get Labels by id or name. + rpc GetLabels(GetLabelsRequest) returns (GetLabelsResponse) { + option idempotency_level = NO_SIDE_EFFECTS; + } + // List Labels for a given Module, Commit, or CommitDigest. + rpc ListLabels(ListLabelsRequest) returns (ListLabelsResponse) { + option idempotency_level = NO_SIDE_EFFECTS; + } + // List the history of a Label. + rpc ListLabelHistory(ListLabelHistoryRequest) returns (ListLabelHistoryResponse) { + option idempotency_level = NO_SIDE_EFFECTS; + } + // Create or update Labels on a Module. + // + // If the Label does not exist, it will be created. + // If the Label was archived, it will be unarchived. + // If the Label already existed, the Commit in the request has to be newer than the Commit that + // the Label is currently pointing to, otherwise an error is returned. + // + // This operation is atomic. Either all Labels are created/updated or an error is returned. + rpc CreateOrUpdateLabels(CreateOrUpdateLabelsRequest) returns (CreateOrUpdateLabelsResponse) { + option idempotency_level = IDEMPOTENT; + } + // Archive existing Labels. + // + // This operation is atomic. Either all Labels are archived or an error is returned. + rpc ArchiveLabels(ArchiveLabelsRequest) returns (ArchiveLabelsResponse) { + option idempotency_level = IDEMPOTENT; + } +} + +message GetLabelsRequest { + // The Labels to request. + // + // This may reference archived Labels. + repeated LabelRef label_refs = 1 [ + (buf.validate.field).repeated.min_items = 1, + (buf.validate.field).repeated.max_items = 250 + ]; +} + +message GetLabelsResponse { + // The retrieved Labels in the same order as requested. + repeated Label labels = 1 [(buf.validate.field).repeated.min_items = 1]; +} + +message ListLabelsRequest { + // The list order. + enum Order { + ORDER_UNSPECIFIED = 0; + // Order by create_time oldest to newest. + ORDER_CREATE_TIME_ASC = 1; + // Order by create_time newest to oldest. + ORDER_CREATE_TIME_DESC = 2; + } + // The maximum number of items to return. + // + // The default value is 10. + uint32 page_size = 1 [(buf.validate.field).uint32.lte = 250]; + // The page to start from. + // + // If empty, the first page is returned, + string page_token = 2 [(buf.validate.field).string.max_len = 4096]; + // The reference to list Labels for. + // + // See the documentation on Ref for resource resolution details. + // + // Once the resource is resolved, the following Labels are listed: + // - If a Module is referenced, all Labels for the Module are returned. + // - If a Label is referenced, this Label is returned. + // - If a Commit is referenced, all Labels that currently point to the Commit are returned. Note that + // Labels only point to passed or approved Commits, or Commits where policy checks were disabled. + ResourceRef resource_ref = 3 [(buf.validate.field).required = true]; + // The order to return the Labels. + // + // If not specified, defaults to ORDER_CREATE_TIME_ASC. + // + // TODO: Do we want ORDER_CREATE_TIME_ASC to be the default? + // TODO: We are purposefully not making the default the zero enum value, however + // we may want to consider this. + Order order = 4 [(buf.validate.field).enum.defined_only = true]; + // Only return Labels that point to a Commit with one of these CommitCheckStatus values. + // + // If not set, Labels that point to a Commit with any CommitCheckStatus value are returned. + // + // It is an error to filter on CommitCheckStatuses of pending or rejected, as Labels will only + // point to Commits that are passed or approved, or that have policy checks disabled. + // + // TODO: Add custom CEL validation to validate the status field is one of DISABLED, PASSED, APPROVED. + repeated CommitCheckStatus commit_check_statuses = 5 [(buf.validate.field).repeated.items.enum.defined_only = true]; +} + +message ListLabelsResponse { + // The next page token. + // + /// If empty, there are no more pages. + string next_page_token = 1 [(buf.validate.field).string.max_len = 4096]; + // The listed Labels. + repeated Label labels = 2; +} + +message ListLabelHistoryRequest { + // The list order. + enum Order { + ORDER_UNSPECIFIED = 0; + // Order by association time newest to oldest. + // + // The Commits most recently associated with the Label will be listed first. + ORDER_DESC = 1; + // Order by association time oldest to newest. + ORDER_ASC = 2; + } + // The maximum number of items to return. + // + // The default value is 10. + uint32 page_size = 1 [(buf.validate.field).uint32.lte = 250]; + // The page to start from. + // + // If empty, the first page is returned. + string page_token = 2 [(buf.validate.field).string.max_len = 4096]; + // The Label to list history for. + // + // This may reference archived Labels. + LabelRef label_ref = 3 [(buf.validate.field).required = true]; + // The order to list the Labels. + // + // If not specified, defaults to ORDER_DESC. + // + // TODO: We are purposefully not making the default the zero enum value, however + // we may want to consider this. + Order order = 4 [(buf.validate.field).enum.defined_only = true]; +} + +message ListLabelHistoryResponse { + message Value { + // The Commit. + Commit commit = 1 [(buf.validate.field).required = true]; + // The CommitCheckState for this Commit on this Label. + CommitCheckState commit_check_state = 2 [(buf.validate.field).required = true]; + } + + // The next page token. + // + /// If empty, there are no more pages. + string next_page_token = 1 [(buf.validate.field).string.max_len = 4096]; + // The ordered history of the Label. + repeated Value values = 2; +} + +message CreateOrUpdateLabelsRequest { + // An individual request to create or update a Label. + message Value { + // The Labels to create or update. + LabelRef label_ref = 1 [(buf.validate.field).required = true]; + // The id of the Commit to associate with the Label. + // + // If the Label already existed, the Label will now point to this Commit, as long as this Commit + // is newer than the Commit that the Label is currently pointing to, otherwise an error is + // returned. + // If the Label was archived, it will be unarchived. + string commit_id = 2 [ + (buf.validate.field).required = true, + (buf.validate.field).string.uuid = true + ]; + } + // The Labels to create. + repeated Value values = 1 [ + (buf.validate.field).repeated.min_items = 1, + (buf.validate.field).repeated.max_items = 250 + ]; +} + +message CreateOrUpdateLabelsResponse { + // The created or updated Labels in the same order as given on the request. + repeated Label labels = 1 [(buf.validate.field).repeated.min_items = 1]; +} + +message ArchiveLabelsRequest { + // The Labels to archive. + repeated LabelRef label_refs = 1 [ + (buf.validate.field).repeated.min_items = 1, + (buf.validate.field).repeated.max_items = 250 + ]; +} + +message ArchiveLabelsResponse {} diff --git a/buf/registry/module/v1/module.proto b/buf/registry/module/v1/module.proto new file mode 100644 index 0000000..27429de --- /dev/null +++ b/buf/registry/module/v1/module.proto @@ -0,0 +1,132 @@ +// Copyright 2023-2024 Buf 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. + +syntax = "proto3"; + +package buf.registry.module.v1; + +import "buf/registry/priv/extension/v1beta1/extension.proto"; +import "buf/validate/validate.proto"; +import "google/protobuf/timestamp.proto"; + +option go_package = "buf.build/gen/go/bufbuild/registry/protocolbuffers/go/buf/registry/module/v1"; + +// A module within the BSR. +message Module { + option (buf.registry.priv.extension.v1beta1.message).response_only = true; + + // The id of the Module. + string id = 1 [ + (buf.validate.field).required = true, + (buf.validate.field).string.uuid = true + ]; + // The time the Module was created on the BSR. + google.protobuf.Timestamp create_time = 2 [(buf.validate.field).required = true]; + // The last time the Module was updated on the BSR. + google.protobuf.Timestamp update_time = 3 [(buf.validate.field).required = true]; + // The name of the Module. + // + // Unique within a given User or Organization. + string name = 4 [(buf.validate.field).string = { + min_len: 2, + max_len: 100 + }]; + // The id of the User or Organization that owns the Module. + string owner_id = 5 [ + (buf.validate.field).required = true, + (buf.validate.field).string.uuid = true + ]; + // The Module's visibility, either public or private. + ModuleVisibility visibility = 6 [ + (buf.validate.field).required = true, + (buf.validate.field).enum.defined_only = true + ]; + // The Module state, either active or deprecated. + ModuleState state = 7 [ + (buf.validate.field).required = true, + (buf.validate.field).enum.defined_only = true + ]; + // The configurable description of the Module. + string description = 8 [(buf.validate.field).string.max_len = 350]; + // The configurable URL in the description of the Module, + string url = 9 [ + (buf.validate.field).string.uri = true, + (buf.validate.field).string.max_len = 255, + (buf.validate.field).ignore = IGNORE_IF_UNPOPULATED + ]; + // The name of the default Label of the Module. + // + // This Label may not yet exist. When a Module is created, it has no Commits, and Labels + // must have a Commit, so this Label is not created when a Module is created. Additionally, + // a User may modify the name of the default Label without this Label yet being created. + // + // This could also be the name of an archived Label. An important note, an archived Label + // will not be considered a valid ResourceRef for resolving a Module. Archived Labels + // can only be retrieved using LabelService.GetLabels. + string default_label_name = 10 [ + (buf.validate.field).required = true, + (buf.validate.field).string.max_len = 250 + ]; +} + +// The visibility of a Module, currently either public or private. +enum ModuleVisibility { + MODULE_VISIBILITY_UNSPECIFIED = 0; + // MODULE_VISIBILITY_PUBLIC says that the module is publicly available. + MODULE_VISIBILITY_PUBLIC = 1; + // MODULE_VISIBILITY_PRIVATE says that the module is private. + MODULE_VISIBILITY_PRIVATE = 2; +} + +// The state of a Module, currently either active or deprecated. +enum ModuleState { + MODULE_STATE_UNSPECIFIED = 0; + // MODULE_STATE_ACTIVE says that the Module is currently active. + MODULE_STATE_ACTIVE = 1; + // MODULE_STATE_DEPRECATED says that the Module has been deprecated and should not longer be + // used. + MODULE_STATE_DEPRECATED = 2; +} + +// ModuleRef is a reference to a Module, either an id or a fully-qualified name. +// +// This is used in requests. +message ModuleRef { + option (buf.registry.priv.extension.v1beta1.message).request_only = true; + + // The fully-qualified name of a Module within a BSR instance. + // + // A Name uniquely identifies a Module. + // This is used for requests when a caller only has the module name and not the ID. + message Name { + // The name of the owner of the Module, either a User or Organization. + string owner = 1 [ + (buf.validate.field).required = true, + (buf.validate.field).string.max_len = 32 + ]; + // The name of the Module. + string module = 2 [(buf.validate.field).string = { + min_len: 2, + max_len: 100 + }]; + } + + oneof value { + option (buf.validate.oneof).required = true; + // The id of the Module. + string id = 1 [(buf.validate.field).string.uuid = true]; + // The fully-qualified name of the Module. + Name name = 2; + } +} diff --git a/buf/registry/module/v1/module_service.proto b/buf/registry/module/v1/module_service.proto new file mode 100644 index 0000000..1509483 --- /dev/null +++ b/buf/registry/module/v1/module_service.proto @@ -0,0 +1,198 @@ +// Copyright 2023-2024 Buf 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. + +syntax = "proto3"; + +package buf.registry.module.v1; + +import "buf/registry/module/v1/module.proto"; +import "buf/registry/owner/v1/owner.proto"; +import "buf/validate/validate.proto"; + +option go_package = "buf.build/gen/go/bufbuild/registry/protocolbuffers/go/buf/registry/module/v1"; + +// Operate on Modules. +service ModuleService { + // Get Modules by id or name. + rpc GetModules(GetModulesRequest) returns (GetModulesResponse) { + option idempotency_level = NO_SIDE_EFFECTS; + } + // List Modules, usually for a specific User or Organization. + rpc ListModules(ListModulesRequest) returns (ListModulesResponse) { + option idempotency_level = NO_SIDE_EFFECTS; + } + // Create new Modules. + // + // When a Module is created, a Branch representing the release Branch + // is created as well. + // + // This operation is atomic. Either all Modules are created or an error is returned. + rpc CreateModules(CreateModulesRequest) returns (CreateModulesResponse) { + option idempotency_level = IDEMPOTENT; + } + // Update existing Modules. + // + // This operation is atomic. Either all Modules are updated or an error is returned. + rpc UpdateModules(UpdateModulesRequest) returns (UpdateModulesResponse) { + option idempotency_level = IDEMPOTENT; + } + // Delete existing Modules. + // + // This operation is atomic. Either all Modules are deleted or an error is returned. + rpc DeleteModules(DeleteModulesRequest) returns (DeleteModulesResponse) { + option idempotency_level = IDEMPOTENT; + } +} + +message GetModulesRequest { + // The Modules to request. + repeated ModuleRef module_refs = 1 [ + (buf.validate.field).repeated.min_items = 1, + (buf.validate.field).repeated.max_items = 250 + ]; +} + +message GetModulesResponse { + // The retrieved Modules in the same order as requested. + repeated Module modules = 1 [(buf.validate.field).repeated.min_items = 1]; +} + +message ListModulesRequest { + // The list order. + enum Order { + ORDER_UNSPECIFIED = 0; + // Order by create_time oldest to newest. + ORDER_CREATE_TIME_ASC = 1; + // Order by create_time newest to oldest. + ORDER_CREATE_TIME_DESC = 2; + } + // The maximum number of items to return. + // + // The default value is 10. + uint32 page_size = 1 [(buf.validate.field).uint32.lte = 250]; + // The page to start from. + // + // If empty, the first page is returned, + string page_token = 2 [(buf.validate.field).string.max_len = 4096]; + // The specific Users or Organizations to list Modules for. + // + // If empty, all Modules for all owners are listed, but this functionality + // is limited to Users with the necessary permissions. + repeated buf.registry.owner.v1.OwnerRef owner_refs = 3; + // The order to return the Modules. + // + // If not specified, defaults to ORDER_CREATE_TIME_ASC. + // + // TODO: Do we want ORDER_CREATE_TIME_ASC to be the default? + // TODO: We are purposefully not making the default the zero enum value, however + // we may want to consider this. + Order order = 4 [(buf.validate.field).enum.defined_only = true]; +} + +message ListModulesResponse { + // The next page token. + // + /// If empty, there are no more pages. + string next_page_token = 1 [(buf.validate.field).string.max_len = 4096]; + // The listed Modules. + repeated Module modules = 2; +} + +message CreateModulesRequest { + // An individual request to create a Module. + message Value { + // The User or Organization to create the Module under. + buf.registry.owner.v1.OwnerRef owner_ref = 1 [(buf.validate.field).required = true]; + // The name of the Module. + string name = 2 [(buf.validate.field).string = { + min_len: 2, + max_len: 100 + }]; + // The module's visibility. + ModuleVisibility visibility = 3 [ + (buf.validate.field).required = true, + (buf.validate.field).enum.defined_only = true + ]; + // The configurable description of the Module. + string description = 4 [(buf.validate.field).string.max_len = 350]; + // The configurable URL in the description of the module. + string url = 5 [ + (buf.validate.field).string.uri = true, + (buf.validate.field).string.max_len = 255, + (buf.validate.field).ignore = IGNORE_IF_UNPOPULATED + ]; + // The name of the default Label of the Module. + // + // If not set, the default Label will be named "main" upon creation. + // + // This may point to an archived Label. + string default_label_name = 6 [(buf.validate.field).string.max_len = 250]; + } + // The Modules to create. + repeated Value values = 1 [ + (buf.validate.field).repeated.min_items = 1, + (buf.validate.field).repeated.max_items = 250 + ]; +} + +message CreateModulesResponse { + // The created Modules in the same order as given on the request. + repeated Module modules = 1 [(buf.validate.field).repeated.min_items = 1]; +} + +message UpdateModulesRequest { + // An individual request to update a Module. + message Value { + // The Module to update. + ModuleRef module_ref = 1 [(buf.validate.field).required = true]; + // The module's visibility. + optional ModuleVisibility visibility = 3 [(buf.validate.field).enum.defined_only = true]; + // The deprecation status of the module. + optional ModuleState state = 4 [(buf.validate.field).enum.defined_only = true]; + // The configurable description of the module. + optional string description = 5 [(buf.validate.field).string.max_len = 350]; + // The configurable URL in the description of the module. + optional string url = 6 [ + (buf.validate.field).string.uri = true, + (buf.validate.field).string.max_len = 255, + (buf.validate.field).ignore_empty = true + ]; + // The name of the default Label of the Module. + // + // This Label may not yet exist. + // + // This may point to an archived Label. + optional string default_label_name = 7 [(buf.validate.field).string.max_len = 250]; + } + // The Modules to update. + repeated Value values = 1 [ + (buf.validate.field).repeated.min_items = 1, + (buf.validate.field).repeated.max_items = 250 + ]; +} + +message UpdateModulesResponse { + // The updated Modules in the same order as given on the request. + repeated Module modules = 1 [(buf.validate.field).repeated.min_items = 1]; +} + +message DeleteModulesRequest { + // The Modules to delete. + repeated ModuleRef module_refs = 1 [ + (buf.validate.field).repeated.min_items = 1, + (buf.validate.field).repeated.max_items = 250 + ]; +} + +message DeleteModulesResponse {} diff --git a/buf/registry/legacy/federation/v1beta1/resource.proto b/buf/registry/module/v1/resource.proto similarity index 90% rename from buf/registry/legacy/federation/v1beta1/resource.proto rename to buf/registry/module/v1/resource.proto index 6d56c14..35670a8 100644 --- a/buf/registry/legacy/federation/v1beta1/resource.proto +++ b/buf/registry/module/v1/resource.proto @@ -14,12 +14,26 @@ syntax = "proto3"; -package buf.registry.legacy.federation.v1beta1; +package buf.registry.module.v1; +import "buf/registry/module/v1/commit.proto"; +import "buf/registry/module/v1/label.proto"; +import "buf/registry/module/v1/module.proto"; import "buf/registry/priv/extension/v1beta1/extension.proto"; import "buf/validate/validate.proto"; -option go_package = "buf.build/gen/go/bufbuild/registry/protocolbuffers/go/buf/registry/legacy/federation/v1beta1"; +option go_package = "buf.build/gen/go/bufbuild/registry/protocolbuffers/go/buf/registry/module/v1"; + +// A Module, Label, or Commit. +message Resource { + oneof value { + option (buf.validate.oneof).required = true; + + Module module = 1; + Label label = 2; + Commit commit = 3; + } +} // A reference to any of: // - Module @@ -35,9 +49,6 @@ option go_package = "buf.build/gen/go/bufbuild/registry/protocolbuffers/go/buf/r // // ResourceRefs cannot reference archived Labels. The only way to retrieve an archived Label // is to use LabelService.GetLabels. -// -// See the package documentation for more details. You should likely use buf.registry.module.v1beta1 -// and not this package. message ResourceRef { option (buf.registry.priv.extension.v1beta1.message).request_only = true; option (buf.registry.priv.extension.v1beta1.message).no_side_effects_only = true; @@ -92,7 +103,4 @@ message ResourceRef { // The fully-qualified name of the resource. Name name = 2; } - - // The registry hostname of the resource. - string registry = 3 [(buf.validate.field).required = true]; } diff --git a/buf/registry/module/v1/resource_service.proto b/buf/registry/module/v1/resource_service.proto new file mode 100644 index 0000000..bc4f2b6 --- /dev/null +++ b/buf/registry/module/v1/resource_service.proto @@ -0,0 +1,45 @@ +// Copyright 2023-2024 Buf 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. + +syntax = "proto3"; + +package buf.registry.module.v1; + +import "buf/registry/module/v1/resource.proto"; +import "buf/validate/validate.proto"; + +option go_package = "buf.build/gen/go/bufbuild/registry/protocolbuffers/go/buf/registry/module/v1"; + +// Operate on Resources. +service ResourceService { + // Get Resources. + rpc GetResources(GetResourcesRequest) returns (GetResourcesResponse) { + option idempotency_level = NO_SIDE_EFFECTS; + } +} + +message GetResourcesRequest { + // References to request a Resource for. + // + // See the documentation on ResourceRef for resource resolution details. + repeated ResourceRef resource_refs = 1 [ + (buf.validate.field).repeated.min_items = 1, + (buf.validate.field).repeated.max_items = 250 + ]; +} + +message GetResourcesResponse { + // The found Resources in the same order as requested. + repeated Resource resources = 1 [(buf.validate.field).repeated.min_items = 1]; +} diff --git a/buf/registry/legacy/federation/v1beta1/upload_service.proto b/buf/registry/module/v1/upload_service.proto similarity index 50% rename from buf/registry/legacy/federation/v1beta1/upload_service.proto rename to buf/registry/module/v1/upload_service.proto index 25e8693..8c8277f 100644 --- a/buf/registry/legacy/federation/v1beta1/upload_service.proto +++ b/buf/registry/module/v1/upload_service.proto @@ -14,67 +14,33 @@ syntax = "proto3"; -package buf.registry.legacy.federation.v1beta1; +package buf.registry.module.v1; -import "buf/registry/module/v1beta1/commit.proto"; -import "buf/registry/module/v1beta1/file.proto"; -import "buf/registry/module/v1beta1/label.proto"; -import "buf/registry/module/v1beta1/module.proto"; +import "buf/registry/module/v1/commit.proto"; +import "buf/registry/module/v1/file.proto"; +import "buf/registry/module/v1/label.proto"; +import "buf/registry/module/v1/module.proto"; import "buf/validate/validate.proto"; -option go_package = "buf.build/gen/go/bufbuild/registry/protocolbuffers/go/buf/registry/legacy/federation/v1beta1"; +option go_package = "buf.build/gen/go/bufbuild/registry/protocolbuffers/go/buf/registry/module/v1"; // Upload contents. -// -// See the package documentation for more details. You should likely use buf.registry.module.v1beta1 -// and not this package. service UploadService { // Upload contents for given set of Modules. // // Content consists of the Files: .proto files, license files, and documentation files. - // - // See the package documentation for more details. You should likely use buf.registry.module.v1beta1 - // and not this package. rpc Upload(UploadRequest) returns (UploadResponse) {} } -// See the package documentation for more details. You should likely use buf.registry.module.v1beta1 -// and not this package. message UploadRequest { - // A dependency of one or more references specified by Contents. - // - // Dependencies between Contents are implicit and do not need to be specified. The BSR will detect - // dependencies between Contents via .proto imports. - message DepRef { - // The commit_id of the dependency. - string commit_id = 1 [ - (buf.validate.field).required = true, - (buf.validate.field).string.uuid = true - ]; - // The registry hostname of the dependency. - string registry = 2 [(buf.validate.field).required = true]; - } // Content to upload for a given reference. message Content { // The Module of the reference. - buf.registry.module.v1beta1.ModuleRef module_ref = 1 [(buf.validate.field).required = true]; + ModuleRef module_ref = 1 [(buf.validate.field).required = true]; // The Files of the Content. // // This will consist of the .proto files, license files, and documentation files. - repeated buf.registry.module.v1beta1.File files = 2 [(buf.validate.field).repeated.min_items = 1]; - // The original v1beta1 or v1 buf.yaml file that encapsulated this reference, if it existed. - // - // This is used in deprecated digest calculations only. None of the structured - // information within this File will or should convey further information about the reference. - buf.registry.module.v1beta1.File v1_buf_yaml_file = 3; - // The original v1beta1 or v1 buf.lock file that encapsulated this reference, if it existed. - // - // This is used in deprecated digest calculations only. None of the structured - // information within this File will or should convey further information about the reference. - // - // Importantly, this file is *not* used to determine the dependencies of the reference. To - // specify the dependencies, use the dep_refs fields. - buf.registry.module.v1beta1.File v1_buf_lock_file = 4; + repeated File files = 2 [(buf.validate.field).repeated.min_items = 1]; // The labels to associate with the Commit for the Content. // // If an id is set, this id must represent a Label that already exists and is @@ -85,12 +51,12 @@ message UploadRequest { // // If the Labels do not exist, they will be created. // If the Labels were archived, they will be unarchived. - repeated buf.registry.module.v1beta1.ScopedLabelRef scoped_label_refs = 5; + repeated ScopedLabelRef scoped_label_refs = 3; // The URL of the source control commit to associate with the Commit for this Content. // // BSR users can navigate to this link to find source control information that is relevant to this Commit // (e.g. commit description, PR discussion, authors, approvers, etc.). - string source_control_url = 6 [ + string source_control_url = 4 [ (buf.validate.field).string.uri = true, (buf.validate.field).string.max_len = 255, (buf.validate.field).ignore = IGNORE_IF_UNPOPULATED @@ -100,22 +66,20 @@ message UploadRequest { repeated Content contents = 1 [(buf.validate.field).repeated.min_items = 1]; // The dependencies of the references specified by Contents. // - // This will include all transitive dependencies. - // // Dependencies between Contents are implicit and do not need to be specified. The BSR will detect - // dependencies between Contents via .proto imports. + // dependencies between Contenta via .proto imports. + // + // This will include all transitive dependencies. // - // Commits should be unique by Module, that is no two dep_refs should have the same Module but + // Commits should be unique by Module, that is no two dep_commit_ids should have the same Module but // different Commit IDs. - repeated DepRef dep_refs = 2; + repeated string dep_commit_ids = 2 [(buf.validate.field).repeated.items.string.uuid = true]; } -// See the package documentation for more details. You should likely use buf.registry.module.v1beta1 -// and not this package. message UploadResponse { // The Commits for each reference in the same order as given on the request. // // A single Commit will be returned for each reference. These Commits may or may not be new. // If nothing changed for a given reference, the existing Commit will be returned. - repeated buf.registry.module.v1beta1.Commit commits = 1 [(buf.validate.field).repeated.min_items = 1]; + repeated Commit commits = 1 [(buf.validate.field).repeated.min_items = 1]; } diff --git a/buf/registry/module/v1beta1/commit_service.proto b/buf/registry/module/v1beta1/commit_service.proto index e62066f..d92309d 100644 --- a/buf/registry/module/v1beta1/commit_service.proto +++ b/buf/registry/module/v1beta1/commit_service.proto @@ -40,8 +40,6 @@ message GetCommitsRequest { // - If a Module is referenced, the Commit of the default Label is returned. // - If a Label is referenced, the Commit of this Label is returned. // - If a Commit is referenced, this Commit is returned. - // - // TODO: It's a little incongruent to have a Get request take a ResourceRef. repeated ResourceRef resource_refs = 1 [ (buf.validate.field).repeated.min_items = 1, (buf.validate.field).repeated.max_items = 250 diff --git a/buf/registry/module/v1beta1/digest.proto b/buf/registry/module/v1beta1/digest.proto index 72f78e6..ef668b1 100644 --- a/buf/registry/module/v1beta1/digest.proto +++ b/buf/registry/module/v1beta1/digest.proto @@ -24,8 +24,6 @@ option go_package = "buf.build/gen/go/bufbuild/registry/protocolbuffers/go/buf/r // // A digest represents all content for a single Commit, including its .proto files, documentation // files, license files, and the digests of its dependencies. -// -// TODO: CommitDigest? What to do about naming in bufbuild/buf (ModuleDigest)? message Digest { // The type of the Digest. DigestType type = 1 [ diff --git a/buf/registry/module/v1beta1/download_service.proto b/buf/registry/module/v1beta1/download_service.proto index 8863efa..de7e35b 100644 --- a/buf/registry/module/v1beta1/download_service.proto +++ b/buf/registry/module/v1beta1/download_service.proto @@ -118,7 +118,7 @@ message DownloadResponse { // // This is used in deprecated digest calculations only. None of the structured // information within this File conveys further information about the reference. - File v1_buf_yaml_file = 3 [(buf.validate.field).required = true]; + File v1_buf_yaml_file = 3; // The original buf.lock file that encapsulated this reference, if it existed. // // If the reference was encapsulated by a v2 buf.lock with dependencies, this will be a diff --git a/buf/registry/module/v1beta1/graph.proto b/buf/registry/module/v1beta1/graph.proto index 85910a0..3a3606c 100644 --- a/buf/registry/module/v1beta1/graph.proto +++ b/buf/registry/module/v1beta1/graph.proto @@ -26,6 +26,15 @@ option go_package = "buf.build/gen/go/bufbuild/registry/protocolbuffers/go/buf/r message Graph { option (buf.registry.priv.extension.v1beta1.message).response_only = true; + // A Commit in the dependency graph. + // + // This wraps the top-level Commit. + message Commit { + // The top-level Commit. + buf.registry.module.v1beta1.Commit commit = 1 [(buf.validate.field).required = true]; + // The registry hostname of the Commit. + string registry = 2 [(buf.validate.field).required = true]; + } // A node in the dependency graph. message Node { // The commit of the node. @@ -33,6 +42,8 @@ message Graph { (buf.validate.field).required = true, (buf.validate.field).string.uuid = true ]; + // The registry hostname of the Node. + string registry = 2 [(buf.validate.field).required = true]; } // An edge in the dependency graph. message Edge { diff --git a/buf/registry/module/v1beta1/graph_service.proto b/buf/registry/module/v1beta1/graph_service.proto index 1ab82f1..f0c8302 100644 --- a/buf/registry/module/v1beta1/graph_service.proto +++ b/buf/registry/module/v1beta1/graph_service.proto @@ -37,6 +37,15 @@ service GraphService { } message GetGraphRequest { + // A ResourceRef to reference a Commit to include in the Graph. + // + // This wraps the top-level ResourceRef. + message ResourceRef { + // The top-level ResourceRef. + buf.registry.module.v1beta1.ResourceRef resource_ref = 1 [(buf.validate.field).required = true]; + // The registry hostname of the Resourceref. + string registry = 2 [(buf.validate.field).required = true]; + } // The references to resolve to Commits to include in the graph. // // See the documentation on ResourceRef for resource resolution details. @@ -61,6 +70,8 @@ message GetGraphRequest { DigestType digest_type = 2 [(buf.validate.field).enum.defined_only = true]; } +// See the package documentation for more details. You should likely use buf.registry.module.v1beta1 +// and not this package. message GetGraphResponse { // The Graph calculated for the Commits. Graph graph = 1 [(buf.validate.field).required = true]; diff --git a/buf/registry/module/v1beta1/module_service.proto b/buf/registry/module/v1beta1/module_service.proto index a7fc873..9229cb2 100644 --- a/buf/registry/module/v1beta1/module_service.proto +++ b/buf/registry/module/v1beta1/module_service.proto @@ -17,7 +17,7 @@ syntax = "proto3"; package buf.registry.module.v1beta1; import "buf/registry/module/v1beta1/module.proto"; -import "buf/registry/owner/v1beta1/owner.proto"; +import "buf/registry/owner/v1/owner.proto"; import "buf/validate/validate.proto"; option go_package = "buf.build/gen/go/bufbuild/registry/protocolbuffers/go/buf/registry/module/v1beta1"; @@ -89,7 +89,7 @@ message ListModulesRequest { // // If empty, all Modules for all owners are listed, but this functionality // is limited to Users with the necessary permissions. - repeated buf.registry.owner.v1beta1.OwnerRef owner_refs = 3; + repeated buf.registry.owner.v1.OwnerRef owner_refs = 3; // The order to return the Modules. // // If not specified, defaults to ORDER_CREATE_TIME_ASC. @@ -113,7 +113,7 @@ message CreateModulesRequest { // An individual request to create a Module. message Value { // The User or Organization to create the Module under. - buf.registry.owner.v1beta1.OwnerRef owner_ref = 1 [(buf.validate.field).required = true]; + buf.registry.owner.v1.OwnerRef owner_ref = 1 [(buf.validate.field).required = true]; // The name of the Module. string name = 2 [(buf.validate.field).string = { min_len: 2, diff --git a/buf/registry/module/v1beta1/upload_service.proto b/buf/registry/module/v1beta1/upload_service.proto index 8c35b81..a302944 100644 --- a/buf/registry/module/v1beta1/upload_service.proto +++ b/buf/registry/module/v1beta1/upload_service.proto @@ -33,6 +33,19 @@ service UploadService { } message UploadRequest { + // A dependency of one or more references specified by Contents. + // + // Dependencies between Contents are implicit and do not need to be specified. The BSR will detect + // dependencies between Contents via .proto imports. + message DepRef { + // The commit_id of the dependency. + string commit_id = 1 [ + (buf.validate.field).required = true, + (buf.validate.field).string.uuid = true + ]; + // The registry hostname of the dependency. + string registry = 2 [(buf.validate.field).required = true]; + } // Content to upload for a given reference. message Content { // The Module of the reference. @@ -41,19 +54,6 @@ message UploadRequest { // // This will consist of the .proto files, license files, and documentation files. repeated File files = 2 [(buf.validate.field).repeated.min_items = 1]; - // The original v1beta1 or v1 buf.yaml file that encapsulated this reference, if it existed. - // - // This is used in deprecated digest calculations only. None of the structured - // information within this File will or should convey further information about the reference. - File v1_buf_yaml_file = 3; - // The original v1beta1 or v1 buf.lock file that encapsulated this reference, if it existed. - // - // This is used in deprecated digest calculations only. None of the structured - // information within this File will or should convey further information about the reference. - // - // Importantly, this file is *not* used to determine the dependencies of the reference. To - // specify the dependencies, use the dep_refs fields. - File v1_buf_lock_file = 4; // The labels to associate with the Commit for the Content. // // If an id is set, this id must represent a Label that already exists and is @@ -64,12 +64,12 @@ message UploadRequest { // // If the Labels do not exist, they will be created. // If the Labels were archived, they will be unarchived. - repeated ScopedLabelRef scoped_label_refs = 5; + repeated ScopedLabelRef scoped_label_refs = 3; // The URL of the source control commit to associate with the Commit for this Content. // // BSR users can navigate to this link to find source control information that is relevant to this Commit // (e.g. commit description, PR discussion, authors, approvers, etc.). - string source_control_url = 6 [ + string source_control_url = 4 [ (buf.validate.field).string.uri = true, (buf.validate.field).string.max_len = 255, (buf.validate.field).ignore = IGNORE_IF_UNPOPULATED @@ -79,16 +79,18 @@ message UploadRequest { repeated Content contents = 1 [(buf.validate.field).repeated.min_items = 1]; // The dependencies of the references specified by Contents. // - // Dependencies between Contents are implicit and do not need to be specified. The BSR will detect - // dependencies between Contenta via .proto imports. - // // This will include all transitive dependencies. // - // Commits should be unique by Module, that is no two dep_commit_ids should have the same Module but + // Dependencies between Contents are implicit and do not need to be specified. The BSR will detect + // dependencies between Contents via .proto imports. + // + // Commits should be unique by Module, that is no two dep_refs should have the same Module but // different Commit IDs. - repeated string dep_commit_ids = 2 [(buf.validate.field).repeated.items.string.uuid = true]; + repeated DepRef dep_refs = 2; } +// See the package documentation for more details. You should likely use buf.registry.module.v1beta1 +// and not this package. message UploadResponse { // The Commits for each reference in the same order as given on the request. // diff --git a/buf/registry/owner/v1beta1/organization.proto b/buf/registry/owner/v1/organization.proto similarity index 97% rename from buf/registry/owner/v1beta1/organization.proto rename to buf/registry/owner/v1/organization.proto index 987601b..6628990 100644 --- a/buf/registry/owner/v1beta1/organization.proto +++ b/buf/registry/owner/v1/organization.proto @@ -14,13 +14,13 @@ syntax = "proto3"; -package buf.registry.owner.v1beta1; +package buf.registry.owner.v1; import "buf/registry/priv/extension/v1beta1/extension.proto"; import "buf/validate/validate.proto"; import "google/protobuf/timestamp.proto"; -option go_package = "buf.build/gen/go/bufbuild/registry/protocolbuffers/go/buf/registry/owner/v1beta1"; +option go_package = "buf.build/gen/go/bufbuild/registry/protocolbuffers/go/buf/registry/owner/v1"; // Organization is an organization on the BSR. // diff --git a/buf/registry/owner/v1beta1/organization_service.proto b/buf/registry/owner/v1/organization_service.proto similarity index 97% rename from buf/registry/owner/v1beta1/organization_service.proto rename to buf/registry/owner/v1/organization_service.proto index ab27764..79b4550 100644 --- a/buf/registry/owner/v1beta1/organization_service.proto +++ b/buf/registry/owner/v1/organization_service.proto @@ -14,13 +14,13 @@ syntax = "proto3"; -package buf.registry.owner.v1beta1; +package buf.registry.owner.v1; -import "buf/registry/owner/v1beta1/organization.proto"; -import "buf/registry/owner/v1beta1/user.proto"; +import "buf/registry/owner/v1/organization.proto"; +import "buf/registry/owner/v1/user.proto"; import "buf/validate/validate.proto"; -option go_package = "buf.build/gen/go/bufbuild/registry/protocolbuffers/go/buf/registry/owner/v1beta1"; +option go_package = "buf.build/gen/go/bufbuild/registry/protocolbuffers/go/buf/registry/owner/v1"; // Operate on Organizations service OrganizationService { diff --git a/buf/registry/owner/v1beta1/owner.proto b/buf/registry/owner/v1/owner.proto similarity index 90% rename from buf/registry/owner/v1beta1/owner.proto rename to buf/registry/owner/v1/owner.proto index 0dde4ed..9661615 100644 --- a/buf/registry/owner/v1beta1/owner.proto +++ b/buf/registry/owner/v1/owner.proto @@ -14,14 +14,14 @@ syntax = "proto3"; -package buf.registry.owner.v1beta1; +package buf.registry.owner.v1; -import "buf/registry/owner/v1beta1/organization.proto"; -import "buf/registry/owner/v1beta1/user.proto"; +import "buf/registry/owner/v1/organization.proto"; +import "buf/registry/owner/v1/user.proto"; import "buf/registry/priv/extension/v1beta1/extension.proto"; import "buf/validate/validate.proto"; -option go_package = "buf.build/gen/go/bufbuild/registry/protocolbuffers/go/buf/registry/owner/v1beta1"; +option go_package = "buf.build/gen/go/bufbuild/registry/protocolbuffers/go/buf/registry/owner/v1"; // A User or Organization. message Owner { diff --git a/buf/registry/owner/v1beta1/owner_service.proto b/buf/registry/owner/v1/owner_service.proto similarity index 92% rename from buf/registry/owner/v1beta1/owner_service.proto rename to buf/registry/owner/v1/owner_service.proto index b0bdd86..abea103 100644 --- a/buf/registry/owner/v1beta1/owner_service.proto +++ b/buf/registry/owner/v1/owner_service.proto @@ -14,12 +14,12 @@ syntax = "proto3"; -package buf.registry.owner.v1beta1; +package buf.registry.owner.v1; -import "buf/registry/owner/v1beta1/owner.proto"; +import "buf/registry/owner/v1/owner.proto"; import "buf/validate/validate.proto"; -option go_package = "buf.build/gen/go/bufbuild/registry/protocolbuffers/go/buf/registry/owner/v1beta1"; +option go_package = "buf.build/gen/go/bufbuild/registry/protocolbuffers/go/buf/registry/owner/v1"; // Operate on Users and Organizations in situations where you only // know a reference to an owner, without knowing whether or not that diff --git a/buf/registry/owner/v1beta1/user.proto b/buf/registry/owner/v1/user.proto similarity index 98% rename from buf/registry/owner/v1beta1/user.proto rename to buf/registry/owner/v1/user.proto index 9b779dc..8255a94 100644 --- a/buf/registry/owner/v1beta1/user.proto +++ b/buf/registry/owner/v1/user.proto @@ -14,13 +14,13 @@ syntax = "proto3"; -package buf.registry.owner.v1beta1; +package buf.registry.owner.v1; import "buf/registry/priv/extension/v1beta1/extension.proto"; import "buf/validate/validate.proto"; import "google/protobuf/timestamp.proto"; -option go_package = "buf.build/gen/go/bufbuild/registry/protocolbuffers/go/buf/registry/owner/v1beta1"; +option go_package = "buf.build/gen/go/bufbuild/registry/protocolbuffers/go/buf/registry/owner/v1"; // A user on the BSR. // diff --git a/buf/registry/owner/v1beta1/user_service.proto b/buf/registry/owner/v1/user_service.proto similarity index 97% rename from buf/registry/owner/v1beta1/user_service.proto rename to buf/registry/owner/v1/user_service.proto index 7a1e69c..9d1aba6 100644 --- a/buf/registry/owner/v1beta1/user_service.proto +++ b/buf/registry/owner/v1/user_service.proto @@ -14,13 +14,13 @@ syntax = "proto3"; -package buf.registry.owner.v1beta1; +package buf.registry.owner.v1; -import "buf/registry/owner/v1beta1/organization.proto"; -import "buf/registry/owner/v1beta1/user.proto"; +import "buf/registry/owner/v1/organization.proto"; +import "buf/registry/owner/v1/user.proto"; import "buf/validate/validate.proto"; -option go_package = "buf.build/gen/go/bufbuild/registry/protocolbuffers/go/buf/registry/owner/v1beta1"; +option go_package = "buf.build/gen/go/bufbuild/registry/protocolbuffers/go/buf/registry/owner/v1"; // Operate on Users. service UserService {