From 81aff0449f6c041834c1d498585237bcd1716c30 Mon Sep 17 00:00:00 2001 From: Michael Fridman Date: Fri, 25 Oct 2024 10:01:40 -0400 Subject: [PATCH] Add initial Plugin specification (#132) --- buf.lock | 3 + buf.yaml | 1 + buf/registry/plugin/v1beta1/collection.proto | 65 +++++ .../plugin/v1beta1/collection_service.proto | 104 ++++++++ buf/registry/plugin/v1beta1/commit.proto | 78 ++++++ .../plugin/v1beta1/commit_service.proto | 114 ++++++++ buf/registry/plugin/v1beta1/compression.proto | 28 ++ buf/registry/plugin/v1beta1/digest.proto | 41 +++ .../plugin/v1beta1/download_service.proto | 71 +++++ buf/registry/plugin/v1beta1/label.proto | 129 +++++++++ .../plugin/v1beta1/label_service.proto | 248 ++++++++++++++++++ buf/registry/plugin/v1beta1/plugin.proto | 129 +++++++++ .../plugin/v1beta1/plugin_service.proto | 195 ++++++++++++++ buf/registry/plugin/v1beta1/resource.proto | 103 ++++++++ .../plugin/v1beta1/upload_service.proto | 82 ++++++ 15 files changed, 1391 insertions(+) create mode 100644 buf/registry/plugin/v1beta1/collection.proto create mode 100644 buf/registry/plugin/v1beta1/collection_service.proto create mode 100644 buf/registry/plugin/v1beta1/commit.proto create mode 100644 buf/registry/plugin/v1beta1/commit_service.proto create mode 100644 buf/registry/plugin/v1beta1/compression.proto create mode 100644 buf/registry/plugin/v1beta1/digest.proto create mode 100644 buf/registry/plugin/v1beta1/download_service.proto create mode 100644 buf/registry/plugin/v1beta1/label.proto create mode 100644 buf/registry/plugin/v1beta1/label_service.proto create mode 100644 buf/registry/plugin/v1beta1/plugin.proto create mode 100644 buf/registry/plugin/v1beta1/plugin_service.proto create mode 100644 buf/registry/plugin/v1beta1/resource.proto create mode 100644 buf/registry/plugin/v1beta1/upload_service.proto diff --git a/buf.lock b/buf.lock index fd5634ae..010cf0cd 100644 --- a/buf.lock +++ b/buf.lock @@ -1,6 +1,9 @@ # Generated by buf. DO NOT EDIT. version: v2 deps: + - name: buf.build/bufbuild/bufplugin + commit: 42bdb4b676254830a221d52d10bf17be + digest: b5:c9fb96550e52b1b899f667d2371d2aee37b4b5b0d8e21d83dd620207d466f3a95b96fc072fe9a49785da293f1fe379f0b4ac8ce054b6a1cedcafba8f2145d086 - name: buf.build/bufbuild/protovalidate commit: b983156c5e994cc9892e0ce3e64e17e0 digest: b5:a02a4a5a0a9306cf1391d17e8811bbd6a0dbd0e0e29ddfc34b9d103311164974472d43627c3d63e6a8abaffd6c7a301c4f7965bbab2dc56f7f7812429a84b812 diff --git a/buf.yaml b/buf.yaml index 32ac5eb7..4fb42361 100644 --- a/buf.yaml +++ b/buf.yaml @@ -1,6 +1,7 @@ version: v2 name: buf.build/bufbuild/registry deps: + - buf.build/bufbuild/bufplugin - buf.build/bufbuild/protovalidate lint: use: diff --git a/buf/registry/plugin/v1beta1/collection.proto b/buf/registry/plugin/v1beta1/collection.proto new file mode 100644 index 00000000..6c773fb4 --- /dev/null +++ b/buf/registry/plugin/v1beta1/collection.proto @@ -0,0 +1,65 @@ +// 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.plugin.v1beta1; + +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/plugin/v1beta1"; + +// A collection for a Plugin. +// +// These collections help organize plugins based on their functionality or ecosystem. +message Collection { + option (buf.registry.priv.extension.v1beta1.message).response_only = true; + + // The id of the Collection. + string id = 1 [ + (buf.validate.field).required = true, + (buf.validate.field).string.tuuid = true + ]; + // The time the Collection was created on the BSR. + google.protobuf.Timestamp create_time = 2 [(buf.validate.field).required = true]; + // The last time the Collection was updated on the BSR. + google.protobuf.Timestamp update_time = 3 [(buf.validate.field).required = true]; + // The name of the Collection. + // + // Unique within a BSR instance. + string name = 4 [ + (buf.validate.field).required = true, + (buf.validate.field).string.max_len = 250 + ]; + // The configurable description of the Collection. + string description = 5 [(buf.validate.field).string.max_len = 350]; +} + +// CollectionRef is a reference to a Collection, either an id or a name. +message CollectionRef { + option (buf.registry.priv.extension.v1beta1.message).request_only = true; + + oneof value { + option (buf.validate.oneof).required = true; + // The id of the Collection. + string id = 1 [(buf.validate.field).string.tuuid = true]; + // The name of the Collection. + string name = 2 [(buf.validate.field).string = { + min_len: 2 + max_len: 100 + }]; + } +} diff --git a/buf/registry/plugin/v1beta1/collection_service.proto b/buf/registry/plugin/v1beta1/collection_service.proto new file mode 100644 index 00000000..4b43743c --- /dev/null +++ b/buf/registry/plugin/v1beta1/collection_service.proto @@ -0,0 +1,104 @@ +// 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.plugin.v1beta1; + +import "buf/registry/plugin/v1beta1/collection.proto"; +import "buf/registry/plugin/v1beta1/plugin.proto"; +import "buf/validate/validate.proto"; + +option go_package = "buf.build/gen/go/bufbuild/registry/protocolbuffers/go/buf/registry/plugin/v1beta1"; + +// Operate on Collections. +service CollectionService { + // Get Collections. + rpc GetCollections(GetCollectionsRequest) returns (GetCollectionsResponse) { + option idempotency_level = NO_SIDE_EFFECTS; + } + // List Collections for a given Plugin. + rpc ListCollections(ListCollectionsRequest) returns (ListCollectionsResponse) { + option idempotency_level = NO_SIDE_EFFECTS; + } + // Get the Collections for the given Plugins. + rpc GetPluginCollectionAssociations(GetPluginCollectionAssociationsRequest) returns (GetPluginCollectionAssociationsResponse) { + option idempotency_level = NO_SIDE_EFFECTS; + } +} + +message GetCollectionsRequest { + // The Collections to request. + repeated CollectionRef collection_refs = 1 [ + (buf.validate.field).repeated.min_items = 1, + (buf.validate.field).repeated.max_items = 250 + ]; +} + +message GetCollectionsResponse { + // The retrieved Collections in the same order as requested. + repeated Collection collections = 1 [(buf.validate.field).repeated.min_items = 1]; +} + +message ListCollectionsRequest { + // The list order. + enum Order { + ORDER_UNSPECIFIED = 0; + // Order by create_time newest to oldest. + ORDER_CREATE_TIME_DESC = 1; + // Order by create_time oldest to newest. + ORDER_CREATE_TIME_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 order to return the Plugins. + // + // If not specified, defaults to ORDER_CREATE_TIME_DESC. + Order order = 3 [(buf.validate.field).enum.defined_only = true]; +} + +message ListCollectionsResponse { + // 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 Collections. + repeated Collection collections = 2; +} + +message GetPluginCollectionAssociationsRequest { + // The Plugins to request Collections for. + repeated PluginRef plugin_refs = 1 [ + (buf.validate.field).repeated.min_items = 1, + (buf.validate.field).repeated.max_items = 250 + ]; +} + +message GetPluginCollectionAssociationsResponse { + // The Associations for the requested Plugins. + message Association { + // The id of the Plugin. + string plugin_id = 1; + // The collection ids associated with the Plugin. + repeated string collection_ids = 2; + } + // The Associations for the requested Plugins in the same order as requested. + repeated Association associations = 1; +} diff --git a/buf/registry/plugin/v1beta1/commit.proto b/buf/registry/plugin/v1beta1/commit.proto new file mode 100644 index 00000000..66b502fd --- /dev/null +++ b/buf/registry/plugin/v1beta1/commit.proto @@ -0,0 +1,78 @@ +// 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.plugin.v1beta1; + +import "buf/plugin/info/v1/plugin_info.proto"; +import "buf/registry/plugin/v1beta1/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/plugin/v1beta1"; + +// A commit on a specific Plugin. +// +// Commits are immutable. +// +// Many Commits may be associated with one Digest. +// +// Not 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.tuuid = 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 Organization that owns the Plugin that the Commit is associated with. + string owner_id = 3 [ + (buf.validate.field).required = true, + (buf.validate.field).string.tuuid = true + ]; + // The id of the Plugin that the Commit is associated with. + string plugin_id = 4 [ + (buf.validate.field).required = true, + (buf.validate.field).string.tuuid = true + ]; + // The Digest of the Commit's contents. + 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.tuuid = true, + (buf.validate.field).ignore = IGNORE_IF_UNPOPULATED + ]; + // 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 + ]; + // The plugin information as stored directly within the plugin. This is part of the Bufplugin API, + // and can be returned from a plugin's GetPluginInfo implementation. + buf.plugin.info.v1.PluginInfo plugin_info = 8; +} diff --git a/buf/registry/plugin/v1beta1/commit_service.proto b/buf/registry/plugin/v1beta1/commit_service.proto new file mode 100644 index 00000000..3bdf05b0 --- /dev/null +++ b/buf/registry/plugin/v1beta1/commit_service.proto @@ -0,0 +1,114 @@ +// 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.plugin.v1beta1; + +import "buf/registry/plugin/v1beta1/commit.proto"; +import "buf/registry/plugin/v1beta1/digest.proto"; +import "buf/registry/plugin/v1beta1/resource.proto"; +import "buf/validate/validate.proto"; + +option go_package = "buf.build/gen/go/bufbuild/registry/protocolbuffers/go/buf/registry/plugin/v1beta1"; + +// Operate on Commits. +service CommitService { + // Get Commits. + rpc GetCommits(GetCommitsRequest) returns (GetCommitsResponse) { + option idempotency_level = NO_SIDE_EFFECTS; + } + // List Commits for a given Plugin, Label, or Commit. + rpc ListCommits(ListCommitsRequest) returns (ListCommitsResponse) { + 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 Plugin 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 + ]; + // The DigestType to use for Digests returned on Commits. + // + // 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, currently p1. + DigestType digest_type = 2 [(buf.validate.field).enum.defined_only = true]; +} + +message GetCommitsResponse { + // The found Commits in the same order as requested. + repeated Commit commits = 1 [(buf.validate.field).repeated.min_items = 1]; +} + +message ListCommitsRequest { + // The list order. + enum Order { + ORDER_UNSPECIFIED = 0; + // Order by create_time newest to oldest. + ORDER_CREATE_TIME_DESC = 1; + // Order by create_time oldest to newest. + ORDER_CREATE_TIME_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 reference to list Commits for. + // + // See the documentation on Ref for resource resolution details. + // + // Once the resource is resolved, the following Commits are listed (subject to any additional filters in the request): + // - If a Plugin is referenced, all Commits for the Plugin are returned. + // - If a Label is referenced, the Commit the Label points to is returned. + // Use ListLabelHistory to get the history of Commits for a Label. + // - If a Commit is referenced, this Commit is returned. + ResourceRef resource_ref = 3 [(buf.validate.field).required = true]; + // The order to return the Commits. + // + // If not specified, defaults to ORDER_CREATE_TIME_DESC. + Order order = 4 [(buf.validate.field).enum.defined_only = true]; + // The DigestType to use for Digests returned on Commits. + // + // 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, currently p1. + DigestType digest_type = 5 [(buf.validate.field).enum.defined_only = true]; + // Only return Commits with an id that contains this string using a case-insensitive comparison. + string id_query = 6 [(buf.validate.field).string.max_len = 36]; +} + +message ListCommitsResponse { + // 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 Commits. + repeated Commit commits = 2; +} diff --git a/buf/registry/plugin/v1beta1/compression.proto b/buf/registry/plugin/v1beta1/compression.proto new file mode 100644 index 00000000..e2feaca1 --- /dev/null +++ b/buf/registry/plugin/v1beta1/compression.proto @@ -0,0 +1,28 @@ +// 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.plugin.v1beta1; + +option go_package = "buf.build/gen/go/bufbuild/registry/protocolbuffers/go/buf/registry/plugin/v1beta1"; + +// The type of compression. +enum CompressionType { + COMPRESSION_TYPE_UNSPECIFIED = 0; + // No compression. + COMPRESSION_TYPE_NONE = 1; + // Zstandard compression. + COMPRESSION_TYPE_ZSTD = 2; +} diff --git a/buf/registry/plugin/v1beta1/digest.proto b/buf/registry/plugin/v1beta1/digest.proto new file mode 100644 index 00000000..77d8076a --- /dev/null +++ b/buf/registry/plugin/v1beta1/digest.proto @@ -0,0 +1,41 @@ +// 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.plugin.v1beta1; + +import "buf/validate/validate.proto"; + +option go_package = "buf.build/gen/go/bufbuild/registry/protocolbuffers/go/buf/registry/plugin/v1beta1"; + +// A digest of a Commit's content. +// +// A digest represents all content for a single Commit. +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 p1 digest function. + DIGEST_TYPE_P1 = 1; +} diff --git a/buf/registry/plugin/v1beta1/download_service.proto b/buf/registry/plugin/v1beta1/download_service.proto new file mode 100644 index 00000000..71f0e6df --- /dev/null +++ b/buf/registry/plugin/v1beta1/download_service.proto @@ -0,0 +1,71 @@ +// 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.plugin.v1beta1; + +import "buf/registry/plugin/v1beta1/commit.proto"; +import "buf/registry/plugin/v1beta1/compression.proto"; +import "buf/registry/plugin/v1beta1/resource.proto"; +import "buf/validate/validate.proto"; + +option go_package = "buf.build/gen/go/bufbuild/registry/protocolbuffers/go/buf/registry/plugin/v1beta1"; + +// Download contents. +service DownloadService { + // Download contents for given set of Plugins. + // + // Contents are WASM modules that are compiled and executed within a suitable runtime. + rpc Download(DownloadRequest) returns (DownloadResponse) { + option idempotency_level = NO_SIDE_EFFECTS; + } +} + +message DownloadRequest { + // A request for content for a single version of a Plugin. + message Value { + // The reference to get content for. + // + // See the documentation on Reference for reference resolution details. + // + // Once the resource is resolved, the following content is returned: + // - If a Plugin is referenced, the content of the latest 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]; + } + // 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 version of a Plugin. + message Content { + // The Commit associated with the Content. + Commit commit = 1 [(buf.validate.field).required = true]; + // The compression type. + CompressionType compression_type = 2 [ + (buf.validate.field).required = true, + (buf.validate.field).enum.defined_only = true + ]; + // The content. + bytes content = 3 [(buf.validate.field).required = true]; + } + repeated Content contents = 1 [(buf.validate.field).repeated.min_items = 1]; +} diff --git a/buf/registry/plugin/v1beta1/label.proto b/buf/registry/plugin/v1beta1/label.proto new file mode 100644 index 00000000..14698142 --- /dev/null +++ b/buf/registry/plugin/v1beta1/label.proto @@ -0,0 +1,129 @@ +// 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.plugin.v1beta1; + +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/plugin/v1beta1"; + +// A label on a specific Plugin. +// +// 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.tuuid = 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]; + // The time the Label was archived if it is currently archived. + // + // If this field is not set, the Label is not currently archived. + google.protobuf.Timestamp archive_time = 4; + // The name of the Label. + // + // Unique within a given Plugin. + string name = 5 [ + (buf.validate.field).required = true, + (buf.validate.field).string.max_len = 250 + ]; + // The id of the Organization that owns the Plugin that the Label is associated with. + string owner_id = 6 [ + (buf.validate.field).required = true, + (buf.validate.field).string.tuuid = true + ]; + // The id of the Plugin that the Label is associated with. + string plugin_id = 7 [ + (buf.validate.field).required = true, + (buf.validate.field).string.tuuid = 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.tuuid = true + ]; + // The id of the User that last updated this Label on the BSR. + // + // May be empty if the User is no longer available. + string updated_by_user_id = 9 [ + (buf.validate.field).string.tuuid = true, + (buf.validate.field).ignore = IGNORE_IF_UNPOPULATED + ]; +} + +// 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 Plugin that contains the Label, an Organization. + string owner = 1 [ + (buf.validate.field).required = true, + (buf.validate.field).string.max_len = 32 + ]; + // The name of the Plugin that contains the Label. + string plugin = 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.tuuid = true]; + // The fully-qualified name of the Label. + Name name = 2; + } +} + +// A reference to a Label scoped to a Plugin, 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.tuuid = true]; + // The name of the Label. + string name = 2; + } +} diff --git a/buf/registry/plugin/v1beta1/label_service.proto b/buf/registry/plugin/v1beta1/label_service.proto new file mode 100644 index 00000000..3a4f8f2a --- /dev/null +++ b/buf/registry/plugin/v1beta1/label_service.proto @@ -0,0 +1,248 @@ +// 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.plugin.v1beta1; + +import "buf/registry/plugin/v1beta1/commit.proto"; +import "buf/registry/plugin/v1beta1/digest.proto"; +import "buf/registry/plugin/v1beta1/label.proto"; +import "buf/registry/plugin/v1beta1/resource.proto"; +import "buf/validate/validate.proto"; + +option go_package = "buf.build/gen/go/bufbuild/registry/protocolbuffers/go/buf/registry/plugin/v1beta1"; + +// 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 Plugin, 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 Plugin. + // + // 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; + } + // Unarchive existing Labels. + // + // This operation is atomic. Either all Labels are unarchived or an error is returned. + rpc UnarchiveLabels(UnarchiveLabelsRequest) returns (UnarchiveLabelsResponse) { + 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 newest to oldest. + ORDER_CREATE_TIME_DESC = 1; + // Order by create_time oldest to newest. + ORDER_CREATE_TIME_ASC = 2; + // Order by update_time newest to oldest. + ORDER_UPDATE_TIME_DESC = 3; + // Order by update_time oldest to newest. + ORDER_UPDATE_TIME_ASC = 4; + } + // A filter on whether a Label is archived or not. + enum ArchiveFilter { + ARCHIVE_FILTER_UNSPECIFIED = 0; + // Return only unarchived labels. + ARCHIVE_FILTER_UNARCHIVED_ONLY = 1; + // Return only archived labels. + ARCHIVE_FILTER_ARCHIVED_ONLY = 2; + // Return both archived and unarchived labels. + ARCHIVE_FILTER_ALL = 3; + } + // 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 (subject to any additional + // filters in the request): + // - If a Plugin is referenced, all Labels for the Plugin 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_DESC. + Order order = 4 [(buf.validate.field).enum.defined_only = true]; + // Only return Labels with a name that contains this string using a case-insensitive comparison. + string name_query = 5 [(buf.validate.field).string.max_len = 250]; + // The archive filter on the returned Labels. + // + // If not specified, defaults to ARCHIVE_FILTER_UNARCHIVED_ONLY. + ArchiveFilter archive_filter = 6 [(buf.validate.field).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. + Order order = 4 [(buf.validate.field).enum.defined_only = true]; + // The DigestType to use for Digests returned on Commits. + // + // 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, currently B5. + DigestType digest_type = 5 [(buf.validate.field).enum.defined_only = true]; + // The Commit id to start from. + // + // It is an error to provide a Commit id that doesn't exist on the Label. + string start_commit_id = 6 [ + (buf.validate.field).string.tuuid = true, + (buf.validate.field).ignore = IGNORE_IF_UNPOPULATED + ]; + // Only list Commits where the Digest has changed from the previous Commit in the history of this + // Label. + bool only_commits_with_changed_digests = 7; +} + +message ListLabelHistoryResponse { + message Value { + // The Commit. + Commit commit = 1 [(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.tuuid = 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 {} + +message UnarchiveLabelsRequest { + // The Labels to unarchive. + repeated LabelRef label_refs = 1 [ + (buf.validate.field).repeated.min_items = 1, + (buf.validate.field).repeated.max_items = 250 + ]; +} + +message UnarchiveLabelsResponse {} diff --git a/buf/registry/plugin/v1beta1/plugin.proto b/buf/registry/plugin/v1beta1/plugin.proto new file mode 100644 index 00000000..17f6ceb0 --- /dev/null +++ b/buf/registry/plugin/v1beta1/plugin.proto @@ -0,0 +1,129 @@ +// 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.plugin.v1beta1; + +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/plugin/v1beta1"; + +message Plugin { + option (buf.registry.priv.extension.v1beta1.message).response_only = true; + + // The id of the Plugin. + string id = 1 [ + (buf.validate.field).required = true, + (buf.validate.field).string.tuuid = true + ]; + // The time the Plugin was created on the BSR. + google.protobuf.Timestamp create_time = 2 [(buf.validate.field).required = true]; + // The last time the Plugin was updated on the BSR. + google.protobuf.Timestamp update_time = 3 [(buf.validate.field).required = true]; + // The name of the Plugin. + // + // Unique within a given Organization. + string name = 4 [(buf.validate.field).string = { + min_len: 2 + max_len: 100 + }]; + // The id of the Organization that owns the Plugin. + string owner_id = 5 [ + (buf.validate.field).required = true, + (buf.validate.field).string.tuuid = true + ]; + // The Plugin's visibility, either public or private. + PluginVisibility visibility = 6 [ + (buf.validate.field).required = true, + (buf.validate.field).enum.defined_only = true + ]; + // The Plugin state, either active or deprecated. + PluginState state = 7 [ + (buf.validate.field).required = true, + (buf.validate.field).enum.defined_only = true + ]; + // The Plugin type. + PluginType type = 8 [ + (buf.validate.field).required = true, + (buf.validate.field).enum.defined_only = true + ]; + // The configurable short description of the Plugin. + string description = 9 [(buf.validate.field).string.max_len = 350]; + // The configurable source URL of the Plugin. + string source_url = 10 [ + (buf.validate.field).string.uri = true, + (buf.validate.field).string.max_len = 255, + (buf.validate.field).ignore = IGNORE_IF_UNPOPULATED + ]; +} + +// The visibility of a Plugin, currently either public or private. +enum PluginVisibility { + PLUGIN_VISIBILITY_UNSPECIFIED = 0; + // PLUGIN_VISIBILITY_PUBLIC says that the plugin is publicly available. + PLUGIN_VISIBILITY_PUBLIC = 1; + // PLUGIN_VISIBILITY_PRIVATE says that the plugin is private. + PLUGIN_VISIBILITY_PRIVATE = 2; +} + +// The state of a Plugin, currently either active or deprecated. +enum PluginState { + PLUGIN_STATE_UNSPECIFIED = 0; + // PLUGIN_STATE_ACTIVE says that the Plugin is currently active. + PLUGIN_STATE_ACTIVE = 1; + // PLUGIN_STATE_DEPRECATED says that the Plugin has been deprecated and should no longer be used. + PLUGIN_STATE_DEPRECATED = 2; +} + +// The type of the Plugin. +enum PluginType { + PLUGIN_TYPE_UNSPECIFIED = 0; + // PLUGIN_TYPE_CHECK says that the Plugin is a check plugin. + PLUGIN_TYPE_CHECK = 1; +} + +// PluginRef is a reference to a Plugin, either an id or a fully-qualified name. +// +// This is used in requests. +message PluginRef { + option (buf.registry.priv.extension.v1beta1.message).request_only = true; + + // The fully-qualified name of a Plugin within a BSR instance. + // + // A Name uniquely identifies a Plugin. This is used for requests when a caller only has the + // plugin name and not the ID. + message Name { + // The name of the Organization owner. + string owner = 1 [ + (buf.validate.field).required = true, + (buf.validate.field).string.max_len = 32 + ]; + // The name of the Plugin. + string plugin = 2 [(buf.validate.field).string = { + min_len: 2 + max_len: 100 + }]; + } + + oneof value { + option (buf.validate.oneof).required = true; + // The id of the Plugin. + string id = 1 [(buf.validate.field).string.tuuid = true]; + // The fully-qualified name of the Plugin. + Name name = 2; + } +} diff --git a/buf/registry/plugin/v1beta1/plugin_service.proto b/buf/registry/plugin/v1beta1/plugin_service.proto new file mode 100644 index 00000000..d668ab3a --- /dev/null +++ b/buf/registry/plugin/v1beta1/plugin_service.proto @@ -0,0 +1,195 @@ +// 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.plugin.v1beta1; + +import "buf/registry/owner/v1/owner.proto"; +import "buf/registry/plugin/v1beta1/collection.proto"; +import "buf/registry/plugin/v1beta1/plugin.proto"; +import "buf/validate/validate.proto"; + +option go_package = "buf.build/gen/go/bufbuild/registry/protocolbuffers/go/buf/registry/plugin/v1beta1"; + +// Operate on Plugins. +service PluginService { + // Get Plugins by id or name. + rpc GetPlugins(GetPluginsRequest) returns (GetPluginsResponse) { + option idempotency_level = NO_SIDE_EFFECTS; + } + // List Plugins, usually for a specific Organization. + rpc ListPlugins(ListPluginsRequest) returns (ListPluginsResponse) { + option idempotency_level = NO_SIDE_EFFECTS; + } + // Create new Plugins. + // + // This operation is atomic. Either all Plugins are created or an error is returned. + rpc CreatePlugins(CreatePluginsRequest) returns (CreatePluginsResponse) { + option idempotency_level = IDEMPOTENT; + } + // Update existing Plugins. + // + // This operation is atomic. Either all Plugins are updated or an error is returned. + rpc UpdatePlugins(UpdatePluginsRequest) returns (UpdatePluginsResponse) { + option idempotency_level = IDEMPOTENT; + } + // Delete existing Plugins. + // + // This operation is atomic. Either all Plugins are deleted or an error is returned. + rpc DeletePlugins(DeletePluginsRequest) returns (DeletePluginsResponse) { + option idempotency_level = IDEMPOTENT; + } +} + +message GetPluginsRequest { + // The Plugins to request. + repeated PluginRef plugin_refs = 1 [ + (buf.validate.field).repeated.min_items = 1, + (buf.validate.field).repeated.max_items = 250 + ]; +} + +message GetPluginsResponse { + // The retrieved Plugins in the same order as requested. + repeated Plugin plugins = 1 [(buf.validate.field).repeated.min_items = 1]; +} + +message ListPluginsRequest { + // The list order. + enum Order { + ORDER_UNSPECIFIED = 0; + // Order by create_time newest to oldest. + ORDER_CREATE_TIME_DESC = 1; + // Order by create_time oldest to newest. + ORDER_CREATE_TIME_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 specific Organizations to list Plugins for. + // + // If empty, all Plugins for all Organizations are listed, but this functionality is limited to + // Users with the necessary permissions. + repeated buf.registry.owner.v1.OwnerRef owner_refs = 3; + // The specific Collections to list Plugins for. + // + // If empty, all Plugins are listed regardless of collection. + repeated CollectionRef collection_refs = 4; + // The order to return the Plugins. + // + // If not specified, defaults to ORDER_CREATE_TIME_DESC. + Order order = 5 [(buf.validate.field).enum.defined_only = true]; +} + +message ListPluginsResponse { + // 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 Plugins. + repeated Plugin plugins = 2; +} + +message CreatePluginsRequest { + // An individual request to create a Plugin. + message Value { + // The Organization to create the Plugin under. The OwnerRef must be a reference to an + // Organization and cannot be a User reference. + buf.registry.owner.v1.OwnerRef owner_ref = 1 [(buf.validate.field).required = true]; + // The name of the Plugin. + string name = 2 [(buf.validate.field).string = { + min_len: 2 + max_len: 100 + }]; + // The plugin's visibility. + PluginVisibility visibility = 3 [ + (buf.validate.field).required = true, + (buf.validate.field).enum.defined_only = true + ]; + // The configurable description of the Plugin. + string description = 4 [(buf.validate.field).string.max_len = 350]; + // The configurable source URL of the Plugin. + string source_url = 5 [ + (buf.validate.field).string.uri = true, + (buf.validate.field).string.max_len = 255, + (buf.validate.field).ignore = IGNORE_IF_UNPOPULATED + ]; + // The Plugin type. + PluginType type = 6 [ + (buf.validate.field).required = true, + (buf.validate.field).enum.defined_only = true + ]; + } + // The Plugins to create. + repeated Value values = 1 [ + (buf.validate.field).repeated.min_items = 1, + (buf.validate.field).repeated.max_items = 250 + ]; +} + +message CreatePluginsResponse { + repeated Plugin plugins = 1 [(buf.validate.field).repeated.min_items = 1]; +} + +message UpdatePluginsRequest { + // An individual request to update a Plugin. + message Value { + // The Plugin to update. + PluginRef plugin_ref = 1 [(buf.validate.field).required = true]; + // The plugins's visibility. + optional PluginVisibility visibility = 2 [ + (buf.validate.field).enum.defined_only = true, + (buf.validate.field).enum.not_in = 0 + ]; + // The deprecation status of the Plugin. + optional PluginState state = 3 [ + (buf.validate.field).enum.defined_only = true, + (buf.validate.field).enum.not_in = 0 + ]; + // The configurable description of the Plugin. + optional string description = 4 [(buf.validate.field).string.max_len = 350]; + // The configurable source URL in the description of the Plugin. + optional string source_url = 5 [ + (buf.validate.field).string.uri = true, + (buf.validate.field).string.max_len = 255, + (buf.validate.field).ignore = IGNORE_IF_DEFAULT_VALUE + ]; + } + // The Plugins to update. + repeated Value values = 1 [ + (buf.validate.field).repeated.min_items = 1, + (buf.validate.field).repeated.max_items = 250 + ]; +} + +message UpdatePluginsResponse { + // The updated Plugins in the same order as given on the request. + repeated Plugin plugins = 1 [(buf.validate.field).repeated.min_items = 1]; +} + +message DeletePluginsRequest { + // The Plugins to delete. + repeated PluginRef plugin_refs = 1 [ + (buf.validate.field).repeated.min_items = 1, + (buf.validate.field).repeated.max_items = 250 + ]; +} + +message DeletePluginsResponse {} diff --git a/buf/registry/plugin/v1beta1/resource.proto b/buf/registry/plugin/v1beta1/resource.proto new file mode 100644 index 00000000..df342129 --- /dev/null +++ b/buf/registry/plugin/v1beta1/resource.proto @@ -0,0 +1,103 @@ +// 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.plugin.v1beta1; + +import "buf/registry/plugin/v1beta1/commit.proto"; +import "buf/registry/plugin/v1beta1/label.proto"; +import "buf/registry/plugin/v1beta1/plugin.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/plugin/v1beta1"; + +// A Plugin, Label, or Commit. +message Resource { + oneof value { + option (buf.validate.oneof).required = true; + + Plugin plugin = 1; + Label label = 2; + Commit commit = 3; + } +} + +// A reference to any of: +// - Plugin +// - Label +// - Commit +// +// The id or name is resolved to a specific resource. If an id is passed, this is interpreted as +// being the id of the resource. If a name is passed, the semantics according to ResourceRef.Name +// are applied. +// +// ResourceRefs can only be used in requests, and only for read-only RPCs, that is you should not +// use an arbitrary reference when modifying a specific resource. +message ResourceRef { + option (buf.registry.priv.extension.v1beta1.message).request_only = true; + option (buf.registry.priv.extension.v1beta1.message).no_side_effects_only = true; + + // The fully-qualified name component of a ResourceRef. + // + // The following semantics are applied: + // - If the child oneof is not specified, the name is interpreted to reference a Plugin. + // - If label_name is specified, the name is interpreted to reference a Label. + // - If ref is specified, it is interpreted to be either an id or name. + // - If an id, this is equivalent to setting the id field on ResourceRef. However, backends + // can choose to validate that the owner and plugin fields match the resource referenced, as + // additional validation. + // - If a name, this is interpreted to be a Label name. + // - If there is a conflict between names across resources (for example, there is a Commit id + // and Label name of the same value), the following order of precedence is applied: + // - Commit + // - Label + // + // Names can only be used in requests, and only for read-only RPCs, that is you should not use an + // arbitrary reference when modifying a specific resource. + message Name { + // The name of the Organization that owns the resource. + string owner = 1 [ + (buf.validate.field).required = true, + (buf.validate.field).string.max_len = 32 + ]; + // The name of the Plugin that contains or is the resource. + string plugin = 2 [(buf.validate.field).string = { + min_len: 2 + max_len: 100 + }]; + // If the oneof is present but empty, this should be treated as not present. + oneof child { + // The name of the Label. + // + // If this value is present but empty, this should be treated as not present, that is an empty + // value is the same as a null value. + string label_name = 3 [(buf.validate.field).string.max_len = 250]; + // The untyped reference, applying the semantics as documented on the Name message. + // + // If this value is present but empty, this should be treated as not present, that is an empty + // value is the same as a null value. + string ref = 4; + } + } + + oneof value { + option (buf.validate.oneof).required = true; + // The id of the resource. + string id = 1 [(buf.validate.field).string.tuuid = true]; + // The fully-qualified name of the resource. + Name name = 2; + } +} diff --git a/buf/registry/plugin/v1beta1/upload_service.proto b/buf/registry/plugin/v1beta1/upload_service.proto new file mode 100644 index 00000000..e9a2fde5 --- /dev/null +++ b/buf/registry/plugin/v1beta1/upload_service.proto @@ -0,0 +1,82 @@ +// 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.plugin.v1beta1; + +import "buf/registry/plugin/v1beta1/commit.proto"; +import "buf/registry/plugin/v1beta1/compression.proto"; +import "buf/registry/plugin/v1beta1/label.proto"; +import "buf/registry/plugin/v1beta1/plugin.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/plugin/v1beta1"; + +// Upload contents. +service UploadService { + // Upload contents for given set of Plugins. + // + // Contents are expected to be WASM modules. + rpc Upload(UploadRequest) returns (UploadResponse) {} +} + +message UploadRequest { + option (buf.registry.priv.extension.v1beta1.message).request_only = true; + + // Content to upload. + message Content { + // The Plugin of the reference. + PluginRef plugin_ref = 1 [(buf.validate.field).required = true]; + // Compression type of the content. + CompressionType compression_type = 2 [ + (buf.validate.field).required = true, + (buf.validate.field).enum.defined_only = true + ]; + // The content to upload. + bytes content = 3 [(buf.validate.field).required = true]; + // 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 + // owned by the Plugin. The Label will point to the newly-created Commits for the References, + // or will be updated to point to the pre-existing Commit for the Reference. + // + // If no labels are referenced, the default Label for the Plugin is used. + // + // If the Labels do not exist, they will be created. If the Labels were archived, they will be + // unarchived. + repeated ScopedLabelRef scoped_label_refs = 4; + // 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 = 5 [ + (buf.validate.field).string.uri = true, + (buf.validate.field).string.max_len = 255, + (buf.validate.field).ignore = IGNORE_IF_UNPOPULATED + ]; + } + // The Contents of all references. + repeated Content contents = 1 [ + (buf.validate.field).repeated.min_items = 1, + (buf.validate.field).repeated.max_items = 10 + ]; +} + +message UploadResponse { + option (buf.registry.priv.extension.v1beta1.message).response_only = true; + + repeated Commit commits = 1 [(buf.validate.field).repeated.min_items = 1]; +}