feat(api): add merge requests, web sessions and signing key
Add MergeRequestService, SessionService, ServerService.GetSigningKey, RepoSettings (merge modes, failing checks) on Repo and UpdateRepo, the MergeMode enum and the merge request event kinds. Compatible additions only.
- commit
- 303f037eb5ed30b94157b8eecadcea11ec97509b
- author
- brice · · 2026-10-10 15:50 UTC
- parent
- 6c7e2b3
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
19 files · +3961 -140
M README.md +6 -4
| @@ -2,7 +2,7 @@ | |||
| 2 | 2 | ||
| 3 | 3 | The public API contract of [ermite](https://git.bnema.dev/bnema/ermite), a single-user Git forge: protobuf definitions for its ConnectRPC services and the Go code generated from them. | |
| 4 | 4 | ||
| 5 | - | Status: early development. The contract defines five services (below); the server that implements them is being built. | |
| 5 | + | Status: early development. The contract defines seven services (below); the server that implements them is being built. | |
| 6 | 6 | ||
| 7 | 7 | ```go | |
| 8 | 8 | import "bnema.dev/ermite-api/gen/ermite" | |
| @@ -16,17 +16,19 @@ Handlers are mounted under `/-/api/` by the server. Errors are Connect codes. | |||
| 16 | 16 | ||
| 17 | 17 | | Service | RPCs | | |
| 18 | 18 | |---|---| | |
| 19 | - | | `RepoService` | `ListRepos`, `GetRepo`, `CreateRepo`, `UpdateRepo` (field mask), `DeleteRepo` | | |
| 19 | + | | `RepoService` | `ListRepos`, `GetRepo`, `CreateRepo`, `UpdateRepo` (field mask, merge settings), `DeleteRepo` | | |
| 20 | 20 | | `GitService` | `ListRefs`, `GetTree`, `GetBlob` (streamed), `ListCommits`, `GetCommit` (structured diff), `ResolveRevision` | | |
| 21 | 21 | | `TokenService` | `CreateToken` (secret shown once), `ListTokens`, `RevokeToken` | | |
| 22 | + | | `MergeRequestService` | `CreateMergeRequest`, `ListMergeRequests`, `GetMergeRequest` (commits, diff, comments), `AddComment`, `ResolveComment`, `CloseMergeRequest`, `MergeMergeRequest`, `MarkRead` | | |
| 23 | + | | `SessionService` | `CreateLoginLink`, `SignOutEverywhere` (owner only) | | |
| 22 | 24 | | `EventService` | `Watch` (streamed, resumable) | | |
| 23 | - | | `ServerService` | `GetVersion` (server version and feature list) | | |
| 25 | + | | `ServerService` | `GetVersion` (server version and feature list), `GetSigningKey` (commit signing key) | | |
| 24 | 26 | ||
| 25 | 27 | Tokens carry scopes only; presets such as `cli` or `agent` are a client concern. | |
| 26 | 28 | ||
| 27 | 29 | ## Layout | |
| 28 | 30 | ||
| 29 | - | - `proto/ermite/`: `.proto` files of the `ermite` package, one per service (`repo`, `git`, `token`, `event`, `server`) plus shared `types`. Checked by `buf lint` and `buf breaking`. | |
| 31 | + | - `proto/ermite/`: `.proto` files of the `ermite` package, one per service (`repo`, `git`, `merge_request`, `token`, `session`, `event`, `server`) plus shared `types`. Checked by `buf lint` and `buf breaking`. | |
| 30 | 32 | - `gen/ermite/`: generated Go messages. `gen/ermite/ermiteconnect/`: generated Connect clients and handlers. Committed, never edited by hand. | |
| 31 | 33 | ||
| 32 | 34 | ## Generate | |
| @@ -2,7 +2,7 @@ | |||||
| 2 | 2 | ||||
| 3 | The public API contract of [ermite](https://git.bnema.dev/bnema/ermite), a single-user Git forge: protobuf definitions for its ConnectRPC services and the Go code generated from them. | 3 | The public API contract of [ermite](https://git.bnema.dev/bnema/ermite), a single-user Git forge: protobuf definitions for its ConnectRPC services and the Go code generated from them. | ||
| 4 | 4 | ||||
| 5 | - | Status: early development. The contract defines five services (below); the server that implements them is being built. | 5 | + | Status: early development. The contract defines seven services (below); the server that implements them is being built. |
| 6 | 6 | ||||
| 7 | ```go | 7 | ```go | ||
| 8 | import "bnema.dev/ermite-api/gen/ermite" | 8 | import "bnema.dev/ermite-api/gen/ermite" | ||
| @@ -16,17 +16,19 @@ Handlers are mounted under `/-/api/` by the server. Errors are Connect codes. | |||||
| 16 | 16 | ||||
| 17 | | Service | RPCs | | 17 | | Service | RPCs | | ||
| 18 | |---|---| | 18 | |---|---| | ||
| 19 | - | | `RepoService` | `ListRepos`, `GetRepo`, `CreateRepo`, `UpdateRepo` (field mask), `DeleteRepo` | | 19 | + | | `RepoService` | `ListRepos`, `GetRepo`, `CreateRepo`, `UpdateRepo` (field mask, merge settings), `DeleteRepo` | |
| 20 | | `GitService` | `ListRefs`, `GetTree`, `GetBlob` (streamed), `ListCommits`, `GetCommit` (structured diff), `ResolveRevision` | | 20 | | `GitService` | `ListRefs`, `GetTree`, `GetBlob` (streamed), `ListCommits`, `GetCommit` (structured diff), `ResolveRevision` | | ||
| 21 | | `TokenService` | `CreateToken` (secret shown once), `ListTokens`, `RevokeToken` | | 21 | | `TokenService` | `CreateToken` (secret shown once), `ListTokens`, `RevokeToken` | | ||
| 22 | + | | `MergeRequestService` | `CreateMergeRequest`, `ListMergeRequests`, `GetMergeRequest` (commits, diff, comments), `AddComment`, `ResolveComment`, `CloseMergeRequest`, `MergeMergeRequest`, `MarkRead` | | |||
| 23 | + | | `SessionService` | `CreateLoginLink`, `SignOutEverywhere` (owner only) | | |||
| 22 | | `EventService` | `Watch` (streamed, resumable) | | 24 | | `EventService` | `Watch` (streamed, resumable) | | ||
| 23 | - | | `ServerService` | `GetVersion` (server version and feature list) | | 25 | + | | `ServerService` | `GetVersion` (server version and feature list), `GetSigningKey` (commit signing key) | |
| 24 | 26 | ||||
| 25 | Tokens carry scopes only; presets such as `cli` or `agent` are a client concern. | 27 | Tokens carry scopes only; presets such as `cli` or `agent` are a client concern. | ||
| 26 | 28 | ||||
| 27 | ## Layout | 29 | ## Layout | ||
| 28 | 30 | ||||
| 29 | - | - `proto/ermite/`: `.proto` files of the `ermite` package, one per service (`repo`, `git`, `token`, `event`, `server`) plus shared `types`. Checked by `buf lint` and `buf breaking`. | 31 | + | - `proto/ermite/`: `.proto` files of the `ermite` package, one per service (`repo`, `git`, `merge_request`, `token`, `session`, `event`, `server`) plus shared `types`. Checked by `buf lint` and `buf breaking`. |
| 30 | - `gen/ermite/`: generated Go messages. `gen/ermite/ermiteconnect/`: generated Connect clients and handlers. Committed, never edited by hand. | 32 | - `gen/ermite/`: generated Go messages. `gen/ermite/ermiteconnect/`: generated Connect clients and handlers. Committed, never edited by hand. | ||
| 31 | 33 | ||||
| 32 | ## Generate | 34 | ## Generate | ||
M gen/ermite/ermiteconnect/event.connect.go +18 -0
| @@ -45,6 +45,15 @@ type EventServiceClient interface { | |||
| 45 | 45 | // down. Events are filtered by the caller's access: events of a private | |
| 46 | 46 | // repository are only sent to callers that may read it. | |
| 47 | 47 | // | |
| 48 | + | // The events are repo_created, repo_updated, repo_deleted, pushed, gap and, | |
| 49 | + | // for merge requests, merge_request_opened, merge_request_merged, | |
| 50 | + | // merge_request_closed and comment_added. Each one is delivered on the | |
| 51 | + | // "repo:<name>" topic of its repository and on "home", subject to the | |
| 52 | + | // visibility of the repository. There is no event for a change of title or | |
| 53 | + | // description, nor for a resolved comment: after a gap, or to see such | |
| 54 | + | // changes, clients read the merge request again. A merge publishes | |
| 55 | + | // merge_request_merged, then pushed for the target branch. | |
| 56 | + | // | |
| 48 | 57 | // The server keeps a bounded buffer of recent events. With resume_after set, | |
| 49 | 58 | // buffered events after that id are replayed first, then live events follow. | |
| 50 | 59 | // When resume_after is no longer buffered (or unknown), the stream begins | |
| @@ -98,6 +107,15 @@ type EventServiceHandler interface { | |||
| 98 | 107 | // down. Events are filtered by the caller's access: events of a private | |
| 99 | 108 | // repository are only sent to callers that may read it. | |
| 100 | 109 | // | |
| 110 | + | // The events are repo_created, repo_updated, repo_deleted, pushed, gap and, | |
| 111 | + | // for merge requests, merge_request_opened, merge_request_merged, | |
| 112 | + | // merge_request_closed and comment_added. Each one is delivered on the | |
| 113 | + | // "repo:<name>" topic of its repository and on "home", subject to the | |
| 114 | + | // visibility of the repository. There is no event for a change of title or | |
| 115 | + | // description, nor for a resolved comment: after a gap, or to see such | |
| 116 | + | // changes, clients read the merge request again. A merge publishes | |
| 117 | + | // merge_request_merged, then pushed for the target branch. | |
| 118 | + | // | |
| 101 | 119 | // The server keeps a bounded buffer of recent events. With resume_after set, | |
| 102 | 120 | // buffered events after that id are replayed first, then live events follow. | |
| 103 | 121 | // When resume_after is no longer buffered (or unknown), the stream begins | |
| @@ -45,6 +45,15 @@ type EventServiceClient interface { | |||||
| 45 | // down. Events are filtered by the caller's access: events of a private | 45 | // down. Events are filtered by the caller's access: events of a private | ||
| 46 | // repository are only sent to callers that may read it. | 46 | // repository are only sent to callers that may read it. | ||
| 47 | // | 47 | // | ||
| 48 | + | // The events are repo_created, repo_updated, repo_deleted, pushed, gap and, | |||
| 49 | + | // for merge requests, merge_request_opened, merge_request_merged, | |||
| 50 | + | // merge_request_closed and comment_added. Each one is delivered on the | |||
| 51 | + | // "repo:<name>" topic of its repository and on "home", subject to the | |||
| 52 | + | // visibility of the repository. There is no event for a change of title or | |||
| 53 | + | // description, nor for a resolved comment: after a gap, or to see such | |||
| 54 | + | // changes, clients read the merge request again. A merge publishes | |||
| 55 | + | // merge_request_merged, then pushed for the target branch. | |||
| 56 | + | // | |||
| 48 | // The server keeps a bounded buffer of recent events. With resume_after set, | 57 | // The server keeps a bounded buffer of recent events. With resume_after set, | ||
| 49 | // buffered events after that id are replayed first, then live events follow. | 58 | // buffered events after that id are replayed first, then live events follow. | ||
| 50 | // When resume_after is no longer buffered (or unknown), the stream begins | 59 | // When resume_after is no longer buffered (or unknown), the stream begins | ||
| @@ -98,6 +107,15 @@ type EventServiceHandler interface { | |||||
| 98 | // down. Events are filtered by the caller's access: events of a private | 107 | // down. Events are filtered by the caller's access: events of a private | ||
| 99 | // repository are only sent to callers that may read it. | 108 | // repository are only sent to callers that may read it. | ||
| 100 | // | 109 | // | ||
| 110 | + | // The events are repo_created, repo_updated, repo_deleted, pushed, gap and, | |||
| 111 | + | // for merge requests, merge_request_opened, merge_request_merged, | |||
| 112 | + | // merge_request_closed and comment_added. Each one is delivered on the | |||
| 113 | + | // "repo:<name>" topic of its repository and on "home", subject to the | |||
| 114 | + | // visibility of the repository. There is no event for a change of title or | |||
| 115 | + | // description, nor for a resolved comment: after a gap, or to see such | |||
| 116 | + | // changes, clients read the merge request again. A merge publishes | |||
| 117 | + | // merge_request_merged, then pushed for the target branch. | |||
| 118 | + | // | |||
| 101 | // The server keeps a bounded buffer of recent events. With resume_after set, | 119 | // The server keeps a bounded buffer of recent events. With resume_after set, | ||
| 102 | // buffered events after that id are replayed first, then live events follow. | 120 | // buffered events after that id are replayed first, then live events follow. | ||
| 103 | // When resume_after is no longer buffered (or unknown), the stream begins | 121 | // When resume_after is no longer buffered (or unknown), the stream begins | ||
A gen/ermite/ermiteconnect/merge_request.connect.go +396 -0
| @@ -0,0 +1,396 @@ | |||
| 1 | + | // SPDX-License-Identifier: MIT | |
| 2 | + | ||
| 3 | + | // Code generated by protoc-gen-connect-go. DO NOT EDIT. | |
| 4 | + | // | |
| 5 | + | // Source: ermite/merge_request.proto | |
| 6 | + | ||
| 7 | + | package ermiteconnect | |
| 8 | + | ||
| 9 | + | import ( | |
| 10 | + | ermite "bnema.dev/ermite-api/gen/ermite" | |
| 11 | + | connect "connectrpc.com/connect" | |
| 12 | + | context "context" | |
| 13 | + | errors "errors" | |
| 14 | + | http "net/http" | |
| 15 | + | strings "strings" | |
| 16 | + | ) | |
| 17 | + | ||
| 18 | + | // This is a compile-time assertion to ensure that this generated file and the connect package are | |
| 19 | + | // compatible. If you get a compiler error that this constant is not defined, this code was | |
| 20 | + | // generated with a version of connect newer than the one compiled into your binary. You can fix the | |
| 21 | + | // problem by either regenerating this code with an older version of connect or updating the connect | |
| 22 | + | // version compiled into your binary. | |
| 23 | + | const _ = connect.IsAtLeastVersion1_13_0 | |
| 24 | + | ||
| 25 | + | const ( | |
| 26 | + | // MergeRequestServiceName is the fully-qualified name of the MergeRequestService service. | |
| 27 | + | MergeRequestServiceName = "ermite.MergeRequestService" | |
| 28 | + | ) | |
| 29 | + | ||
| 30 | + | // These constants are the fully-qualified names of the RPCs defined in this package. They're | |
| 31 | + | // exposed at runtime as Spec.Procedure and as the final two segments of the HTTP route. | |
| 32 | + | // | |
| 33 | + | // Note that these are different from the fully-qualified method names used by | |
| 34 | + | // google.golang.org/protobuf/reflect/protoreflect. To convert from these constants to | |
| 35 | + | // reflection-formatted method names, remove the leading slash and convert the remaining slash to a | |
| 36 | + | // period. | |
| 37 | + | const ( | |
| 38 | + | // MergeRequestServiceCreateMergeRequestProcedure is the fully-qualified name of the | |
| 39 | + | // MergeRequestService's CreateMergeRequest RPC. | |
| 40 | + | MergeRequestServiceCreateMergeRequestProcedure = "/ermite.MergeRequestService/CreateMergeRequest" | |
| 41 | + | // MergeRequestServiceListMergeRequestsProcedure is the fully-qualified name of the | |
| 42 | + | // MergeRequestService's ListMergeRequests RPC. | |
| 43 | + | MergeRequestServiceListMergeRequestsProcedure = "/ermite.MergeRequestService/ListMergeRequests" | |
| 44 | + | // MergeRequestServiceGetMergeRequestProcedure is the fully-qualified name of the | |
| 45 | + | // MergeRequestService's GetMergeRequest RPC. | |
| 46 | + | MergeRequestServiceGetMergeRequestProcedure = "/ermite.MergeRequestService/GetMergeRequest" | |
| 47 | + | // MergeRequestServiceAddCommentProcedure is the fully-qualified name of the MergeRequestService's | |
| 48 | + | // AddComment RPC. | |
| 49 | + | MergeRequestServiceAddCommentProcedure = "/ermite.MergeRequestService/AddComment" | |
| 50 | + | // MergeRequestServiceResolveCommentProcedure is the fully-qualified name of the | |
| 51 | + | // MergeRequestService's ResolveComment RPC. | |
| 52 | + | MergeRequestServiceResolveCommentProcedure = "/ermite.MergeRequestService/ResolveComment" | |
| 53 | + | // MergeRequestServiceCloseMergeRequestProcedure is the fully-qualified name of the | |
| 54 | + | // MergeRequestService's CloseMergeRequest RPC. | |
| 55 | + | MergeRequestServiceCloseMergeRequestProcedure = "/ermite.MergeRequestService/CloseMergeRequest" | |
| 56 | + | // MergeRequestServiceMergeMergeRequestProcedure is the fully-qualified name of the | |
| 57 | + | // MergeRequestService's MergeMergeRequest RPC. | |
| 58 | + | MergeRequestServiceMergeMergeRequestProcedure = "/ermite.MergeRequestService/MergeMergeRequest" | |
| 59 | + | // MergeRequestServiceMarkReadProcedure is the fully-qualified name of the MergeRequestService's | |
| 60 | + | // MarkRead RPC. | |
| 61 | + | MergeRequestServiceMarkReadProcedure = "/ermite.MergeRequestService/MarkRead" | |
| 62 | + | ) | |
| 63 | + | ||
| 64 | + | // MergeRequestServiceClient is a client for the ermite.MergeRequestService service. | |
| 65 | + | type MergeRequestServiceClient interface { | |
| 66 | + | // CreateMergeRequest opens a merge request. Needs the mr:write scope. Fails | |
| 67 | + | // with invalid_argument if a text rule is broken, if a branch does not exist | |
| 68 | + | // or if source and target are the same branch, and with already_exists if an | |
| 69 | + | // open merge request already has the same source and target. | |
| 70 | + | CreateMergeRequest(context.Context, *connect.Request[ermite.CreateMergeRequestRequest]) (*connect.Response[ermite.CreateMergeRequestResponse], error) | |
| 71 | + | // ListMergeRequests lists the merge requests of a repository, highest | |
| 72 | + | // number (newest) first, optionally restricted to one state. The listed | |
| 73 | + | // merge requests carry no diff or comments; head_id is set. Fails with | |
| 74 | + | // not_found if the repository does not exist or is not readable. | |
| 75 | + | ListMergeRequests(context.Context, *connect.Request[ermite.ListMergeRequestsRequest]) (*connect.Response[ermite.ListMergeRequestsResponse], error) | |
| 76 | + | // GetMergeRequest returns one merge request with its commits, its diff and | |
| 77 | + | // its comments. The diff compares the target with the head (what the merge | |
| 78 | + | // would bring: "target...head"), or, with since_last_read, the head the | |
| 79 | + | // caller last marked read with the current head. Fails with not_found if | |
| 80 | + | // the repository or the number is unknown. | |
| 81 | + | GetMergeRequest(context.Context, *connect.Request[ermite.GetMergeRequestRequest]) (*connect.Response[ermite.GetMergeRequestResponse], error) | |
| 82 | + | // AddComment adds a general comment or a comment on a line of the diff. | |
| 83 | + | // Needs the mr:write scope. Fails with invalid_argument if the text breaks | |
| 84 | + | // a rule or if path, line and side do not designate a line of the current | |
| 85 | + | // diff of the merge request, and with failed_precondition if the merge | |
| 86 | + | // request is not open. | |
| 87 | + | AddComment(context.Context, *connect.Request[ermite.AddCommentRequest]) (*connect.Response[ermite.AddCommentResponse], error) | |
| 88 | + | // ResolveComment marks a comment resolved or unresolved. Needs the mr:write | |
| 89 | + | // scope. Fails with not_found if the comment is unknown and with | |
| 90 | + | // failed_precondition if the merge request is not open. Setting the state | |
| 91 | + | // the comment already has succeeds and changes nothing. | |
| 92 | + | ResolveComment(context.Context, *connect.Request[ermite.ResolveCommentRequest]) (*connect.Response[ermite.ResolveCommentResponse], error) | |
| 93 | + | // CloseMergeRequest closes an open merge request without merging it. Needs | |
| 94 | + | // the mr:write scope. Fails with failed_precondition if the merge request | |
| 95 | + | // is not open. A closed merge request cannot be reopened: open a new one. | |
| 96 | + | CloseMergeRequest(context.Context, *connect.Request[ermite.CloseMergeRequestRequest]) (*connect.Response[ermite.CloseMergeRequestResponse], error) | |
| 97 | + | // MergeMergeRequest merges an open merge request. Needs the mr:merge scope. | |
| 98 | + | // The caller passes the head it reviewed: the server merges only if the | |
| 99 | + | // source branch still points to it, so a push between review and merge is | |
| 100 | + | // never merged unseen. Fails with invalid_argument if head_id is empty or | |
| 101 | + | // not a commit id, and with failed_precondition if the merge request is not | |
| 102 | + | // open, if the source branch no longer points to head_id ("branch moved, | |
| 103 | + | // read again"), if the target is not an ancestor of the head (rebase and | |
| 104 | + | // push again), if the mode is not allowed by RepoSettings, or if a check | |
| 105 | + | // fails and RepoSettings.failing_checks_block is set. Merges of one | |
| 106 | + | // repository run one at a time. Repeating a call that succeeded fails with | |
| 107 | + | // failed_precondition (not open). On success the server publishes | |
| 108 | + | // MergeRequestMerged then Pushed for the target branch. | |
| 109 | + | MergeMergeRequest(context.Context, *connect.Request[ermite.MergeMergeRequestRequest]) (*connect.Response[ermite.MergeMergeRequestResponse], error) | |
| 110 | + | // MarkRead records the head the caller has reviewed, for the since_last_read | |
| 111 | + | // option of GetMergeRequest. There is one read position per merge request, | |
| 112 | + | // the reviewer's. Needs the mr:write scope. Marking a commit that does not | |
| 113 | + | // exist in the repository is invalid_argument. | |
| 114 | + | MarkRead(context.Context, *connect.Request[ermite.MarkReadRequest]) (*connect.Response[ermite.MarkReadResponse], error) | |
| 115 | + | } | |
| 116 | + | ||
| 117 | + | // NewMergeRequestServiceClient constructs a client for the ermite.MergeRequestService service. By | |
| 118 | + | // default, it uses the Connect protocol with the binary Protobuf Codec, asks for gzipped responses, | |
| 119 | + | // and sends uncompressed requests. To use the gRPC or gRPC-Web protocols, supply the | |
| 120 | + | // connect.WithGRPC() or connect.WithGRPCWeb() options. | |
| 121 | + | // | |
| 122 | + | // The URL supplied here should be the base URL for the Connect or gRPC server (for example, | |
| 123 | + | // http://api.acme.com or https://acme.com/grpc). | |
| 124 | + | func NewMergeRequestServiceClient(httpClient connect.HTTPClient, baseURL string, opts ...connect.ClientOption) MergeRequestServiceClient { | |
| 125 | + | baseURL = strings.TrimRight(baseURL, "/") | |
| 126 | + | mergeRequestServiceMethods := ermite.File_ermite_merge_request_proto.Services().ByName("MergeRequestService").Methods() | |
| 127 | + | return &mergeRequestServiceClient{ | |
| 128 | + | createMergeRequest: connect.NewClient[ermite.CreateMergeRequestRequest, ermite.CreateMergeRequestResponse]( | |
| 129 | + | httpClient, | |
| 130 | + | baseURL+MergeRequestServiceCreateMergeRequestProcedure, | |
| 131 | + | connect.WithSchema(mergeRequestServiceMethods.ByName("CreateMergeRequest")), | |
| 132 | + | connect.WithClientOptions(opts...), | |
| 133 | + | ), | |
| 134 | + | listMergeRequests: connect.NewClient[ermite.ListMergeRequestsRequest, ermite.ListMergeRequestsResponse]( | |
| 135 | + | httpClient, | |
| 136 | + | baseURL+MergeRequestServiceListMergeRequestsProcedure, | |
| 137 | + | connect.WithSchema(mergeRequestServiceMethods.ByName("ListMergeRequests")), | |
| 138 | + | connect.WithClientOptions(opts...), | |
| 139 | + | ), | |
| 140 | + | getMergeRequest: connect.NewClient[ermite.GetMergeRequestRequest, ermite.GetMergeRequestResponse]( | |
| 141 | + | httpClient, | |
| 142 | + | baseURL+MergeRequestServiceGetMergeRequestProcedure, | |
| 143 | + | connect.WithSchema(mergeRequestServiceMethods.ByName("GetMergeRequest")), | |
| 144 | + | connect.WithClientOptions(opts...), | |
| 145 | + | ), | |
| 146 | + | addComment: connect.NewClient[ermite.AddCommentRequest, ermite.AddCommentResponse]( | |
| 147 | + | httpClient, | |
| 148 | + | baseURL+MergeRequestServiceAddCommentProcedure, | |
| 149 | + | connect.WithSchema(mergeRequestServiceMethods.ByName("AddComment")), | |
| 150 | + | connect.WithClientOptions(opts...), | |
| 151 | + | ), | |
| 152 | + | resolveComment: connect.NewClient[ermite.ResolveCommentRequest, ermite.ResolveCommentResponse]( | |
| 153 | + | httpClient, | |
| 154 | + | baseURL+MergeRequestServiceResolveCommentProcedure, | |
| 155 | + | connect.WithSchema(mergeRequestServiceMethods.ByName("ResolveComment")), | |
| 156 | + | connect.WithClientOptions(opts...), | |
| 157 | + | ), | |
| 158 | + | closeMergeRequest: connect.NewClient[ermite.CloseMergeRequestRequest, ermite.CloseMergeRequestResponse]( | |
| 159 | + | httpClient, | |
| 160 | + | baseURL+MergeRequestServiceCloseMergeRequestProcedure, | |
| 161 | + | connect.WithSchema(mergeRequestServiceMethods.ByName("CloseMergeRequest")), | |
| 162 | + | connect.WithClientOptions(opts...), | |
| 163 | + | ), | |
| 164 | + | mergeMergeRequest: connect.NewClient[ermite.MergeMergeRequestRequest, ermite.MergeMergeRequestResponse]( | |
| 165 | + | httpClient, | |
| 166 | + | baseURL+MergeRequestServiceMergeMergeRequestProcedure, | |
| 167 | + | connect.WithSchema(mergeRequestServiceMethods.ByName("MergeMergeRequest")), | |
| 168 | + | connect.WithClientOptions(opts...), | |
| 169 | + | ), | |
| 170 | + | markRead: connect.NewClient[ermite.MarkReadRequest, ermite.MarkReadResponse]( | |
| 171 | + | httpClient, | |
| 172 | + | baseURL+MergeRequestServiceMarkReadProcedure, | |
| 173 | + | connect.WithSchema(mergeRequestServiceMethods.ByName("MarkRead")), | |
| 174 | + | connect.WithClientOptions(opts...), | |
| 175 | + | ), | |
| 176 | + | } | |
| 177 | + | } | |
| 178 | + | ||
| 179 | + | // mergeRequestServiceClient implements MergeRequestServiceClient. | |
| 180 | + | type mergeRequestServiceClient struct { | |
| 181 | + | createMergeRequest *connect.Client[ermite.CreateMergeRequestRequest, ermite.CreateMergeRequestResponse] | |
| 182 | + | listMergeRequests *connect.Client[ermite.ListMergeRequestsRequest, ermite.ListMergeRequestsResponse] | |
| 183 | + | getMergeRequest *connect.Client[ermite.GetMergeRequestRequest, ermite.GetMergeRequestResponse] | |
| 184 | + | addComment *connect.Client[ermite.AddCommentRequest, ermite.AddCommentResponse] | |
| 185 | + | resolveComment *connect.Client[ermite.ResolveCommentRequest, ermite.ResolveCommentResponse] | |
| 186 | + | closeMergeRequest *connect.Client[ermite.CloseMergeRequestRequest, ermite.CloseMergeRequestResponse] | |
| 187 | + | mergeMergeRequest *connect.Client[ermite.MergeMergeRequestRequest, ermite.MergeMergeRequestResponse] | |
| 188 | + | markRead *connect.Client[ermite.MarkReadRequest, ermite.MarkReadResponse] | |
| 189 | + | } | |
| 190 | + | ||
| 191 | + | // CreateMergeRequest calls ermite.MergeRequestService.CreateMergeRequest. | |
| 192 | + | func (c *mergeRequestServiceClient) CreateMergeRequest(ctx context.Context, req *connect.Request[ermite.CreateMergeRequestRequest]) (*connect.Response[ermite.CreateMergeRequestResponse], error) { | |
| 193 | + | return c.createMergeRequest.CallUnary(ctx, req) | |
| 194 | + | } | |
| 195 | + | ||
| 196 | + | // ListMergeRequests calls ermite.MergeRequestService.ListMergeRequests. | |
| 197 | + | func (c *mergeRequestServiceClient) ListMergeRequests(ctx context.Context, req *connect.Request[ermite.ListMergeRequestsRequest]) (*connect.Response[ermite.ListMergeRequestsResponse], error) { | |
| 198 | + | return c.listMergeRequests.CallUnary(ctx, req) | |
| 199 | + | } | |
| 200 | + | ||
| 201 | + | // GetMergeRequest calls ermite.MergeRequestService.GetMergeRequest. | |
| 202 | + | func (c *mergeRequestServiceClient) GetMergeRequest(ctx context.Context, req *connect.Request[ermite.GetMergeRequestRequest]) (*connect.Response[ermite.GetMergeRequestResponse], error) { | |
| 203 | + | return c.getMergeRequest.CallUnary(ctx, req) | |
| 204 | + | } | |
| 205 | + | ||
| 206 | + | // AddComment calls ermite.MergeRequestService.AddComment. | |
| 207 | + | func (c *mergeRequestServiceClient) AddComment(ctx context.Context, req *connect.Request[ermite.AddCommentRequest]) (*connect.Response[ermite.AddCommentResponse], error) { | |
| 208 | + | return c.addComment.CallUnary(ctx, req) | |
| 209 | + | } | |
| 210 | + | ||
| 211 | + | // ResolveComment calls ermite.MergeRequestService.ResolveComment. | |
| 212 | + | func (c *mergeRequestServiceClient) ResolveComment(ctx context.Context, req *connect.Request[ermite.ResolveCommentRequest]) (*connect.Response[ermite.ResolveCommentResponse], error) { | |
| 213 | + | return c.resolveComment.CallUnary(ctx, req) | |
| 214 | + | } | |
| 215 | + | ||
| 216 | + | // CloseMergeRequest calls ermite.MergeRequestService.CloseMergeRequest. | |
| 217 | + | func (c *mergeRequestServiceClient) CloseMergeRequest(ctx context.Context, req *connect.Request[ermite.CloseMergeRequestRequest]) (*connect.Response[ermite.CloseMergeRequestResponse], error) { | |
| 218 | + | return c.closeMergeRequest.CallUnary(ctx, req) | |
| 219 | + | } | |
| 220 | + | ||
| 221 | + | // MergeMergeRequest calls ermite.MergeRequestService.MergeMergeRequest. | |
| 222 | + | func (c *mergeRequestServiceClient) MergeMergeRequest(ctx context.Context, req *connect.Request[ermite.MergeMergeRequestRequest]) (*connect.Response[ermite.MergeMergeRequestResponse], error) { | |
| 223 | + | return c.mergeMergeRequest.CallUnary(ctx, req) | |
| 224 | + | } | |
| 225 | + | ||
| 226 | + | // MarkRead calls ermite.MergeRequestService.MarkRead. | |
| 227 | + | func (c *mergeRequestServiceClient) MarkRead(ctx context.Context, req *connect.Request[ermite.MarkReadRequest]) (*connect.Response[ermite.MarkReadResponse], error) { | |
| 228 | + | return c.markRead.CallUnary(ctx, req) | |
| 229 | + | } | |
| 230 | + | ||
| 231 | + | // MergeRequestServiceHandler is an implementation of the ermite.MergeRequestService service. | |
| 232 | + | type MergeRequestServiceHandler interface { | |
| 233 | + | // CreateMergeRequest opens a merge request. Needs the mr:write scope. Fails | |
| 234 | + | // with invalid_argument if a text rule is broken, if a branch does not exist | |
| 235 | + | // or if source and target are the same branch, and with already_exists if an | |
| 236 | + | // open merge request already has the same source and target. | |
| 237 | + | CreateMergeRequest(context.Context, *connect.Request[ermite.CreateMergeRequestRequest]) (*connect.Response[ermite.CreateMergeRequestResponse], error) | |
| 238 | + | // ListMergeRequests lists the merge requests of a repository, highest | |
| 239 | + | // number (newest) first, optionally restricted to one state. The listed | |
| 240 | + | // merge requests carry no diff or comments; head_id is set. Fails with | |
| 241 | + | // not_found if the repository does not exist or is not readable. | |
| 242 | + | ListMergeRequests(context.Context, *connect.Request[ermite.ListMergeRequestsRequest]) (*connect.Response[ermite.ListMergeRequestsResponse], error) | |
| 243 | + | // GetMergeRequest returns one merge request with its commits, its diff and | |
| 244 | + | // its comments. The diff compares the target with the head (what the merge | |
| 245 | + | // would bring: "target...head"), or, with since_last_read, the head the | |
| 246 | + | // caller last marked read with the current head. Fails with not_found if | |
| 247 | + | // the repository or the number is unknown. | |
| 248 | + | GetMergeRequest(context.Context, *connect.Request[ermite.GetMergeRequestRequest]) (*connect.Response[ermite.GetMergeRequestResponse], error) | |
| 249 | + | // AddComment adds a general comment or a comment on a line of the diff. | |
| 250 | + | // Needs the mr:write scope. Fails with invalid_argument if the text breaks | |
| 251 | + | // a rule or if path, line and side do not designate a line of the current | |
| 252 | + | // diff of the merge request, and with failed_precondition if the merge | |
| 253 | + | // request is not open. | |
| 254 | + | AddComment(context.Context, *connect.Request[ermite.AddCommentRequest]) (*connect.Response[ermite.AddCommentResponse], error) | |
| 255 | + | // ResolveComment marks a comment resolved or unresolved. Needs the mr:write | |
| 256 | + | // scope. Fails with not_found if the comment is unknown and with | |
| 257 | + | // failed_precondition if the merge request is not open. Setting the state | |
| 258 | + | // the comment already has succeeds and changes nothing. | |
| 259 | + | ResolveComment(context.Context, *connect.Request[ermite.ResolveCommentRequest]) (*connect.Response[ermite.ResolveCommentResponse], error) | |
| 260 | + | // CloseMergeRequest closes an open merge request without merging it. Needs | |
| 261 | + | // the mr:write scope. Fails with failed_precondition if the merge request | |
| 262 | + | // is not open. A closed merge request cannot be reopened: open a new one. | |
| 263 | + | CloseMergeRequest(context.Context, *connect.Request[ermite.CloseMergeRequestRequest]) (*connect.Response[ermite.CloseMergeRequestResponse], error) | |
| 264 | + | // MergeMergeRequest merges an open merge request. Needs the mr:merge scope. | |
| 265 | + | // The caller passes the head it reviewed: the server merges only if the | |
| 266 | + | // source branch still points to it, so a push between review and merge is | |
| 267 | + | // never merged unseen. Fails with invalid_argument if head_id is empty or | |
| 268 | + | // not a commit id, and with failed_precondition if the merge request is not | |
| 269 | + | // open, if the source branch no longer points to head_id ("branch moved, | |
| 270 | + | // read again"), if the target is not an ancestor of the head (rebase and | |
| 271 | + | // push again), if the mode is not allowed by RepoSettings, or if a check | |
| 272 | + | // fails and RepoSettings.failing_checks_block is set. Merges of one | |
| 273 | + | // repository run one at a time. Repeating a call that succeeded fails with | |
| 274 | + | // failed_precondition (not open). On success the server publishes | |
| 275 | + | // MergeRequestMerged then Pushed for the target branch. | |
| 276 | + | MergeMergeRequest(context.Context, *connect.Request[ermite.MergeMergeRequestRequest]) (*connect.Response[ermite.MergeMergeRequestResponse], error) | |
| 277 | + | // MarkRead records the head the caller has reviewed, for the since_last_read | |
| 278 | + | // option of GetMergeRequest. There is one read position per merge request, | |
| 279 | + | // the reviewer's. Needs the mr:write scope. Marking a commit that does not | |
| 280 | + | // exist in the repository is invalid_argument. | |
| 281 | + | MarkRead(context.Context, *connect.Request[ermite.MarkReadRequest]) (*connect.Response[ermite.MarkReadResponse], error) | |
| 282 | + | } | |
| 283 | + | ||
| 284 | + | // NewMergeRequestServiceHandler builds an HTTP handler from the service implementation. It returns | |
| 285 | + | // the path on which to mount the handler and the handler itself. | |
| 286 | + | // | |
| 287 | + | // By default, handlers support the Connect, gRPC, and gRPC-Web protocols with the binary Protobuf | |
| 288 | + | // and JSON codecs. They also support gzip compression. | |
| 289 | + | func NewMergeRequestServiceHandler(svc MergeRequestServiceHandler, opts ...connect.HandlerOption) (string, http.Handler) { | |
| 290 | + | mergeRequestServiceMethods := ermite.File_ermite_merge_request_proto.Services().ByName("MergeRequestService").Methods() | |
| 291 | + | mergeRequestServiceCreateMergeRequestHandler := connect.NewUnaryHandler( | |
| 292 | + | MergeRequestServiceCreateMergeRequestProcedure, | |
| 293 | + | svc.CreateMergeRequest, | |
| 294 | + | connect.WithSchema(mergeRequestServiceMethods.ByName("CreateMergeRequest")), | |
| 295 | + | connect.WithHandlerOptions(opts...), | |
| 296 | + | ) | |
| 297 | + | mergeRequestServiceListMergeRequestsHandler := connect.NewUnaryHandler( | |
| 298 | + | MergeRequestServiceListMergeRequestsProcedure, | |
| 299 | + | svc.ListMergeRequests, | |
| 300 | + | connect.WithSchema(mergeRequestServiceMethods.ByName("ListMergeRequests")), | |
| 301 | + | connect.WithHandlerOptions(opts...), | |
| 302 | + | ) | |
| 303 | + | mergeRequestServiceGetMergeRequestHandler := connect.NewUnaryHandler( | |
| 304 | + | MergeRequestServiceGetMergeRequestProcedure, | |
| 305 | + | svc.GetMergeRequest, | |
| 306 | + | connect.WithSchema(mergeRequestServiceMethods.ByName("GetMergeRequest")), | |
| 307 | + | connect.WithHandlerOptions(opts...), | |
| 308 | + | ) | |
| 309 | + | mergeRequestServiceAddCommentHandler := connect.NewUnaryHandler( | |
| 310 | + | MergeRequestServiceAddCommentProcedure, | |
| 311 | + | svc.AddComment, | |
| 312 | + | connect.WithSchema(mergeRequestServiceMethods.ByName("AddComment")), | |
| 313 | + | connect.WithHandlerOptions(opts...), | |
| 314 | + | ) | |
| 315 | + | mergeRequestServiceResolveCommentHandler := connect.NewUnaryHandler( | |
| 316 | + | MergeRequestServiceResolveCommentProcedure, | |
| 317 | + | svc.ResolveComment, | |
| 318 | + | connect.WithSchema(mergeRequestServiceMethods.ByName("ResolveComment")), | |
| 319 | + | connect.WithHandlerOptions(opts...), | |
| 320 | + | ) | |
| 321 | + | mergeRequestServiceCloseMergeRequestHandler := connect.NewUnaryHandler( | |
| 322 | + | MergeRequestServiceCloseMergeRequestProcedure, | |
| 323 | + | svc.CloseMergeRequest, | |
| 324 | + | connect.WithSchema(mergeRequestServiceMethods.ByName("CloseMergeRequest")), | |
| 325 | + | connect.WithHandlerOptions(opts...), | |
| 326 | + | ) | |
| 327 | + | mergeRequestServiceMergeMergeRequestHandler := connect.NewUnaryHandler( | |
| 328 | + | MergeRequestServiceMergeMergeRequestProcedure, | |
| 329 | + | svc.MergeMergeRequest, | |
| 330 | + | connect.WithSchema(mergeRequestServiceMethods.ByName("MergeMergeRequest")), | |
| 331 | + | connect.WithHandlerOptions(opts...), | |
| 332 | + | ) | |
| 333 | + | mergeRequestServiceMarkReadHandler := connect.NewUnaryHandler( | |
| 334 | + | MergeRequestServiceMarkReadProcedure, | |
| 335 | + | svc.MarkRead, | |
| 336 | + | connect.WithSchema(mergeRequestServiceMethods.ByName("MarkRead")), | |
| 337 | + | connect.WithHandlerOptions(opts...), | |
| 338 | + | ) | |
| 339 | + | return "/ermite.MergeRequestService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | |
| 340 | + | switch r.URL.Path { | |
| 341 | + | case MergeRequestServiceCreateMergeRequestProcedure: | |
| 342 | + | mergeRequestServiceCreateMergeRequestHandler.ServeHTTP(w, r) | |
| 343 | + | case MergeRequestServiceListMergeRequestsProcedure: | |
| 344 | + | mergeRequestServiceListMergeRequestsHandler.ServeHTTP(w, r) | |
| 345 | + | case MergeRequestServiceGetMergeRequestProcedure: | |
| 346 | + | mergeRequestServiceGetMergeRequestHandler.ServeHTTP(w, r) | |
| 347 | + | case MergeRequestServiceAddCommentProcedure: | |
| 348 | + | mergeRequestServiceAddCommentHandler.ServeHTTP(w, r) | |
| 349 | + | case MergeRequestServiceResolveCommentProcedure: | |
| 350 | + | mergeRequestServiceResolveCommentHandler.ServeHTTP(w, r) | |
| 351 | + | case MergeRequestServiceCloseMergeRequestProcedure: | |
| 352 | + | mergeRequestServiceCloseMergeRequestHandler.ServeHTTP(w, r) | |
| 353 | + | case MergeRequestServiceMergeMergeRequestProcedure: | |
| 354 | + | mergeRequestServiceMergeMergeRequestHandler.ServeHTTP(w, r) | |
| 355 | + | case MergeRequestServiceMarkReadProcedure: | |
| 356 | + | mergeRequestServiceMarkReadHandler.ServeHTTP(w, r) | |
| 357 | + | default: | |
| 358 | + | http.NotFound(w, r) | |
| 359 | + | } | |
| 360 | + | }) | |
| 361 | + | } | |
| 362 | + | ||
| 363 | + | // UnimplementedMergeRequestServiceHandler returns CodeUnimplemented from all methods. | |
| 364 | + | type UnimplementedMergeRequestServiceHandler struct{} | |
| 365 | + | ||
| 366 | + | func (UnimplementedMergeRequestServiceHandler) CreateMergeRequest(context.Context, *connect.Request[ermite.CreateMergeRequestRequest]) (*connect.Response[ermite.CreateMergeRequestResponse], error) { | |
| 367 | + | return nil, connect.NewError(connect.CodeUnimplemented, errors.New("ermite.MergeRequestService.CreateMergeRequest is not implemented")) | |
| 368 | + | } | |
| 369 | + | ||
| 370 | + | func (UnimplementedMergeRequestServiceHandler) ListMergeRequests(context.Context, *connect.Request[ermite.ListMergeRequestsRequest]) (*connect.Response[ermite.ListMergeRequestsResponse], error) { | |
| 371 | + | return nil, connect.NewError(connect.CodeUnimplemented, errors.New("ermite.MergeRequestService.ListMergeRequests is not implemented")) | |
| 372 | + | } | |
| 373 | + | ||
| 374 | + | func (UnimplementedMergeRequestServiceHandler) GetMergeRequest(context.Context, *connect.Request[ermite.GetMergeRequestRequest]) (*connect.Response[ermite.GetMergeRequestResponse], error) { | |
| 375 | + | return nil, connect.NewError(connect.CodeUnimplemented, errors.New("ermite.MergeRequestService.GetMergeRequest is not implemented")) | |
| 376 | + | } | |
| 377 | + | ||
| 378 | + | func (UnimplementedMergeRequestServiceHandler) AddComment(context.Context, *connect.Request[ermite.AddCommentRequest]) (*connect.Response[ermite.AddCommentResponse], error) { | |
| 379 | + | return nil, connect.NewError(connect.CodeUnimplemented, errors.New("ermite.MergeRequestService.AddComment is not implemented")) | |
| 380 | + | } | |
| 381 | + | ||
| 382 | + | func (UnimplementedMergeRequestServiceHandler) ResolveComment(context.Context, *connect.Request[ermite.ResolveCommentRequest]) (*connect.Response[ermite.ResolveCommentResponse], error) { | |
| 383 | + | return nil, connect.NewError(connect.CodeUnimplemented, errors.New("ermite.MergeRequestService.ResolveComment is not implemented")) | |
| 384 | + | } | |
| 385 | + | ||
| 386 | + | func (UnimplementedMergeRequestServiceHandler) CloseMergeRequest(context.Context, *connect.Request[ermite.CloseMergeRequestRequest]) (*connect.Response[ermite.CloseMergeRequestResponse], error) { | |
| 387 | + | return nil, connect.NewError(connect.CodeUnimplemented, errors.New("ermite.MergeRequestService.CloseMergeRequest is not implemented")) | |
| 388 | + | } | |
| 389 | + | ||
| 390 | + | func (UnimplementedMergeRequestServiceHandler) MergeMergeRequest(context.Context, *connect.Request[ermite.MergeMergeRequestRequest]) (*connect.Response[ermite.MergeMergeRequestResponse], error) { | |
| 391 | + | return nil, connect.NewError(connect.CodeUnimplemented, errors.New("ermite.MergeRequestService.MergeMergeRequest is not implemented")) | |
| 392 | + | } | |
| 393 | + | ||
| 394 | + | func (UnimplementedMergeRequestServiceHandler) MarkRead(context.Context, *connect.Request[ermite.MarkReadRequest]) (*connect.Response[ermite.MarkReadResponse], error) { | |
| 395 | + | return nil, connect.NewError(connect.CodeUnimplemented, errors.New("ermite.MergeRequestService.MarkRead is not implemented")) | |
| 396 | + | } | |
| @@ -0,0 +1,396 @@ | |||||
| 1 | + | // SPDX-License-Identifier: MIT | |||
| 2 | + | ||||
| 3 | + | // Code generated by protoc-gen-connect-go. DO NOT EDIT. | |||
| 4 | + | // | |||
| 5 | + | // Source: ermite/merge_request.proto | |||
| 6 | + | ||||
| 7 | + | package ermiteconnect | |||
| 8 | + | ||||
| 9 | + | import ( | |||
| 10 | + | ermite "bnema.dev/ermite-api/gen/ermite" | |||
| 11 | + | connect "connectrpc.com/connect" | |||
| 12 | + | context "context" | |||
| 13 | + | errors "errors" | |||
| 14 | + | http "net/http" | |||
| 15 | + | strings "strings" | |||
| 16 | + | ) | |||
| 17 | + | ||||
| 18 | + | // This is a compile-time assertion to ensure that this generated file and the connect package are | |||
| 19 | + | // compatible. If you get a compiler error that this constant is not defined, this code was | |||
| 20 | + | // generated with a version of connect newer than the one compiled into your binary. You can fix the | |||
| 21 | + | // problem by either regenerating this code with an older version of connect or updating the connect | |||
| 22 | + | // version compiled into your binary. | |||
| 23 | + | const _ = connect.IsAtLeastVersion1_13_0 | |||
| 24 | + | ||||
| 25 | + | const ( | |||
| 26 | + | // MergeRequestServiceName is the fully-qualified name of the MergeRequestService service. | |||
| 27 | + | MergeRequestServiceName = "ermite.MergeRequestService" | |||
| 28 | + | ) | |||
| 29 | + | ||||
| 30 | + | // These constants are the fully-qualified names of the RPCs defined in this package. They're | |||
| 31 | + | // exposed at runtime as Spec.Procedure and as the final two segments of the HTTP route. | |||
| 32 | + | // | |||
| 33 | + | // Note that these are different from the fully-qualified method names used by | |||
| 34 | + | // google.golang.org/protobuf/reflect/protoreflect. To convert from these constants to | |||
| 35 | + | // reflection-formatted method names, remove the leading slash and convert the remaining slash to a | |||
| 36 | + | // period. | |||
| 37 | + | const ( | |||
| 38 | + | // MergeRequestServiceCreateMergeRequestProcedure is the fully-qualified name of the | |||
| 39 | + | // MergeRequestService's CreateMergeRequest RPC. | |||
| 40 | + | MergeRequestServiceCreateMergeRequestProcedure = "/ermite.MergeRequestService/CreateMergeRequest" | |||
| 41 | + | // MergeRequestServiceListMergeRequestsProcedure is the fully-qualified name of the | |||
| 42 | + | // MergeRequestService's ListMergeRequests RPC. | |||
| 43 | + | MergeRequestServiceListMergeRequestsProcedure = "/ermite.MergeRequestService/ListMergeRequests" | |||
| 44 | + | // MergeRequestServiceGetMergeRequestProcedure is the fully-qualified name of the | |||
| 45 | + | // MergeRequestService's GetMergeRequest RPC. | |||
| 46 | + | MergeRequestServiceGetMergeRequestProcedure = "/ermite.MergeRequestService/GetMergeRequest" | |||
| 47 | + | // MergeRequestServiceAddCommentProcedure is the fully-qualified name of the MergeRequestService's | |||
| 48 | + | // AddComment RPC. | |||
| 49 | + | MergeRequestServiceAddCommentProcedure = "/ermite.MergeRequestService/AddComment" | |||
| 50 | + | // MergeRequestServiceResolveCommentProcedure is the fully-qualified name of the | |||
| 51 | + | // MergeRequestService's ResolveComment RPC. | |||
| 52 | + | MergeRequestServiceResolveCommentProcedure = "/ermite.MergeRequestService/ResolveComment" | |||
| 53 | + | // MergeRequestServiceCloseMergeRequestProcedure is the fully-qualified name of the | |||
| 54 | + | // MergeRequestService's CloseMergeRequest RPC. | |||
| 55 | + | MergeRequestServiceCloseMergeRequestProcedure = "/ermite.MergeRequestService/CloseMergeRequest" | |||
| 56 | + | // MergeRequestServiceMergeMergeRequestProcedure is the fully-qualified name of the | |||
| 57 | + | // MergeRequestService's MergeMergeRequest RPC. | |||
| 58 | + | MergeRequestServiceMergeMergeRequestProcedure = "/ermite.MergeRequestService/MergeMergeRequest" | |||
| 59 | + | // MergeRequestServiceMarkReadProcedure is the fully-qualified name of the MergeRequestService's | |||
| 60 | + | // MarkRead RPC. | |||
| 61 | + | MergeRequestServiceMarkReadProcedure = "/ermite.MergeRequestService/MarkRead" | |||
| 62 | + | ) | |||
| 63 | + | ||||
| 64 | + | // MergeRequestServiceClient is a client for the ermite.MergeRequestService service. | |||
| 65 | + | type MergeRequestServiceClient interface { | |||
| 66 | + | // CreateMergeRequest opens a merge request. Needs the mr:write scope. Fails | |||
| 67 | + | // with invalid_argument if a text rule is broken, if a branch does not exist | |||
| 68 | + | // or if source and target are the same branch, and with already_exists if an | |||
| 69 | + | // open merge request already has the same source and target. | |||
| 70 | + | CreateMergeRequest(context.Context, *connect.Request[ermite.CreateMergeRequestRequest]) (*connect.Response[ermite.CreateMergeRequestResponse], error) | |||
| 71 | + | // ListMergeRequests lists the merge requests of a repository, highest | |||
| 72 | + | // number (newest) first, optionally restricted to one state. The listed | |||
| 73 | + | // merge requests carry no diff or comments; head_id is set. Fails with | |||
| 74 | + | // not_found if the repository does not exist or is not readable. | |||
| 75 | + | ListMergeRequests(context.Context, *connect.Request[ermite.ListMergeRequestsRequest]) (*connect.Response[ermite.ListMergeRequestsResponse], error) | |||
| 76 | + | // GetMergeRequest returns one merge request with its commits, its diff and | |||
| 77 | + | // its comments. The diff compares the target with the head (what the merge | |||
| 78 | + | // would bring: "target...head"), or, with since_last_read, the head the | |||
| 79 | + | // caller last marked read with the current head. Fails with not_found if | |||
| 80 | + | // the repository or the number is unknown. | |||
| 81 | + | GetMergeRequest(context.Context, *connect.Request[ermite.GetMergeRequestRequest]) (*connect.Response[ermite.GetMergeRequestResponse], error) | |||
| 82 | + | // AddComment adds a general comment or a comment on a line of the diff. | |||
| 83 | + | // Needs the mr:write scope. Fails with invalid_argument if the text breaks | |||
| 84 | + | // a rule or if path, line and side do not designate a line of the current | |||
| 85 | + | // diff of the merge request, and with failed_precondition if the merge | |||
| 86 | + | // request is not open. | |||
| 87 | + | AddComment(context.Context, *connect.Request[ermite.AddCommentRequest]) (*connect.Response[ermite.AddCommentResponse], error) | |||
| 88 | + | // ResolveComment marks a comment resolved or unresolved. Needs the mr:write | |||
| 89 | + | // scope. Fails with not_found if the comment is unknown and with | |||
| 90 | + | // failed_precondition if the merge request is not open. Setting the state | |||
| 91 | + | // the comment already has succeeds and changes nothing. | |||
| 92 | + | ResolveComment(context.Context, *connect.Request[ermite.ResolveCommentRequest]) (*connect.Response[ermite.ResolveCommentResponse], error) | |||
| 93 | + | // CloseMergeRequest closes an open merge request without merging it. Needs | |||
| 94 | + | // the mr:write scope. Fails with failed_precondition if the merge request | |||
| 95 | + | // is not open. A closed merge request cannot be reopened: open a new one. | |||
| 96 | + | CloseMergeRequest(context.Context, *connect.Request[ermite.CloseMergeRequestRequest]) (*connect.Response[ermite.CloseMergeRequestResponse], error) | |||
| 97 | + | // MergeMergeRequest merges an open merge request. Needs the mr:merge scope. | |||
| 98 | + | // The caller passes the head it reviewed: the server merges only if the | |||
| 99 | + | // source branch still points to it, so a push between review and merge is | |||
| 100 | + | // never merged unseen. Fails with invalid_argument if head_id is empty or | |||
| 101 | + | // not a commit id, and with failed_precondition if the merge request is not | |||
| 102 | + | // open, if the source branch no longer points to head_id ("branch moved, | |||
| 103 | + | // read again"), if the target is not an ancestor of the head (rebase and | |||
| 104 | + | // push again), if the mode is not allowed by RepoSettings, or if a check | |||
| 105 | + | // fails and RepoSettings.failing_checks_block is set. Merges of one | |||
| 106 | + | // repository run one at a time. Repeating a call that succeeded fails with | |||
| 107 | + | // failed_precondition (not open). On success the server publishes | |||
| 108 | + | // MergeRequestMerged then Pushed for the target branch. | |||
| 109 | + | MergeMergeRequest(context.Context, *connect.Request[ermite.MergeMergeRequestRequest]) (*connect.Response[ermite.MergeMergeRequestResponse], error) | |||
| 110 | + | // MarkRead records the head the caller has reviewed, for the since_last_read | |||
| 111 | + | // option of GetMergeRequest. There is one read position per merge request, | |||
| 112 | + | // the reviewer's. Needs the mr:write scope. Marking a commit that does not | |||
| 113 | + | // exist in the repository is invalid_argument. | |||
| 114 | + | MarkRead(context.Context, *connect.Request[ermite.MarkReadRequest]) (*connect.Response[ermite.MarkReadResponse], error) | |||
| 115 | + | } | |||
| 116 | + | ||||
| 117 | + | // NewMergeRequestServiceClient constructs a client for the ermite.MergeRequestService service. By | |||
| 118 | + | // default, it uses the Connect protocol with the binary Protobuf Codec, asks for gzipped responses, | |||
| 119 | + | // and sends uncompressed requests. To use the gRPC or gRPC-Web protocols, supply the | |||
| 120 | + | // connect.WithGRPC() or connect.WithGRPCWeb() options. | |||
| 121 | + | // | |||
| 122 | + | // The URL supplied here should be the base URL for the Connect or gRPC server (for example, | |||
| 123 | + | // http://api.acme.com or https://acme.com/grpc). | |||
| 124 | + | func NewMergeRequestServiceClient(httpClient connect.HTTPClient, baseURL string, opts ...connect.ClientOption) MergeRequestServiceClient { | |||
| 125 | + | baseURL = strings.TrimRight(baseURL, "/") | |||
| 126 | + | mergeRequestServiceMethods := ermite.File_ermite_merge_request_proto.Services().ByName("MergeRequestService").Methods() | |||
| 127 | + | return &mergeRequestServiceClient{ | |||
| 128 | + | createMergeRequest: connect.NewClient[ermite.CreateMergeRequestRequest, ermite.CreateMergeRequestResponse]( | |||
| 129 | + | httpClient, | |||
| 130 | + | baseURL+MergeRequestServiceCreateMergeRequestProcedure, | |||
| 131 | + | connect.WithSchema(mergeRequestServiceMethods.ByName("CreateMergeRequest")), | |||
| 132 | + | connect.WithClientOptions(opts...), | |||
| 133 | + | ), | |||
| 134 | + | listMergeRequests: connect.NewClient[ermite.ListMergeRequestsRequest, ermite.ListMergeRequestsResponse]( | |||
| 135 | + | httpClient, | |||
| 136 | + | baseURL+MergeRequestServiceListMergeRequestsProcedure, | |||
| 137 | + | connect.WithSchema(mergeRequestServiceMethods.ByName("ListMergeRequests")), | |||
| 138 | + | connect.WithClientOptions(opts...), | |||
| 139 | + | ), | |||
| 140 | + | getMergeRequest: connect.NewClient[ermite.GetMergeRequestRequest, ermite.GetMergeRequestResponse]( | |||
| 141 | + | httpClient, | |||
| 142 | + | baseURL+MergeRequestServiceGetMergeRequestProcedure, | |||
| 143 | + | connect.WithSchema(mergeRequestServiceMethods.ByName("GetMergeRequest")), | |||
| 144 | + | connect.WithClientOptions(opts...), | |||
| 145 | + | ), | |||
| 146 | + | addComment: connect.NewClient[ermite.AddCommentRequest, ermite.AddCommentResponse]( | |||
| 147 | + | httpClient, | |||
| 148 | + | baseURL+MergeRequestServiceAddCommentProcedure, | |||
| 149 | + | connect.WithSchema(mergeRequestServiceMethods.ByName("AddComment")), | |||
| 150 | + | connect.WithClientOptions(opts...), | |||
| 151 | + | ), | |||
| 152 | + | resolveComment: connect.NewClient[ermite.ResolveCommentRequest, ermite.ResolveCommentResponse]( | |||
| 153 | + | httpClient, | |||
| 154 | + | baseURL+MergeRequestServiceResolveCommentProcedure, | |||
| 155 | + | connect.WithSchema(mergeRequestServiceMethods.ByName("ResolveComment")), | |||
| 156 | + | connect.WithClientOptions(opts...), | |||
| 157 | + | ), | |||
| 158 | + | closeMergeRequest: connect.NewClient[ermite.CloseMergeRequestRequest, ermite.CloseMergeRequestResponse]( | |||
| 159 | + | httpClient, | |||
| 160 | + | baseURL+MergeRequestServiceCloseMergeRequestProcedure, | |||
| 161 | + | connect.WithSchema(mergeRequestServiceMethods.ByName("CloseMergeRequest")), | |||
| 162 | + | connect.WithClientOptions(opts...), | |||
| 163 | + | ), | |||
| 164 | + | mergeMergeRequest: connect.NewClient[ermite.MergeMergeRequestRequest, ermite.MergeMergeRequestResponse]( | |||
| 165 | + | httpClient, | |||
| 166 | + | baseURL+MergeRequestServiceMergeMergeRequestProcedure, | |||
| 167 | + | connect.WithSchema(mergeRequestServiceMethods.ByName("MergeMergeRequest")), | |||
| 168 | + | connect.WithClientOptions(opts...), | |||
| 169 | + | ), | |||
| 170 | + | markRead: connect.NewClient[ermite.MarkReadRequest, ermite.MarkReadResponse]( | |||
| 171 | + | httpClient, | |||
| 172 | + | baseURL+MergeRequestServiceMarkReadProcedure, | |||
| 173 | + | connect.WithSchema(mergeRequestServiceMethods.ByName("MarkRead")), | |||
| 174 | + | connect.WithClientOptions(opts...), | |||
| 175 | + | ), | |||
| 176 | + | } | |||
| 177 | + | } | |||
| 178 | + | ||||
| 179 | + | // mergeRequestServiceClient implements MergeRequestServiceClient. | |||
| 180 | + | type mergeRequestServiceClient struct { | |||
| 181 | + | createMergeRequest *connect.Client[ermite.CreateMergeRequestRequest, ermite.CreateMergeRequestResponse] | |||
| 182 | + | listMergeRequests *connect.Client[ermite.ListMergeRequestsRequest, ermite.ListMergeRequestsResponse] | |||
| 183 | + | getMergeRequest *connect.Client[ermite.GetMergeRequestRequest, ermite.GetMergeRequestResponse] | |||
| 184 | + | addComment *connect.Client[ermite.AddCommentRequest, ermite.AddCommentResponse] | |||
| 185 | + | resolveComment *connect.Client[ermite.ResolveCommentRequest, ermite.ResolveCommentResponse] | |||
| 186 | + | closeMergeRequest *connect.Client[ermite.CloseMergeRequestRequest, ermite.CloseMergeRequestResponse] | |||
| 187 | + | mergeMergeRequest *connect.Client[ermite.MergeMergeRequestRequest, ermite.MergeMergeRequestResponse] | |||
| 188 | + | markRead *connect.Client[ermite.MarkReadRequest, ermite.MarkReadResponse] | |||
| 189 | + | } | |||
| 190 | + | ||||
| 191 | + | // CreateMergeRequest calls ermite.MergeRequestService.CreateMergeRequest. | |||
| 192 | + | func (c *mergeRequestServiceClient) CreateMergeRequest(ctx context.Context, req *connect.Request[ermite.CreateMergeRequestRequest]) (*connect.Response[ermite.CreateMergeRequestResponse], error) { | |||
| 193 | + | return c.createMergeRequest.CallUnary(ctx, req) | |||
| 194 | + | } | |||
| 195 | + | ||||
| 196 | + | // ListMergeRequests calls ermite.MergeRequestService.ListMergeRequests. | |||
| 197 | + | func (c *mergeRequestServiceClient) ListMergeRequests(ctx context.Context, req *connect.Request[ermite.ListMergeRequestsRequest]) (*connect.Response[ermite.ListMergeRequestsResponse], error) { | |||
| 198 | + | return c.listMergeRequests.CallUnary(ctx, req) | |||
| 199 | + | } | |||
| 200 | + | ||||
| 201 | + | // GetMergeRequest calls ermite.MergeRequestService.GetMergeRequest. | |||
| 202 | + | func (c *mergeRequestServiceClient) GetMergeRequest(ctx context.Context, req *connect.Request[ermite.GetMergeRequestRequest]) (*connect.Response[ermite.GetMergeRequestResponse], error) { | |||
| 203 | + | return c.getMergeRequest.CallUnary(ctx, req) | |||
| 204 | + | } | |||
| 205 | + | ||||
| 206 | + | // AddComment calls ermite.MergeRequestService.AddComment. | |||
| 207 | + | func (c *mergeRequestServiceClient) AddComment(ctx context.Context, req *connect.Request[ermite.AddCommentRequest]) (*connect.Response[ermite.AddCommentResponse], error) { | |||
| 208 | + | return c.addComment.CallUnary(ctx, req) | |||
| 209 | + | } | |||
| 210 | + | ||||
| 211 | + | // ResolveComment calls ermite.MergeRequestService.ResolveComment. | |||
| 212 | + | func (c *mergeRequestServiceClient) ResolveComment(ctx context.Context, req *connect.Request[ermite.ResolveCommentRequest]) (*connect.Response[ermite.ResolveCommentResponse], error) { | |||
| 213 | + | return c.resolveComment.CallUnary(ctx, req) | |||
| 214 | + | } | |||
| 215 | + | ||||
| 216 | + | // CloseMergeRequest calls ermite.MergeRequestService.CloseMergeRequest. | |||
| 217 | + | func (c *mergeRequestServiceClient) CloseMergeRequest(ctx context.Context, req *connect.Request[ermite.CloseMergeRequestRequest]) (*connect.Response[ermite.CloseMergeRequestResponse], error) { | |||
| 218 | + | return c.closeMergeRequest.CallUnary(ctx, req) | |||
| 219 | + | } | |||
| 220 | + | ||||
| 221 | + | // MergeMergeRequest calls ermite.MergeRequestService.MergeMergeRequest. | |||
| 222 | + | func (c *mergeRequestServiceClient) MergeMergeRequest(ctx context.Context, req *connect.Request[ermite.MergeMergeRequestRequest]) (*connect.Response[ermite.MergeMergeRequestResponse], error) { | |||
| 223 | + | return c.mergeMergeRequest.CallUnary(ctx, req) | |||
| 224 | + | } | |||
| 225 | + | ||||
| 226 | + | // MarkRead calls ermite.MergeRequestService.MarkRead. | |||
| 227 | + | func (c *mergeRequestServiceClient) MarkRead(ctx context.Context, req *connect.Request[ermite.MarkReadRequest]) (*connect.Response[ermite.MarkReadResponse], error) { | |||
| 228 | + | return c.markRead.CallUnary(ctx, req) | |||
| 229 | + | } | |||
| 230 | + | ||||
| 231 | + | // MergeRequestServiceHandler is an implementation of the ermite.MergeRequestService service. | |||
| 232 | + | type MergeRequestServiceHandler interface { | |||
| 233 | + | // CreateMergeRequest opens a merge request. Needs the mr:write scope. Fails | |||
| 234 | + | // with invalid_argument if a text rule is broken, if a branch does not exist | |||
| 235 | + | // or if source and target are the same branch, and with already_exists if an | |||
| 236 | + | // open merge request already has the same source and target. | |||
| 237 | + | CreateMergeRequest(context.Context, *connect.Request[ermite.CreateMergeRequestRequest]) (*connect.Response[ermite.CreateMergeRequestResponse], error) | |||
| 238 | + | // ListMergeRequests lists the merge requests of a repository, highest | |||
| 239 | + | // number (newest) first, optionally restricted to one state. The listed | |||
| 240 | + | // merge requests carry no diff or comments; head_id is set. Fails with | |||
| 241 | + | // not_found if the repository does not exist or is not readable. | |||
| 242 | + | ListMergeRequests(context.Context, *connect.Request[ermite.ListMergeRequestsRequest]) (*connect.Response[ermite.ListMergeRequestsResponse], error) | |||
| 243 | + | // GetMergeRequest returns one merge request with its commits, its diff and | |||
| 244 | + | // its comments. The diff compares the target with the head (what the merge | |||
| 245 | + | // would bring: "target...head"), or, with since_last_read, the head the | |||
| 246 | + | // caller last marked read with the current head. Fails with not_found if | |||
| 247 | + | // the repository or the number is unknown. | |||
| 248 | + | GetMergeRequest(context.Context, *connect.Request[ermite.GetMergeRequestRequest]) (*connect.Response[ermite.GetMergeRequestResponse], error) | |||
| 249 | + | // AddComment adds a general comment or a comment on a line of the diff. | |||
| 250 | + | // Needs the mr:write scope. Fails with invalid_argument if the text breaks | |||
| 251 | + | // a rule or if path, line and side do not designate a line of the current | |||
| 252 | + | // diff of the merge request, and with failed_precondition if the merge | |||
| 253 | + | // request is not open. | |||
| 254 | + | AddComment(context.Context, *connect.Request[ermite.AddCommentRequest]) (*connect.Response[ermite.AddCommentResponse], error) | |||
| 255 | + | // ResolveComment marks a comment resolved or unresolved. Needs the mr:write | |||
| 256 | + | // scope. Fails with not_found if the comment is unknown and with | |||
| 257 | + | // failed_precondition if the merge request is not open. Setting the state | |||
| 258 | + | // the comment already has succeeds and changes nothing. | |||
| 259 | + | ResolveComment(context.Context, *connect.Request[ermite.ResolveCommentRequest]) (*connect.Response[ermite.ResolveCommentResponse], error) | |||
| 260 | + | // CloseMergeRequest closes an open merge request without merging it. Needs | |||
| 261 | + | // the mr:write scope. Fails with failed_precondition if the merge request | |||
| 262 | + | // is not open. A closed merge request cannot be reopened: open a new one. | |||
| 263 | + | CloseMergeRequest(context.Context, *connect.Request[ermite.CloseMergeRequestRequest]) (*connect.Response[ermite.CloseMergeRequestResponse], error) | |||
| 264 | + | // MergeMergeRequest merges an open merge request. Needs the mr:merge scope. | |||
| 265 | + | // The caller passes the head it reviewed: the server merges only if the | |||
| 266 | + | // source branch still points to it, so a push between review and merge is | |||
| 267 | + | // never merged unseen. Fails with invalid_argument if head_id is empty or | |||
| 268 | + | // not a commit id, and with failed_precondition if the merge request is not | |||
| 269 | + | // open, if the source branch no longer points to head_id ("branch moved, | |||
| 270 | + | // read again"), if the target is not an ancestor of the head (rebase and | |||
| 271 | + | // push again), if the mode is not allowed by RepoSettings, or if a check | |||
| 272 | + | // fails and RepoSettings.failing_checks_block is set. Merges of one | |||
| 273 | + | // repository run one at a time. Repeating a call that succeeded fails with | |||
| 274 | + | // failed_precondition (not open). On success the server publishes | |||
| 275 | + | // MergeRequestMerged then Pushed for the target branch. | |||
| 276 | + | MergeMergeRequest(context.Context, *connect.Request[ermite.MergeMergeRequestRequest]) (*connect.Response[ermite.MergeMergeRequestResponse], error) | |||
| 277 | + | // MarkRead records the head the caller has reviewed, for the since_last_read | |||
| 278 | + | // option of GetMergeRequest. There is one read position per merge request, | |||
| 279 | + | // the reviewer's. Needs the mr:write scope. Marking a commit that does not | |||
| 280 | + | // exist in the repository is invalid_argument. | |||
| 281 | + | MarkRead(context.Context, *connect.Request[ermite.MarkReadRequest]) (*connect.Response[ermite.MarkReadResponse], error) | |||
| 282 | + | } | |||
| 283 | + | ||||
| 284 | + | // NewMergeRequestServiceHandler builds an HTTP handler from the service implementation. It returns | |||
| 285 | + | // the path on which to mount the handler and the handler itself. | |||
| 286 | + | // | |||
| 287 | + | // By default, handlers support the Connect, gRPC, and gRPC-Web protocols with the binary Protobuf | |||
| 288 | + | // and JSON codecs. They also support gzip compression. | |||
| 289 | + | func NewMergeRequestServiceHandler(svc MergeRequestServiceHandler, opts ...connect.HandlerOption) (string, http.Handler) { | |||
| 290 | + | mergeRequestServiceMethods := ermite.File_ermite_merge_request_proto.Services().ByName("MergeRequestService").Methods() | |||
| 291 | + | mergeRequestServiceCreateMergeRequestHandler := connect.NewUnaryHandler( | |||
| 292 | + | MergeRequestServiceCreateMergeRequestProcedure, | |||
| 293 | + | svc.CreateMergeRequest, | |||
| 294 | + | connect.WithSchema(mergeRequestServiceMethods.ByName("CreateMergeRequest")), | |||
| 295 | + | connect.WithHandlerOptions(opts...), | |||
| 296 | + | ) | |||
| 297 | + | mergeRequestServiceListMergeRequestsHandler := connect.NewUnaryHandler( | |||
| 298 | + | MergeRequestServiceListMergeRequestsProcedure, | |||
| 299 | + | svc.ListMergeRequests, | |||
| 300 | + | connect.WithSchema(mergeRequestServiceMethods.ByName("ListMergeRequests")), | |||
| 301 | + | connect.WithHandlerOptions(opts...), | |||
| 302 | + | ) | |||
| 303 | + | mergeRequestServiceGetMergeRequestHandler := connect.NewUnaryHandler( | |||
| 304 | + | MergeRequestServiceGetMergeRequestProcedure, | |||
| 305 | + | svc.GetMergeRequest, | |||
| 306 | + | connect.WithSchema(mergeRequestServiceMethods.ByName("GetMergeRequest")), | |||
| 307 | + | connect.WithHandlerOptions(opts...), | |||
| 308 | + | ) | |||
| 309 | + | mergeRequestServiceAddCommentHandler := connect.NewUnaryHandler( | |||
| 310 | + | MergeRequestServiceAddCommentProcedure, | |||
| 311 | + | svc.AddComment, | |||
| 312 | + | connect.WithSchema(mergeRequestServiceMethods.ByName("AddComment")), | |||
| 313 | + | connect.WithHandlerOptions(opts...), | |||
| 314 | + | ) | |||
| 315 | + | mergeRequestServiceResolveCommentHandler := connect.NewUnaryHandler( | |||
| 316 | + | MergeRequestServiceResolveCommentProcedure, | |||
| 317 | + | svc.ResolveComment, | |||
| 318 | + | connect.WithSchema(mergeRequestServiceMethods.ByName("ResolveComment")), | |||
| 319 | + | connect.WithHandlerOptions(opts...), | |||
| 320 | + | ) | |||
| 321 | + | mergeRequestServiceCloseMergeRequestHandler := connect.NewUnaryHandler( | |||
| 322 | + | MergeRequestServiceCloseMergeRequestProcedure, | |||
| 323 | + | svc.CloseMergeRequest, | |||
| 324 | + | connect.WithSchema(mergeRequestServiceMethods.ByName("CloseMergeRequest")), | |||
| 325 | + | connect.WithHandlerOptions(opts...), | |||
| 326 | + | ) | |||
| 327 | + | mergeRequestServiceMergeMergeRequestHandler := connect.NewUnaryHandler( | |||
| 328 | + | MergeRequestServiceMergeMergeRequestProcedure, | |||
| 329 | + | svc.MergeMergeRequest, | |||
| 330 | + | connect.WithSchema(mergeRequestServiceMethods.ByName("MergeMergeRequest")), | |||
| 331 | + | connect.WithHandlerOptions(opts...), | |||
| 332 | + | ) | |||
| 333 | + | mergeRequestServiceMarkReadHandler := connect.NewUnaryHandler( | |||
| 334 | + | MergeRequestServiceMarkReadProcedure, | |||
| 335 | + | svc.MarkRead, | |||
| 336 | + | connect.WithSchema(mergeRequestServiceMethods.ByName("MarkRead")), | |||
| 337 | + | connect.WithHandlerOptions(opts...), | |||
| 338 | + | ) | |||
| 339 | + | return "/ermite.MergeRequestService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | |||
| 340 | + | switch r.URL.Path { | |||
| 341 | + | case MergeRequestServiceCreateMergeRequestProcedure: | |||
| 342 | + | mergeRequestServiceCreateMergeRequestHandler.ServeHTTP(w, r) | |||
| 343 | + | case MergeRequestServiceListMergeRequestsProcedure: | |||
| 344 | + | mergeRequestServiceListMergeRequestsHandler.ServeHTTP(w, r) | |||
| 345 | + | case MergeRequestServiceGetMergeRequestProcedure: | |||
| 346 | + | mergeRequestServiceGetMergeRequestHandler.ServeHTTP(w, r) | |||
| 347 | + | case MergeRequestServiceAddCommentProcedure: | |||
| 348 | + | mergeRequestServiceAddCommentHandler.ServeHTTP(w, r) | |||
| 349 | + | case MergeRequestServiceResolveCommentProcedure: | |||
| 350 | + | mergeRequestServiceResolveCommentHandler.ServeHTTP(w, r) | |||
| 351 | + | case MergeRequestServiceCloseMergeRequestProcedure: | |||
| 352 | + | mergeRequestServiceCloseMergeRequestHandler.ServeHTTP(w, r) | |||
| 353 | + | case MergeRequestServiceMergeMergeRequestProcedure: | |||
| 354 | + | mergeRequestServiceMergeMergeRequestHandler.ServeHTTP(w, r) | |||
| 355 | + | case MergeRequestServiceMarkReadProcedure: | |||
| 356 | + | mergeRequestServiceMarkReadHandler.ServeHTTP(w, r) | |||
| 357 | + | default: | |||
| 358 | + | http.NotFound(w, r) | |||
| 359 | + | } | |||
| 360 | + | }) | |||
| 361 | + | } | |||
| 362 | + | ||||
| 363 | + | // UnimplementedMergeRequestServiceHandler returns CodeUnimplemented from all methods. | |||
| 364 | + | type UnimplementedMergeRequestServiceHandler struct{} | |||
| 365 | + | ||||
| 366 | + | func (UnimplementedMergeRequestServiceHandler) CreateMergeRequest(context.Context, *connect.Request[ermite.CreateMergeRequestRequest]) (*connect.Response[ermite.CreateMergeRequestResponse], error) { | |||
| 367 | + | return nil, connect.NewError(connect.CodeUnimplemented, errors.New("ermite.MergeRequestService.CreateMergeRequest is not implemented")) | |||
| 368 | + | } | |||
| 369 | + | ||||
| 370 | + | func (UnimplementedMergeRequestServiceHandler) ListMergeRequests(context.Context, *connect.Request[ermite.ListMergeRequestsRequest]) (*connect.Response[ermite.ListMergeRequestsResponse], error) { | |||
| 371 | + | return nil, connect.NewError(connect.CodeUnimplemented, errors.New("ermite.MergeRequestService.ListMergeRequests is not implemented")) | |||
| 372 | + | } | |||
| 373 | + | ||||
| 374 | + | func (UnimplementedMergeRequestServiceHandler) GetMergeRequest(context.Context, *connect.Request[ermite.GetMergeRequestRequest]) (*connect.Response[ermite.GetMergeRequestResponse], error) { | |||
| 375 | + | return nil, connect.NewError(connect.CodeUnimplemented, errors.New("ermite.MergeRequestService.GetMergeRequest is not implemented")) | |||
| 376 | + | } | |||
| 377 | + | ||||
| 378 | + | func (UnimplementedMergeRequestServiceHandler) AddComment(context.Context, *connect.Request[ermite.AddCommentRequest]) (*connect.Response[ermite.AddCommentResponse], error) { | |||
| 379 | + | return nil, connect.NewError(connect.CodeUnimplemented, errors.New("ermite.MergeRequestService.AddComment is not implemented")) | |||
| 380 | + | } | |||
| 381 | + | ||||
| 382 | + | func (UnimplementedMergeRequestServiceHandler) ResolveComment(context.Context, *connect.Request[ermite.ResolveCommentRequest]) (*connect.Response[ermite.ResolveCommentResponse], error) { | |||
| 383 | + | return nil, connect.NewError(connect.CodeUnimplemented, errors.New("ermite.MergeRequestService.ResolveComment is not implemented")) | |||
| 384 | + | } | |||
| 385 | + | ||||
| 386 | + | func (UnimplementedMergeRequestServiceHandler) CloseMergeRequest(context.Context, *connect.Request[ermite.CloseMergeRequestRequest]) (*connect.Response[ermite.CloseMergeRequestResponse], error) { | |||
| 387 | + | return nil, connect.NewError(connect.CodeUnimplemented, errors.New("ermite.MergeRequestService.CloseMergeRequest is not implemented")) | |||
| 388 | + | } | |||
| 389 | + | ||||
| 390 | + | func (UnimplementedMergeRequestServiceHandler) MergeMergeRequest(context.Context, *connect.Request[ermite.MergeMergeRequestRequest]) (*connect.Response[ermite.MergeMergeRequestResponse], error) { | |||
| 391 | + | return nil, connect.NewError(connect.CodeUnimplemented, errors.New("ermite.MergeRequestService.MergeMergeRequest is not implemented")) | |||
| 392 | + | } | |||
| 393 | + | ||||
| 394 | + | func (UnimplementedMergeRequestServiceHandler) MarkRead(context.Context, *connect.Request[ermite.MarkReadRequest]) (*connect.Response[ermite.MarkReadResponse], error) { | |||
| 395 | + | return nil, connect.NewError(connect.CodeUnimplemented, errors.New("ermite.MergeRequestService.MarkRead is not implemented")) | |||
| 396 | + | } | |||
M gen/ermite/ermiteconnect/repo.connect.go +8 -6
| @@ -54,12 +54,13 @@ type RepoServiceClient interface { | |||
| 54 | 54 | // GetRepo returns one repository. Fails with not_found if it does not exist | |
| 55 | 55 | // or is private and not readable by the caller. | |
| 56 | 56 | GetRepo(context.Context, *connect.Request[ermite.GetRepoRequest]) (*connect.Response[ermite.GetRepoResponse], error) | |
| 57 | - | // CreateRepo creates an empty repository. Needs the repo:write scope. Fails | |
| 57 | + | // CreateRepo creates an empty repository with the default settings. Needs | |
| 58 | + | // the repo:write scope. Fails | |
| 58 | 59 | // with already_exists if the name is taken and invalid_argument if the name | |
| 59 | 60 | // is not valid. | |
| 60 | 61 | CreateRepo(context.Context, *connect.Request[ermite.CreateRepoRequest]) (*connect.Response[ermite.CreateRepoResponse], error) | |
| 61 | - | // UpdateRepo changes the fields named in update_mask. Needs the repo:admin | |
| 62 | - | // scope. | |
| 62 | + | // UpdateRepo changes the fields named in update_mask, including the merge | |
| 63 | + | // settings. Needs the repo:admin scope. | |
| 63 | 64 | UpdateRepo(context.Context, *connect.Request[ermite.UpdateRepoRequest]) (*connect.Response[ermite.UpdateRepoResponse], error) | |
| 64 | 65 | // DeleteRepo deletes a repository. Needs the repo:admin scope. The server | |
| 65 | 66 | // moves the data aside rather than destroying it; there is no undelete RPC. | |
| @@ -151,12 +152,13 @@ type RepoServiceHandler interface { | |||
| 151 | 152 | // GetRepo returns one repository. Fails with not_found if it does not exist | |
| 152 | 153 | // or is private and not readable by the caller. | |
| 153 | 154 | GetRepo(context.Context, *connect.Request[ermite.GetRepoRequest]) (*connect.Response[ermite.GetRepoResponse], error) | |
| 154 | - | // CreateRepo creates an empty repository. Needs the repo:write scope. Fails | |
| 155 | + | // CreateRepo creates an empty repository with the default settings. Needs | |
| 156 | + | // the repo:write scope. Fails | |
| 155 | 157 | // with already_exists if the name is taken and invalid_argument if the name | |
| 156 | 158 | // is not valid. | |
| 157 | 159 | CreateRepo(context.Context, *connect.Request[ermite.CreateRepoRequest]) (*connect.Response[ermite.CreateRepoResponse], error) | |
| 158 | - | // UpdateRepo changes the fields named in update_mask. Needs the repo:admin | |
| 159 | - | // scope. | |
| 160 | + | // UpdateRepo changes the fields named in update_mask, including the merge | |
| 161 | + | // settings. Needs the repo:admin scope. | |
| 160 | 162 | UpdateRepo(context.Context, *connect.Request[ermite.UpdateRepoRequest]) (*connect.Response[ermite.UpdateRepoResponse], error) | |
| 161 | 163 | // DeleteRepo deletes a repository. Needs the repo:admin scope. The server | |
| 162 | 164 | // moves the data aside rather than destroying it; there is no undelete RPC. | |
| @@ -54,12 +54,13 @@ type RepoServiceClient interface { | |||||
| 54 | // GetRepo returns one repository. Fails with not_found if it does not exist | 54 | // GetRepo returns one repository. Fails with not_found if it does not exist | ||
| 55 | // or is private and not readable by the caller. | 55 | // or is private and not readable by the caller. | ||
| 56 | GetRepo(context.Context, *connect.Request[ermite.GetRepoRequest]) (*connect.Response[ermite.GetRepoResponse], error) | 56 | GetRepo(context.Context, *connect.Request[ermite.GetRepoRequest]) (*connect.Response[ermite.GetRepoResponse], error) | ||
| 57 | - | // CreateRepo creates an empty repository. Needs the repo:write scope. Fails | 57 | + | // CreateRepo creates an empty repository with the default settings. Needs |
| 58 | + | // the repo:write scope. Fails | |||
| 58 | // with already_exists if the name is taken and invalid_argument if the name | 59 | // with already_exists if the name is taken and invalid_argument if the name | ||
| 59 | // is not valid. | 60 | // is not valid. | ||
| 60 | CreateRepo(context.Context, *connect.Request[ermite.CreateRepoRequest]) (*connect.Response[ermite.CreateRepoResponse], error) | 61 | CreateRepo(context.Context, *connect.Request[ermite.CreateRepoRequest]) (*connect.Response[ermite.CreateRepoResponse], error) | ||
| 61 | - | // UpdateRepo changes the fields named in update_mask. Needs the repo:admin | 62 | + | // UpdateRepo changes the fields named in update_mask, including the merge |
| 62 | - | // scope. | 63 | + | // settings. Needs the repo:admin scope. |
| 63 | UpdateRepo(context.Context, *connect.Request[ermite.UpdateRepoRequest]) (*connect.Response[ermite.UpdateRepoResponse], error) | 64 | UpdateRepo(context.Context, *connect.Request[ermite.UpdateRepoRequest]) (*connect.Response[ermite.UpdateRepoResponse], error) | ||
| 64 | // DeleteRepo deletes a repository. Needs the repo:admin scope. The server | 65 | // DeleteRepo deletes a repository. Needs the repo:admin scope. The server | ||
| 65 | // moves the data aside rather than destroying it; there is no undelete RPC. | 66 | // moves the data aside rather than destroying it; there is no undelete RPC. | ||
| @@ -151,12 +152,13 @@ type RepoServiceHandler interface { | |||||
| 151 | // GetRepo returns one repository. Fails with not_found if it does not exist | 152 | // GetRepo returns one repository. Fails with not_found if it does not exist | ||
| 152 | // or is private and not readable by the caller. | 153 | // or is private and not readable by the caller. | ||
| 153 | GetRepo(context.Context, *connect.Request[ermite.GetRepoRequest]) (*connect.Response[ermite.GetRepoResponse], error) | 154 | GetRepo(context.Context, *connect.Request[ermite.GetRepoRequest]) (*connect.Response[ermite.GetRepoResponse], error) | ||
| 154 | - | // CreateRepo creates an empty repository. Needs the repo:write scope. Fails | 155 | + | // CreateRepo creates an empty repository with the default settings. Needs |
| 156 | + | // the repo:write scope. Fails | |||
| 155 | // with already_exists if the name is taken and invalid_argument if the name | 157 | // with already_exists if the name is taken and invalid_argument if the name | ||
| 156 | // is not valid. | 158 | // is not valid. | ||
| 157 | CreateRepo(context.Context, *connect.Request[ermite.CreateRepoRequest]) (*connect.Response[ermite.CreateRepoResponse], error) | 159 | CreateRepo(context.Context, *connect.Request[ermite.CreateRepoRequest]) (*connect.Response[ermite.CreateRepoResponse], error) | ||
| 158 | - | // UpdateRepo changes the fields named in update_mask. Needs the repo:admin | 160 | + | // UpdateRepo changes the fields named in update_mask, including the merge |
| 159 | - | // scope. | 161 | + | // settings. Needs the repo:admin scope. |
| 160 | UpdateRepo(context.Context, *connect.Request[ermite.UpdateRepoRequest]) (*connect.Response[ermite.UpdateRepoResponse], error) | 162 | UpdateRepo(context.Context, *connect.Request[ermite.UpdateRepoRequest]) (*connect.Response[ermite.UpdateRepoResponse], error) | ||
| 161 | // DeleteRepo deletes a repository. Needs the repo:admin scope. The server | 163 | // DeleteRepo deletes a repository. Needs the repo:admin scope. The server | ||
| 162 | // moves the data aside rather than destroying it; there is no undelete RPC. | 164 | // moves the data aside rather than destroying it; there is no undelete RPC. | ||
M gen/ermite/ermiteconnect/server.connect.go +40 -1
| @@ -38,6 +38,9 @@ const ( | |||
| 38 | 38 | // ServerServiceGetVersionProcedure is the fully-qualified name of the ServerService's GetVersion | |
| 39 | 39 | // RPC. | |
| 40 | 40 | ServerServiceGetVersionProcedure = "/ermite.ServerService/GetVersion" | |
| 41 | + | // ServerServiceGetSigningKeyProcedure is the fully-qualified name of the ServerService's | |
| 42 | + | // GetSigningKey RPC. | |
| 43 | + | ServerServiceGetSigningKeyProcedure = "/ermite.ServerService/GetSigningKey" | |
| 41 | 44 | ) | |
| 42 | 45 | ||
| 43 | 46 | // ServerServiceClient is a client for the ermite.ServerService service. | |
| @@ -46,6 +49,12 @@ type ServerServiceClient interface { | |||
| 46 | 49 | // contract it implements. It needs no authentication, so a client can call | |
| 47 | 50 | // it first to check compatibility. | |
| 48 | 51 | GetVersion(context.Context, *connect.Request[ermite.GetVersionRequest]) (*connect.Response[ermite.GetVersionResponse], error) | |
| 52 | + | // GetSigningKey returns the public key with which the server signs the | |
| 53 | + | // commits it creates (squash merges, see MergeMode). It needs no | |
| 54 | + | // authentication: the key is public, and anyone verifying a commit needs it. | |
| 55 | + | // Servers that implement it list "signing_key" in | |
| 56 | + | // GetVersionResponse.features. | |
| 57 | + | GetSigningKey(context.Context, *connect.Request[ermite.GetSigningKeyRequest]) (*connect.Response[ermite.GetSigningKeyResponse], error) | |
| 49 | 58 | } | |
| 50 | 59 | ||
| 51 | 60 | // NewServerServiceClient constructs a client for the ermite.ServerService service. By default, it | |
| @@ -65,12 +74,19 @@ func NewServerServiceClient(httpClient connect.HTTPClient, baseURL string, opts | |||
| 65 | 74 | connect.WithSchema(serverServiceMethods.ByName("GetVersion")), | |
| 66 | 75 | connect.WithClientOptions(opts...), | |
| 67 | 76 | ), | |
| 77 | + | getSigningKey: connect.NewClient[ermite.GetSigningKeyRequest, ermite.GetSigningKeyResponse]( | |
| 78 | + | httpClient, | |
| 79 | + | baseURL+ServerServiceGetSigningKeyProcedure, | |
| 80 | + | connect.WithSchema(serverServiceMethods.ByName("GetSigningKey")), | |
| 81 | + | connect.WithClientOptions(opts...), | |
| 82 | + | ), | |
| 68 | 83 | } | |
| 69 | 84 | } | |
| 70 | 85 | ||
| 71 | 86 | // serverServiceClient implements ServerServiceClient. | |
| 72 | 87 | type serverServiceClient struct { | |
| 73 | - | getVersion *connect.Client[ermite.GetVersionRequest, ermite.GetVersionResponse] | |
| 88 | + | getVersion *connect.Client[ermite.GetVersionRequest, ermite.GetVersionResponse] | |
| 89 | + | getSigningKey *connect.Client[ermite.GetSigningKeyRequest, ermite.GetSigningKeyResponse] | |
| 74 | 90 | } | |
| 75 | 91 | ||
| 76 | 92 | // GetVersion calls ermite.ServerService.GetVersion. | |
| @@ -78,12 +94,23 @@ func (c *serverServiceClient) GetVersion(ctx context.Context, req *connect.Reque | |||
| 78 | 94 | return c.getVersion.CallUnary(ctx, req) | |
| 79 | 95 | } | |
| 80 | 96 | ||
| 97 | + | // GetSigningKey calls ermite.ServerService.GetSigningKey. | |
| 98 | + | func (c *serverServiceClient) GetSigningKey(ctx context.Context, req *connect.Request[ermite.GetSigningKeyRequest]) (*connect.Response[ermite.GetSigningKeyResponse], error) { | |
| 99 | + | return c.getSigningKey.CallUnary(ctx, req) | |
| 100 | + | } | |
| 101 | + | ||
| 81 | 102 | // ServerServiceHandler is an implementation of the ermite.ServerService service. | |
| 82 | 103 | type ServerServiceHandler interface { | |
| 83 | 104 | // GetVersion returns the server version and the optional capabilities of the | |
| 84 | 105 | // contract it implements. It needs no authentication, so a client can call | |
| 85 | 106 | // it first to check compatibility. | |
| 86 | 107 | GetVersion(context.Context, *connect.Request[ermite.GetVersionRequest]) (*connect.Response[ermite.GetVersionResponse], error) | |
| 108 | + | // GetSigningKey returns the public key with which the server signs the | |
| 109 | + | // commits it creates (squash merges, see MergeMode). It needs no | |
| 110 | + | // authentication: the key is public, and anyone verifying a commit needs it. | |
| 111 | + | // Servers that implement it list "signing_key" in | |
| 112 | + | // GetVersionResponse.features. | |
| 113 | + | GetSigningKey(context.Context, *connect.Request[ermite.GetSigningKeyRequest]) (*connect.Response[ermite.GetSigningKeyResponse], error) | |
| 87 | 114 | } | |
| 88 | 115 | ||
| 89 | 116 | // NewServerServiceHandler builds an HTTP handler from the service implementation. It returns the | |
| @@ -99,10 +126,18 @@ func NewServerServiceHandler(svc ServerServiceHandler, opts ...connect.HandlerOp | |||
| 99 | 126 | connect.WithSchema(serverServiceMethods.ByName("GetVersion")), | |
| 100 | 127 | connect.WithHandlerOptions(opts...), | |
| 101 | 128 | ) | |
| 129 | + | serverServiceGetSigningKeyHandler := connect.NewUnaryHandler( | |
| 130 | + | ServerServiceGetSigningKeyProcedure, | |
| 131 | + | svc.GetSigningKey, | |
| 132 | + | connect.WithSchema(serverServiceMethods.ByName("GetSigningKey")), | |
| 133 | + | connect.WithHandlerOptions(opts...), | |
| 134 | + | ) | |
| 102 | 135 | return "/ermite.ServerService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | |
| 103 | 136 | switch r.URL.Path { | |
| 104 | 137 | case ServerServiceGetVersionProcedure: | |
| 105 | 138 | serverServiceGetVersionHandler.ServeHTTP(w, r) | |
| 139 | + | case ServerServiceGetSigningKeyProcedure: | |
| 140 | + | serverServiceGetSigningKeyHandler.ServeHTTP(w, r) | |
| 106 | 141 | default: | |
| 107 | 142 | http.NotFound(w, r) | |
| 108 | 143 | } | |
| @@ -115,3 +150,7 @@ type UnimplementedServerServiceHandler struct{} | |||
| 115 | 150 | func (UnimplementedServerServiceHandler) GetVersion(context.Context, *connect.Request[ermite.GetVersionRequest]) (*connect.Response[ermite.GetVersionResponse], error) { | |
| 116 | 151 | return nil, connect.NewError(connect.CodeUnimplemented, errors.New("ermite.ServerService.GetVersion is not implemented")) | |
| 117 | 152 | } | |
| 153 | + | ||
| 154 | + | func (UnimplementedServerServiceHandler) GetSigningKey(context.Context, *connect.Request[ermite.GetSigningKeyRequest]) (*connect.Response[ermite.GetSigningKeyResponse], error) { | |
| 155 | + | return nil, connect.NewError(connect.CodeUnimplemented, errors.New("ermite.ServerService.GetSigningKey is not implemented")) | |
| 156 | + | } | |
| @@ -38,6 +38,9 @@ const ( | |||||
| 38 | // ServerServiceGetVersionProcedure is the fully-qualified name of the ServerService's GetVersion | 38 | // ServerServiceGetVersionProcedure is the fully-qualified name of the ServerService's GetVersion | ||
| 39 | // RPC. | 39 | // RPC. | ||
| 40 | ServerServiceGetVersionProcedure = "/ermite.ServerService/GetVersion" | 40 | ServerServiceGetVersionProcedure = "/ermite.ServerService/GetVersion" | ||
| 41 | + | // ServerServiceGetSigningKeyProcedure is the fully-qualified name of the ServerService's | |||
| 42 | + | // GetSigningKey RPC. | |||
| 43 | + | ServerServiceGetSigningKeyProcedure = "/ermite.ServerService/GetSigningKey" | |||
| 41 | ) | 44 | ) | ||
| 42 | 45 | ||||
| 43 | // ServerServiceClient is a client for the ermite.ServerService service. | 46 | // ServerServiceClient is a client for the ermite.ServerService service. | ||
| @@ -46,6 +49,12 @@ type ServerServiceClient interface { | |||||
| 46 | // contract it implements. It needs no authentication, so a client can call | 49 | // contract it implements. It needs no authentication, so a client can call | ||
| 47 | // it first to check compatibility. | 50 | // it first to check compatibility. | ||
| 48 | GetVersion(context.Context, *connect.Request[ermite.GetVersionRequest]) (*connect.Response[ermite.GetVersionResponse], error) | 51 | GetVersion(context.Context, *connect.Request[ermite.GetVersionRequest]) (*connect.Response[ermite.GetVersionResponse], error) | ||
| 52 | + | // GetSigningKey returns the public key with which the server signs the | |||
| 53 | + | // commits it creates (squash merges, see MergeMode). It needs no | |||
| 54 | + | // authentication: the key is public, and anyone verifying a commit needs it. | |||
| 55 | + | // Servers that implement it list "signing_key" in | |||
| 56 | + | // GetVersionResponse.features. | |||
| 57 | + | GetSigningKey(context.Context, *connect.Request[ermite.GetSigningKeyRequest]) (*connect.Response[ermite.GetSigningKeyResponse], error) | |||
| 49 | } | 58 | } | ||
| 50 | 59 | ||||
| 51 | // NewServerServiceClient constructs a client for the ermite.ServerService service. By default, it | 60 | // NewServerServiceClient constructs a client for the ermite.ServerService service. By default, it | ||
| @@ -65,12 +74,19 @@ func NewServerServiceClient(httpClient connect.HTTPClient, baseURL string, opts | |||||
| 65 | connect.WithSchema(serverServiceMethods.ByName("GetVersion")), | 74 | connect.WithSchema(serverServiceMethods.ByName("GetVersion")), | ||
| 66 | connect.WithClientOptions(opts...), | 75 | connect.WithClientOptions(opts...), | ||
| 67 | ), | 76 | ), | ||
| 77 | + | getSigningKey: connect.NewClient[ermite.GetSigningKeyRequest, ermite.GetSigningKeyResponse]( | |||
| 78 | + | httpClient, | |||
| 79 | + | baseURL+ServerServiceGetSigningKeyProcedure, | |||
| 80 | + | connect.WithSchema(serverServiceMethods.ByName("GetSigningKey")), | |||
| 81 | + | connect.WithClientOptions(opts...), | |||
| 82 | + | ), | |||
| 68 | } | 83 | } | ||
| 69 | } | 84 | } | ||
| 70 | 85 | ||||
| 71 | // serverServiceClient implements ServerServiceClient. | 86 | // serverServiceClient implements ServerServiceClient. | ||
| 72 | type serverServiceClient struct { | 87 | type serverServiceClient struct { | ||
| 73 | - | getVersion *connect.Client[ermite.GetVersionRequest, ermite.GetVersionResponse] | 88 | + | getVersion *connect.Client[ermite.GetVersionRequest, ermite.GetVersionResponse] |
| 89 | + | getSigningKey *connect.Client[ermite.GetSigningKeyRequest, ermite.GetSigningKeyResponse] | |||
| 74 | } | 90 | } | ||
| 75 | 91 | ||||
| 76 | // GetVersion calls ermite.ServerService.GetVersion. | 92 | // GetVersion calls ermite.ServerService.GetVersion. | ||
| @@ -78,12 +94,23 @@ func (c *serverServiceClient) GetVersion(ctx context.Context, req *connect.Reque | |||||
| 78 | return c.getVersion.CallUnary(ctx, req) | 94 | return c.getVersion.CallUnary(ctx, req) | ||
| 79 | } | 95 | } | ||
| 80 | 96 | ||||
| 97 | + | // GetSigningKey calls ermite.ServerService.GetSigningKey. | |||
| 98 | + | func (c *serverServiceClient) GetSigningKey(ctx context.Context, req *connect.Request[ermite.GetSigningKeyRequest]) (*connect.Response[ermite.GetSigningKeyResponse], error) { | |||
| 99 | + | return c.getSigningKey.CallUnary(ctx, req) | |||
| 100 | + | } | |||
| 101 | + | ||||
| 81 | // ServerServiceHandler is an implementation of the ermite.ServerService service. | 102 | // ServerServiceHandler is an implementation of the ermite.ServerService service. | ||
| 82 | type ServerServiceHandler interface { | 103 | type ServerServiceHandler interface { | ||
| 83 | // GetVersion returns the server version and the optional capabilities of the | 104 | // GetVersion returns the server version and the optional capabilities of the | ||
| 84 | // contract it implements. It needs no authentication, so a client can call | 105 | // contract it implements. It needs no authentication, so a client can call | ||
| 85 | // it first to check compatibility. | 106 | // it first to check compatibility. | ||
| 86 | GetVersion(context.Context, *connect.Request[ermite.GetVersionRequest]) (*connect.Response[ermite.GetVersionResponse], error) | 107 | GetVersion(context.Context, *connect.Request[ermite.GetVersionRequest]) (*connect.Response[ermite.GetVersionResponse], error) | ||
| 108 | + | // GetSigningKey returns the public key with which the server signs the | |||
| 109 | + | // commits it creates (squash merges, see MergeMode). It needs no | |||
| 110 | + | // authentication: the key is public, and anyone verifying a commit needs it. | |||
| 111 | + | // Servers that implement it list "signing_key" in | |||
| 112 | + | // GetVersionResponse.features. | |||
| 113 | + | GetSigningKey(context.Context, *connect.Request[ermite.GetSigningKeyRequest]) (*connect.Response[ermite.GetSigningKeyResponse], error) | |||
| 87 | } | 114 | } | ||
| 88 | 115 | ||||
| 89 | // NewServerServiceHandler builds an HTTP handler from the service implementation. It returns the | 116 | // NewServerServiceHandler builds an HTTP handler from the service implementation. It returns the | ||
| @@ -99,10 +126,18 @@ func NewServerServiceHandler(svc ServerServiceHandler, opts ...connect.HandlerOp | |||||
| 99 | connect.WithSchema(serverServiceMethods.ByName("GetVersion")), | 126 | connect.WithSchema(serverServiceMethods.ByName("GetVersion")), | ||
| 100 | connect.WithHandlerOptions(opts...), | 127 | connect.WithHandlerOptions(opts...), | ||
| 101 | ) | 128 | ) | ||
| 129 | + | serverServiceGetSigningKeyHandler := connect.NewUnaryHandler( | |||
| 130 | + | ServerServiceGetSigningKeyProcedure, | |||
| 131 | + | svc.GetSigningKey, | |||
| 132 | + | connect.WithSchema(serverServiceMethods.ByName("GetSigningKey")), | |||
| 133 | + | connect.WithHandlerOptions(opts...), | |||
| 134 | + | ) | |||
| 102 | return "/ermite.ServerService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | 135 | return "/ermite.ServerService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | ||
| 103 | switch r.URL.Path { | 136 | switch r.URL.Path { | ||
| 104 | case ServerServiceGetVersionProcedure: | 137 | case ServerServiceGetVersionProcedure: | ||
| 105 | serverServiceGetVersionHandler.ServeHTTP(w, r) | 138 | serverServiceGetVersionHandler.ServeHTTP(w, r) | ||
| 139 | + | case ServerServiceGetSigningKeyProcedure: | |||
| 140 | + | serverServiceGetSigningKeyHandler.ServeHTTP(w, r) | |||
| 106 | default: | 141 | default: | ||
| 107 | http.NotFound(w, r) | 142 | http.NotFound(w, r) | ||
| 108 | } | 143 | } | ||
| @@ -115,3 +150,7 @@ type UnimplementedServerServiceHandler struct{} | |||||
| 115 | func (UnimplementedServerServiceHandler) GetVersion(context.Context, *connect.Request[ermite.GetVersionRequest]) (*connect.Response[ermite.GetVersionResponse], error) { | 150 | func (UnimplementedServerServiceHandler) GetVersion(context.Context, *connect.Request[ermite.GetVersionRequest]) (*connect.Response[ermite.GetVersionResponse], error) { | ||
| 116 | return nil, connect.NewError(connect.CodeUnimplemented, errors.New("ermite.ServerService.GetVersion is not implemented")) | 151 | return nil, connect.NewError(connect.CodeUnimplemented, errors.New("ermite.ServerService.GetVersion is not implemented")) | ||
| 117 | } | 152 | } | ||
| 153 | + | ||||
| 154 | + | func (UnimplementedServerServiceHandler) GetSigningKey(context.Context, *connect.Request[ermite.GetSigningKeyRequest]) (*connect.Response[ermite.GetSigningKeyResponse], error) { | |||
| 155 | + | return nil, connect.NewError(connect.CodeUnimplemented, errors.New("ermite.ServerService.GetSigningKey is not implemented")) | |||
| 156 | + | } | |||
A gen/ermite/ermiteconnect/session.connect.go +158 -0
| @@ -0,0 +1,158 @@ | |||
| 1 | + | // SPDX-License-Identifier: MIT | |
| 2 | + | ||
| 3 | + | // Code generated by protoc-gen-connect-go. DO NOT EDIT. | |
| 4 | + | // | |
| 5 | + | // Source: ermite/session.proto | |
| 6 | + | ||
| 7 | + | package ermiteconnect | |
| 8 | + | ||
| 9 | + | import ( | |
| 10 | + | ermite "bnema.dev/ermite-api/gen/ermite" | |
| 11 | + | connect "connectrpc.com/connect" | |
| 12 | + | context "context" | |
| 13 | + | errors "errors" | |
| 14 | + | http "net/http" | |
| 15 | + | strings "strings" | |
| 16 | + | ) | |
| 17 | + | ||
| 18 | + | // This is a compile-time assertion to ensure that this generated file and the connect package are | |
| 19 | + | // compatible. If you get a compiler error that this constant is not defined, this code was | |
| 20 | + | // generated with a version of connect newer than the one compiled into your binary. You can fix the | |
| 21 | + | // problem by either regenerating this code with an older version of connect or updating the connect | |
| 22 | + | // version compiled into your binary. | |
| 23 | + | const _ = connect.IsAtLeastVersion1_13_0 | |
| 24 | + | ||
| 25 | + | const ( | |
| 26 | + | // SessionServiceName is the fully-qualified name of the SessionService service. | |
| 27 | + | SessionServiceName = "ermite.SessionService" | |
| 28 | + | ) | |
| 29 | + | ||
| 30 | + | // These constants are the fully-qualified names of the RPCs defined in this package. They're | |
| 31 | + | // exposed at runtime as Spec.Procedure and as the final two segments of the HTTP route. | |
| 32 | + | // | |
| 33 | + | // Note that these are different from the fully-qualified method names used by | |
| 34 | + | // google.golang.org/protobuf/reflect/protoreflect. To convert from these constants to | |
| 35 | + | // reflection-formatted method names, remove the leading slash and convert the remaining slash to a | |
| 36 | + | // period. | |
| 37 | + | const ( | |
| 38 | + | // SessionServiceCreateLoginLinkProcedure is the fully-qualified name of the SessionService's | |
| 39 | + | // CreateLoginLink RPC. | |
| 40 | + | SessionServiceCreateLoginLinkProcedure = "/ermite.SessionService/CreateLoginLink" | |
| 41 | + | // SessionServiceSignOutEverywhereProcedure is the fully-qualified name of the SessionService's | |
| 42 | + | // SignOutEverywhere RPC. | |
| 43 | + | SessionServiceSignOutEverywhereProcedure = "/ermite.SessionService/SignOutEverywhere" | |
| 44 | + | ) | |
| 45 | + | ||
| 46 | + | // SessionServiceClient is a client for the ermite.SessionService service. | |
| 47 | + | type SessionServiceClient interface { | |
| 48 | + | // CreateLoginLink creates a one-time link that signs the owner's browser | |
| 49 | + | // in. The link is valid for a short time (about a minute), can be used | |
| 50 | + | // once, and is kept in memory only: a server restart voids it. Opening it | |
| 51 | + | // shows a confirmation page; only confirming it consumes the link and sets | |
| 52 | + | // the session. Creating a new link does not void an earlier one. Fails with | |
| 53 | + | // resource_exhausted when too many links are pending. | |
| 54 | + | CreateLoginLink(context.Context, *connect.Request[ermite.CreateLoginLinkRequest]) (*connect.Response[ermite.CreateLoginLinkResponse], error) | |
| 55 | + | // SignOutEverywhere ends every browser session at once, including those on | |
| 56 | + | // other devices. Pending login links are not affected. Tokens are not | |
| 57 | + | // affected either: revoke them with TokenService. | |
| 58 | + | SignOutEverywhere(context.Context, *connect.Request[ermite.SignOutEverywhereRequest]) (*connect.Response[ermite.SignOutEverywhereResponse], error) | |
| 59 | + | } | |
| 60 | + | ||
| 61 | + | // NewSessionServiceClient constructs a client for the ermite.SessionService service. By default, it | |
| 62 | + | // uses the Connect protocol with the binary Protobuf Codec, asks for gzipped responses, and sends | |
| 63 | + | // uncompressed requests. To use the gRPC or gRPC-Web protocols, supply the connect.WithGRPC() or | |
| 64 | + | // connect.WithGRPCWeb() options. | |
| 65 | + | // | |
| 66 | + | // The URL supplied here should be the base URL for the Connect or gRPC server (for example, | |
| 67 | + | // http://api.acme.com or https://acme.com/grpc). | |
| 68 | + | func NewSessionServiceClient(httpClient connect.HTTPClient, baseURL string, opts ...connect.ClientOption) SessionServiceClient { | |
| 69 | + | baseURL = strings.TrimRight(baseURL, "/") | |
| 70 | + | sessionServiceMethods := ermite.File_ermite_session_proto.Services().ByName("SessionService").Methods() | |
| 71 | + | return &sessionServiceClient{ | |
| 72 | + | createLoginLink: connect.NewClient[ermite.CreateLoginLinkRequest, ermite.CreateLoginLinkResponse]( | |
| 73 | + | httpClient, | |
| 74 | + | baseURL+SessionServiceCreateLoginLinkProcedure, | |
| 75 | + | connect.WithSchema(sessionServiceMethods.ByName("CreateLoginLink")), | |
| 76 | + | connect.WithClientOptions(opts...), | |
| 77 | + | ), | |
| 78 | + | signOutEverywhere: connect.NewClient[ermite.SignOutEverywhereRequest, ermite.SignOutEverywhereResponse]( | |
| 79 | + | httpClient, | |
| 80 | + | baseURL+SessionServiceSignOutEverywhereProcedure, | |
| 81 | + | connect.WithSchema(sessionServiceMethods.ByName("SignOutEverywhere")), | |
| 82 | + | connect.WithClientOptions(opts...), | |
| 83 | + | ), | |
| 84 | + | } | |
| 85 | + | } | |
| 86 | + | ||
| 87 | + | // sessionServiceClient implements SessionServiceClient. | |
| 88 | + | type sessionServiceClient struct { | |
| 89 | + | createLoginLink *connect.Client[ermite.CreateLoginLinkRequest, ermite.CreateLoginLinkResponse] | |
| 90 | + | signOutEverywhere *connect.Client[ermite.SignOutEverywhereRequest, ermite.SignOutEverywhereResponse] | |
| 91 | + | } | |
| 92 | + | ||
| 93 | + | // CreateLoginLink calls ermite.SessionService.CreateLoginLink. | |
| 94 | + | func (c *sessionServiceClient) CreateLoginLink(ctx context.Context, req *connect.Request[ermite.CreateLoginLinkRequest]) (*connect.Response[ermite.CreateLoginLinkResponse], error) { | |
| 95 | + | return c.createLoginLink.CallUnary(ctx, req) | |
| 96 | + | } | |
| 97 | + | ||
| 98 | + | // SignOutEverywhere calls ermite.SessionService.SignOutEverywhere. | |
| 99 | + | func (c *sessionServiceClient) SignOutEverywhere(ctx context.Context, req *connect.Request[ermite.SignOutEverywhereRequest]) (*connect.Response[ermite.SignOutEverywhereResponse], error) { | |
| 100 | + | return c.signOutEverywhere.CallUnary(ctx, req) | |
| 101 | + | } | |
| 102 | + | ||
| 103 | + | // SessionServiceHandler is an implementation of the ermite.SessionService service. | |
| 104 | + | type SessionServiceHandler interface { | |
| 105 | + | // CreateLoginLink creates a one-time link that signs the owner's browser | |
| 106 | + | // in. The link is valid for a short time (about a minute), can be used | |
| 107 | + | // once, and is kept in memory only: a server restart voids it. Opening it | |
| 108 | + | // shows a confirmation page; only confirming it consumes the link and sets | |
| 109 | + | // the session. Creating a new link does not void an earlier one. Fails with | |
| 110 | + | // resource_exhausted when too many links are pending. | |
| 111 | + | CreateLoginLink(context.Context, *connect.Request[ermite.CreateLoginLinkRequest]) (*connect.Response[ermite.CreateLoginLinkResponse], error) | |
| 112 | + | // SignOutEverywhere ends every browser session at once, including those on | |
| 113 | + | // other devices. Pending login links are not affected. Tokens are not | |
| 114 | + | // affected either: revoke them with TokenService. | |
| 115 | + | SignOutEverywhere(context.Context, *connect.Request[ermite.SignOutEverywhereRequest]) (*connect.Response[ermite.SignOutEverywhereResponse], error) | |
| 116 | + | } | |
| 117 | + | ||
| 118 | + | // NewSessionServiceHandler builds an HTTP handler from the service implementation. It returns the | |
| 119 | + | // path on which to mount the handler and the handler itself. | |
| 120 | + | // | |
| 121 | + | // By default, handlers support the Connect, gRPC, and gRPC-Web protocols with the binary Protobuf | |
| 122 | + | // and JSON codecs. They also support gzip compression. | |
| 123 | + | func NewSessionServiceHandler(svc SessionServiceHandler, opts ...connect.HandlerOption) (string, http.Handler) { | |
| 124 | + | sessionServiceMethods := ermite.File_ermite_session_proto.Services().ByName("SessionService").Methods() | |
| 125 | + | sessionServiceCreateLoginLinkHandler := connect.NewUnaryHandler( | |
| 126 | + | SessionServiceCreateLoginLinkProcedure, | |
| 127 | + | svc.CreateLoginLink, | |
| 128 | + | connect.WithSchema(sessionServiceMethods.ByName("CreateLoginLink")), | |
| 129 | + | connect.WithHandlerOptions(opts...), | |
| 130 | + | ) | |
| 131 | + | sessionServiceSignOutEverywhereHandler := connect.NewUnaryHandler( | |
| 132 | + | SessionServiceSignOutEverywhereProcedure, | |
| 133 | + | svc.SignOutEverywhere, | |
| 134 | + | connect.WithSchema(sessionServiceMethods.ByName("SignOutEverywhere")), | |
| 135 | + | connect.WithHandlerOptions(opts...), | |
| 136 | + | ) | |
| 137 | + | return "/ermite.SessionService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | |
| 138 | + | switch r.URL.Path { | |
| 139 | + | case SessionServiceCreateLoginLinkProcedure: | |
| 140 | + | sessionServiceCreateLoginLinkHandler.ServeHTTP(w, r) | |
| 141 | + | case SessionServiceSignOutEverywhereProcedure: | |
| 142 | + | sessionServiceSignOutEverywhereHandler.ServeHTTP(w, r) | |
| 143 | + | default: | |
| 144 | + | http.NotFound(w, r) | |
| 145 | + | } | |
| 146 | + | }) | |
| 147 | + | } | |
| 148 | + | ||
| 149 | + | // UnimplementedSessionServiceHandler returns CodeUnimplemented from all methods. | |
| 150 | + | type UnimplementedSessionServiceHandler struct{} | |
| 151 | + | ||
| 152 | + | func (UnimplementedSessionServiceHandler) CreateLoginLink(context.Context, *connect.Request[ermite.CreateLoginLinkRequest]) (*connect.Response[ermite.CreateLoginLinkResponse], error) { | |
| 153 | + | return nil, connect.NewError(connect.CodeUnimplemented, errors.New("ermite.SessionService.CreateLoginLink is not implemented")) | |
| 154 | + | } | |
| 155 | + | ||
| 156 | + | func (UnimplementedSessionServiceHandler) SignOutEverywhere(context.Context, *connect.Request[ermite.SignOutEverywhereRequest]) (*connect.Response[ermite.SignOutEverywhereResponse], error) { | |
| 157 | + | return nil, connect.NewError(connect.CodeUnimplemented, errors.New("ermite.SessionService.SignOutEverywhere is not implemented")) | |
| 158 | + | } | |
| @@ -0,0 +1,158 @@ | |||||
| 1 | + | // SPDX-License-Identifier: MIT | |||
| 2 | + | ||||
| 3 | + | // Code generated by protoc-gen-connect-go. DO NOT EDIT. | |||
| 4 | + | // | |||
| 5 | + | // Source: ermite/session.proto | |||
| 6 | + | ||||
| 7 | + | package ermiteconnect | |||
| 8 | + | ||||
| 9 | + | import ( | |||
| 10 | + | ermite "bnema.dev/ermite-api/gen/ermite" | |||
| 11 | + | connect "connectrpc.com/connect" | |||
| 12 | + | context "context" | |||
| 13 | + | errors "errors" | |||
| 14 | + | http "net/http" | |||
| 15 | + | strings "strings" | |||
| 16 | + | ) | |||
| 17 | + | ||||
| 18 | + | // This is a compile-time assertion to ensure that this generated file and the connect package are | |||
| 19 | + | // compatible. If you get a compiler error that this constant is not defined, this code was | |||
| 20 | + | // generated with a version of connect newer than the one compiled into your binary. You can fix the | |||
| 21 | + | // problem by either regenerating this code with an older version of connect or updating the connect | |||
| 22 | + | // version compiled into your binary. | |||
| 23 | + | const _ = connect.IsAtLeastVersion1_13_0 | |||
| 24 | + | ||||
| 25 | + | const ( | |||
| 26 | + | // SessionServiceName is the fully-qualified name of the SessionService service. | |||
| 27 | + | SessionServiceName = "ermite.SessionService" | |||
| 28 | + | ) | |||
| 29 | + | ||||
| 30 | + | // These constants are the fully-qualified names of the RPCs defined in this package. They're | |||
| 31 | + | // exposed at runtime as Spec.Procedure and as the final two segments of the HTTP route. | |||
| 32 | + | // | |||
| 33 | + | // Note that these are different from the fully-qualified method names used by | |||
| 34 | + | // google.golang.org/protobuf/reflect/protoreflect. To convert from these constants to | |||
| 35 | + | // reflection-formatted method names, remove the leading slash and convert the remaining slash to a | |||
| 36 | + | // period. | |||
| 37 | + | const ( | |||
| 38 | + | // SessionServiceCreateLoginLinkProcedure is the fully-qualified name of the SessionService's | |||
| 39 | + | // CreateLoginLink RPC. | |||
| 40 | + | SessionServiceCreateLoginLinkProcedure = "/ermite.SessionService/CreateLoginLink" | |||
| 41 | + | // SessionServiceSignOutEverywhereProcedure is the fully-qualified name of the SessionService's | |||
| 42 | + | // SignOutEverywhere RPC. | |||
| 43 | + | SessionServiceSignOutEverywhereProcedure = "/ermite.SessionService/SignOutEverywhere" | |||
| 44 | + | ) | |||
| 45 | + | ||||
| 46 | + | // SessionServiceClient is a client for the ermite.SessionService service. | |||
| 47 | + | type SessionServiceClient interface { | |||
| 48 | + | // CreateLoginLink creates a one-time link that signs the owner's browser | |||
| 49 | + | // in. The link is valid for a short time (about a minute), can be used | |||
| 50 | + | // once, and is kept in memory only: a server restart voids it. Opening it | |||
| 51 | + | // shows a confirmation page; only confirming it consumes the link and sets | |||
| 52 | + | // the session. Creating a new link does not void an earlier one. Fails with | |||
| 53 | + | // resource_exhausted when too many links are pending. | |||
| 54 | + | CreateLoginLink(context.Context, *connect.Request[ermite.CreateLoginLinkRequest]) (*connect.Response[ermite.CreateLoginLinkResponse], error) | |||
| 55 | + | // SignOutEverywhere ends every browser session at once, including those on | |||
| 56 | + | // other devices. Pending login links are not affected. Tokens are not | |||
| 57 | + | // affected either: revoke them with TokenService. | |||
| 58 | + | SignOutEverywhere(context.Context, *connect.Request[ermite.SignOutEverywhereRequest]) (*connect.Response[ermite.SignOutEverywhereResponse], error) | |||
| 59 | + | } | |||
| 60 | + | ||||
| 61 | + | // NewSessionServiceClient constructs a client for the ermite.SessionService service. By default, it | |||
| 62 | + | // uses the Connect protocol with the binary Protobuf Codec, asks for gzipped responses, and sends | |||
| 63 | + | // uncompressed requests. To use the gRPC or gRPC-Web protocols, supply the connect.WithGRPC() or | |||
| 64 | + | // connect.WithGRPCWeb() options. | |||
| 65 | + | // | |||
| 66 | + | // The URL supplied here should be the base URL for the Connect or gRPC server (for example, | |||
| 67 | + | // http://api.acme.com or https://acme.com/grpc). | |||
| 68 | + | func NewSessionServiceClient(httpClient connect.HTTPClient, baseURL string, opts ...connect.ClientOption) SessionServiceClient { | |||
| 69 | + | baseURL = strings.TrimRight(baseURL, "/") | |||
| 70 | + | sessionServiceMethods := ermite.File_ermite_session_proto.Services().ByName("SessionService").Methods() | |||
| 71 | + | return &sessionServiceClient{ | |||
| 72 | + | createLoginLink: connect.NewClient[ermite.CreateLoginLinkRequest, ermite.CreateLoginLinkResponse]( | |||
| 73 | + | httpClient, | |||
| 74 | + | baseURL+SessionServiceCreateLoginLinkProcedure, | |||
| 75 | + | connect.WithSchema(sessionServiceMethods.ByName("CreateLoginLink")), | |||
| 76 | + | connect.WithClientOptions(opts...), | |||
| 77 | + | ), | |||
| 78 | + | signOutEverywhere: connect.NewClient[ermite.SignOutEverywhereRequest, ermite.SignOutEverywhereResponse]( | |||
| 79 | + | httpClient, | |||
| 80 | + | baseURL+SessionServiceSignOutEverywhereProcedure, | |||
| 81 | + | connect.WithSchema(sessionServiceMethods.ByName("SignOutEverywhere")), | |||
| 82 | + | connect.WithClientOptions(opts...), | |||
| 83 | + | ), | |||
| 84 | + | } | |||
| 85 | + | } | |||
| 86 | + | ||||
| 87 | + | // sessionServiceClient implements SessionServiceClient. | |||
| 88 | + | type sessionServiceClient struct { | |||
| 89 | + | createLoginLink *connect.Client[ermite.CreateLoginLinkRequest, ermite.CreateLoginLinkResponse] | |||
| 90 | + | signOutEverywhere *connect.Client[ermite.SignOutEverywhereRequest, ermite.SignOutEverywhereResponse] | |||
| 91 | + | } | |||
| 92 | + | ||||
| 93 | + | // CreateLoginLink calls ermite.SessionService.CreateLoginLink. | |||
| 94 | + | func (c *sessionServiceClient) CreateLoginLink(ctx context.Context, req *connect.Request[ermite.CreateLoginLinkRequest]) (*connect.Response[ermite.CreateLoginLinkResponse], error) { | |||
| 95 | + | return c.createLoginLink.CallUnary(ctx, req) | |||
| 96 | + | } | |||
| 97 | + | ||||
| 98 | + | // SignOutEverywhere calls ermite.SessionService.SignOutEverywhere. | |||
| 99 | + | func (c *sessionServiceClient) SignOutEverywhere(ctx context.Context, req *connect.Request[ermite.SignOutEverywhereRequest]) (*connect.Response[ermite.SignOutEverywhereResponse], error) { | |||
| 100 | + | return c.signOutEverywhere.CallUnary(ctx, req) | |||
| 101 | + | } | |||
| 102 | + | ||||
| 103 | + | // SessionServiceHandler is an implementation of the ermite.SessionService service. | |||
| 104 | + | type SessionServiceHandler interface { | |||
| 105 | + | // CreateLoginLink creates a one-time link that signs the owner's browser | |||
| 106 | + | // in. The link is valid for a short time (about a minute), can be used | |||
| 107 | + | // once, and is kept in memory only: a server restart voids it. Opening it | |||
| 108 | + | // shows a confirmation page; only confirming it consumes the link and sets | |||
| 109 | + | // the session. Creating a new link does not void an earlier one. Fails with | |||
| 110 | + | // resource_exhausted when too many links are pending. | |||
| 111 | + | CreateLoginLink(context.Context, *connect.Request[ermite.CreateLoginLinkRequest]) (*connect.Response[ermite.CreateLoginLinkResponse], error) | |||
| 112 | + | // SignOutEverywhere ends every browser session at once, including those on | |||
| 113 | + | // other devices. Pending login links are not affected. Tokens are not | |||
| 114 | + | // affected either: revoke them with TokenService. | |||
| 115 | + | SignOutEverywhere(context.Context, *connect.Request[ermite.SignOutEverywhereRequest]) (*connect.Response[ermite.SignOutEverywhereResponse], error) | |||
| 116 | + | } | |||
| 117 | + | ||||
| 118 | + | // NewSessionServiceHandler builds an HTTP handler from the service implementation. It returns the | |||
| 119 | + | // path on which to mount the handler and the handler itself. | |||
| 120 | + | // | |||
| 121 | + | // By default, handlers support the Connect, gRPC, and gRPC-Web protocols with the binary Protobuf | |||
| 122 | + | // and JSON codecs. They also support gzip compression. | |||
| 123 | + | func NewSessionServiceHandler(svc SessionServiceHandler, opts ...connect.HandlerOption) (string, http.Handler) { | |||
| 124 | + | sessionServiceMethods := ermite.File_ermite_session_proto.Services().ByName("SessionService").Methods() | |||
| 125 | + | sessionServiceCreateLoginLinkHandler := connect.NewUnaryHandler( | |||
| 126 | + | SessionServiceCreateLoginLinkProcedure, | |||
| 127 | + | svc.CreateLoginLink, | |||
| 128 | + | connect.WithSchema(sessionServiceMethods.ByName("CreateLoginLink")), | |||
| 129 | + | connect.WithHandlerOptions(opts...), | |||
| 130 | + | ) | |||
| 131 | + | sessionServiceSignOutEverywhereHandler := connect.NewUnaryHandler( | |||
| 132 | + | SessionServiceSignOutEverywhereProcedure, | |||
| 133 | + | svc.SignOutEverywhere, | |||
| 134 | + | connect.WithSchema(sessionServiceMethods.ByName("SignOutEverywhere")), | |||
| 135 | + | connect.WithHandlerOptions(opts...), | |||
| 136 | + | ) | |||
| 137 | + | return "/ermite.SessionService/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | |||
| 138 | + | switch r.URL.Path { | |||
| 139 | + | case SessionServiceCreateLoginLinkProcedure: | |||
| 140 | + | sessionServiceCreateLoginLinkHandler.ServeHTTP(w, r) | |||
| 141 | + | case SessionServiceSignOutEverywhereProcedure: | |||
| 142 | + | sessionServiceSignOutEverywhereHandler.ServeHTTP(w, r) | |||
| 143 | + | default: | |||
| 144 | + | http.NotFound(w, r) | |||
| 145 | + | } | |||
| 146 | + | }) | |||
| 147 | + | } | |||
| 148 | + | ||||
| 149 | + | // UnimplementedSessionServiceHandler returns CodeUnimplemented from all methods. | |||
| 150 | + | type UnimplementedSessionServiceHandler struct{} | |||
| 151 | + | ||||
| 152 | + | func (UnimplementedSessionServiceHandler) CreateLoginLink(context.Context, *connect.Request[ermite.CreateLoginLinkRequest]) (*connect.Response[ermite.CreateLoginLinkResponse], error) { | |||
| 153 | + | return nil, connect.NewError(connect.CodeUnimplemented, errors.New("ermite.SessionService.CreateLoginLink is not implemented")) | |||
| 154 | + | } | |||
| 155 | + | ||||
| 156 | + | func (UnimplementedSessionServiceHandler) SignOutEverywhere(context.Context, *connect.Request[ermite.SignOutEverywhereRequest]) (*connect.Response[ermite.SignOutEverywhereResponse], error) { | |||
| 157 | + | return nil, connect.NewError(connect.CodeUnimplemented, errors.New("ermite.SessionService.SignOutEverywhere is not implemented")) | |||
| 158 | + | } | |||
M gen/ermite/event.pb.go +331 -25 generated file: collapsed
A gen/ermite/merge_request.pb.go +1716 -0 generated file: collapsed
M gen/ermite/repo.pb.go +179 -81
| @@ -80,6 +80,68 @@ func (Visibility) EnumDescriptor() ([]byte, []int) { | |||
| 80 | 80 | return file_ermite_repo_proto_rawDescGZIP(), []int{0} | |
| 81 | 81 | } | |
| 82 | 82 | ||
| 83 | + | // RepoSettings are the settings of a repository that govern its merge | |
| 84 | + | // requests. | |
| 85 | + | type RepoSettings struct { | |
| 86 | + | state protoimpl.MessageState `protogen:"open.v1"` | |
| 87 | + | // AllowedMergeModes are the modes with which a merge request of the | |
| 88 | + | // repository may be merged. It is never empty in a response and has no | |
| 89 | + | // duplicate. Both MERGE_MODE_FAST_FORWARD and MERGE_MODE_SQUASH are allowed | |
| 90 | + | // by default. MERGE_MODE_UNSPECIFIED is rejected. | |
| 91 | + | AllowedMergeModes []MergeMode `protobuf:"varint,1,rep,packed,name=allowed_merge_modes,json=allowedMergeModes,proto3,enum=ermite.MergeMode" json:"allowed_merge_modes,omitempty"` | |
| 92 | + | // FailingChecksBlock says whether a merge request whose checks fail cannot be | |
| 93 | + | // merged. It is true at creation of the repository and always stored | |
| 94 | + | // explicitly, so a later change of the server default never alters an | |
| 95 | + | // existing repository. | |
| 96 | + | FailingChecksBlock bool `protobuf:"varint,2,opt,name=failing_checks_block,json=failingChecksBlock,proto3" json:"failing_checks_block,omitempty"` | |
| 97 | + | unknownFields protoimpl.UnknownFields | |
| 98 | + | sizeCache protoimpl.SizeCache | |
| 99 | + | } | |
| 100 | + | ||
| 101 | + | func (x *RepoSettings) Reset() { | |
| 102 | + | *x = RepoSettings{} | |
| 103 | + | mi := &file_ermite_repo_proto_msgTypes[0] | |
| 104 | + | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | |
| 105 | + | ms.StoreMessageInfo(mi) | |
| 106 | + | } | |
| 107 | + | ||
| 108 | + | func (x *RepoSettings) String() string { | |
| 109 | + | return protoimpl.X.MessageStringOf(x) | |
| 110 | + | } | |
| 111 | + | ||
| 112 | + | func (*RepoSettings) ProtoMessage() {} | |
| 113 | + | ||
| 114 | + | func (x *RepoSettings) ProtoReflect() protoreflect.Message { | |
| 115 | + | mi := &file_ermite_repo_proto_msgTypes[0] | |
| 116 | + | if x != nil { | |
| 117 | + | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | |
| 118 | + | if ms.LoadMessageInfo() == nil { | |
| 119 | + | ms.StoreMessageInfo(mi) | |
| 120 | + | } | |
| 121 | + | return ms | |
| 122 | + | } | |
| 123 | + | return mi.MessageOf(x) | |
| 124 | + | } | |
| 125 | + | ||
| 126 | + | // Deprecated: Use RepoSettings.ProtoReflect.Descriptor instead. | |
| 127 | + | func (*RepoSettings) Descriptor() ([]byte, []int) { | |
| 128 | + | return file_ermite_repo_proto_rawDescGZIP(), []int{0} | |
| 129 | + | } | |
| 130 | + | ||
| 131 | + | func (x *RepoSettings) GetAllowedMergeModes() []MergeMode { | |
| 132 | + | if x != nil { | |
| 133 | + | return x.AllowedMergeModes | |
| 134 | + | } | |
| 135 | + | return nil | |
| 136 | + | } | |
| 137 | + | ||
| 138 | + | func (x *RepoSettings) GetFailingChecksBlock() bool { | |
| 139 | + | if x != nil { | |
| 140 | + | return x.FailingChecksBlock | |
| 141 | + | } | |
| 142 | + | return false | |
| 143 | + | } | |
| 144 | + | ||
| 83 | 145 | // Repo is the metadata of a repository. Git-owned state (refs, trees, history) | |
| 84 | 146 | // is read through GitService. | |
| 85 | 147 | type Repo struct { | |
| @@ -98,14 +160,17 @@ type Repo struct { | |||
| 98 | 160 | // CreatedAt is when the repository was created. | |
| 99 | 161 | CreatedAt *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` | |
| 100 | 162 | // PushedAt is the time of the last push. It is unset until the first push. | |
| 101 | - | PushedAt *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=pushed_at,json=pushedAt,proto3" json:"pushed_at,omitempty"` | |
| 163 | + | PushedAt *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=pushed_at,json=pushedAt,proto3" json:"pushed_at,omitempty"` | |
| 164 | + | // Settings are the merge settings of the repository. Always set in a | |
| 165 | + | // response, with the defaults for a repository that never changed them. | |
| 166 | + | Settings *RepoSettings `protobuf:"bytes,7,opt,name=settings,proto3" json:"settings,omitempty"` | |
| 102 | 167 | unknownFields protoimpl.UnknownFields | |
| 103 | 168 | sizeCache protoimpl.SizeCache | |
| 104 | 169 | } | |
| 105 | 170 | ||
| 106 | 171 | func (x *Repo) Reset() { | |
| 107 | 172 | *x = Repo{} | |
| 108 | - | mi := &file_ermite_repo_proto_msgTypes[0] | |
| 173 | + | mi := &file_ermite_repo_proto_msgTypes[1] | |
| 109 | 174 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | |
| 110 | 175 | ms.StoreMessageInfo(mi) | |
| 111 | 176 | } | |
| @@ -117,7 +182,7 @@ func (x *Repo) String() string { | |||
| 117 | 182 | func (*Repo) ProtoMessage() {} | |
| 118 | 183 | ||
| 119 | 184 | func (x *Repo) ProtoReflect() protoreflect.Message { | |
| 120 | - | mi := &file_ermite_repo_proto_msgTypes[0] | |
| 185 | + | mi := &file_ermite_repo_proto_msgTypes[1] | |
| 121 | 186 | if x != nil { | |
| 122 | 187 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | |
| 123 | 188 | if ms.LoadMessageInfo() == nil { | |
| @@ -130,7 +195,7 @@ func (x *Repo) ProtoReflect() protoreflect.Message { | |||
| 130 | 195 | ||
| 131 | 196 | // Deprecated: Use Repo.ProtoReflect.Descriptor instead. | |
| 132 | 197 | func (*Repo) Descriptor() ([]byte, []int) { | |
| 133 | - | return file_ermite_repo_proto_rawDescGZIP(), []int{0} | |
| 198 | + | return file_ermite_repo_proto_rawDescGZIP(), []int{1} | |
| 134 | 199 | } | |
| 135 | 200 | ||
| 136 | 201 | func (x *Repo) GetName() string { | |
| @@ -175,6 +240,13 @@ func (x *Repo) GetPushedAt() *timestamppb.Timestamp { | |||
| 175 | 240 | return nil | |
| 176 | 241 | } | |
| 177 | 242 | ||
| 243 | + | func (x *Repo) GetSettings() *RepoSettings { | |
| 244 | + | if x != nil { | |
| 245 | + | return x.Settings | |
| 246 | + | } | |
| 247 | + | return nil | |
| 248 | + | } | |
| 249 | + | ||
| 178 | 250 | // ListReposRequest selects a page of repositories. | |
| 179 | 251 | type ListReposRequest struct { | |
| 180 | 252 | state protoimpl.MessageState `protogen:"open.v1"` | |
| @@ -190,7 +262,7 @@ type ListReposRequest struct { | |||
| 190 | 262 | ||
| 191 | 263 | func (x *ListReposRequest) Reset() { | |
| 192 | 264 | *x = ListReposRequest{} | |
| 193 | - | mi := &file_ermite_repo_proto_msgTypes[1] | |
| 265 | + | mi := &file_ermite_repo_proto_msgTypes[2] | |
| 194 | 266 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | |
| 195 | 267 | ms.StoreMessageInfo(mi) | |
| 196 | 268 | } | |
| @@ -202,7 +274,7 @@ func (x *ListReposRequest) String() string { | |||
| 202 | 274 | func (*ListReposRequest) ProtoMessage() {} | |
| 203 | 275 | ||
| 204 | 276 | func (x *ListReposRequest) ProtoReflect() protoreflect.Message { | |
| 205 | - | mi := &file_ermite_repo_proto_msgTypes[1] | |
| 277 | + | mi := &file_ermite_repo_proto_msgTypes[2] | |
| 206 | 278 | if x != nil { | |
| 207 | 279 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | |
| 208 | 280 | if ms.LoadMessageInfo() == nil { | |
| @@ -215,7 +287,7 @@ func (x *ListReposRequest) ProtoReflect() protoreflect.Message { | |||
| 215 | 287 | ||
| 216 | 288 | // Deprecated: Use ListReposRequest.ProtoReflect.Descriptor instead. | |
| 217 | 289 | func (*ListReposRequest) Descriptor() ([]byte, []int) { | |
| 218 | - | return file_ermite_repo_proto_rawDescGZIP(), []int{1} | |
| 290 | + | return file_ermite_repo_proto_rawDescGZIP(), []int{2} | |
| 219 | 291 | } | |
| 220 | 292 | ||
| 221 | 293 | func (x *ListReposRequest) GetPageSize() int32 { | |
| @@ -246,7 +318,7 @@ type ListReposResponse struct { | |||
| 246 | 318 | ||
| 247 | 319 | func (x *ListReposResponse) Reset() { | |
| 248 | 320 | *x = ListReposResponse{} | |
| 249 | - | mi := &file_ermite_repo_proto_msgTypes[2] | |
| 321 | + | mi := &file_ermite_repo_proto_msgTypes[3] | |
| 250 | 322 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | |
| 251 | 323 | ms.StoreMessageInfo(mi) | |
| 252 | 324 | } | |
| @@ -258,7 +330,7 @@ func (x *ListReposResponse) String() string { | |||
| 258 | 330 | func (*ListReposResponse) ProtoMessage() {} | |
| 259 | 331 | ||
| 260 | 332 | func (x *ListReposResponse) ProtoReflect() protoreflect.Message { | |
| 261 | - | mi := &file_ermite_repo_proto_msgTypes[2] | |
| 333 | + | mi := &file_ermite_repo_proto_msgTypes[3] | |
| 262 | 334 | if x != nil { | |
| 263 | 335 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | |
| 264 | 336 | if ms.LoadMessageInfo() == nil { | |
| @@ -271,7 +343,7 @@ func (x *ListReposResponse) ProtoReflect() protoreflect.Message { | |||
| 271 | 343 | ||
| 272 | 344 | // Deprecated: Use ListReposResponse.ProtoReflect.Descriptor instead. | |
| 273 | 345 | func (*ListReposResponse) Descriptor() ([]byte, []int) { | |
| 274 | - | return file_ermite_repo_proto_rawDescGZIP(), []int{2} | |
| 346 | + | return file_ermite_repo_proto_rawDescGZIP(), []int{3} | |
| 275 | 347 | } | |
| 276 | 348 | ||
| 277 | 349 | func (x *ListReposResponse) GetRepos() []*Repo { | |
| @@ -299,7 +371,7 @@ type GetRepoRequest struct { | |||
| 299 | 371 | ||
| 300 | 372 | func (x *GetRepoRequest) Reset() { | |
| 301 | 373 | *x = GetRepoRequest{} | |
| 302 | - | mi := &file_ermite_repo_proto_msgTypes[3] | |
| 374 | + | mi := &file_ermite_repo_proto_msgTypes[4] | |
| 303 | 375 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | |
| 304 | 376 | ms.StoreMessageInfo(mi) | |
| 305 | 377 | } | |
| @@ -311,7 +383,7 @@ func (x *GetRepoRequest) String() string { | |||
| 311 | 383 | func (*GetRepoRequest) ProtoMessage() {} | |
| 312 | 384 | ||
| 313 | 385 | func (x *GetRepoRequest) ProtoReflect() protoreflect.Message { | |
| 314 | - | mi := &file_ermite_repo_proto_msgTypes[3] | |
| 386 | + | mi := &file_ermite_repo_proto_msgTypes[4] | |
| 315 | 387 | if x != nil { | |
| 316 | 388 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | |
| 317 | 389 | if ms.LoadMessageInfo() == nil { | |
| @@ -324,7 +396,7 @@ func (x *GetRepoRequest) ProtoReflect() protoreflect.Message { | |||
| 324 | 396 | ||
| 325 | 397 | // Deprecated: Use GetRepoRequest.ProtoReflect.Descriptor instead. | |
| 326 | 398 | func (*GetRepoRequest) Descriptor() ([]byte, []int) { | |
| 327 | - | return file_ermite_repo_proto_rawDescGZIP(), []int{3} | |
| 399 | + | return file_ermite_repo_proto_rawDescGZIP(), []int{4} | |
| 328 | 400 | } | |
| 329 | 401 | ||
| 330 | 402 | func (x *GetRepoRequest) GetRepo() string { | |
| @@ -345,7 +417,7 @@ type GetRepoResponse struct { | |||
| 345 | 417 | ||
| 346 | 418 | func (x *GetRepoResponse) Reset() { | |
| 347 | 419 | *x = GetRepoResponse{} | |
| 348 | - | mi := &file_ermite_repo_proto_msgTypes[4] | |
| 420 | + | mi := &file_ermite_repo_proto_msgTypes[5] | |
| 349 | 421 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | |
| 350 | 422 | ms.StoreMessageInfo(mi) | |
| 351 | 423 | } | |
| @@ -357,7 +429,7 @@ func (x *GetRepoResponse) String() string { | |||
| 357 | 429 | func (*GetRepoResponse) ProtoMessage() {} | |
| 358 | 430 | ||
| 359 | 431 | func (x *GetRepoResponse) ProtoReflect() protoreflect.Message { | |
| 360 | - | mi := &file_ermite_repo_proto_msgTypes[4] | |
| 432 | + | mi := &file_ermite_repo_proto_msgTypes[5] | |
| 361 | 433 | if x != nil { | |
| 362 | 434 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | |
| 363 | 435 | if ms.LoadMessageInfo() == nil { | |
| @@ -370,7 +442,7 @@ func (x *GetRepoResponse) ProtoReflect() protoreflect.Message { | |||
| 370 | 442 | ||
| 371 | 443 | // Deprecated: Use GetRepoResponse.ProtoReflect.Descriptor instead. | |
| 372 | 444 | func (*GetRepoResponse) Descriptor() ([]byte, []int) { | |
| 373 | - | return file_ermite_repo_proto_rawDescGZIP(), []int{4} | |
| 445 | + | return file_ermite_repo_proto_rawDescGZIP(), []int{5} | |
| 374 | 446 | } | |
| 375 | 447 | ||
| 376 | 448 | func (x *GetRepoResponse) GetRepo() *Repo { | |
| @@ -396,7 +468,7 @@ type CreateRepoRequest struct { | |||
| 396 | 468 | ||
| 397 | 469 | func (x *CreateRepoRequest) Reset() { | |
| 398 | 470 | *x = CreateRepoRequest{} | |
| 399 | - | mi := &file_ermite_repo_proto_msgTypes[5] | |
| 471 | + | mi := &file_ermite_repo_proto_msgTypes[6] | |
| 400 | 472 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | |
| 401 | 473 | ms.StoreMessageInfo(mi) | |
| 402 | 474 | } | |
| @@ -408,7 +480,7 @@ func (x *CreateRepoRequest) String() string { | |||
| 408 | 480 | func (*CreateRepoRequest) ProtoMessage() {} | |
| 409 | 481 | ||
| 410 | 482 | func (x *CreateRepoRequest) ProtoReflect() protoreflect.Message { | |
| 411 | - | mi := &file_ermite_repo_proto_msgTypes[5] | |
| 483 | + | mi := &file_ermite_repo_proto_msgTypes[6] | |
| 412 | 484 | if x != nil { | |
| 413 | 485 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | |
| 414 | 486 | if ms.LoadMessageInfo() == nil { | |
| @@ -421,7 +493,7 @@ func (x *CreateRepoRequest) ProtoReflect() protoreflect.Message { | |||
| 421 | 493 | ||
| 422 | 494 | // Deprecated: Use CreateRepoRequest.ProtoReflect.Descriptor instead. | |
| 423 | 495 | func (*CreateRepoRequest) Descriptor() ([]byte, []int) { | |
| 424 | - | return file_ermite_repo_proto_rawDescGZIP(), []int{5} | |
| 496 | + | return file_ermite_repo_proto_rawDescGZIP(), []int{6} | |
| 425 | 497 | } | |
| 426 | 498 | ||
| 427 | 499 | func (x *CreateRepoRequest) GetName() string { | |
| @@ -456,7 +528,7 @@ type CreateRepoResponse struct { | |||
| 456 | 528 | ||
| 457 | 529 | func (x *CreateRepoResponse) Reset() { | |
| 458 | 530 | *x = CreateRepoResponse{} | |
| 459 | - | mi := &file_ermite_repo_proto_msgTypes[6] | |
| 531 | + | mi := &file_ermite_repo_proto_msgTypes[7] | |
| 460 | 532 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | |
| 461 | 533 | ms.StoreMessageInfo(mi) | |
| 462 | 534 | } | |
| @@ -468,7 +540,7 @@ func (x *CreateRepoResponse) String() string { | |||
| 468 | 540 | func (*CreateRepoResponse) ProtoMessage() {} | |
| 469 | 541 | ||
| 470 | 542 | func (x *CreateRepoResponse) ProtoReflect() protoreflect.Message { | |
| 471 | - | mi := &file_ermite_repo_proto_msgTypes[6] | |
| 543 | + | mi := &file_ermite_repo_proto_msgTypes[7] | |
| 472 | 544 | if x != nil { | |
| 473 | 545 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | |
| 474 | 546 | if ms.LoadMessageInfo() == nil { | |
| @@ -481,7 +553,7 @@ func (x *CreateRepoResponse) ProtoReflect() protoreflect.Message { | |||
| 481 | 553 | ||
| 482 | 554 | // Deprecated: Use CreateRepoResponse.ProtoReflect.Descriptor instead. | |
| 483 | 555 | func (*CreateRepoResponse) Descriptor() ([]byte, []int) { | |
| 484 | - | return file_ermite_repo_proto_rawDescGZIP(), []int{6} | |
| 556 | + | return file_ermite_repo_proto_rawDescGZIP(), []int{7} | |
| 485 | 557 | } | |
| 486 | 558 | ||
| 487 | 559 | func (x *CreateRepoResponse) GetRepo() *Repo { | |
| @@ -507,16 +579,24 @@ type UpdateRepoRequest struct { | |||
| 507 | 579 | // update_mask contains "default_branch". The branch must exist, otherwise | |
| 508 | 580 | // the call fails with failed_precondition. | |
| 509 | 581 | DefaultBranch string `protobuf:"bytes,4,opt,name=default_branch,json=defaultBranch,proto3" json:"default_branch,omitempty"` | |
| 510 | - | // UpdateMask lists the fields to change: "description", "visibility" and/or | |
| 511 | - | // "default_branch". It must not be empty. Other paths are invalid_argument. | |
| 512 | - | UpdateMask *fieldmaskpb.FieldMask `protobuf:"bytes,5,opt,name=update_mask,json=updateMask,proto3" json:"update_mask,omitempty"` | |
| 582 | + | // UpdateMask lists the fields to change: "description", "visibility", | |
| 583 | + | // "default_branch", "settings.allowed_merge_modes" and/or | |
| 584 | + | // "settings.failing_checks_block". "settings" stands for both settings | |
| 585 | + | // paths. It must not be empty. Other paths are invalid_argument. | |
| 586 | + | UpdateMask *fieldmaskpb.FieldMask `protobuf:"bytes,5,opt,name=update_mask,json=updateMask,proto3" json:"update_mask,omitempty"` | |
| 587 | + | // Settings holds the new merge settings. Only the fields named in | |
| 588 | + | // update_mask are used. allowed_merge_modes must then not be empty nor | |
| 589 | + | // contain MERGE_MODE_UNSPECIFIED, otherwise the call fails with | |
| 590 | + | // invalid_argument. Changing settings needs the repo:admin scope, like any | |
| 591 | + | // other field. | |
| 592 | + | Settings *RepoSettings `protobuf:"bytes,6,opt,name=settings,proto3" json:"settings,omitempty"` | |
| 513 | 593 | unknownFields protoimpl.UnknownFields | |
| 514 | 594 | sizeCache protoimpl.SizeCache | |
| 515 | 595 | } | |
| 516 | 596 | ||
| 517 | 597 | func (x *UpdateRepoRequest) Reset() { | |
| 518 | 598 | *x = UpdateRepoRequest{} | |
| 519 | - | mi := &file_ermite_repo_proto_msgTypes[7] | |
| 599 | + | mi := &file_ermite_repo_proto_msgTypes[8] | |
| 520 | 600 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | |
| 521 | 601 | ms.StoreMessageInfo(mi) | |
| 522 | 602 | } | |
| @@ -528,7 +608,7 @@ func (x *UpdateRepoRequest) String() string { | |||
| 528 | 608 | func (*UpdateRepoRequest) ProtoMessage() {} | |
| 529 | 609 | ||
| 530 | 610 | func (x *UpdateRepoRequest) ProtoReflect() protoreflect.Message { | |
| 531 | - | mi := &file_ermite_repo_proto_msgTypes[7] | |
| 611 | + | mi := &file_ermite_repo_proto_msgTypes[8] | |
| 532 | 612 | if x != nil { | |
| 533 | 613 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | |
| 534 | 614 | if ms.LoadMessageInfo() == nil { | |
| @@ -541,7 +621,7 @@ func (x *UpdateRepoRequest) ProtoReflect() protoreflect.Message { | |||
| 541 | 621 | ||
| 542 | 622 | // Deprecated: Use UpdateRepoRequest.ProtoReflect.Descriptor instead. | |
| 543 | 623 | func (*UpdateRepoRequest) Descriptor() ([]byte, []int) { | |
| 544 | - | return file_ermite_repo_proto_rawDescGZIP(), []int{7} | |
| 624 | + | return file_ermite_repo_proto_rawDescGZIP(), []int{8} | |
| 545 | 625 | } | |
| 546 | 626 | ||
| 547 | 627 | func (x *UpdateRepoRequest) GetRepo() string { | |
| @@ -579,6 +659,13 @@ func (x *UpdateRepoRequest) GetUpdateMask() *fieldmaskpb.FieldMask { | |||
| 579 | 659 | return nil | |
| 580 | 660 | } | |
| 581 | 661 | ||
| 662 | + | func (x *UpdateRepoRequest) GetSettings() *RepoSettings { | |
| 663 | + | if x != nil { | |
| 664 | + | return x.Settings | |
| 665 | + | } | |
| 666 | + | return nil | |
| 667 | + | } | |
| 668 | + | ||
| 582 | 669 | // UpdateRepoResponse holds the repository after the update. | |
| 583 | 670 | type UpdateRepoResponse struct { | |
| 584 | 671 | state protoimpl.MessageState `protogen:"open.v1"` | |
| @@ -590,7 +677,7 @@ type UpdateRepoResponse struct { | |||
| 590 | 677 | ||
| 591 | 678 | func (x *UpdateRepoResponse) Reset() { | |
| 592 | 679 | *x = UpdateRepoResponse{} | |
| 593 | - | mi := &file_ermite_repo_proto_msgTypes[8] | |
| 680 | + | mi := &file_ermite_repo_proto_msgTypes[9] | |
| 594 | 681 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | |
| 595 | 682 | ms.StoreMessageInfo(mi) | |
| 596 | 683 | } | |
| @@ -602,7 +689,7 @@ func (x *UpdateRepoResponse) String() string { | |||
| 602 | 689 | func (*UpdateRepoResponse) ProtoMessage() {} | |
| 603 | 690 | ||
| 604 | 691 | func (x *UpdateRepoResponse) ProtoReflect() protoreflect.Message { | |
| 605 | - | mi := &file_ermite_repo_proto_msgTypes[8] | |
| 692 | + | mi := &file_ermite_repo_proto_msgTypes[9] | |
| 606 | 693 | if x != nil { | |
| 607 | 694 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | |
| 608 | 695 | if ms.LoadMessageInfo() == nil { | |
| @@ -615,7 +702,7 @@ func (x *UpdateRepoResponse) ProtoReflect() protoreflect.Message { | |||
| 615 | 702 | ||
| 616 | 703 | // Deprecated: Use UpdateRepoResponse.ProtoReflect.Descriptor instead. | |
| 617 | 704 | func (*UpdateRepoResponse) Descriptor() ([]byte, []int) { | |
| 618 | - | return file_ermite_repo_proto_rawDescGZIP(), []int{8} | |
| 705 | + | return file_ermite_repo_proto_rawDescGZIP(), []int{9} | |
| 619 | 706 | } | |
| 620 | 707 | ||
| 621 | 708 | func (x *UpdateRepoResponse) GetRepo() *Repo { | |
| @@ -636,7 +723,7 @@ type DeleteRepoRequest struct { | |||
| 636 | 723 | ||
| 637 | 724 | func (x *DeleteRepoRequest) Reset() { | |
| 638 | 725 | *x = DeleteRepoRequest{} | |
| 639 | - | mi := &file_ermite_repo_proto_msgTypes[9] | |
| 726 | + | mi := &file_ermite_repo_proto_msgTypes[10] | |
| 640 | 727 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | |
| 641 | 728 | ms.StoreMessageInfo(mi) | |
| 642 | 729 | } | |
| @@ -648,7 +735,7 @@ func (x *DeleteRepoRequest) String() string { | |||
| 648 | 735 | func (*DeleteRepoRequest) ProtoMessage() {} | |
| 649 | 736 | ||
| 650 | 737 | func (x *DeleteRepoRequest) ProtoReflect() protoreflect.Message { | |
| 651 | - | mi := &file_ermite_repo_proto_msgTypes[9] | |
| 738 | + | mi := &file_ermite_repo_proto_msgTypes[10] | |
| 652 | 739 | if x != nil { | |
| 653 | 740 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | |
| 654 | 741 | if ms.LoadMessageInfo() == nil { | |
| @@ -661,7 +748,7 @@ func (x *DeleteRepoRequest) ProtoReflect() protoreflect.Message { | |||
| 661 | 748 | ||
| 662 | 749 | // Deprecated: Use DeleteRepoRequest.ProtoReflect.Descriptor instead. | |
| 663 | 750 | func (*DeleteRepoRequest) Descriptor() ([]byte, []int) { | |
| 664 | - | return file_ermite_repo_proto_rawDescGZIP(), []int{9} | |
| 751 | + | return file_ermite_repo_proto_rawDescGZIP(), []int{10} | |
| 665 | 752 | } | |
| 666 | 753 | ||
| 667 | 754 | func (x *DeleteRepoRequest) GetRepo() string { | |
| @@ -680,7 +767,7 @@ type DeleteRepoResponse struct { | |||
| 680 | 767 | ||
| 681 | 768 | func (x *DeleteRepoResponse) Reset() { | |
| 682 | 769 | *x = DeleteRepoResponse{} | |
| 683 | - | mi := &file_ermite_repo_proto_msgTypes[10] | |
| 770 | + | mi := &file_ermite_repo_proto_msgTypes[11] | |
| 684 | 771 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | |
| 685 | 772 | ms.StoreMessageInfo(mi) | |
| 686 | 773 | } | |
| @@ -692,7 +779,7 @@ func (x *DeleteRepoResponse) String() string { | |||
| 692 | 779 | func (*DeleteRepoResponse) ProtoMessage() {} | |
| 693 | 780 | ||
| 694 | 781 | func (x *DeleteRepoResponse) ProtoReflect() protoreflect.Message { | |
| 695 | - | mi := &file_ermite_repo_proto_msgTypes[10] | |
| 782 | + | mi := &file_ermite_repo_proto_msgTypes[11] | |
| 696 | 783 | if x != nil { | |
| 697 | 784 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | |
| 698 | 785 | if ms.LoadMessageInfo() == nil { | |
| @@ -705,14 +792,17 @@ func (x *DeleteRepoResponse) ProtoReflect() protoreflect.Message { | |||
| 705 | 792 | ||
| 706 | 793 | // Deprecated: Use DeleteRepoResponse.ProtoReflect.Descriptor instead. | |
| 707 | 794 | func (*DeleteRepoResponse) Descriptor() ([]byte, []int) { | |
| 708 | - | return file_ermite_repo_proto_rawDescGZIP(), []int{10} | |
| 795 | + | return file_ermite_repo_proto_rawDescGZIP(), []int{11} | |
| 709 | 796 | } | |
| 710 | 797 | ||
| 711 | 798 | var File_ermite_repo_proto protoreflect.FileDescriptor | |
| 712 | 799 | ||
| 713 | 800 | const file_ermite_repo_proto_rawDesc = "" + | |
| 714 | 801 | "\n" + | |
| 715 | - | "\x11ermite/repo.proto\x12\x06ermite\x1a google/protobuf/field_mask.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\x8b\x02\n" + | |
| 802 | + | "\x11ermite/repo.proto\x12\x06ermite\x1a google/protobuf/field_mask.proto\x1a\x12ermite/types.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\x83\x01\n" + | |
| 803 | + | "\fRepoSettings\x12A\n" + | |
| 804 | + | "\x13allowed_merge_modes\x18\x01 \x03(\x0e2\x11.ermite.MergeModeR\x11allowedMergeModes\x120\n" + | |
| 805 | + | "\x14failing_checks_block\x18\x02 \x01(\bR\x12failingChecksBlock\"\xbd\x02\n" + | |
| 716 | 806 | "\x04Repo\x12\x12\n" + | |
| 717 | 807 | "\x04name\x18\x01 \x01(\tR\x04name\x12 \n" + | |
| 718 | 808 | "\vdescription\x18\x02 \x01(\tR\vdescription\x122\n" + | |
| @@ -722,7 +812,8 @@ const file_ermite_repo_proto_rawDesc = "" + | |||
| 722 | 812 | "\x0edefault_branch\x18\x04 \x01(\tR\rdefaultBranch\x129\n" + | |
| 723 | 813 | "\n" + | |
| 724 | 814 | "created_at\x18\x05 \x01(\v2\x1a.google.protobuf.TimestampR\tcreatedAt\x127\n" + | |
| 725 | - | "\tpushed_at\x18\x06 \x01(\v2\x1a.google.protobuf.TimestampR\bpushedAt\"N\n" + | |
| 815 | + | "\tpushed_at\x18\x06 \x01(\v2\x1a.google.protobuf.TimestampR\bpushedAt\x120\n" + | |
| 816 | + | "\bsettings\x18\a \x01(\v2\x14.ermite.RepoSettingsR\bsettings\"N\n" + | |
| 726 | 817 | "\x10ListReposRequest\x12\x1b\n" + | |
| 727 | 818 | "\tpage_size\x18\x01 \x01(\x05R\bpageSize\x12\x1d\n" + | |
| 728 | 819 | "\n" + | |
| @@ -741,7 +832,7 @@ const file_ermite_repo_proto_rawDesc = "" + | |||
| 741 | 832 | "visibility\x18\x03 \x01(\x0e2\x12.ermite.VisibilityR\n" + | |
| 742 | 833 | "visibility\"6\n" + | |
| 743 | 834 | "\x12CreateRepoResponse\x12 \n" + | |
| 744 | - | "\x04repo\x18\x01 \x01(\v2\f.ermite.RepoR\x04repo\"\xe1\x01\n" + | |
| 835 | + | "\x04repo\x18\x01 \x01(\v2\f.ermite.RepoR\x04repo\"\x93\x02\n" + | |
| 745 | 836 | "\x11UpdateRepoRequest\x12\x12\n" + | |
| 746 | 837 | "\x04repo\x18\x01 \x01(\tR\x04repo\x12 \n" + | |
| 747 | 838 | "\vdescription\x18\x02 \x01(\tR\vdescription\x122\n" + | |
| @@ -750,7 +841,8 @@ const file_ermite_repo_proto_rawDesc = "" + | |||
| 750 | 841 | "visibility\x12%\n" + | |
| 751 | 842 | "\x0edefault_branch\x18\x04 \x01(\tR\rdefaultBranch\x12;\n" + | |
| 752 | 843 | "\vupdate_mask\x18\x05 \x01(\v2\x1a.google.protobuf.FieldMaskR\n" + | |
| 753 | - | "updateMask\"6\n" + | |
| 844 | + | "updateMask\x120\n" + | |
| 845 | + | "\bsettings\x18\x06 \x01(\v2\x14.ermite.RepoSettingsR\bsettings\"6\n" + | |
| 754 | 846 | "\x12UpdateRepoResponse\x12 \n" + | |
| 755 | 847 | "\x04repo\x18\x01 \x01(\v2\f.ermite.RepoR\x04repo\"'\n" + | |
| 756 | 848 | "\x11DeleteRepoRequest\x12\x12\n" + | |
| @@ -786,49 +878,54 @@ func file_ermite_repo_proto_rawDescGZIP() []byte { | |||
| 786 | 878 | } | |
| 787 | 879 | ||
| 788 | 880 | var file_ermite_repo_proto_enumTypes = make([]protoimpl.EnumInfo, 1) | |
| 789 | - | var file_ermite_repo_proto_msgTypes = make([]protoimpl.MessageInfo, 11) | |
| 881 | + | var file_ermite_repo_proto_msgTypes = make([]protoimpl.MessageInfo, 12) | |
| 790 | 882 | var file_ermite_repo_proto_goTypes = []any{ | |
| 791 | 883 | (Visibility)(0), // 0: ermite.Visibility | |
| 792 | - | (*Repo)(nil), // 1: ermite.Repo | |
| 793 | - | (*ListReposRequest)(nil), // 2: ermite.ListReposRequest | |
| 794 | - | (*ListReposResponse)(nil), // 3: ermite.ListReposResponse | |
| 795 | - | (*GetRepoRequest)(nil), // 4: ermite.GetRepoRequest | |
| 796 | - | (*GetRepoResponse)(nil), // 5: ermite.GetRepoResponse | |
| 797 | - | (*CreateRepoRequest)(nil), // 6: ermite.CreateRepoRequest | |
| 798 | - | (*CreateRepoResponse)(nil), // 7: ermite.CreateRepoResponse | |
| 799 | - | (*UpdateRepoRequest)(nil), // 8: ermite.UpdateRepoRequest | |
| 800 | - | (*UpdateRepoResponse)(nil), // 9: ermite.UpdateRepoResponse | |
| 801 | - | (*DeleteRepoRequest)(nil), // 10: ermite.DeleteRepoRequest | |
| 802 | - | (*DeleteRepoResponse)(nil), // 11: ermite.DeleteRepoResponse | |
| 803 | - | (*timestamppb.Timestamp)(nil), // 12: google.protobuf.Timestamp | |
| 804 | - | (*fieldmaskpb.FieldMask)(nil), // 13: google.protobuf.FieldMask | |
| 884 | + | (*RepoSettings)(nil), // 1: ermite.RepoSettings | |
| 885 | + | (*Repo)(nil), // 2: ermite.Repo | |
| 886 | + | (*ListReposRequest)(nil), // 3: ermite.ListReposRequest | |
| 887 | + | (*ListReposResponse)(nil), // 4: ermite.ListReposResponse | |
| 888 | + | (*GetRepoRequest)(nil), // 5: ermite.GetRepoRequest | |
| 889 | + | (*GetRepoResponse)(nil), // 6: ermite.GetRepoResponse | |
| 890 | + | (*CreateRepoRequest)(nil), // 7: ermite.CreateRepoRequest | |
| 891 | + | (*CreateRepoResponse)(nil), // 8: ermite.CreateRepoResponse | |
| 892 | + | (*UpdateRepoRequest)(nil), // 9: ermite.UpdateRepoRequest | |
| 893 | + | (*UpdateRepoResponse)(nil), // 10: ermite.UpdateRepoResponse | |
| 894 | + | (*DeleteRepoRequest)(nil), // 11: ermite.DeleteRepoRequest | |
| 895 | + | (*DeleteRepoResponse)(nil), // 12: ermite.DeleteRepoResponse | |
| 896 | + | (MergeMode)(0), // 13: ermite.MergeMode | |
| 897 | + | (*timestamppb.Timestamp)(nil), // 14: google.protobuf.Timestamp | |
| 898 | + | (*fieldmaskpb.FieldMask)(nil), // 15: google.protobuf.FieldMask | |
| 805 | 899 | } | |
| 806 | 900 | var file_ermite_repo_proto_depIdxs = []int32{ | |
| 807 | - | 0, // 0: ermite.Repo.visibility:type_name -> ermite.Visibility | |
| 808 | - | 12, // 1: ermite.Repo.created_at:type_name -> google.protobuf.Timestamp | |
| 809 | - | 12, // 2: ermite.Repo.pushed_at:type_name -> google.protobuf.Timestamp | |
| 810 | - | 1, // 3: ermite.ListReposResponse.repos:type_name -> ermite.Repo | |
| 811 | - | 1, // 4: ermite.GetRepoResponse.repo:type_name -> ermite.Repo | |
| 812 | - | 0, // 5: ermite.CreateRepoRequest.visibility:type_name -> ermite.Visibility | |
| 813 | - | 1, // 6: ermite.CreateRepoResponse.repo:type_name -> ermite.Repo | |
| 814 | - | 0, // 7: ermite.UpdateRepoRequest.visibility:type_name -> ermite.Visibility | |
| 815 | - | 13, // 8: ermite.UpdateRepoRequest.update_mask:type_name -> google.protobuf.FieldMask | |
| 816 | - | 1, // 9: ermite.UpdateRepoResponse.repo:type_name -> ermite.Repo | |
| 817 | - | 2, // 10: ermite.RepoService.ListRepos:input_type -> ermite.ListReposRequest | |
| 818 | - | 4, // 11: ermite.RepoService.GetRepo:input_type -> ermite.GetRepoRequest | |
| 819 | - | 6, // 12: ermite.RepoService.CreateRepo:input_type -> ermite.CreateRepoRequest | |
| 820 | - | 8, // 13: ermite.RepoService.UpdateRepo:input_type -> ermite.UpdateRepoRequest | |
| 821 | - | 10, // 14: ermite.RepoService.DeleteRepo:input_type -> ermite.DeleteRepoRequest | |
| 822 | - | 3, // 15: ermite.RepoService.ListRepos:output_type -> ermite.ListReposResponse | |
| 823 | - | 5, // 16: ermite.RepoService.GetRepo:output_type -> ermite.GetRepoResponse | |
| 824 | - | 7, // 17: ermite.RepoService.CreateRepo:output_type -> ermite.CreateRepoResponse | |
| 825 | - | 9, // 18: ermite.RepoService.UpdateRepo:output_type -> ermite.UpdateRepoResponse | |
| 826 | - | 11, // 19: ermite.RepoService.DeleteRepo:output_type -> ermite.DeleteRepoResponse | |
| 827 | - | 15, // [15:20] is the sub-list for method output_type | |
| 828 | - | 10, // [10:15] is the sub-list for method input_type | |
| 829 | - | 10, // [10:10] is the sub-list for extension type_name | |
| 830 | - | 10, // [10:10] is the sub-list for extension extendee | |
| 831 | - | 0, // [0:10] is the sub-list for field type_name | |
| 901 | + | 13, // 0: ermite.RepoSettings.allowed_merge_modes:type_name -> ermite.MergeMode | |
| 902 | + | 0, // 1: ermite.Repo.visibility:type_name -> ermite.Visibility | |
| 903 | + | 14, // 2: ermite.Repo.created_at:type_name -> google.protobuf.Timestamp | |
| 904 | + | 14, // 3: ermite.Repo.pushed_at:type_name -> google.protobuf.Timestamp | |
| 905 | + | 1, // 4: ermite.Repo.settings:type_name -> ermite.RepoSettings | |
| 906 | + | 2, // 5: ermite.ListReposResponse.repos:type_name -> ermite.Repo | |
| 907 | + | 2, // 6: ermite.GetRepoResponse.repo:type_name -> ermite.Repo | |
| 908 | + | 0, // 7: ermite.CreateRepoRequest.visibility:type_name -> ermite.Visibility | |
| 909 | + | 2, // 8: ermite.CreateRepoResponse.repo:type_name -> ermite.Repo | |
| 910 | + | 0, // 9: ermite.UpdateRepoRequest.visibility:type_name -> ermite.Visibility | |
| 911 | + | 15, // 10: ermite.UpdateRepoRequest.update_mask:type_name -> google.protobuf.FieldMask | |
| 912 | + | 1, // 11: ermite.UpdateRepoRequest.settings:type_name -> ermite.RepoSettings | |
| 913 | + | 2, // 12: ermite.UpdateRepoResponse.repo:type_name -> ermite.Repo | |
| 914 | + | 3, // 13: ermite.RepoService.ListRepos:input_type -> ermite.ListReposRequest | |
| 915 | + | 5, // 14: ermite.RepoService.GetRepo:input_type -> ermite.GetRepoRequest | |
| 916 | + | 7, // 15: ermite.RepoService.CreateRepo:input_type -> ermite.CreateRepoRequest | |
| 917 | + | 9, // 16: ermite.RepoService.UpdateRepo:input_type -> ermite.UpdateRepoRequest | |
| 918 | + | 11, // 17: ermite.RepoService.DeleteRepo:input_type -> ermite.DeleteRepoRequest | |
| 919 | + | 4, // 18: ermite.RepoService.ListRepos:output_type -> ermite.ListReposResponse | |
| 920 | + | 6, // 19: ermite.RepoService.GetRepo:output_type -> ermite.GetRepoResponse | |
| 921 | + | 8, // 20: ermite.RepoService.CreateRepo:output_type -> ermite.CreateRepoResponse | |
| 922 | + | 10, // 21: ermite.RepoService.UpdateRepo:output_type -> ermite.UpdateRepoResponse | |
| 923 | + | 12, // 22: ermite.RepoService.DeleteRepo:output_type -> ermite.DeleteRepoResponse | |
| 924 | + | 18, // [18:23] is the sub-list for method output_type | |
| 925 | + | 13, // [13:18] is the sub-list for method input_type | |
| 926 | + | 13, // [13:13] is the sub-list for extension type_name | |
| 927 | + | 13, // [13:13] is the sub-list for extension extendee | |
| 928 | + | 0, // [0:13] is the sub-list for field type_name | |
| 832 | 929 | } | |
| 833 | 930 | ||
| 834 | 931 | func init() { file_ermite_repo_proto_init() } | |
| @@ -836,13 +933,14 @@ func file_ermite_repo_proto_init() { | |||
| 836 | 933 | if File_ermite_repo_proto != nil { | |
| 837 | 934 | return | |
| 838 | 935 | } | |
| 936 | + | file_ermite_types_proto_init() | |
| 839 | 937 | type x struct{} | |
| 840 | 938 | out := protoimpl.TypeBuilder{ | |
| 841 | 939 | File: protoimpl.DescBuilder{ | |
| 842 | 940 | GoPackagePath: reflect.TypeOf(x{}).PkgPath(), | |
| 843 | 941 | RawDescriptor: unsafe.Slice(unsafe.StringData(file_ermite_repo_proto_rawDesc), len(file_ermite_repo_proto_rawDesc)), | |
| 844 | 942 | NumEnums: 1, | |
| 845 | - | NumMessages: 11, | |
| 943 | + | NumMessages: 12, | |
| 846 | 944 | NumExtensions: 0, | |
| 847 | 945 | NumServices: 1, | |
| 848 | 946 | }, | |
| @@ -80,6 +80,68 @@ func (Visibility) EnumDescriptor() ([]byte, []int) { | |||||
| 80 | return file_ermite_repo_proto_rawDescGZIP(), []int{0} | 80 | return file_ermite_repo_proto_rawDescGZIP(), []int{0} | ||
| 81 | } | 81 | } | ||
| 82 | 82 | ||||
| 83 | + | // RepoSettings are the settings of a repository that govern its merge | |||
| 84 | + | // requests. | |||
| 85 | + | type RepoSettings struct { | |||
| 86 | + | state protoimpl.MessageState `protogen:"open.v1"` | |||
| 87 | + | // AllowedMergeModes are the modes with which a merge request of the | |||
| 88 | + | // repository may be merged. It is never empty in a response and has no | |||
| 89 | + | // duplicate. Both MERGE_MODE_FAST_FORWARD and MERGE_MODE_SQUASH are allowed | |||
| 90 | + | // by default. MERGE_MODE_UNSPECIFIED is rejected. | |||
| 91 | + | AllowedMergeModes []MergeMode `protobuf:"varint,1,rep,packed,name=allowed_merge_modes,json=allowedMergeModes,proto3,enum=ermite.MergeMode" json:"allowed_merge_modes,omitempty"` | |||
| 92 | + | // FailingChecksBlock says whether a merge request whose checks fail cannot be | |||
| 93 | + | // merged. It is true at creation of the repository and always stored | |||
| 94 | + | // explicitly, so a later change of the server default never alters an | |||
| 95 | + | // existing repository. | |||
| 96 | + | FailingChecksBlock bool `protobuf:"varint,2,opt,name=failing_checks_block,json=failingChecksBlock,proto3" json:"failing_checks_block,omitempty"` | |||
| 97 | + | unknownFields protoimpl.UnknownFields | |||
| 98 | + | sizeCache protoimpl.SizeCache | |||
| 99 | + | } | |||
| 100 | + | ||||
| 101 | + | func (x *RepoSettings) Reset() { | |||
| 102 | + | *x = RepoSettings{} | |||
| 103 | + | mi := &file_ermite_repo_proto_msgTypes[0] | |||
| 104 | + | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | |||
| 105 | + | ms.StoreMessageInfo(mi) | |||
| 106 | + | } | |||
| 107 | + | ||||
| 108 | + | func (x *RepoSettings) String() string { | |||
| 109 | + | return protoimpl.X.MessageStringOf(x) | |||
| 110 | + | } | |||
| 111 | + | ||||
| 112 | + | func (*RepoSettings) ProtoMessage() {} | |||
| 113 | + | ||||
| 114 | + | func (x *RepoSettings) ProtoReflect() protoreflect.Message { | |||
| 115 | + | mi := &file_ermite_repo_proto_msgTypes[0] | |||
| 116 | + | if x != nil { | |||
| 117 | + | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | |||
| 118 | + | if ms.LoadMessageInfo() == nil { | |||
| 119 | + | ms.StoreMessageInfo(mi) | |||
| 120 | + | } | |||
| 121 | + | return ms | |||
| 122 | + | } | |||
| 123 | + | return mi.MessageOf(x) | |||
| 124 | + | } | |||
| 125 | + | ||||
| 126 | + | // Deprecated: Use RepoSettings.ProtoReflect.Descriptor instead. | |||
| 127 | + | func (*RepoSettings) Descriptor() ([]byte, []int) { | |||
| 128 | + | return file_ermite_repo_proto_rawDescGZIP(), []int{0} | |||
| 129 | + | } | |||
| 130 | + | ||||
| 131 | + | func (x *RepoSettings) GetAllowedMergeModes() []MergeMode { | |||
| 132 | + | if x != nil { | |||
| 133 | + | return x.AllowedMergeModes | |||
| 134 | + | } | |||
| 135 | + | return nil | |||
| 136 | + | } | |||
| 137 | + | ||||
| 138 | + | func (x *RepoSettings) GetFailingChecksBlock() bool { | |||
| 139 | + | if x != nil { | |||
| 140 | + | return x.FailingChecksBlock | |||
| 141 | + | } | |||
| 142 | + | return false | |||
| 143 | + | } | |||
| 144 | + | ||||
| 83 | // Repo is the metadata of a repository. Git-owned state (refs, trees, history) | 145 | // Repo is the metadata of a repository. Git-owned state (refs, trees, history) | ||
| 84 | // is read through GitService. | 146 | // is read through GitService. | ||
| 85 | type Repo struct { | 147 | type Repo struct { | ||
| @@ -98,14 +160,17 @@ type Repo struct { | |||||
| 98 | // CreatedAt is when the repository was created. | 160 | // CreatedAt is when the repository was created. | ||
| 99 | CreatedAt *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` | 161 | CreatedAt *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` | ||
| 100 | // PushedAt is the time of the last push. It is unset until the first push. | 162 | // PushedAt is the time of the last push. It is unset until the first push. | ||
| 101 | - | PushedAt *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=pushed_at,json=pushedAt,proto3" json:"pushed_at,omitempty"` | 163 | + | PushedAt *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=pushed_at,json=pushedAt,proto3" json:"pushed_at,omitempty"` |
| 164 | + | // Settings are the merge settings of the repository. Always set in a | |||
| 165 | + | // response, with the defaults for a repository that never changed them. | |||
| 166 | + | Settings *RepoSettings `protobuf:"bytes,7,opt,name=settings,proto3" json:"settings,omitempty"` | |||
| 102 | unknownFields protoimpl.UnknownFields | 167 | unknownFields protoimpl.UnknownFields | ||
| 103 | sizeCache protoimpl.SizeCache | 168 | sizeCache protoimpl.SizeCache | ||
| 104 | } | 169 | } | ||
| 105 | 170 | ||||
| 106 | func (x *Repo) Reset() { | 171 | func (x *Repo) Reset() { | ||
| 107 | *x = Repo{} | 172 | *x = Repo{} | ||
| 108 | - | mi := &file_ermite_repo_proto_msgTypes[0] | 173 | + | mi := &file_ermite_repo_proto_msgTypes[1] |
| 109 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 174 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||
| 110 | ms.StoreMessageInfo(mi) | 175 | ms.StoreMessageInfo(mi) | ||
| 111 | } | 176 | } | ||
| @@ -117,7 +182,7 @@ func (x *Repo) String() string { | |||||
| 117 | func (*Repo) ProtoMessage() {} | 182 | func (*Repo) ProtoMessage() {} | ||
| 118 | 183 | ||||
| 119 | func (x *Repo) ProtoReflect() protoreflect.Message { | 184 | func (x *Repo) ProtoReflect() protoreflect.Message { | ||
| 120 | - | mi := &file_ermite_repo_proto_msgTypes[0] | 185 | + | mi := &file_ermite_repo_proto_msgTypes[1] |
| 121 | if x != nil { | 186 | if x != nil { | ||
| 122 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 187 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||
| 123 | if ms.LoadMessageInfo() == nil { | 188 | if ms.LoadMessageInfo() == nil { | ||
| @@ -130,7 +195,7 @@ func (x *Repo) ProtoReflect() protoreflect.Message { | |||||
| 130 | 195 | ||||
| 131 | // Deprecated: Use Repo.ProtoReflect.Descriptor instead. | 196 | // Deprecated: Use Repo.ProtoReflect.Descriptor instead. | ||
| 132 | func (*Repo) Descriptor() ([]byte, []int) { | 197 | func (*Repo) Descriptor() ([]byte, []int) { | ||
| 133 | - | return file_ermite_repo_proto_rawDescGZIP(), []int{0} | 198 | + | return file_ermite_repo_proto_rawDescGZIP(), []int{1} |
| 134 | } | 199 | } | ||
| 135 | 200 | ||||
| 136 | func (x *Repo) GetName() string { | 201 | func (x *Repo) GetName() string { | ||
| @@ -175,6 +240,13 @@ func (x *Repo) GetPushedAt() *timestamppb.Timestamp { | |||||
| 175 | return nil | 240 | return nil | ||
| 176 | } | 241 | } | ||
| 177 | 242 | ||||
| 243 | + | func (x *Repo) GetSettings() *RepoSettings { | |||
| 244 | + | if x != nil { | |||
| 245 | + | return x.Settings | |||
| 246 | + | } | |||
| 247 | + | return nil | |||
| 248 | + | } | |||
| 249 | + | ||||
| 178 | // ListReposRequest selects a page of repositories. | 250 | // ListReposRequest selects a page of repositories. | ||
| 179 | type ListReposRequest struct { | 251 | type ListReposRequest struct { | ||
| 180 | state protoimpl.MessageState `protogen:"open.v1"` | 252 | state protoimpl.MessageState `protogen:"open.v1"` | ||
| @@ -190,7 +262,7 @@ type ListReposRequest struct { | |||||
| 190 | 262 | ||||
| 191 | func (x *ListReposRequest) Reset() { | 263 | func (x *ListReposRequest) Reset() { | ||
| 192 | *x = ListReposRequest{} | 264 | *x = ListReposRequest{} | ||
| 193 | - | mi := &file_ermite_repo_proto_msgTypes[1] | 265 | + | mi := &file_ermite_repo_proto_msgTypes[2] |
| 194 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 266 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||
| 195 | ms.StoreMessageInfo(mi) | 267 | ms.StoreMessageInfo(mi) | ||
| 196 | } | 268 | } | ||
| @@ -202,7 +274,7 @@ func (x *ListReposRequest) String() string { | |||||
| 202 | func (*ListReposRequest) ProtoMessage() {} | 274 | func (*ListReposRequest) ProtoMessage() {} | ||
| 203 | 275 | ||||
| 204 | func (x *ListReposRequest) ProtoReflect() protoreflect.Message { | 276 | func (x *ListReposRequest) ProtoReflect() protoreflect.Message { | ||
| 205 | - | mi := &file_ermite_repo_proto_msgTypes[1] | 277 | + | mi := &file_ermite_repo_proto_msgTypes[2] |
| 206 | if x != nil { | 278 | if x != nil { | ||
| 207 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 279 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||
| 208 | if ms.LoadMessageInfo() == nil { | 280 | if ms.LoadMessageInfo() == nil { | ||
| @@ -215,7 +287,7 @@ func (x *ListReposRequest) ProtoReflect() protoreflect.Message { | |||||
| 215 | 287 | ||||
| 216 | // Deprecated: Use ListReposRequest.ProtoReflect.Descriptor instead. | 288 | // Deprecated: Use ListReposRequest.ProtoReflect.Descriptor instead. | ||
| 217 | func (*ListReposRequest) Descriptor() ([]byte, []int) { | 289 | func (*ListReposRequest) Descriptor() ([]byte, []int) { | ||
| 218 | - | return file_ermite_repo_proto_rawDescGZIP(), []int{1} | 290 | + | return file_ermite_repo_proto_rawDescGZIP(), []int{2} |
| 219 | } | 291 | } | ||
| 220 | 292 | ||||
| 221 | func (x *ListReposRequest) GetPageSize() int32 { | 293 | func (x *ListReposRequest) GetPageSize() int32 { | ||
| @@ -246,7 +318,7 @@ type ListReposResponse struct { | |||||
| 246 | 318 | ||||
| 247 | func (x *ListReposResponse) Reset() { | 319 | func (x *ListReposResponse) Reset() { | ||
| 248 | *x = ListReposResponse{} | 320 | *x = ListReposResponse{} | ||
| 249 | - | mi := &file_ermite_repo_proto_msgTypes[2] | 321 | + | mi := &file_ermite_repo_proto_msgTypes[3] |
| 250 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 322 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||
| 251 | ms.StoreMessageInfo(mi) | 323 | ms.StoreMessageInfo(mi) | ||
| 252 | } | 324 | } | ||
| @@ -258,7 +330,7 @@ func (x *ListReposResponse) String() string { | |||||
| 258 | func (*ListReposResponse) ProtoMessage() {} | 330 | func (*ListReposResponse) ProtoMessage() {} | ||
| 259 | 331 | ||||
| 260 | func (x *ListReposResponse) ProtoReflect() protoreflect.Message { | 332 | func (x *ListReposResponse) ProtoReflect() protoreflect.Message { | ||
| 261 | - | mi := &file_ermite_repo_proto_msgTypes[2] | 333 | + | mi := &file_ermite_repo_proto_msgTypes[3] |
| 262 | if x != nil { | 334 | if x != nil { | ||
| 263 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 335 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||
| 264 | if ms.LoadMessageInfo() == nil { | 336 | if ms.LoadMessageInfo() == nil { | ||
| @@ -271,7 +343,7 @@ func (x *ListReposResponse) ProtoReflect() protoreflect.Message { | |||||
| 271 | 343 | ||||
| 272 | // Deprecated: Use ListReposResponse.ProtoReflect.Descriptor instead. | 344 | // Deprecated: Use ListReposResponse.ProtoReflect.Descriptor instead. | ||
| 273 | func (*ListReposResponse) Descriptor() ([]byte, []int) { | 345 | func (*ListReposResponse) Descriptor() ([]byte, []int) { | ||
| 274 | - | return file_ermite_repo_proto_rawDescGZIP(), []int{2} | 346 | + | return file_ermite_repo_proto_rawDescGZIP(), []int{3} |
| 275 | } | 347 | } | ||
| 276 | 348 | ||||
| 277 | func (x *ListReposResponse) GetRepos() []*Repo { | 349 | func (x *ListReposResponse) GetRepos() []*Repo { | ||
| @@ -299,7 +371,7 @@ type GetRepoRequest struct { | |||||
| 299 | 371 | ||||
| 300 | func (x *GetRepoRequest) Reset() { | 372 | func (x *GetRepoRequest) Reset() { | ||
| 301 | *x = GetRepoRequest{} | 373 | *x = GetRepoRequest{} | ||
| 302 | - | mi := &file_ermite_repo_proto_msgTypes[3] | 374 | + | mi := &file_ermite_repo_proto_msgTypes[4] |
| 303 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 375 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||
| 304 | ms.StoreMessageInfo(mi) | 376 | ms.StoreMessageInfo(mi) | ||
| 305 | } | 377 | } | ||
| @@ -311,7 +383,7 @@ func (x *GetRepoRequest) String() string { | |||||
| 311 | func (*GetRepoRequest) ProtoMessage() {} | 383 | func (*GetRepoRequest) ProtoMessage() {} | ||
| 312 | 384 | ||||
| 313 | func (x *GetRepoRequest) ProtoReflect() protoreflect.Message { | 385 | func (x *GetRepoRequest) ProtoReflect() protoreflect.Message { | ||
| 314 | - | mi := &file_ermite_repo_proto_msgTypes[3] | 386 | + | mi := &file_ermite_repo_proto_msgTypes[4] |
| 315 | if x != nil { | 387 | if x != nil { | ||
| 316 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 388 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||
| 317 | if ms.LoadMessageInfo() == nil { | 389 | if ms.LoadMessageInfo() == nil { | ||
| @@ -324,7 +396,7 @@ func (x *GetRepoRequest) ProtoReflect() protoreflect.Message { | |||||
| 324 | 396 | ||||
| 325 | // Deprecated: Use GetRepoRequest.ProtoReflect.Descriptor instead. | 397 | // Deprecated: Use GetRepoRequest.ProtoReflect.Descriptor instead. | ||
| 326 | func (*GetRepoRequest) Descriptor() ([]byte, []int) { | 398 | func (*GetRepoRequest) Descriptor() ([]byte, []int) { | ||
| 327 | - | return file_ermite_repo_proto_rawDescGZIP(), []int{3} | 399 | + | return file_ermite_repo_proto_rawDescGZIP(), []int{4} |
| 328 | } | 400 | } | ||
| 329 | 401 | ||||
| 330 | func (x *GetRepoRequest) GetRepo() string { | 402 | func (x *GetRepoRequest) GetRepo() string { | ||
| @@ -345,7 +417,7 @@ type GetRepoResponse struct { | |||||
| 345 | 417 | ||||
| 346 | func (x *GetRepoResponse) Reset() { | 418 | func (x *GetRepoResponse) Reset() { | ||
| 347 | *x = GetRepoResponse{} | 419 | *x = GetRepoResponse{} | ||
| 348 | - | mi := &file_ermite_repo_proto_msgTypes[4] | 420 | + | mi := &file_ermite_repo_proto_msgTypes[5] |
| 349 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 421 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||
| 350 | ms.StoreMessageInfo(mi) | 422 | ms.StoreMessageInfo(mi) | ||
| 351 | } | 423 | } | ||
| @@ -357,7 +429,7 @@ func (x *GetRepoResponse) String() string { | |||||
| 357 | func (*GetRepoResponse) ProtoMessage() {} | 429 | func (*GetRepoResponse) ProtoMessage() {} | ||
| 358 | 430 | ||||
| 359 | func (x *GetRepoResponse) ProtoReflect() protoreflect.Message { | 431 | func (x *GetRepoResponse) ProtoReflect() protoreflect.Message { | ||
| 360 | - | mi := &file_ermite_repo_proto_msgTypes[4] | 432 | + | mi := &file_ermite_repo_proto_msgTypes[5] |
| 361 | if x != nil { | 433 | if x != nil { | ||
| 362 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 434 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||
| 363 | if ms.LoadMessageInfo() == nil { | 435 | if ms.LoadMessageInfo() == nil { | ||
| @@ -370,7 +442,7 @@ func (x *GetRepoResponse) ProtoReflect() protoreflect.Message { | |||||
| 370 | 442 | ||||
| 371 | // Deprecated: Use GetRepoResponse.ProtoReflect.Descriptor instead. | 443 | // Deprecated: Use GetRepoResponse.ProtoReflect.Descriptor instead. | ||
| 372 | func (*GetRepoResponse) Descriptor() ([]byte, []int) { | 444 | func (*GetRepoResponse) Descriptor() ([]byte, []int) { | ||
| 373 | - | return file_ermite_repo_proto_rawDescGZIP(), []int{4} | 445 | + | return file_ermite_repo_proto_rawDescGZIP(), []int{5} |
| 374 | } | 446 | } | ||
| 375 | 447 | ||||
| 376 | func (x *GetRepoResponse) GetRepo() *Repo { | 448 | func (x *GetRepoResponse) GetRepo() *Repo { | ||
| @@ -396,7 +468,7 @@ type CreateRepoRequest struct { | |||||
| 396 | 468 | ||||
| 397 | func (x *CreateRepoRequest) Reset() { | 469 | func (x *CreateRepoRequest) Reset() { | ||
| 398 | *x = CreateRepoRequest{} | 470 | *x = CreateRepoRequest{} | ||
| 399 | - | mi := &file_ermite_repo_proto_msgTypes[5] | 471 | + | mi := &file_ermite_repo_proto_msgTypes[6] |
| 400 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 472 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||
| 401 | ms.StoreMessageInfo(mi) | 473 | ms.StoreMessageInfo(mi) | ||
| 402 | } | 474 | } | ||
| @@ -408,7 +480,7 @@ func (x *CreateRepoRequest) String() string { | |||||
| 408 | func (*CreateRepoRequest) ProtoMessage() {} | 480 | func (*CreateRepoRequest) ProtoMessage() {} | ||
| 409 | 481 | ||||
| 410 | func (x *CreateRepoRequest) ProtoReflect() protoreflect.Message { | 482 | func (x *CreateRepoRequest) ProtoReflect() protoreflect.Message { | ||
| 411 | - | mi := &file_ermite_repo_proto_msgTypes[5] | 483 | + | mi := &file_ermite_repo_proto_msgTypes[6] |
| 412 | if x != nil { | 484 | if x != nil { | ||
| 413 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 485 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||
| 414 | if ms.LoadMessageInfo() == nil { | 486 | if ms.LoadMessageInfo() == nil { | ||
| @@ -421,7 +493,7 @@ func (x *CreateRepoRequest) ProtoReflect() protoreflect.Message { | |||||
| 421 | 493 | ||||
| 422 | // Deprecated: Use CreateRepoRequest.ProtoReflect.Descriptor instead. | 494 | // Deprecated: Use CreateRepoRequest.ProtoReflect.Descriptor instead. | ||
| 423 | func (*CreateRepoRequest) Descriptor() ([]byte, []int) { | 495 | func (*CreateRepoRequest) Descriptor() ([]byte, []int) { | ||
| 424 | - | return file_ermite_repo_proto_rawDescGZIP(), []int{5} | 496 | + | return file_ermite_repo_proto_rawDescGZIP(), []int{6} |
| 425 | } | 497 | } | ||
| 426 | 498 | ||||
| 427 | func (x *CreateRepoRequest) GetName() string { | 499 | func (x *CreateRepoRequest) GetName() string { | ||
| @@ -456,7 +528,7 @@ type CreateRepoResponse struct { | |||||
| 456 | 528 | ||||
| 457 | func (x *CreateRepoResponse) Reset() { | 529 | func (x *CreateRepoResponse) Reset() { | ||
| 458 | *x = CreateRepoResponse{} | 530 | *x = CreateRepoResponse{} | ||
| 459 | - | mi := &file_ermite_repo_proto_msgTypes[6] | 531 | + | mi := &file_ermite_repo_proto_msgTypes[7] |
| 460 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 532 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||
| 461 | ms.StoreMessageInfo(mi) | 533 | ms.StoreMessageInfo(mi) | ||
| 462 | } | 534 | } | ||
| @@ -468,7 +540,7 @@ func (x *CreateRepoResponse) String() string { | |||||
| 468 | func (*CreateRepoResponse) ProtoMessage() {} | 540 | func (*CreateRepoResponse) ProtoMessage() {} | ||
| 469 | 541 | ||||
| 470 | func (x *CreateRepoResponse) ProtoReflect() protoreflect.Message { | 542 | func (x *CreateRepoResponse) ProtoReflect() protoreflect.Message { | ||
| 471 | - | mi := &file_ermite_repo_proto_msgTypes[6] | 543 | + | mi := &file_ermite_repo_proto_msgTypes[7] |
| 472 | if x != nil { | 544 | if x != nil { | ||
| 473 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 545 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||
| 474 | if ms.LoadMessageInfo() == nil { | 546 | if ms.LoadMessageInfo() == nil { | ||
| @@ -481,7 +553,7 @@ func (x *CreateRepoResponse) ProtoReflect() protoreflect.Message { | |||||
| 481 | 553 | ||||
| 482 | // Deprecated: Use CreateRepoResponse.ProtoReflect.Descriptor instead. | 554 | // Deprecated: Use CreateRepoResponse.ProtoReflect.Descriptor instead. | ||
| 483 | func (*CreateRepoResponse) Descriptor() ([]byte, []int) { | 555 | func (*CreateRepoResponse) Descriptor() ([]byte, []int) { | ||
| 484 | - | return file_ermite_repo_proto_rawDescGZIP(), []int{6} | 556 | + | return file_ermite_repo_proto_rawDescGZIP(), []int{7} |
| 485 | } | 557 | } | ||
| 486 | 558 | ||||
| 487 | func (x *CreateRepoResponse) GetRepo() *Repo { | 559 | func (x *CreateRepoResponse) GetRepo() *Repo { | ||
| @@ -507,16 +579,24 @@ type UpdateRepoRequest struct { | |||||
| 507 | // update_mask contains "default_branch". The branch must exist, otherwise | 579 | // update_mask contains "default_branch". The branch must exist, otherwise | ||
| 508 | // the call fails with failed_precondition. | 580 | // the call fails with failed_precondition. | ||
| 509 | DefaultBranch string `protobuf:"bytes,4,opt,name=default_branch,json=defaultBranch,proto3" json:"default_branch,omitempty"` | 581 | DefaultBranch string `protobuf:"bytes,4,opt,name=default_branch,json=defaultBranch,proto3" json:"default_branch,omitempty"` | ||
| 510 | - | // UpdateMask lists the fields to change: "description", "visibility" and/or | 582 | + | // UpdateMask lists the fields to change: "description", "visibility", |
| 511 | - | // "default_branch". It must not be empty. Other paths are invalid_argument. | 583 | + | // "default_branch", "settings.allowed_merge_modes" and/or |
| 512 | - | UpdateMask *fieldmaskpb.FieldMask `protobuf:"bytes,5,opt,name=update_mask,json=updateMask,proto3" json:"update_mask,omitempty"` | 584 | + | // "settings.failing_checks_block". "settings" stands for both settings |
| 585 | + | // paths. It must not be empty. Other paths are invalid_argument. | |||
| 586 | + | UpdateMask *fieldmaskpb.FieldMask `protobuf:"bytes,5,opt,name=update_mask,json=updateMask,proto3" json:"update_mask,omitempty"` | |||
| 587 | + | // Settings holds the new merge settings. Only the fields named in | |||
| 588 | + | // update_mask are used. allowed_merge_modes must then not be empty nor | |||
| 589 | + | // contain MERGE_MODE_UNSPECIFIED, otherwise the call fails with | |||
| 590 | + | // invalid_argument. Changing settings needs the repo:admin scope, like any | |||
| 591 | + | // other field. | |||
| 592 | + | Settings *RepoSettings `protobuf:"bytes,6,opt,name=settings,proto3" json:"settings,omitempty"` | |||
| 513 | unknownFields protoimpl.UnknownFields | 593 | unknownFields protoimpl.UnknownFields | ||
| 514 | sizeCache protoimpl.SizeCache | 594 | sizeCache protoimpl.SizeCache | ||
| 515 | } | 595 | } | ||
| 516 | 596 | ||||
| 517 | func (x *UpdateRepoRequest) Reset() { | 597 | func (x *UpdateRepoRequest) Reset() { | ||
| 518 | *x = UpdateRepoRequest{} | 598 | *x = UpdateRepoRequest{} | ||
| 519 | - | mi := &file_ermite_repo_proto_msgTypes[7] | 599 | + | mi := &file_ermite_repo_proto_msgTypes[8] |
| 520 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 600 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||
| 521 | ms.StoreMessageInfo(mi) | 601 | ms.StoreMessageInfo(mi) | ||
| 522 | } | 602 | } | ||
| @@ -528,7 +608,7 @@ func (x *UpdateRepoRequest) String() string { | |||||
| 528 | func (*UpdateRepoRequest) ProtoMessage() {} | 608 | func (*UpdateRepoRequest) ProtoMessage() {} | ||
| 529 | 609 | ||||
| 530 | func (x *UpdateRepoRequest) ProtoReflect() protoreflect.Message { | 610 | func (x *UpdateRepoRequest) ProtoReflect() protoreflect.Message { | ||
| 531 | - | mi := &file_ermite_repo_proto_msgTypes[7] | 611 | + | mi := &file_ermite_repo_proto_msgTypes[8] |
| 532 | if x != nil { | 612 | if x != nil { | ||
| 533 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 613 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||
| 534 | if ms.LoadMessageInfo() == nil { | 614 | if ms.LoadMessageInfo() == nil { | ||
| @@ -541,7 +621,7 @@ func (x *UpdateRepoRequest) ProtoReflect() protoreflect.Message { | |||||
| 541 | 621 | ||||
| 542 | // Deprecated: Use UpdateRepoRequest.ProtoReflect.Descriptor instead. | 622 | // Deprecated: Use UpdateRepoRequest.ProtoReflect.Descriptor instead. | ||
| 543 | func (*UpdateRepoRequest) Descriptor() ([]byte, []int) { | 623 | func (*UpdateRepoRequest) Descriptor() ([]byte, []int) { | ||
| 544 | - | return file_ermite_repo_proto_rawDescGZIP(), []int{7} | 624 | + | return file_ermite_repo_proto_rawDescGZIP(), []int{8} |
| 545 | } | 625 | } | ||
| 546 | 626 | ||||
| 547 | func (x *UpdateRepoRequest) GetRepo() string { | 627 | func (x *UpdateRepoRequest) GetRepo() string { | ||
| @@ -579,6 +659,13 @@ func (x *UpdateRepoRequest) GetUpdateMask() *fieldmaskpb.FieldMask { | |||||
| 579 | return nil | 659 | return nil | ||
| 580 | } | 660 | } | ||
| 581 | 661 | ||||
| 662 | + | func (x *UpdateRepoRequest) GetSettings() *RepoSettings { | |||
| 663 | + | if x != nil { | |||
| 664 | + | return x.Settings | |||
| 665 | + | } | |||
| 666 | + | return nil | |||
| 667 | + | } | |||
| 668 | + | ||||
| 582 | // UpdateRepoResponse holds the repository after the update. | 669 | // UpdateRepoResponse holds the repository after the update. | ||
| 583 | type UpdateRepoResponse struct { | 670 | type UpdateRepoResponse struct { | ||
| 584 | state protoimpl.MessageState `protogen:"open.v1"` | 671 | state protoimpl.MessageState `protogen:"open.v1"` | ||
| @@ -590,7 +677,7 @@ type UpdateRepoResponse struct { | |||||
| 590 | 677 | ||||
| 591 | func (x *UpdateRepoResponse) Reset() { | 678 | func (x *UpdateRepoResponse) Reset() { | ||
| 592 | *x = UpdateRepoResponse{} | 679 | *x = UpdateRepoResponse{} | ||
| 593 | - | mi := &file_ermite_repo_proto_msgTypes[8] | 680 | + | mi := &file_ermite_repo_proto_msgTypes[9] |
| 594 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 681 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||
| 595 | ms.StoreMessageInfo(mi) | 682 | ms.StoreMessageInfo(mi) | ||
| 596 | } | 683 | } | ||
| @@ -602,7 +689,7 @@ func (x *UpdateRepoResponse) String() string { | |||||
| 602 | func (*UpdateRepoResponse) ProtoMessage() {} | 689 | func (*UpdateRepoResponse) ProtoMessage() {} | ||
| 603 | 690 | ||||
| 604 | func (x *UpdateRepoResponse) ProtoReflect() protoreflect.Message { | 691 | func (x *UpdateRepoResponse) ProtoReflect() protoreflect.Message { | ||
| 605 | - | mi := &file_ermite_repo_proto_msgTypes[8] | 692 | + | mi := &file_ermite_repo_proto_msgTypes[9] |
| 606 | if x != nil { | 693 | if x != nil { | ||
| 607 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 694 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||
| 608 | if ms.LoadMessageInfo() == nil { | 695 | if ms.LoadMessageInfo() == nil { | ||
| @@ -615,7 +702,7 @@ func (x *UpdateRepoResponse) ProtoReflect() protoreflect.Message { | |||||
| 615 | 702 | ||||
| 616 | // Deprecated: Use UpdateRepoResponse.ProtoReflect.Descriptor instead. | 703 | // Deprecated: Use UpdateRepoResponse.ProtoReflect.Descriptor instead. | ||
| 617 | func (*UpdateRepoResponse) Descriptor() ([]byte, []int) { | 704 | func (*UpdateRepoResponse) Descriptor() ([]byte, []int) { | ||
| 618 | - | return file_ermite_repo_proto_rawDescGZIP(), []int{8} | 705 | + | return file_ermite_repo_proto_rawDescGZIP(), []int{9} |
| 619 | } | 706 | } | ||
| 620 | 707 | ||||
| 621 | func (x *UpdateRepoResponse) GetRepo() *Repo { | 708 | func (x *UpdateRepoResponse) GetRepo() *Repo { | ||
| @@ -636,7 +723,7 @@ type DeleteRepoRequest struct { | |||||
| 636 | 723 | ||||
| 637 | func (x *DeleteRepoRequest) Reset() { | 724 | func (x *DeleteRepoRequest) Reset() { | ||
| 638 | *x = DeleteRepoRequest{} | 725 | *x = DeleteRepoRequest{} | ||
| 639 | - | mi := &file_ermite_repo_proto_msgTypes[9] | 726 | + | mi := &file_ermite_repo_proto_msgTypes[10] |
| 640 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 727 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||
| 641 | ms.StoreMessageInfo(mi) | 728 | ms.StoreMessageInfo(mi) | ||
| 642 | } | 729 | } | ||
| @@ -648,7 +735,7 @@ func (x *DeleteRepoRequest) String() string { | |||||
| 648 | func (*DeleteRepoRequest) ProtoMessage() {} | 735 | func (*DeleteRepoRequest) ProtoMessage() {} | ||
| 649 | 736 | ||||
| 650 | func (x *DeleteRepoRequest) ProtoReflect() protoreflect.Message { | 737 | func (x *DeleteRepoRequest) ProtoReflect() protoreflect.Message { | ||
| 651 | - | mi := &file_ermite_repo_proto_msgTypes[9] | 738 | + | mi := &file_ermite_repo_proto_msgTypes[10] |
| 652 | if x != nil { | 739 | if x != nil { | ||
| 653 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 740 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||
| 654 | if ms.LoadMessageInfo() == nil { | 741 | if ms.LoadMessageInfo() == nil { | ||
| @@ -661,7 +748,7 @@ func (x *DeleteRepoRequest) ProtoReflect() protoreflect.Message { | |||||
| 661 | 748 | ||||
| 662 | // Deprecated: Use DeleteRepoRequest.ProtoReflect.Descriptor instead. | 749 | // Deprecated: Use DeleteRepoRequest.ProtoReflect.Descriptor instead. | ||
| 663 | func (*DeleteRepoRequest) Descriptor() ([]byte, []int) { | 750 | func (*DeleteRepoRequest) Descriptor() ([]byte, []int) { | ||
| 664 | - | return file_ermite_repo_proto_rawDescGZIP(), []int{9} | 751 | + | return file_ermite_repo_proto_rawDescGZIP(), []int{10} |
| 665 | } | 752 | } | ||
| 666 | 753 | ||||
| 667 | func (x *DeleteRepoRequest) GetRepo() string { | 754 | func (x *DeleteRepoRequest) GetRepo() string { | ||
| @@ -680,7 +767,7 @@ type DeleteRepoResponse struct { | |||||
| 680 | 767 | ||||
| 681 | func (x *DeleteRepoResponse) Reset() { | 768 | func (x *DeleteRepoResponse) Reset() { | ||
| 682 | *x = DeleteRepoResponse{} | 769 | *x = DeleteRepoResponse{} | ||
| 683 | - | mi := &file_ermite_repo_proto_msgTypes[10] | 770 | + | mi := &file_ermite_repo_proto_msgTypes[11] |
| 684 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 771 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||
| 685 | ms.StoreMessageInfo(mi) | 772 | ms.StoreMessageInfo(mi) | ||
| 686 | } | 773 | } | ||
| @@ -692,7 +779,7 @@ func (x *DeleteRepoResponse) String() string { | |||||
| 692 | func (*DeleteRepoResponse) ProtoMessage() {} | 779 | func (*DeleteRepoResponse) ProtoMessage() {} | ||
| 693 | 780 | ||||
| 694 | func (x *DeleteRepoResponse) ProtoReflect() protoreflect.Message { | 781 | func (x *DeleteRepoResponse) ProtoReflect() protoreflect.Message { | ||
| 695 | - | mi := &file_ermite_repo_proto_msgTypes[10] | 782 | + | mi := &file_ermite_repo_proto_msgTypes[11] |
| 696 | if x != nil { | 783 | if x != nil { | ||
| 697 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | 784 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) | ||
| 698 | if ms.LoadMessageInfo() == nil { | 785 | if ms.LoadMessageInfo() == nil { | ||
| @@ -705,14 +792,17 @@ func (x *DeleteRepoResponse) ProtoReflect() protoreflect.Message { | |||||
| 705 | 792 | ||||
| 706 | // Deprecated: Use DeleteRepoResponse.ProtoReflect.Descriptor instead. | 793 | // Deprecated: Use DeleteRepoResponse.ProtoReflect.Descriptor instead. | ||
| 707 | func (*DeleteRepoResponse) Descriptor() ([]byte, []int) { | 794 | func (*DeleteRepoResponse) Descriptor() ([]byte, []int) { | ||
| 708 | - | return file_ermite_repo_proto_rawDescGZIP(), []int{10} | 795 | + | return file_ermite_repo_proto_rawDescGZIP(), []int{11} |
| 709 | } | 796 | } | ||
| 710 | 797 | ||||
| 711 | var File_ermite_repo_proto protoreflect.FileDescriptor | 798 | var File_ermite_repo_proto protoreflect.FileDescriptor | ||
| 712 | 799 | ||||
| 713 | const file_ermite_repo_proto_rawDesc = "" + | 800 | const file_ermite_repo_proto_rawDesc = "" + | ||
| 714 | "\n" + | 801 | "\n" + | ||
| 715 | - | "\x11ermite/repo.proto\x12\x06ermite\x1a google/protobuf/field_mask.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\x8b\x02\n" + | 802 | + | "\x11ermite/repo.proto\x12\x06ermite\x1a google/protobuf/field_mask.proto\x1a\x12ermite/types.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\x83\x01\n" + |
| 803 | + | "\fRepoSettings\x12A\n" + | |||
| 804 | + | "\x13allowed_merge_modes\x18\x01 \x03(\x0e2\x11.ermite.MergeModeR\x11allowedMergeModes\x120\n" + | |||
| 805 | + | "\x14failing_checks_block\x18\x02 \x01(\bR\x12failingChecksBlock\"\xbd\x02\n" + | |||
| 716 | "\x04Repo\x12\x12\n" + | 806 | "\x04Repo\x12\x12\n" + | ||
| 717 | "\x04name\x18\x01 \x01(\tR\x04name\x12 \n" + | 807 | "\x04name\x18\x01 \x01(\tR\x04name\x12 \n" + | ||
| 718 | "\vdescription\x18\x02 \x01(\tR\vdescription\x122\n" + | 808 | "\vdescription\x18\x02 \x01(\tR\vdescription\x122\n" + | ||
| @@ -722,7 +812,8 @@ const file_ermite_repo_proto_rawDesc = "" + | |||||
| 722 | "\x0edefault_branch\x18\x04 \x01(\tR\rdefaultBranch\x129\n" + | 812 | "\x0edefault_branch\x18\x04 \x01(\tR\rdefaultBranch\x129\n" + | ||
| 723 | "\n" + | 813 | "\n" + | ||
| 724 | "created_at\x18\x05 \x01(\v2\x1a.google.protobuf.TimestampR\tcreatedAt\x127\n" + | 814 | "created_at\x18\x05 \x01(\v2\x1a.google.protobuf.TimestampR\tcreatedAt\x127\n" + | ||
| 725 | - | "\tpushed_at\x18\x06 \x01(\v2\x1a.google.protobuf.TimestampR\bpushedAt\"N\n" + | 815 | + | "\tpushed_at\x18\x06 \x01(\v2\x1a.google.protobuf.TimestampR\bpushedAt\x120\n" + |
| 816 | + | "\bsettings\x18\a \x01(\v2\x14.ermite.RepoSettingsR\bsettings\"N\n" + | |||
| 726 | "\x10ListReposRequest\x12\x1b\n" + | 817 | "\x10ListReposRequest\x12\x1b\n" + | ||
| 727 | "\tpage_size\x18\x01 \x01(\x05R\bpageSize\x12\x1d\n" + | 818 | "\tpage_size\x18\x01 \x01(\x05R\bpageSize\x12\x1d\n" + | ||
| 728 | "\n" + | 819 | "\n" + | ||
| @@ -741,7 +832,7 @@ const file_ermite_repo_proto_rawDesc = "" + | |||||
| 741 | "visibility\x18\x03 \x01(\x0e2\x12.ermite.VisibilityR\n" + | 832 | "visibility\x18\x03 \x01(\x0e2\x12.ermite.VisibilityR\n" + | ||
| 742 | "visibility\"6\n" + | 833 | "visibility\"6\n" + | ||
| 743 | "\x12CreateRepoResponse\x12 \n" + | 834 | "\x12CreateRepoResponse\x12 \n" + | ||
| 744 | - | "\x04repo\x18\x01 \x01(\v2\f.ermite.RepoR\x04repo\"\xe1\x01\n" + | 835 | + | "\x04repo\x18\x01 \x01(\v2\f.ermite.RepoR\x04repo\"\x93\x02\n" + |
| 745 | "\x11UpdateRepoRequest\x12\x12\n" + | 836 | "\x11UpdateRepoRequest\x12\x12\n" + | ||
| 746 | "\x04repo\x18\x01 \x01(\tR\x04repo\x12 \n" + | 837 | "\x04repo\x18\x01 \x01(\tR\x04repo\x12 \n" + | ||
| 747 | "\vdescription\x18\x02 \x01(\tR\vdescription\x122\n" + | 838 | "\vdescription\x18\x02 \x01(\tR\vdescription\x122\n" + | ||
| @@ -750,7 +841,8 @@ const file_ermite_repo_proto_rawDesc = "" + | |||||
| 750 | "visibility\x12%\n" + | 841 | "visibility\x12%\n" + | ||
| 751 | "\x0edefault_branch\x18\x04 \x01(\tR\rdefaultBranch\x12;\n" + | 842 | "\x0edefault_branch\x18\x04 \x01(\tR\rdefaultBranch\x12;\n" + | ||
| 752 | "\vupdate_mask\x18\x05 \x01(\v2\x1a.google.protobuf.FieldMaskR\n" + | 843 | "\vupdate_mask\x18\x05 \x01(\v2\x1a.google.protobuf.FieldMaskR\n" + | ||
| 753 | - | "updateMask\"6\n" + | 844 | + | "updateMask\x120\n" + |
| 845 | + | "\bsettings\x18\x06 \x01(\v2\x14.ermite.RepoSettingsR\bsettings\"6\n" + | |||
| 754 | "\x12UpdateRepoResponse\x12 \n" + | 846 | "\x12UpdateRepoResponse\x12 \n" + | ||
| 755 | "\x04repo\x18\x01 \x01(\v2\f.ermite.RepoR\x04repo\"'\n" + | 847 | "\x04repo\x18\x01 \x01(\v2\f.ermite.RepoR\x04repo\"'\n" + | ||
| 756 | "\x11DeleteRepoRequest\x12\x12\n" + | 848 | "\x11DeleteRepoRequest\x12\x12\n" + | ||
| @@ -786,49 +878,54 @@ func file_ermite_repo_proto_rawDescGZIP() []byte { | |||||
| 786 | } | 878 | } | ||
| 787 | 879 | ||||
| 788 | var file_ermite_repo_proto_enumTypes = make([]protoimpl.EnumInfo, 1) | 880 | var file_ermite_repo_proto_enumTypes = make([]protoimpl.EnumInfo, 1) | ||
| 789 | - | var file_ermite_repo_proto_msgTypes = make([]protoimpl.MessageInfo, 11) | 881 | + | var file_ermite_repo_proto_msgTypes = make([]protoimpl.MessageInfo, 12) |
| 790 | var file_ermite_repo_proto_goTypes = []any{ | 882 | var file_ermite_repo_proto_goTypes = []any{ | ||
| 791 | (Visibility)(0), // 0: ermite.Visibility | 883 | (Visibility)(0), // 0: ermite.Visibility | ||
| 792 | - | (*Repo)(nil), // 1: ermite.Repo | 884 | + | (*RepoSettings)(nil), // 1: ermite.RepoSettings |
| 793 | - | (*ListReposRequest)(nil), // 2: ermite.ListReposRequest | 885 | + | (*Repo)(nil), // 2: ermite.Repo |
| 794 | - | (*ListReposResponse)(nil), // 3: ermite.ListReposResponse | 886 | + | (*ListReposRequest)(nil), // 3: ermite.ListReposRequest |
| 795 | - | (*GetRepoRequest)(nil), // 4: ermite.GetRepoRequest | 887 | + | (*ListReposResponse)(nil), // 4: ermite.ListReposResponse |
| 796 | - | (*GetRepoResponse)(nil), // 5: ermite.GetRepoResponse | 888 | + | (*GetRepoRequest)(nil), // 5: ermite.GetRepoRequest |
| 797 | - | (*CreateRepoRequest)(nil), // 6: ermite.CreateRepoRequest | 889 | + | (*GetRepoResponse)(nil), // 6: ermite.GetRepoResponse |
| 798 | - | (*CreateRepoResponse)(nil), // 7: ermite.CreateRepoResponse | 890 | + | (*CreateRepoRequest)(nil), // 7: ermite.CreateRepoRequest |
| 799 | - | (*UpdateRepoRequest)(nil), // 8: ermite.UpdateRepoRequest | 891 | + | (*CreateRepoResponse)(nil), // 8: ermite.CreateRepoResponse |
| 800 | - | (*UpdateRepoResponse)(nil), // 9: ermite.UpdateRepoResponse | 892 | + | (*UpdateRepoRequest)(nil), // 9: ermite.UpdateRepoRequest |
| 801 | - | (*DeleteRepoRequest)(nil), // 10: ermite.DeleteRepoRequest | 893 | + | (*UpdateRepoResponse)(nil), // 10: ermite.UpdateRepoResponse |
| 802 | - | (*DeleteRepoResponse)(nil), // 11: ermite.DeleteRepoResponse | 894 | + | (*DeleteRepoRequest)(nil), // 11: ermite.DeleteRepoRequest |
| 803 | - | (*timestamppb.Timestamp)(nil), // 12: google.protobuf.Timestamp | 895 | + | (*DeleteRepoResponse)(nil), // 12: ermite.DeleteRepoResponse |
| 804 | - | (*fieldmaskpb.FieldMask)(nil), // 13: google.protobuf.FieldMask | 896 | + | (MergeMode)(0), // 13: ermite.MergeMode |
| 897 | + | (*timestamppb.Timestamp)(nil), // 14: google.protobuf.Timestamp | |||
| 898 | + | (*fieldmaskpb.FieldMask)(nil), // 15: google.protobuf.FieldMask | |||
| 805 | } | 899 | } | ||
| 806 | var file_ermite_repo_proto_depIdxs = []int32{ | 900 | var file_ermite_repo_proto_depIdxs = []int32{ | ||
| 807 | - | 0, // 0: ermite.Repo.visibility:type_name -> ermite.Visibility | 901 | + | 13, // 0: ermite.RepoSettings.allowed_merge_modes:type_name -> ermite.MergeMode |
| 808 | - | 12, // 1: ermite.Repo.created_at:type_name -> google.protobuf.Timestamp | 902 | + | 0, // 1: ermite.Repo.visibility:type_name -> ermite.Visibility |
| 809 | - | 12, // 2: ermite.Repo.pushed_at:type_name -> google.protobuf.Timestamp | 903 | + | 14, // 2: ermite.Repo.created_at:type_name -> google.protobuf.Timestamp |
| 810 | - | 1, // 3: ermite.ListReposResponse.repos:type_name -> ermite.Repo | 904 | + | 14, // 3: ermite.Repo.pushed_at:type_name -> google.protobuf.Timestamp |
| 811 | - | 1, // 4: ermite.GetRepoResponse.repo:type_name -> ermite.Repo | 905 | + | 1, // 4: ermite.Repo.settings:type_name -> ermite.RepoSettings |
| 812 | - | 0, // 5: ermite.CreateRepoRequest.visibility:type_name -> ermite.Visibility | 906 | + | 2, // 5: ermite.ListReposResponse.repos:type_name -> ermite.Repo |
| 813 | - | 1, // 6: ermite.CreateRepoResponse.repo:type_name -> ermite.Repo | 907 | + | 2, // 6: ermite.GetRepoResponse.repo:type_name -> ermite.Repo |
| 814 | - | 0, // 7: ermite.UpdateRepoRequest.visibility:type_name -> ermite.Visibility | 908 | + | 0, // 7: ermite.CreateRepoRequest.visibility:type_name -> ermite.Visibility |
| 815 | - | 13, // 8: ermite.UpdateRepoRequest.update_mask:type_name -> google.protobuf.FieldMask | 909 | + | 2, // 8: ermite.CreateRepoResponse.repo:type_name -> ermite.Repo |
| 816 | - | 1, // 9: ermite.UpdateRepoResponse.repo:type_name -> ermite.Repo | 910 | + | 0, // 9: ermite.UpdateRepoRequest.visibility:type_name -> ermite.Visibility |
| 817 | - | 2, // 10: ermite.RepoService.ListRepos:input_type -> ermite.ListReposRequest | 911 | + | 15, // 10: ermite.UpdateRepoRequest.update_mask:type_name -> google.protobuf.FieldMask |
| 818 | - | 4, // 11: ermite.RepoService.GetRepo:input_type -> ermite.GetRepoRequest | 912 | + | 1, // 11: ermite.UpdateRepoRequest.settings:type_name -> ermite.RepoSettings |
| 819 | - | 6, // 12: ermite.RepoService.CreateRepo:input_type -> ermite.CreateRepoRequest | 913 | + | 2, // 12: ermite.UpdateRepoResponse.repo:type_name -> ermite.Repo |
| 820 | - | 8, // 13: ermite.RepoService.UpdateRepo:input_type -> ermite.UpdateRepoRequest | 914 | + | 3, // 13: ermite.RepoService.ListRepos:input_type -> ermite.ListReposRequest |
| 821 | - | 10, // 14: ermite.RepoService.DeleteRepo:input_type -> ermite.DeleteRepoRequest | 915 | + | 5, // 14: ermite.RepoService.GetRepo:input_type -> ermite.GetRepoRequest |
| 822 | - | 3, // 15: ermite.RepoService.ListRepos:output_type -> ermite.ListReposResponse | 916 | + | 7, // 15: ermite.RepoService.CreateRepo:input_type -> ermite.CreateRepoRequest |
| 823 | - | 5, // 16: ermite.RepoService.GetRepo:output_type -> ermite.GetRepoResponse | 917 | + | 9, // 16: ermite.RepoService.UpdateRepo:input_type -> ermite.UpdateRepoRequest |
| 824 | - | 7, // 17: ermite.RepoService.CreateRepo:output_type -> ermite.CreateRepoResponse | 918 | + | 11, // 17: ermite.RepoService.DeleteRepo:input_type -> ermite.DeleteRepoRequest |
| 825 | - | 9, // 18: ermite.RepoService.UpdateRepo:output_type -> ermite.UpdateRepoResponse | 919 | + | 4, // 18: ermite.RepoService.ListRepos:output_type -> ermite.ListReposResponse |
| 826 | - | 11, // 19: ermite.RepoService.DeleteRepo:output_type -> ermite.DeleteRepoResponse | 920 | + | 6, // 19: ermite.RepoService.GetRepo:output_type -> ermite.GetRepoResponse |
| 827 | - | 15, // [15:20] is the sub-list for method output_type | 921 | + | 8, // 20: ermite.RepoService.CreateRepo:output_type -> ermite.CreateRepoResponse |
| 828 | - | 10, // [10:15] is the sub-list for method input_type | 922 | + | 10, // 21: ermite.RepoService.UpdateRepo:output_type -> ermite.UpdateRepoResponse |
| 829 | - | 10, // [10:10] is the sub-list for extension type_name | 923 | + | 12, // 22: ermite.RepoService.DeleteRepo:output_type -> ermite.DeleteRepoResponse |
| 830 | - | 10, // [10:10] is the sub-list for extension extendee | 924 | + | 18, // [18:23] is the sub-list for method output_type |
| 831 | - | 0, // [0:10] is the sub-list for field type_name | 925 | + | 13, // [13:18] is the sub-list for method input_type |
| 926 | + | 13, // [13:13] is the sub-list for extension type_name | |||
| 927 | + | 13, // [13:13] is the sub-list for extension extendee | |||
| 928 | + | 0, // [0:13] is the sub-list for field type_name | |||
| 832 | } | 929 | } | ||
| 833 | 930 | ||||
| 834 | func init() { file_ermite_repo_proto_init() } | 931 | func init() { file_ermite_repo_proto_init() } | ||
| @@ -836,13 +933,14 @@ func file_ermite_repo_proto_init() { | |||||
| 836 | if File_ermite_repo_proto != nil { | 933 | if File_ermite_repo_proto != nil { | ||
| 837 | return | 934 | return | ||
| 838 | } | 935 | } | ||
| 936 | + | file_ermite_types_proto_init() | |||
| 839 | type x struct{} | 937 | type x struct{} | ||
| 840 | out := protoimpl.TypeBuilder{ | 938 | out := protoimpl.TypeBuilder{ | ||
| 841 | File: protoimpl.DescBuilder{ | 939 | File: protoimpl.DescBuilder{ | ||
| 842 | GoPackagePath: reflect.TypeOf(x{}).PkgPath(), | 940 | GoPackagePath: reflect.TypeOf(x{}).PkgPath(), | ||
| 843 | RawDescriptor: unsafe.Slice(unsafe.StringData(file_ermite_repo_proto_rawDesc), len(file_ermite_repo_proto_rawDesc)), | 941 | RawDescriptor: unsafe.Slice(unsafe.StringData(file_ermite_repo_proto_rawDesc), len(file_ermite_repo_proto_rawDesc)), | ||
| 844 | NumEnums: 1, | 942 | NumEnums: 1, | ||
| 845 | - | NumMessages: 11, | 943 | + | NumMessages: 12, |
| 846 | NumExtensions: 0, | 944 | NumExtensions: 0, | ||
| 847 | NumServices: 1, | 945 | NumServices: 1, | ||
| 848 | }, | 946 | }, | ||
M gen/ermite/server.pb.go +148 -9 generated file: collapsed
A gen/ermite/session.pb.go +268 -0 generated file: collapsed
M gen/ermite/types.pb.go +78 -8 generated file: collapsed
M gen_test.go +61 -0
| @@ -30,7 +30,18 @@ func TestProcedures(t *testing.T) { | |||
| 30 | 30 | {ermiteconnect.TokenServiceListTokensProcedure, "/ermite.TokenService/ListTokens"}, | |
| 31 | 31 | {ermiteconnect.TokenServiceRevokeTokenProcedure, "/ermite.TokenService/RevokeToken"}, | |
| 32 | 32 | {ermiteconnect.EventServiceWatchProcedure, "/ermite.EventService/Watch"}, | |
| 33 | + | {ermiteconnect.MergeRequestServiceCreateMergeRequestProcedure, "/ermite.MergeRequestService/CreateMergeRequest"}, | |
| 34 | + | {ermiteconnect.MergeRequestServiceListMergeRequestsProcedure, "/ermite.MergeRequestService/ListMergeRequests"}, | |
| 35 | + | {ermiteconnect.MergeRequestServiceGetMergeRequestProcedure, "/ermite.MergeRequestService/GetMergeRequest"}, | |
| 36 | + | {ermiteconnect.MergeRequestServiceAddCommentProcedure, "/ermite.MergeRequestService/AddComment"}, | |
| 37 | + | {ermiteconnect.MergeRequestServiceResolveCommentProcedure, "/ermite.MergeRequestService/ResolveComment"}, | |
| 38 | + | {ermiteconnect.MergeRequestServiceCloseMergeRequestProcedure, "/ermite.MergeRequestService/CloseMergeRequest"}, | |
| 39 | + | {ermiteconnect.MergeRequestServiceMergeMergeRequestProcedure, "/ermite.MergeRequestService/MergeMergeRequest"}, | |
| 40 | + | {ermiteconnect.MergeRequestServiceMarkReadProcedure, "/ermite.MergeRequestService/MarkRead"}, | |
| 41 | + | {ermiteconnect.SessionServiceCreateLoginLinkProcedure, "/ermite.SessionService/CreateLoginLink"}, | |
| 42 | + | {ermiteconnect.SessionServiceSignOutEverywhereProcedure, "/ermite.SessionService/SignOutEverywhere"}, | |
| 33 | 43 | {ermiteconnect.ServerServiceGetVersionProcedure, "/ermite.ServerService/GetVersion"}, | |
| 44 | + | {ermiteconnect.ServerServiceGetSigningKeyProcedure, "/ermite.ServerService/GetSigningKey"}, | |
| 34 | 45 | } | |
| 35 | 46 | for _, tt := range tests { | |
| 36 | 47 | if tt.got != tt.want { | |
| @@ -50,6 +61,15 @@ func TestEnumNumbers(t *testing.T) { | |||
| 50 | 61 | if got := ermite.Visibility_VISIBILITY_PRIVATE; got != 2 { | |
| 51 | 62 | t.Errorf("VISIBILITY_PRIVATE = %d, want 2", got) | |
| 52 | 63 | } | |
| 64 | + | if got := ermite.MergeMode_MERGE_MODE_SQUASH; got != 2 { | |
| 65 | + | t.Errorf("MERGE_MODE_SQUASH = %d, want 2", got) | |
| 66 | + | } | |
| 67 | + | if got := ermite.MergeRequestState_MERGE_REQUEST_STATE_CLOSED; got != 3 { | |
| 68 | + | t.Errorf("MERGE_REQUEST_STATE_CLOSED = %d, want 3", got) | |
| 69 | + | } | |
| 70 | + | if got := ermite.DiffSide_DIFF_SIDE_NEW; got != 2 { | |
| 71 | + | t.Errorf("DIFF_SIDE_NEW = %d, want 2", got) | |
| 72 | + | } | |
| 53 | 73 | } | |
| 54 | 74 | ||
| 55 | 75 | // TestEventRoundTrip checks that an event with a oneof kind survives the wire. | |
| @@ -90,3 +110,44 @@ func TestUpdateRepoMask(t *testing.T) { | |||
| 90 | 110 | t.Errorf("paths = %v", got) | |
| 91 | 111 | } | |
| 92 | 112 | } | |
| 113 | + | ||
| 114 | + | // TestMergeRequestEventRoundTrip checks the merge request event kinds and the | |
| 115 | + | // repository settings survive the wire. | |
| 116 | + | func TestMergeRequestEventRoundTrip(t *testing.T) { | |
| 117 | + | in := &ermite.WatchResponse{Event: &ermite.Event{ | |
| 118 | + | Id: "43", | |
| 119 | + | Kind: &ermite.Event_CommentAdded{CommentAdded: &ermite.CommentAdded{ | |
| 120 | + | Repo: "ermite", | |
| 121 | + | Number: 7, | |
| 122 | + | Comment: &ermite.Comment{ | |
| 123 | + | Id: "c1", Path: "a.go", Line: 3, Side: ermite.DiffSide_DIFF_SIDE_OLD, Text: "hi", | |
| 124 | + | }, | |
| 125 | + | }}, | |
| 126 | + | }} | |
| 127 | + | b, err := proto.Marshal(in) | |
| 128 | + | if err != nil { | |
| 129 | + | t.Fatal(err) | |
| 130 | + | } | |
| 131 | + | var out ermite.WatchResponse | |
| 132 | + | if err := proto.Unmarshal(b, &out); err != nil { | |
| 133 | + | t.Fatal(err) | |
| 134 | + | } | |
| 135 | + | if !proto.Equal(in, &out) { | |
| 136 | + | t.Errorf("round trip mismatch: %v != %v", &out, in) | |
| 137 | + | } | |
| 138 | + | if got := out.GetEvent().GetCommentAdded().GetNumber(); got != 7 { | |
| 139 | + | t.Errorf("number = %d, want 7", got) | |
| 140 | + | } | |
| 141 | + | ||
| 142 | + | req := &ermite.UpdateRepoRequest{ | |
| 143 | + | Repo: "ermite", | |
| 144 | + | Settings: &ermite.RepoSettings{ | |
| 145 | + | AllowedMergeModes: []ermite.MergeMode{ermite.MergeMode_MERGE_MODE_SQUASH}, | |
| 146 | + | FailingChecksBlock: true, | |
| 147 | + | }, | |
| 148 | + | UpdateMask: &fieldmaskpb.FieldMask{Paths: []string{"settings.allowed_merge_modes", "settings.failing_checks_block"}}, | |
| 149 | + | } | |
| 150 | + | if got := req.GetSettings().GetAllowedMergeModes(); len(got) != 1 || got[0] != ermite.MergeMode_MERGE_MODE_SQUASH { | |
| 151 | + | t.Errorf("modes = %v", got) | |
| 152 | + | } | |
| 153 | + | } | |
| @@ -30,7 +30,18 @@ func TestProcedures(t *testing.T) { | |||||
| 30 | {ermiteconnect.TokenServiceListTokensProcedure, "/ermite.TokenService/ListTokens"}, | 30 | {ermiteconnect.TokenServiceListTokensProcedure, "/ermite.TokenService/ListTokens"}, | ||
| 31 | {ermiteconnect.TokenServiceRevokeTokenProcedure, "/ermite.TokenService/RevokeToken"}, | 31 | {ermiteconnect.TokenServiceRevokeTokenProcedure, "/ermite.TokenService/RevokeToken"}, | ||
| 32 | {ermiteconnect.EventServiceWatchProcedure, "/ermite.EventService/Watch"}, | 32 | {ermiteconnect.EventServiceWatchProcedure, "/ermite.EventService/Watch"}, | ||
| 33 | + | {ermiteconnect.MergeRequestServiceCreateMergeRequestProcedure, "/ermite.MergeRequestService/CreateMergeRequest"}, | |||
| 34 | + | {ermiteconnect.MergeRequestServiceListMergeRequestsProcedure, "/ermite.MergeRequestService/ListMergeRequests"}, | |||
| 35 | + | {ermiteconnect.MergeRequestServiceGetMergeRequestProcedure, "/ermite.MergeRequestService/GetMergeRequest"}, | |||
| 36 | + | {ermiteconnect.MergeRequestServiceAddCommentProcedure, "/ermite.MergeRequestService/AddComment"}, | |||
| 37 | + | {ermiteconnect.MergeRequestServiceResolveCommentProcedure, "/ermite.MergeRequestService/ResolveComment"}, | |||
| 38 | + | {ermiteconnect.MergeRequestServiceCloseMergeRequestProcedure, "/ermite.MergeRequestService/CloseMergeRequest"}, | |||
| 39 | + | {ermiteconnect.MergeRequestServiceMergeMergeRequestProcedure, "/ermite.MergeRequestService/MergeMergeRequest"}, | |||
| 40 | + | {ermiteconnect.MergeRequestServiceMarkReadProcedure, "/ermite.MergeRequestService/MarkRead"}, | |||
| 41 | + | {ermiteconnect.SessionServiceCreateLoginLinkProcedure, "/ermite.SessionService/CreateLoginLink"}, | |||
| 42 | + | {ermiteconnect.SessionServiceSignOutEverywhereProcedure, "/ermite.SessionService/SignOutEverywhere"}, | |||
| 33 | {ermiteconnect.ServerServiceGetVersionProcedure, "/ermite.ServerService/GetVersion"}, | 43 | {ermiteconnect.ServerServiceGetVersionProcedure, "/ermite.ServerService/GetVersion"}, | ||
| 44 | + | {ermiteconnect.ServerServiceGetSigningKeyProcedure, "/ermite.ServerService/GetSigningKey"}, | |||
| 34 | } | 45 | } | ||
| 35 | for _, tt := range tests { | 46 | for _, tt := range tests { | ||
| 36 | if tt.got != tt.want { | 47 | if tt.got != tt.want { | ||
| @@ -50,6 +61,15 @@ func TestEnumNumbers(t *testing.T) { | |||||
| 50 | if got := ermite.Visibility_VISIBILITY_PRIVATE; got != 2 { | 61 | if got := ermite.Visibility_VISIBILITY_PRIVATE; got != 2 { | ||
| 51 | t.Errorf("VISIBILITY_PRIVATE = %d, want 2", got) | 62 | t.Errorf("VISIBILITY_PRIVATE = %d, want 2", got) | ||
| 52 | } | 63 | } | ||
| 64 | + | if got := ermite.MergeMode_MERGE_MODE_SQUASH; got != 2 { | |||
| 65 | + | t.Errorf("MERGE_MODE_SQUASH = %d, want 2", got) | |||
| 66 | + | } | |||
| 67 | + | if got := ermite.MergeRequestState_MERGE_REQUEST_STATE_CLOSED; got != 3 { | |||
| 68 | + | t.Errorf("MERGE_REQUEST_STATE_CLOSED = %d, want 3", got) | |||
| 69 | + | } | |||
| 70 | + | if got := ermite.DiffSide_DIFF_SIDE_NEW; got != 2 { | |||
| 71 | + | t.Errorf("DIFF_SIDE_NEW = %d, want 2", got) | |||
| 72 | + | } | |||
| 53 | } | 73 | } | ||
| 54 | 74 | ||||
| 55 | // TestEventRoundTrip checks that an event with a oneof kind survives the wire. | 75 | // TestEventRoundTrip checks that an event with a oneof kind survives the wire. | ||
| @@ -90,3 +110,44 @@ func TestUpdateRepoMask(t *testing.T) { | |||||
| 90 | t.Errorf("paths = %v", got) | 110 | t.Errorf("paths = %v", got) | ||
| 91 | } | 111 | } | ||
| 92 | } | 112 | } | ||
| 113 | + | ||||
| 114 | + | // TestMergeRequestEventRoundTrip checks the merge request event kinds and the | |||
| 115 | + | // repository settings survive the wire. | |||
| 116 | + | func TestMergeRequestEventRoundTrip(t *testing.T) { | |||
| 117 | + | in := &ermite.WatchResponse{Event: &ermite.Event{ | |||
| 118 | + | Id: "43", | |||
| 119 | + | Kind: &ermite.Event_CommentAdded{CommentAdded: &ermite.CommentAdded{ | |||
| 120 | + | Repo: "ermite", | |||
| 121 | + | Number: 7, | |||
| 122 | + | Comment: &ermite.Comment{ | |||
| 123 | + | Id: "c1", Path: "a.go", Line: 3, Side: ermite.DiffSide_DIFF_SIDE_OLD, Text: "hi", | |||
| 124 | + | }, | |||
| 125 | + | }}, | |||
| 126 | + | }} | |||
| 127 | + | b, err := proto.Marshal(in) | |||
| 128 | + | if err != nil { | |||
| 129 | + | t.Fatal(err) | |||
| 130 | + | } | |||
| 131 | + | var out ermite.WatchResponse | |||
| 132 | + | if err := proto.Unmarshal(b, &out); err != nil { | |||
| 133 | + | t.Fatal(err) | |||
| 134 | + | } | |||
| 135 | + | if !proto.Equal(in, &out) { | |||
| 136 | + | t.Errorf("round trip mismatch: %v != %v", &out, in) | |||
| 137 | + | } | |||
| 138 | + | if got := out.GetEvent().GetCommentAdded().GetNumber(); got != 7 { | |||
| 139 | + | t.Errorf("number = %d, want 7", got) | |||
| 140 | + | } | |||
| 141 | + | ||||
| 142 | + | req := &ermite.UpdateRepoRequest{ | |||
| 143 | + | Repo: "ermite", | |||
| 144 | + | Settings: &ermite.RepoSettings{ | |||
| 145 | + | AllowedMergeModes: []ermite.MergeMode{ermite.MergeMode_MERGE_MODE_SQUASH}, | |||
| 146 | + | FailingChecksBlock: true, | |||
| 147 | + | }, | |||
| 148 | + | UpdateMask: &fieldmaskpb.FieldMask{Paths: []string{"settings.allowed_merge_modes", "settings.failing_checks_block"}}, | |||
| 149 | + | } | |||
| 150 | + | if got := req.GetSettings().GetAllowedMergeModes(); len(got) != 1 || got[0] != ermite.MergeMode_MERGE_MODE_SQUASH { | |||
| 151 | + | t.Errorf("modes = %v", got) | |||
| 152 | + | } | |||
| 153 | + | } | |||
M proto/ermite/event.proto +49 -1
| @@ -4,6 +4,7 @@ syntax = "proto3"; | |||
| 4 | 4 | ||
| 5 | 5 | package ermite; | |
| 6 | 6 | ||
| 7 | + | import "ermite/merge_request.proto"; | |
| 7 | 8 | import "ermite/repo.proto"; | |
| 8 | 9 | import "google/protobuf/timestamp.proto"; | |
| 9 | 10 | ||
| @@ -13,6 +14,15 @@ service EventService { | |||
| 13 | 14 | // down. Events are filtered by the caller's access: events of a private | |
| 14 | 15 | // repository are only sent to callers that may read it. | |
| 15 | 16 | // | |
| 17 | + | // The events are repo_created, repo_updated, repo_deleted, pushed, gap and, | |
| 18 | + | // for merge requests, merge_request_opened, merge_request_merged, | |
| 19 | + | // merge_request_closed and comment_added. Each one is delivered on the | |
| 20 | + | // "repo:<name>" topic of its repository and on "home", subject to the | |
| 21 | + | // visibility of the repository. There is no event for a change of title or | |
| 22 | + | // description, nor for a resolved comment: after a gap, or to see such | |
| 23 | + | // changes, clients read the merge request again. A merge publishes | |
| 24 | + | // merge_request_merged, then pushed for the target branch. | |
| 25 | + | // | |
| 16 | 26 | // The server keeps a bounded buffer of recent events. With resume_after set, | |
| 17 | 27 | // buffered events after that id are replayed first, then live events follow. | |
| 18 | 28 | // When resume_after is no longer buffered (or unknown), the stream begins | |
| @@ -69,6 +79,14 @@ message Event { | |||
| 69 | 79 | Pushed pushed = 6; | |
| 70 | 80 | // Gap: events were lost, reload state. | |
| 71 | 81 | Gap gap = 7; | |
| 82 | + | // MergeRequestOpened: a merge request was opened. | |
| 83 | + | MergeRequestOpened merge_request_opened = 8; | |
| 84 | + | // MergeRequestMerged: a merge request was merged. | |
| 85 | + | MergeRequestMerged merge_request_merged = 9; | |
| 86 | + | // MergeRequestClosed: a merge request was closed without merging. | |
| 87 | + | MergeRequestClosed merge_request_closed = 10; | |
| 88 | + | // CommentAdded: a comment was added to a merge request. | |
| 89 | + | CommentAdded comment_added = 11; | |
| 72 | 90 | } | |
| 73 | 91 | } | |
| 74 | 92 | ||
| @@ -108,7 +126,37 @@ message RefUpdate { | |||
| 108 | 126 | string new_id = 3; | |
| 109 | 127 | } | |
| 110 | 128 | ||
| 129 | + | // MergeRequestOpened reports a new merge request. | |
| 130 | + | message MergeRequestOpened { | |
| 131 | + | // MergeRequest is the new merge request. | |
| 132 | + | MergeRequest merge_request = 1; | |
| 133 | + | } | |
| 134 | + | ||
| 135 | + | // MergeRequestMerged reports a merged merge request. It is published before | |
| 136 | + | // the Pushed event of the target branch. | |
| 137 | + | message MergeRequestMerged { | |
| 138 | + | // MergeRequest is the merge request after the merge. | |
| 139 | + | MergeRequest merge_request = 1; | |
| 140 | + | } | |
| 141 | + | ||
| 142 | + | // MergeRequestClosed reports a merge request closed without merging. | |
| 143 | + | message MergeRequestClosed { | |
| 144 | + | // MergeRequest is the merge request after closing. | |
| 145 | + | MergeRequest merge_request = 1; | |
| 146 | + | } | |
| 147 | + | ||
| 148 | + | // CommentAdded reports a new comment on a merge request. | |
| 149 | + | message CommentAdded { | |
| 150 | + | // Repo is the name of the repository. | |
| 151 | + | string repo = 1; | |
| 152 | + | // Number is the number of the merge request. | |
| 153 | + | int64 number = 2; | |
| 154 | + | // Comment is the new comment. | |
| 155 | + | Comment comment = 3; | |
| 156 | + | } | |
| 157 | + | ||
| 111 | 158 | // Gap tells the client that events were lost: the requested resume point is | |
| 112 | 159 | // older than the server's buffer. It has no fields. The client should reload | |
| 113 | - | // the state it displays (repositories, refs) and carry on with the next events. | |
| 160 | + | // the state it displays (repositories, refs, merge requests and their | |
| 161 | + | // comments) and carry on with the next events. | |
| 114 | 162 | message Gap {} | |
| @@ -4,6 +4,7 @@ syntax = "proto3"; | |||||
| 4 | 4 | ||||
| 5 | package ermite; | 5 | package ermite; | ||
| 6 | 6 | ||||
| 7 | + | import "ermite/merge_request.proto"; | |||
| 7 | import "ermite/repo.proto"; | 8 | import "ermite/repo.proto"; | ||
| 8 | import "google/protobuf/timestamp.proto"; | 9 | import "google/protobuf/timestamp.proto"; | ||
| 9 | 10 | ||||
| @@ -13,6 +14,15 @@ service EventService { | |||||
| 13 | // down. Events are filtered by the caller's access: events of a private | 14 | // down. Events are filtered by the caller's access: events of a private | ||
| 14 | // repository are only sent to callers that may read it. | 15 | // repository are only sent to callers that may read it. | ||
| 15 | // | 16 | // | ||
| 17 | + | // The events are repo_created, repo_updated, repo_deleted, pushed, gap and, | |||
| 18 | + | // for merge requests, merge_request_opened, merge_request_merged, | |||
| 19 | + | // merge_request_closed and comment_added. Each one is delivered on the | |||
| 20 | + | // "repo:<name>" topic of its repository and on "home", subject to the | |||
| 21 | + | // visibility of the repository. There is no event for a change of title or | |||
| 22 | + | // description, nor for a resolved comment: after a gap, or to see such | |||
| 23 | + | // changes, clients read the merge request again. A merge publishes | |||
| 24 | + | // merge_request_merged, then pushed for the target branch. | |||
| 25 | + | // | |||
| 16 | // The server keeps a bounded buffer of recent events. With resume_after set, | 26 | // The server keeps a bounded buffer of recent events. With resume_after set, | ||
| 17 | // buffered events after that id are replayed first, then live events follow. | 27 | // buffered events after that id are replayed first, then live events follow. | ||
| 18 | // When resume_after is no longer buffered (or unknown), the stream begins | 28 | // When resume_after is no longer buffered (or unknown), the stream begins | ||
| @@ -69,6 +79,14 @@ message Event { | |||||
| 69 | Pushed pushed = 6; | 79 | Pushed pushed = 6; | ||
| 70 | // Gap: events were lost, reload state. | 80 | // Gap: events were lost, reload state. | ||
| 71 | Gap gap = 7; | 81 | Gap gap = 7; | ||
| 82 | + | // MergeRequestOpened: a merge request was opened. | |||
| 83 | + | MergeRequestOpened merge_request_opened = 8; | |||
| 84 | + | // MergeRequestMerged: a merge request was merged. | |||
| 85 | + | MergeRequestMerged merge_request_merged = 9; | |||
| 86 | + | // MergeRequestClosed: a merge request was closed without merging. | |||
| 87 | + | MergeRequestClosed merge_request_closed = 10; | |||
| 88 | + | // CommentAdded: a comment was added to a merge request. | |||
| 89 | + | CommentAdded comment_added = 11; | |||
| 72 | } | 90 | } | ||
| 73 | } | 91 | } | ||
| 74 | 92 | ||||
| @@ -108,7 +126,37 @@ message RefUpdate { | |||||
| 108 | string new_id = 3; | 126 | string new_id = 3; | ||
| 109 | } | 127 | } | ||
| 110 | 128 | ||||
| 129 | + | // MergeRequestOpened reports a new merge request. | |||
| 130 | + | message MergeRequestOpened { | |||
| 131 | + | // MergeRequest is the new merge request. | |||
| 132 | + | MergeRequest merge_request = 1; | |||
| 133 | + | } | |||
| 134 | + | ||||
| 135 | + | // MergeRequestMerged reports a merged merge request. It is published before | |||
| 136 | + | // the Pushed event of the target branch. | |||
| 137 | + | message MergeRequestMerged { | |||
| 138 | + | // MergeRequest is the merge request after the merge. | |||
| 139 | + | MergeRequest merge_request = 1; | |||
| 140 | + | } | |||
| 141 | + | ||||
| 142 | + | // MergeRequestClosed reports a merge request closed without merging. | |||
| 143 | + | message MergeRequestClosed { | |||
| 144 | + | // MergeRequest is the merge request after closing. | |||
| 145 | + | MergeRequest merge_request = 1; | |||
| 146 | + | } | |||
| 147 | + | ||||
| 148 | + | // CommentAdded reports a new comment on a merge request. | |||
| 149 | + | message CommentAdded { | |||
| 150 | + | // Repo is the name of the repository. | |||
| 151 | + | string repo = 1; | |||
| 152 | + | // Number is the number of the merge request. | |||
| 153 | + | int64 number = 2; | |||
| 154 | + | // Comment is the new comment. | |||
| 155 | + | Comment comment = 3; | |||
| 156 | + | } | |||
| 157 | + | ||||
| 111 | // Gap tells the client that events were lost: the requested resume point is | 158 | // Gap tells the client that events were lost: the requested resume point is | ||
| 112 | // older than the server's buffer. It has no fields. The client should reload | 159 | // older than the server's buffer. It has no fields. The client should reload | ||
| 113 | - | // the state it displays (repositories, refs) and carry on with the next events. | 160 | + | // the state it displays (repositories, refs, merge requests and their |
| 161 | + | // comments) and carry on with the next events. | |||
| 114 | message Gap {} | 162 | message Gap {} | ||
A proto/ermite/merge_request.proto +371 -0
| @@ -0,0 +1,371 @@ | |||
| 1 | + | // SPDX-License-Identifier: MIT | |
| 2 | + | ||
| 3 | + | syntax = "proto3"; | |
| 4 | + | ||
| 5 | + | package ermite; | |
| 6 | + | ||
| 7 | + | import "ermite/git.proto"; | |
| 8 | + | import "ermite/types.proto"; | |
| 9 | + | import "google/protobuf/timestamp.proto"; | |
| 10 | + | ||
| 11 | + | // MergeRequestState is where a merge request is in its life. | |
| 12 | + | enum MergeRequestState { | |
| 13 | + | // Not set. In ListMergeRequestsRequest.state it means every state. Never | |
| 14 | + | // returned by the server. | |
| 15 | + | MERGE_REQUEST_STATE_UNSPECIFIED = 0; | |
| 16 | + | // The merge request awaits review; it can be commented on, merged or closed. | |
| 17 | + | MERGE_REQUEST_STATE_OPEN = 1; | |
| 18 | + | // The source branch was merged into the target. Final. | |
| 19 | + | MERGE_REQUEST_STATE_MERGED = 2; | |
| 20 | + | // The merge request was closed without merging. Final. | |
| 21 | + | MERGE_REQUEST_STATE_CLOSED = 3; | |
| 22 | + | } | |
| 23 | + | ||
| 24 | + | // DiffSide is the side of a diff a line comment is attached to. | |
| 25 | + | enum DiffSide { | |
| 26 | + | // Not set. On a Comment it means the comment is general, not attached to a | |
| 27 | + | // line. In AddCommentRequest it is valid only for a general comment. | |
| 28 | + | DIFF_SIDE_UNSPECIFIED = 0; | |
| 29 | + | // The old side: the line is a Line.old_number (a deletion or a context line). | |
| 30 | + | DIFF_SIDE_OLD = 1; | |
| 31 | + | // The new side: the line is a Line.new_number (an addition or a context | |
| 32 | + | // line). | |
| 33 | + | DIFF_SIDE_NEW = 2; | |
| 34 | + | } | |
| 35 | + | ||
| 36 | + | // MergeRequest asks to merge one branch of a repository into another branch | |
| 37 | + | // of the same repository. It is about a branch, not about who wrote it. | |
| 38 | + | message MergeRequest { | |
| 39 | + | // Repo is the name of the repository. | |
| 40 | + | string repo = 1; | |
| 41 | + | // Number identifies the merge request within its repository, starting at 1 | |
| 42 | + | // and never reused. It is written "!<number>" in messages and URLs. | |
| 43 | + | int64 number = 2; | |
| 44 | + | // Title is a one-line plain-text title, at most 120 characters. | |
| 45 | + | string title = 3; | |
| 46 | + | // Description is a plain-text description, at most 8,000 characters. It may | |
| 47 | + | // be empty. Clients show it escaped, with line breaks kept. | |
| 48 | + | string description = 4; | |
| 49 | + | // SourceBranch is the short name of the branch to merge, for example | |
| 50 | + | // "feat/x". | |
| 51 | + | string source_branch = 5; | |
| 52 | + | // TargetBranch is the short name of the branch to merge into, for example | |
| 53 | + | // "main". | |
| 54 | + | string target_branch = 6; | |
| 55 | + | // State is where the merge request is in its life. | |
| 56 | + | MergeRequestState state = 7; | |
| 57 | + | // Author names who created the merge request: the label of the token that | |
| 58 | + | // was used, "root" for the root token, or "owner" for a web session. It is | |
| 59 | + | // informational: labels are not unique and the token may be gone. | |
| 60 | + | string author = 8; | |
| 61 | + | // CreatedAt is when the merge request was created. | |
| 62 | + | google.protobuf.Timestamp created_at = 9; | |
| 63 | + | // UpdatedAt is when the merge request last changed: title, description, | |
| 64 | + | // state, or a comment added or resolved. Pushes to the source branch do not | |
| 65 | + | // change it. | |
| 66 | + | google.protobuf.Timestamp updated_at = 10; | |
| 67 | + | // HeadId is the id of the commit the source branch points to. While the | |
| 68 | + | // merge request is open it is read from Git at every call, so it changes | |
| 69 | + | // when the branch is pushed; it is empty if the branch was deleted. Once | |
| 70 | + | // merged or closed it is the head at that moment. | |
| 71 | + | string head_id = 11; | |
| 72 | + | // MergedCommitId is the id of the commit the target branch points to after | |
| 73 | + | // the merge: the head for a fast-forward, the new commit for a squash. | |
| 74 | + | // Empty unless state is MERGED. | |
| 75 | + | string merged_commit_id = 12; | |
| 76 | + | // MergeMode is how the merge request was merged. MERGE_MODE_UNSPECIFIED | |
| 77 | + | // unless state is MERGED. | |
| 78 | + | MergeMode merge_mode = 13; | |
| 79 | + | } | |
| 80 | + | ||
| 81 | + | // Comment is a note on a merge request, either general or attached to a line | |
| 82 | + | // of its diff. | |
| 83 | + | message Comment { | |
| 84 | + | // Id identifies the comment within its merge request. Opaque. | |
| 85 | + | string id = 1; | |
| 86 | + | // Author names who wrote the comment, like MergeRequest.author. | |
| 87 | + | string author = 2; | |
| 88 | + | // Path is the path of the commented file in the diff (the new path, or the | |
| 89 | + | // old path of a deleted file). Empty for a general comment. | |
| 90 | + | string path = 3; | |
| 91 | + | // Line is the 1-based line number on side. 0 for a general comment. | |
| 92 | + | int32 line = 4; | |
| 93 | + | // Side tells whether line counts on the old or the new side of the diff. | |
| 94 | + | // DIFF_SIDE_UNSPECIFIED for a general comment. | |
| 95 | + | DiffSide side = 5; | |
| 96 | + | // CommitId is the head of the merge request when the comment was written. | |
| 97 | + | // When it differs from the current head the line may have moved; clients | |
| 98 | + | // may show the comment as outdated. | |
| 99 | + | string commit_id = 6; | |
| 100 | + | // Text is the plain-text content, at most 8,000 characters. Clients show it | |
| 101 | + | // escaped, with line breaks kept. | |
| 102 | + | string text = 7; | |
| 103 | + | // Resolved is true once the comment was marked resolved. | |
| 104 | + | bool resolved = 8; | |
| 105 | + | // CreatedAt is when the comment was written. | |
| 106 | + | google.protobuf.Timestamp created_at = 9; | |
| 107 | + | } | |
| 108 | + | ||
| 109 | + | // MergeRequestService reviews and merges branches. | |
| 110 | + | // | |
| 111 | + | // Every RPC takes the repository name and, except for creation and listing, | |
| 112 | + | // the merge request number. A repository that does not exist or that the | |
| 113 | + | // caller cannot read gives not_found; so does an unknown number. Reading | |
| 114 | + | // (ListMergeRequests, GetMergeRequest) needs the same access as reading the | |
| 115 | + | // repository: nothing for a public one, the repo:read scope for a private | |
| 116 | + | // one. Writing needs a scope on the repository, given per RPC; a caller | |
| 117 | + | // without it gets permission_denied. | |
| 118 | + | // | |
| 119 | + | // Text fields follow the same rules everywhere: valid UTF-8, no control | |
| 120 | + | // characters (except the line break in description and comment text) and no | |
| 121 | + | // Unicode bidirectional override or isolate characters; title is one line of | |
| 122 | + | // at most 120 characters, description and comment text at most 8,000 | |
| 123 | + | // characters. A request that breaks a rule is rejected whole with | |
| 124 | + | // invalid_argument, and the error carries a BadRequest detail naming the | |
| 125 | + | // fields. | |
| 126 | + | // | |
| 127 | + | // Servers that implement this service list "merge_requests" in | |
| 128 | + | // GetVersionResponse.features. | |
| 129 | + | service MergeRequestService { | |
| 130 | + | // CreateMergeRequest opens a merge request. Needs the mr:write scope. Fails | |
| 131 | + | // with invalid_argument if a text rule is broken, if a branch does not exist | |
| 132 | + | // or if source and target are the same branch, and with already_exists if an | |
| 133 | + | // open merge request already has the same source and target. | |
| 134 | + | rpc CreateMergeRequest(CreateMergeRequestRequest) returns (CreateMergeRequestResponse); | |
| 135 | + | // ListMergeRequests lists the merge requests of a repository, highest | |
| 136 | + | // number (newest) first, optionally restricted to one state. The listed | |
| 137 | + | // merge requests carry no diff or comments; head_id is set. Fails with | |
| 138 | + | // not_found if the repository does not exist or is not readable. | |
| 139 | + | rpc ListMergeRequests(ListMergeRequestsRequest) returns (ListMergeRequestsResponse); | |
| 140 | + | // GetMergeRequest returns one merge request with its commits, its diff and | |
| 141 | + | // its comments. The diff compares the target with the head (what the merge | |
| 142 | + | // would bring: "target...head"), or, with since_last_read, the head the | |
| 143 | + | // caller last marked read with the current head. Fails with not_found if | |
| 144 | + | // the repository or the number is unknown. | |
| 145 | + | rpc GetMergeRequest(GetMergeRequestRequest) returns (GetMergeRequestResponse); | |
| 146 | + | // AddComment adds a general comment or a comment on a line of the diff. | |
| 147 | + | // Needs the mr:write scope. Fails with invalid_argument if the text breaks | |
| 148 | + | // a rule or if path, line and side do not designate a line of the current | |
| 149 | + | // diff of the merge request, and with failed_precondition if the merge | |
| 150 | + | // request is not open. | |
| 151 | + | rpc AddComment(AddCommentRequest) returns (AddCommentResponse); | |
| 152 | + | // ResolveComment marks a comment resolved or unresolved. Needs the mr:write | |
| 153 | + | // scope. Fails with not_found if the comment is unknown and with | |
| 154 | + | // failed_precondition if the merge request is not open. Setting the state | |
| 155 | + | // the comment already has succeeds and changes nothing. | |
| 156 | + | rpc ResolveComment(ResolveCommentRequest) returns (ResolveCommentResponse); | |
| 157 | + | // CloseMergeRequest closes an open merge request without merging it. Needs | |
| 158 | + | // the mr:write scope. Fails with failed_precondition if the merge request | |
| 159 | + | // is not open. A closed merge request cannot be reopened: open a new one. | |
| 160 | + | rpc CloseMergeRequest(CloseMergeRequestRequest) returns (CloseMergeRequestResponse); | |
| 161 | + | // MergeMergeRequest merges an open merge request. Needs the mr:merge scope. | |
| 162 | + | // The caller passes the head it reviewed: the server merges only if the | |
| 163 | + | // source branch still points to it, so a push between review and merge is | |
| 164 | + | // never merged unseen. Fails with invalid_argument if head_id is empty or | |
| 165 | + | // not a commit id, and with failed_precondition if the merge request is not | |
| 166 | + | // open, if the source branch no longer points to head_id ("branch moved, | |
| 167 | + | // read again"), if the target is not an ancestor of the head (rebase and | |
| 168 | + | // push again), if the mode is not allowed by RepoSettings, or if a check | |
| 169 | + | // fails and RepoSettings.failing_checks_block is set. Merges of one | |
| 170 | + | // repository run one at a time. Repeating a call that succeeded fails with | |
| 171 | + | // failed_precondition (not open). On success the server publishes | |
| 172 | + | // MergeRequestMerged then Pushed for the target branch. | |
| 173 | + | rpc MergeMergeRequest(MergeMergeRequestRequest) returns (MergeMergeRequestResponse); | |
| 174 | + | // MarkRead records the head the caller has reviewed, for the since_last_read | |
| 175 | + | // option of GetMergeRequest. There is one read position per merge request, | |
| 176 | + | // the reviewer's. Needs the mr:write scope. Marking a commit that does not | |
| 177 | + | // exist in the repository is invalid_argument. | |
| 178 | + | rpc MarkRead(MarkReadRequest) returns (MarkReadResponse); | |
| 179 | + | } | |
| 180 | + | ||
| 181 | + | // CreateMergeRequestRequest describes the merge request to open. | |
| 182 | + | message CreateMergeRequestRequest { | |
| 183 | + | // Repo is the repository name. | |
| 184 | + | string repo = 1; | |
| 185 | + | // Title is the one-line title. Required. | |
| 186 | + | string title = 2; | |
| 187 | + | // Description is the optional description. | |
| 188 | + | string description = 3; | |
| 189 | + | // SourceBranch is the short name of the branch to merge. Required; the | |
| 190 | + | // branch must exist. | |
| 191 | + | string source_branch = 4; | |
| 192 | + | // TargetBranch is the short name of the branch to merge into. Empty means | |
| 193 | + | // the default branch of the repository. The branch must exist and differ | |
| 194 | + | // from source_branch. | |
| 195 | + | string target_branch = 5; | |
| 196 | + | } | |
| 197 | + | ||
| 198 | + | // CreateMergeRequestResponse holds the new merge request. | |
| 199 | + | message CreateMergeRequestResponse { | |
| 200 | + | // MergeRequest is the created merge request. | |
| 201 | + | MergeRequest merge_request = 1; | |
| 202 | + | } | |
| 203 | + | ||
| 204 | + | // ListMergeRequestsRequest selects a page of merge requests. | |
| 205 | + | message ListMergeRequestsRequest { | |
| 206 | + | // Repo is the repository name. | |
| 207 | + | string repo = 1; | |
| 208 | + | // State restricts the result to one state. MERGE_REQUEST_STATE_UNSPECIFIED | |
| 209 | + | // means every state. | |
| 210 | + | MergeRequestState state = 2; | |
| 211 | + | // PageSize is the maximum number of merge requests to return. 0 means the | |
| 212 | + | // server default; values above the server maximum are lowered to it. | |
| 213 | + | int32 page_size = 3; | |
| 214 | + | // PageToken is the next_page_token of a previous response, to continue the | |
| 215 | + | // same listing. Empty for the first page. Other fields must be unchanged. | |
| 216 | + | string page_token = 4; | |
| 217 | + | } | |
| 218 | + | ||
| 219 | + | // ListMergeRequestsResponse is one page of merge requests. | |
| 220 | + | message ListMergeRequestsResponse { | |
| 221 | + | // MergeRequests are the merge requests of this page, highest number first. | |
| 222 | + | repeated MergeRequest merge_requests = 1; | |
| 223 | + | // NextPageToken is passed as page_token to get the next page. Empty when | |
| 224 | + | // there is no next page. | |
| 225 | + | string next_page_token = 2; | |
| 226 | + | } | |
| 227 | + | ||
| 228 | + | // GetMergeRequestRequest selects a merge request. | |
| 229 | + | message GetMergeRequestRequest { | |
| 230 | + | // Repo is the repository name. | |
| 231 | + | string repo = 1; | |
| 232 | + | // Number is the merge request number. | |
| 233 | + | int64 number = 2; | |
| 234 | + | // SinceLastRead asks for the diff between the head recorded by MarkRead and | |
| 235 | + | // the current head instead of the diff against the target. It works after a | |
| 236 | + | // force-push as long as the recorded commit still exists in the repository. | |
| 237 | + | // When nothing was marked read, or the recorded commit is gone, the response | |
| 238 | + | // holds the diff against the target and says so in last_read_id and | |
| 239 | + | // last_read_lost. | |
| 240 | + | bool since_last_read = 3; | |
| 241 | + | } | |
| 242 | + | ||
| 243 | + | // GetMergeRequestResponse holds a merge request with its review data. | |
| 244 | + | message GetMergeRequestResponse { | |
| 245 | + | // MergeRequest is the merge request. | |
| 246 | + | MergeRequest merge_request = 1; | |
| 247 | + | // Commits are the commits of the head that are not in the target | |
| 248 | + | // ("target..head"), newest first. At most 100 are returned (a server limit | |
| 249 | + | // that may change; rely on commits_truncated, not on the number). Empty when | |
| 250 | + | // the source branch was deleted. | |
| 251 | + | repeated Commit commits = 2; | |
| 252 | + | // CommitsTruncated is true when the branch has more commits than commits | |
| 253 | + | // holds. | |
| 254 | + | bool commits_truncated = 3; | |
| 255 | + | // DiffBaseId is the id of the commit the diff compares from: the merge base | |
| 256 | + | // of the target and the head, or the last read head when since_last_read | |
| 257 | + | // applied. Empty when the source branch was deleted; diff is then empty. | |
| 258 | + | string diff_base_id = 4; | |
| 259 | + | // Stats are the totals of the diff, including files that it omits or | |
| 260 | + | // truncates. | |
| 261 | + | DiffStats stats = 5; | |
| 262 | + | // Diff is the structured diff from diff_base_id to the head, with the same | |
| 263 | + | // limits and truncated flags as GetCommitResponse.diff. | |
| 264 | + | Diff diff = 6; | |
| 265 | + | // Comments are every comment of the merge request, oldest first. | |
| 266 | + | repeated Comment comments = 7; | |
| 267 | + | // LastReadId is the head recorded by MarkRead, whether or not | |
| 268 | + | // since_last_read was set. Empty when nothing was marked read. | |
| 269 | + | string last_read_id = 8; | |
| 270 | + | // LastReadLost is true when since_last_read was set, a head was recorded, | |
| 271 | + | // but that commit no longer exists in the repository: the diff is then the | |
| 272 | + | // diff against the target. A client should tell the reader to review the | |
| 273 | + | // whole change again. | |
| 274 | + | bool last_read_lost = 9; | |
| 275 | + | } | |
| 276 | + | ||
| 277 | + | // AddCommentRequest describes the comment to add. | |
| 278 | + | message AddCommentRequest { | |
| 279 | + | // Repo is the repository name. | |
| 280 | + | string repo = 1; | |
| 281 | + | // Number is the merge request number. | |
| 282 | + | int64 number = 2; | |
| 283 | + | // Path is the file the comment is attached to, as given by the diff of the | |
| 284 | + | // merge request: FileDiff.new_path, or old_path for a deleted file. Empty | |
| 285 | + | // for a general comment; then line must be 0 and side unspecified. | |
| 286 | + | string path = 3; | |
| 287 | + | // Line is the 1-based line number on side. It must be the old_number or | |
| 288 | + | // new_number of a Line of a hunk of the file; a line outside the hunks is | |
| 289 | + | // invalid_argument. 0 for a general comment. | |
| 290 | + | int32 line = 4; | |
| 291 | + | // Side is the side line counts on. Required when path is set. | |
| 292 | + | DiffSide side = 5; | |
| 293 | + | // Text is the plain-text content. Required. | |
| 294 | + | string text = 6; | |
| 295 | + | } | |
| 296 | + | ||
| 297 | + | // AddCommentResponse holds the new comment. | |
| 298 | + | message AddCommentResponse { | |
| 299 | + | // Comment is the created comment. | |
| 300 | + | Comment comment = 1; | |
| 301 | + | } | |
| 302 | + | ||
| 303 | + | // ResolveCommentRequest changes the resolved state of a comment. | |
| 304 | + | message ResolveCommentRequest { | |
| 305 | + | // Repo is the repository name. | |
| 306 | + | string repo = 1; | |
| 307 | + | // Number is the merge request number. | |
| 308 | + | int64 number = 2; | |
| 309 | + | // CommentId is the Comment.id to change. | |
| 310 | + | string comment_id = 3; | |
| 311 | + | // Resolved is the new state: true to resolve, false to unresolve. | |
| 312 | + | bool resolved = 4; | |
| 313 | + | } | |
| 314 | + | ||
| 315 | + | // ResolveCommentResponse holds the comment after the change. | |
| 316 | + | message ResolveCommentResponse { | |
| 317 | + | // Comment is the updated comment. | |
| 318 | + | Comment comment = 1; | |
| 319 | + | } | |
| 320 | + | ||
| 321 | + | // CloseMergeRequestRequest names the merge request to close. | |
| 322 | + | message CloseMergeRequestRequest { | |
| 323 | + | // Repo is the repository name. | |
| 324 | + | string repo = 1; | |
| 325 | + | // Number is the merge request number. | |
| 326 | + | int64 number = 2; | |
| 327 | + | } | |
| 328 | + | ||
| 329 | + | // CloseMergeRequestResponse holds the merge request after closing. | |
| 330 | + | message CloseMergeRequestResponse { | |
| 331 | + | // MergeRequest is the closed merge request. | |
| 332 | + | MergeRequest merge_request = 1; | |
| 333 | + | } | |
| 334 | + | ||
| 335 | + | // MergeMergeRequestRequest describes the merge to perform. | |
| 336 | + | message MergeMergeRequestRequest { | |
| 337 | + | // Repo is the repository name. | |
| 338 | + | string repo = 1; | |
| 339 | + | // Number is the merge request number. | |
| 340 | + | int64 number = 2; | |
| 341 | + | // Mode is how to merge. MERGE_MODE_UNSPECIFIED means fast-forward. The mode | |
| 342 | + | // must be in RepoSettings.allowed_merge_modes of the repository. | |
| 343 | + | MergeMode mode = 3; | |
| 344 | + | // HeadId is the full id of the commit the caller reviewed, that is the | |
| 345 | + | // MergeRequest.head_id it was shown. Required. The merge happens only if the | |
| 346 | + | // source branch still points to it. | |
| 347 | + | string head_id = 4; | |
| 348 | + | } | |
| 349 | + | ||
| 350 | + | // MergeMergeRequestResponse holds the merged merge request. | |
| 351 | + | message MergeMergeRequestResponse { | |
| 352 | + | // MergeRequest is the merge request after the merge: state MERGED, | |
| 353 | + | // merged_commit_id set to the new tip of the target branch and merge_mode | |
| 354 | + | // set to the mode used. | |
| 355 | + | MergeRequest merge_request = 1; | |
| 356 | + | } | |
| 357 | + | ||
| 358 | + | // MarkReadRequest records a read position. | |
| 359 | + | message MarkReadRequest { | |
| 360 | + | // Repo is the repository name. | |
| 361 | + | string repo = 1; | |
| 362 | + | // Number is the merge request number. | |
| 363 | + | int64 number = 2; | |
| 364 | + | // HeadId is the full id of the commit the caller has reviewed, usually the | |
| 365 | + | // MergeRequest.head_id it was shown. Empty means the current head of the | |
| 366 | + | // source branch. | |
| 367 | + | string head_id = 3; | |
| 368 | + | } | |
| 369 | + | ||
| 370 | + | // MarkReadResponse is empty. | |
| 371 | + | message MarkReadResponse {} | |
| @@ -0,0 +1,371 @@ | |||||
| 1 | + | // SPDX-License-Identifier: MIT | |||
| 2 | + | ||||
| 3 | + | syntax = "proto3"; | |||
| 4 | + | ||||
| 5 | + | package ermite; | |||
| 6 | + | ||||
| 7 | + | import "ermite/git.proto"; | |||
| 8 | + | import "ermite/types.proto"; | |||
| 9 | + | import "google/protobuf/timestamp.proto"; | |||
| 10 | + | ||||
| 11 | + | // MergeRequestState is where a merge request is in its life. | |||
| 12 | + | enum MergeRequestState { | |||
| 13 | + | // Not set. In ListMergeRequestsRequest.state it means every state. Never | |||
| 14 | + | // returned by the server. | |||
| 15 | + | MERGE_REQUEST_STATE_UNSPECIFIED = 0; | |||
| 16 | + | // The merge request awaits review; it can be commented on, merged or closed. | |||
| 17 | + | MERGE_REQUEST_STATE_OPEN = 1; | |||
| 18 | + | // The source branch was merged into the target. Final. | |||
| 19 | + | MERGE_REQUEST_STATE_MERGED = 2; | |||
| 20 | + | // The merge request was closed without merging. Final. | |||
| 21 | + | MERGE_REQUEST_STATE_CLOSED = 3; | |||
| 22 | + | } | |||
| 23 | + | ||||
| 24 | + | // DiffSide is the side of a diff a line comment is attached to. | |||
| 25 | + | enum DiffSide { | |||
| 26 | + | // Not set. On a Comment it means the comment is general, not attached to a | |||
| 27 | + | // line. In AddCommentRequest it is valid only for a general comment. | |||
| 28 | + | DIFF_SIDE_UNSPECIFIED = 0; | |||
| 29 | + | // The old side: the line is a Line.old_number (a deletion or a context line). | |||
| 30 | + | DIFF_SIDE_OLD = 1; | |||
| 31 | + | // The new side: the line is a Line.new_number (an addition or a context | |||
| 32 | + | // line). | |||
| 33 | + | DIFF_SIDE_NEW = 2; | |||
| 34 | + | } | |||
| 35 | + | ||||
| 36 | + | // MergeRequest asks to merge one branch of a repository into another branch | |||
| 37 | + | // of the same repository. It is about a branch, not about who wrote it. | |||
| 38 | + | message MergeRequest { | |||
| 39 | + | // Repo is the name of the repository. | |||
| 40 | + | string repo = 1; | |||
| 41 | + | // Number identifies the merge request within its repository, starting at 1 | |||
| 42 | + | // and never reused. It is written "!<number>" in messages and URLs. | |||
| 43 | + | int64 number = 2; | |||
| 44 | + | // Title is a one-line plain-text title, at most 120 characters. | |||
| 45 | + | string title = 3; | |||
| 46 | + | // Description is a plain-text description, at most 8,000 characters. It may | |||
| 47 | + | // be empty. Clients show it escaped, with line breaks kept. | |||
| 48 | + | string description = 4; | |||
| 49 | + | // SourceBranch is the short name of the branch to merge, for example | |||
| 50 | + | // "feat/x". | |||
| 51 | + | string source_branch = 5; | |||
| 52 | + | // TargetBranch is the short name of the branch to merge into, for example | |||
| 53 | + | // "main". | |||
| 54 | + | string target_branch = 6; | |||
| 55 | + | // State is where the merge request is in its life. | |||
| 56 | + | MergeRequestState state = 7; | |||
| 57 | + | // Author names who created the merge request: the label of the token that | |||
| 58 | + | // was used, "root" for the root token, or "owner" for a web session. It is | |||
| 59 | + | // informational: labels are not unique and the token may be gone. | |||
| 60 | + | string author = 8; | |||
| 61 | + | // CreatedAt is when the merge request was created. | |||
| 62 | + | google.protobuf.Timestamp created_at = 9; | |||
| 63 | + | // UpdatedAt is when the merge request last changed: title, description, | |||
| 64 | + | // state, or a comment added or resolved. Pushes to the source branch do not | |||
| 65 | + | // change it. | |||
| 66 | + | google.protobuf.Timestamp updated_at = 10; | |||
| 67 | + | // HeadId is the id of the commit the source branch points to. While the | |||
| 68 | + | // merge request is open it is read from Git at every call, so it changes | |||
| 69 | + | // when the branch is pushed; it is empty if the branch was deleted. Once | |||
| 70 | + | // merged or closed it is the head at that moment. | |||
| 71 | + | string head_id = 11; | |||
| 72 | + | // MergedCommitId is the id of the commit the target branch points to after | |||
| 73 | + | // the merge: the head for a fast-forward, the new commit for a squash. | |||
| 74 | + | // Empty unless state is MERGED. | |||
| 75 | + | string merged_commit_id = 12; | |||
| 76 | + | // MergeMode is how the merge request was merged. MERGE_MODE_UNSPECIFIED | |||
| 77 | + | // unless state is MERGED. | |||
| 78 | + | MergeMode merge_mode = 13; | |||
| 79 | + | } | |||
| 80 | + | ||||
| 81 | + | // Comment is a note on a merge request, either general or attached to a line | |||
| 82 | + | // of its diff. | |||
| 83 | + | message Comment { | |||
| 84 | + | // Id identifies the comment within its merge request. Opaque. | |||
| 85 | + | string id = 1; | |||
| 86 | + | // Author names who wrote the comment, like MergeRequest.author. | |||
| 87 | + | string author = 2; | |||
| 88 | + | // Path is the path of the commented file in the diff (the new path, or the | |||
| 89 | + | // old path of a deleted file). Empty for a general comment. | |||
| 90 | + | string path = 3; | |||
| 91 | + | // Line is the 1-based line number on side. 0 for a general comment. | |||
| 92 | + | int32 line = 4; | |||
| 93 | + | // Side tells whether line counts on the old or the new side of the diff. | |||
| 94 | + | // DIFF_SIDE_UNSPECIFIED for a general comment. | |||
| 95 | + | DiffSide side = 5; | |||
| 96 | + | // CommitId is the head of the merge request when the comment was written. | |||
| 97 | + | // When it differs from the current head the line may have moved; clients | |||
| 98 | + | // may show the comment as outdated. | |||
| 99 | + | string commit_id = 6; | |||
| 100 | + | // Text is the plain-text content, at most 8,000 characters. Clients show it | |||
| 101 | + | // escaped, with line breaks kept. | |||
| 102 | + | string text = 7; | |||
| 103 | + | // Resolved is true once the comment was marked resolved. | |||
| 104 | + | bool resolved = 8; | |||
| 105 | + | // CreatedAt is when the comment was written. | |||
| 106 | + | google.protobuf.Timestamp created_at = 9; | |||
| 107 | + | } | |||
| 108 | + | ||||
| 109 | + | // MergeRequestService reviews and merges branches. | |||
| 110 | + | // | |||
| 111 | + | // Every RPC takes the repository name and, except for creation and listing, | |||
| 112 | + | // the merge request number. A repository that does not exist or that the | |||
| 113 | + | // caller cannot read gives not_found; so does an unknown number. Reading | |||
| 114 | + | // (ListMergeRequests, GetMergeRequest) needs the same access as reading the | |||
| 115 | + | // repository: nothing for a public one, the repo:read scope for a private | |||
| 116 | + | // one. Writing needs a scope on the repository, given per RPC; a caller | |||
| 117 | + | // without it gets permission_denied. | |||
| 118 | + | // | |||
| 119 | + | // Text fields follow the same rules everywhere: valid UTF-8, no control | |||
| 120 | + | // characters (except the line break in description and comment text) and no | |||
| 121 | + | // Unicode bidirectional override or isolate characters; title is one line of | |||
| 122 | + | // at most 120 characters, description and comment text at most 8,000 | |||
| 123 | + | // characters. A request that breaks a rule is rejected whole with | |||
| 124 | + | // invalid_argument, and the error carries a BadRequest detail naming the | |||
| 125 | + | // fields. | |||
| 126 | + | // | |||
| 127 | + | // Servers that implement this service list "merge_requests" in | |||
| 128 | + | // GetVersionResponse.features. | |||
| 129 | + | service MergeRequestService { | |||
| 130 | + | // CreateMergeRequest opens a merge request. Needs the mr:write scope. Fails | |||
| 131 | + | // with invalid_argument if a text rule is broken, if a branch does not exist | |||
| 132 | + | // or if source and target are the same branch, and with already_exists if an | |||
| 133 | + | // open merge request already has the same source and target. | |||
| 134 | + | rpc CreateMergeRequest(CreateMergeRequestRequest) returns (CreateMergeRequestResponse); | |||
| 135 | + | // ListMergeRequests lists the merge requests of a repository, highest | |||
| 136 | + | // number (newest) first, optionally restricted to one state. The listed | |||
| 137 | + | // merge requests carry no diff or comments; head_id is set. Fails with | |||
| 138 | + | // not_found if the repository does not exist or is not readable. | |||
| 139 | + | rpc ListMergeRequests(ListMergeRequestsRequest) returns (ListMergeRequestsResponse); | |||
| 140 | + | // GetMergeRequest returns one merge request with its commits, its diff and | |||
| 141 | + | // its comments. The diff compares the target with the head (what the merge | |||
| 142 | + | // would bring: "target...head"), or, with since_last_read, the head the | |||
| 143 | + | // caller last marked read with the current head. Fails with not_found if | |||
| 144 | + | // the repository or the number is unknown. | |||
| 145 | + | rpc GetMergeRequest(GetMergeRequestRequest) returns (GetMergeRequestResponse); | |||
| 146 | + | // AddComment adds a general comment or a comment on a line of the diff. | |||
| 147 | + | // Needs the mr:write scope. Fails with invalid_argument if the text breaks | |||
| 148 | + | // a rule or if path, line and side do not designate a line of the current | |||
| 149 | + | // diff of the merge request, and with failed_precondition if the merge | |||
| 150 | + | // request is not open. | |||
| 151 | + | rpc AddComment(AddCommentRequest) returns (AddCommentResponse); | |||
| 152 | + | // ResolveComment marks a comment resolved or unresolved. Needs the mr:write | |||
| 153 | + | // scope. Fails with not_found if the comment is unknown and with | |||
| 154 | + | // failed_precondition if the merge request is not open. Setting the state | |||
| 155 | + | // the comment already has succeeds and changes nothing. | |||
| 156 | + | rpc ResolveComment(ResolveCommentRequest) returns (ResolveCommentResponse); | |||
| 157 | + | // CloseMergeRequest closes an open merge request without merging it. Needs | |||
| 158 | + | // the mr:write scope. Fails with failed_precondition if the merge request | |||
| 159 | + | // is not open. A closed merge request cannot be reopened: open a new one. | |||
| 160 | + | rpc CloseMergeRequest(CloseMergeRequestRequest) returns (CloseMergeRequestResponse); | |||
| 161 | + | // MergeMergeRequest merges an open merge request. Needs the mr:merge scope. | |||
| 162 | + | // The caller passes the head it reviewed: the server merges only if the | |||
| 163 | + | // source branch still points to it, so a push between review and merge is | |||
| 164 | + | // never merged unseen. Fails with invalid_argument if head_id is empty or | |||
| 165 | + | // not a commit id, and with failed_precondition if the merge request is not | |||
| 166 | + | // open, if the source branch no longer points to head_id ("branch moved, | |||
| 167 | + | // read again"), if the target is not an ancestor of the head (rebase and | |||
| 168 | + | // push again), if the mode is not allowed by RepoSettings, or if a check | |||
| 169 | + | // fails and RepoSettings.failing_checks_block is set. Merges of one | |||
| 170 | + | // repository run one at a time. Repeating a call that succeeded fails with | |||
| 171 | + | // failed_precondition (not open). On success the server publishes | |||
| 172 | + | // MergeRequestMerged then Pushed for the target branch. | |||
| 173 | + | rpc MergeMergeRequest(MergeMergeRequestRequest) returns (MergeMergeRequestResponse); | |||
| 174 | + | // MarkRead records the head the caller has reviewed, for the since_last_read | |||
| 175 | + | // option of GetMergeRequest. There is one read position per merge request, | |||
| 176 | + | // the reviewer's. Needs the mr:write scope. Marking a commit that does not | |||
| 177 | + | // exist in the repository is invalid_argument. | |||
| 178 | + | rpc MarkRead(MarkReadRequest) returns (MarkReadResponse); | |||
| 179 | + | } | |||
| 180 | + | ||||
| 181 | + | // CreateMergeRequestRequest describes the merge request to open. | |||
| 182 | + | message CreateMergeRequestRequest { | |||
| 183 | + | // Repo is the repository name. | |||
| 184 | + | string repo = 1; | |||
| 185 | + | // Title is the one-line title. Required. | |||
| 186 | + | string title = 2; | |||
| 187 | + | // Description is the optional description. | |||
| 188 | + | string description = 3; | |||
| 189 | + | // SourceBranch is the short name of the branch to merge. Required; the | |||
| 190 | + | // branch must exist. | |||
| 191 | + | string source_branch = 4; | |||
| 192 | + | // TargetBranch is the short name of the branch to merge into. Empty means | |||
| 193 | + | // the default branch of the repository. The branch must exist and differ | |||
| 194 | + | // from source_branch. | |||
| 195 | + | string target_branch = 5; | |||
| 196 | + | } | |||
| 197 | + | ||||
| 198 | + | // CreateMergeRequestResponse holds the new merge request. | |||
| 199 | + | message CreateMergeRequestResponse { | |||
| 200 | + | // MergeRequest is the created merge request. | |||
| 201 | + | MergeRequest merge_request = 1; | |||
| 202 | + | } | |||
| 203 | + | ||||
| 204 | + | // ListMergeRequestsRequest selects a page of merge requests. | |||
| 205 | + | message ListMergeRequestsRequest { | |||
| 206 | + | // Repo is the repository name. | |||
| 207 | + | string repo = 1; | |||
| 208 | + | // State restricts the result to one state. MERGE_REQUEST_STATE_UNSPECIFIED | |||
| 209 | + | // means every state. | |||
| 210 | + | MergeRequestState state = 2; | |||
| 211 | + | // PageSize is the maximum number of merge requests to return. 0 means the | |||
| 212 | + | // server default; values above the server maximum are lowered to it. | |||
| 213 | + | int32 page_size = 3; | |||
| 214 | + | // PageToken is the next_page_token of a previous response, to continue the | |||
| 215 | + | // same listing. Empty for the first page. Other fields must be unchanged. | |||
| 216 | + | string page_token = 4; | |||
| 217 | + | } | |||
| 218 | + | ||||
| 219 | + | // ListMergeRequestsResponse is one page of merge requests. | |||
| 220 | + | message ListMergeRequestsResponse { | |||
| 221 | + | // MergeRequests are the merge requests of this page, highest number first. | |||
| 222 | + | repeated MergeRequest merge_requests = 1; | |||
| 223 | + | // NextPageToken is passed as page_token to get the next page. Empty when | |||
| 224 | + | // there is no next page. | |||
| 225 | + | string next_page_token = 2; | |||
| 226 | + | } | |||
| 227 | + | ||||
| 228 | + | // GetMergeRequestRequest selects a merge request. | |||
| 229 | + | message GetMergeRequestRequest { | |||
| 230 | + | // Repo is the repository name. | |||
| 231 | + | string repo = 1; | |||
| 232 | + | // Number is the merge request number. | |||
| 233 | + | int64 number = 2; | |||
| 234 | + | // SinceLastRead asks for the diff between the head recorded by MarkRead and | |||
| 235 | + | // the current head instead of the diff against the target. It works after a | |||
| 236 | + | // force-push as long as the recorded commit still exists in the repository. | |||
| 237 | + | // When nothing was marked read, or the recorded commit is gone, the response | |||
| 238 | + | // holds the diff against the target and says so in last_read_id and | |||
| 239 | + | // last_read_lost. | |||
| 240 | + | bool since_last_read = 3; | |||
| 241 | + | } | |||
| 242 | + | ||||
| 243 | + | // GetMergeRequestResponse holds a merge request with its review data. | |||
| 244 | + | message GetMergeRequestResponse { | |||
| 245 | + | // MergeRequest is the merge request. | |||
| 246 | + | MergeRequest merge_request = 1; | |||
| 247 | + | // Commits are the commits of the head that are not in the target | |||
| 248 | + | // ("target..head"), newest first. At most 100 are returned (a server limit | |||
| 249 | + | // that may change; rely on commits_truncated, not on the number). Empty when | |||
| 250 | + | // the source branch was deleted. | |||
| 251 | + | repeated Commit commits = 2; | |||
| 252 | + | // CommitsTruncated is true when the branch has more commits than commits | |||
| 253 | + | // holds. | |||
| 254 | + | bool commits_truncated = 3; | |||
| 255 | + | // DiffBaseId is the id of the commit the diff compares from: the merge base | |||
| 256 | + | // of the target and the head, or the last read head when since_last_read | |||
| 257 | + | // applied. Empty when the source branch was deleted; diff is then empty. | |||
| 258 | + | string diff_base_id = 4; | |||
| 259 | + | // Stats are the totals of the diff, including files that it omits or | |||
| 260 | + | // truncates. | |||
| 261 | + | DiffStats stats = 5; | |||
| 262 | + | // Diff is the structured diff from diff_base_id to the head, with the same | |||
| 263 | + | // limits and truncated flags as GetCommitResponse.diff. | |||
| 264 | + | Diff diff = 6; | |||
| 265 | + | // Comments are every comment of the merge request, oldest first. | |||
| 266 | + | repeated Comment comments = 7; | |||
| 267 | + | // LastReadId is the head recorded by MarkRead, whether or not | |||
| 268 | + | // since_last_read was set. Empty when nothing was marked read. | |||
| 269 | + | string last_read_id = 8; | |||
| 270 | + | // LastReadLost is true when since_last_read was set, a head was recorded, | |||
| 271 | + | // but that commit no longer exists in the repository: the diff is then the | |||
| 272 | + | // diff against the target. A client should tell the reader to review the | |||
| 273 | + | // whole change again. | |||
| 274 | + | bool last_read_lost = 9; | |||
| 275 | + | } | |||
| 276 | + | ||||
| 277 | + | // AddCommentRequest describes the comment to add. | |||
| 278 | + | message AddCommentRequest { | |||
| 279 | + | // Repo is the repository name. | |||
| 280 | + | string repo = 1; | |||
| 281 | + | // Number is the merge request number. | |||
| 282 | + | int64 number = 2; | |||
| 283 | + | // Path is the file the comment is attached to, as given by the diff of the | |||
| 284 | + | // merge request: FileDiff.new_path, or old_path for a deleted file. Empty | |||
| 285 | + | // for a general comment; then line must be 0 and side unspecified. | |||
| 286 | + | string path = 3; | |||
| 287 | + | // Line is the 1-based line number on side. It must be the old_number or | |||
| 288 | + | // new_number of a Line of a hunk of the file; a line outside the hunks is | |||
| 289 | + | // invalid_argument. 0 for a general comment. | |||
| 290 | + | int32 line = 4; | |||
| 291 | + | // Side is the side line counts on. Required when path is set. | |||
| 292 | + | DiffSide side = 5; | |||
| 293 | + | // Text is the plain-text content. Required. | |||
| 294 | + | string text = 6; | |||
| 295 | + | } | |||
| 296 | + | ||||
| 297 | + | // AddCommentResponse holds the new comment. | |||
| 298 | + | message AddCommentResponse { | |||
| 299 | + | // Comment is the created comment. | |||
| 300 | + | Comment comment = 1; | |||
| 301 | + | } | |||
| 302 | + | ||||
| 303 | + | // ResolveCommentRequest changes the resolved state of a comment. | |||
| 304 | + | message ResolveCommentRequest { | |||
| 305 | + | // Repo is the repository name. | |||
| 306 | + | string repo = 1; | |||
| 307 | + | // Number is the merge request number. | |||
| 308 | + | int64 number = 2; | |||
| 309 | + | // CommentId is the Comment.id to change. | |||
| 310 | + | string comment_id = 3; | |||
| 311 | + | // Resolved is the new state: true to resolve, false to unresolve. | |||
| 312 | + | bool resolved = 4; | |||
| 313 | + | } | |||
| 314 | + | ||||
| 315 | + | // ResolveCommentResponse holds the comment after the change. | |||
| 316 | + | message ResolveCommentResponse { | |||
| 317 | + | // Comment is the updated comment. | |||
| 318 | + | Comment comment = 1; | |||
| 319 | + | } | |||
| 320 | + | ||||
| 321 | + | // CloseMergeRequestRequest names the merge request to close. | |||
| 322 | + | message CloseMergeRequestRequest { | |||
| 323 | + | // Repo is the repository name. | |||
| 324 | + | string repo = 1; | |||
| 325 | + | // Number is the merge request number. | |||
| 326 | + | int64 number = 2; | |||
| 327 | + | } | |||
| 328 | + | ||||
| 329 | + | // CloseMergeRequestResponse holds the merge request after closing. | |||
| 330 | + | message CloseMergeRequestResponse { | |||
| 331 | + | // MergeRequest is the closed merge request. | |||
| 332 | + | MergeRequest merge_request = 1; | |||
| 333 | + | } | |||
| 334 | + | ||||
| 335 | + | // MergeMergeRequestRequest describes the merge to perform. | |||
| 336 | + | message MergeMergeRequestRequest { | |||
| 337 | + | // Repo is the repository name. | |||
| 338 | + | string repo = 1; | |||
| 339 | + | // Number is the merge request number. | |||
| 340 | + | int64 number = 2; | |||
| 341 | + | // Mode is how to merge. MERGE_MODE_UNSPECIFIED means fast-forward. The mode | |||
| 342 | + | // must be in RepoSettings.allowed_merge_modes of the repository. | |||
| 343 | + | MergeMode mode = 3; | |||
| 344 | + | // HeadId is the full id of the commit the caller reviewed, that is the | |||
| 345 | + | // MergeRequest.head_id it was shown. Required. The merge happens only if the | |||
| 346 | + | // source branch still points to it. | |||
| 347 | + | string head_id = 4; | |||
| 348 | + | } | |||
| 349 | + | ||||
| 350 | + | // MergeMergeRequestResponse holds the merged merge request. | |||
| 351 | + | message MergeMergeRequestResponse { | |||
| 352 | + | // MergeRequest is the merge request after the merge: state MERGED, | |||
| 353 | + | // merged_commit_id set to the new tip of the target branch and merge_mode | |||
| 354 | + | // set to the mode used. | |||
| 355 | + | MergeRequest merge_request = 1; | |||
| 356 | + | } | |||
| 357 | + | ||||
| 358 | + | // MarkReadRequest records a read position. | |||
| 359 | + | message MarkReadRequest { | |||
| 360 | + | // Repo is the repository name. | |||
| 361 | + | string repo = 1; | |||
| 362 | + | // Number is the merge request number. | |||
| 363 | + | int64 number = 2; | |||
| 364 | + | // HeadId is the full id of the commit the caller has reviewed, usually the | |||
| 365 | + | // MergeRequest.head_id it was shown. Empty means the current head of the | |||
| 366 | + | // source branch. | |||
| 367 | + | string head_id = 3; | |||
| 368 | + | } | |||
| 369 | + | ||||
| 370 | + | // MarkReadResponse is empty. | |||
| 371 | + | message MarkReadResponse {} | |||
M proto/ermite/repo.proto +33 -5
| @@ -5,6 +5,7 @@ syntax = "proto3"; | |||
| 5 | 5 | package ermite; | |
| 6 | 6 | ||
| 7 | 7 | import "google/protobuf/field_mask.proto"; | |
| 8 | + | import "ermite/types.proto"; | |
| 8 | 9 | import "google/protobuf/timestamp.proto"; | |
| 9 | 10 | ||
| 10 | 11 | // Visibility says who may read a repository. | |
| @@ -19,6 +20,21 @@ enum Visibility { | |||
| 19 | 20 | VISIBILITY_PRIVATE = 2; | |
| 20 | 21 | } | |
| 21 | 22 | ||
| 23 | + | // RepoSettings are the settings of a repository that govern its merge | |
| 24 | + | // requests. | |
| 25 | + | message RepoSettings { | |
| 26 | + | // AllowedMergeModes are the modes with which a merge request of the | |
| 27 | + | // repository may be merged. It is never empty in a response and has no | |
| 28 | + | // duplicate. Both MERGE_MODE_FAST_FORWARD and MERGE_MODE_SQUASH are allowed | |
| 29 | + | // by default. MERGE_MODE_UNSPECIFIED is rejected. | |
| 30 | + | repeated MergeMode allowed_merge_modes = 1; | |
| 31 | + | // FailingChecksBlock says whether a merge request whose checks fail cannot be | |
| 32 | + | // merged. It is true at creation of the repository and always stored | |
| 33 | + | // explicitly, so a later change of the server default never alters an | |
| 34 | + | // existing repository. | |
| 35 | + | bool failing_checks_block = 2; | |
| 36 | + | } | |
| 37 | + | ||
| 22 | 38 | // Repo is the metadata of a repository. Git-owned state (refs, trees, history) | |
| 23 | 39 | // is read through GitService. | |
| 24 | 40 | message Repo { | |
| @@ -37,6 +53,9 @@ message Repo { | |||
| 37 | 53 | google.protobuf.Timestamp created_at = 5; | |
| 38 | 54 | // PushedAt is the time of the last push. It is unset until the first push. | |
| 39 | 55 | google.protobuf.Timestamp pushed_at = 6; | |
| 56 | + | // Settings are the merge settings of the repository. Always set in a | |
| 57 | + | // response, with the defaults for a repository that never changed them. | |
| 58 | + | RepoSettings settings = 7; | |
| 40 | 59 | } | |
| 41 | 60 | ||
| 42 | 61 | // RepoService manages repositories and their metadata. | |
| @@ -49,12 +68,13 @@ service RepoService { | |||
| 49 | 68 | // GetRepo returns one repository. Fails with not_found if it does not exist | |
| 50 | 69 | // or is private and not readable by the caller. | |
| 51 | 70 | rpc GetRepo(GetRepoRequest) returns (GetRepoResponse); | |
| 52 | - | // CreateRepo creates an empty repository. Needs the repo:write scope. Fails | |
| 71 | + | // CreateRepo creates an empty repository with the default settings. Needs | |
| 72 | + | // the repo:write scope. Fails | |
| 53 | 73 | // with already_exists if the name is taken and invalid_argument if the name | |
| 54 | 74 | // is not valid. | |
| 55 | 75 | rpc CreateRepo(CreateRepoRequest) returns (CreateRepoResponse); | |
| 56 | - | // UpdateRepo changes the fields named in update_mask. Needs the repo:admin | |
| 57 | - | // scope. | |
| 76 | + | // UpdateRepo changes the fields named in update_mask, including the merge | |
| 77 | + | // settings. Needs the repo:admin scope. | |
| 58 | 78 | rpc UpdateRepo(UpdateRepoRequest) returns (UpdateRepoResponse); | |
| 59 | 79 | // DeleteRepo deletes a repository. Needs the repo:admin scope. The server | |
| 60 | 80 | // moves the data aside rather than destroying it; there is no undelete RPC. | |
| @@ -124,9 +144,17 @@ message UpdateRepoRequest { | |||
| 124 | 144 | // update_mask contains "default_branch". The branch must exist, otherwise | |
| 125 | 145 | // the call fails with failed_precondition. | |
| 126 | 146 | string default_branch = 4; | |
| 127 | - | // UpdateMask lists the fields to change: "description", "visibility" and/or | |
| 128 | - | // "default_branch". It must not be empty. Other paths are invalid_argument. | |
| 147 | + | // UpdateMask lists the fields to change: "description", "visibility", | |
| 148 | + | // "default_branch", "settings.allowed_merge_modes" and/or | |
| 149 | + | // "settings.failing_checks_block". "settings" stands for both settings | |
| 150 | + | // paths. It must not be empty. Other paths are invalid_argument. | |
| 129 | 151 | google.protobuf.FieldMask update_mask = 5; | |
| 152 | + | // Settings holds the new merge settings. Only the fields named in | |
| 153 | + | // update_mask are used. allowed_merge_modes must then not be empty nor | |
| 154 | + | // contain MERGE_MODE_UNSPECIFIED, otherwise the call fails with | |
| 155 | + | // invalid_argument. Changing settings needs the repo:admin scope, like any | |
| 156 | + | // other field. | |
| 157 | + | RepoSettings settings = 6; | |
| 130 | 158 | } | |
| 131 | 159 | ||
| 132 | 160 | // UpdateRepoResponse holds the repository after the update. | |
| @@ -5,6 +5,7 @@ syntax = "proto3"; | |||||
| 5 | package ermite; | 5 | package ermite; | ||
| 6 | 6 | ||||
| 7 | import "google/protobuf/field_mask.proto"; | 7 | import "google/protobuf/field_mask.proto"; | ||
| 8 | + | import "ermite/types.proto"; | |||
| 8 | import "google/protobuf/timestamp.proto"; | 9 | import "google/protobuf/timestamp.proto"; | ||
| 9 | 10 | ||||
| 10 | // Visibility says who may read a repository. | 11 | // Visibility says who may read a repository. | ||
| @@ -19,6 +20,21 @@ enum Visibility { | |||||
| 19 | VISIBILITY_PRIVATE = 2; | 20 | VISIBILITY_PRIVATE = 2; | ||
| 20 | } | 21 | } | ||
| 21 | 22 | ||||
| 23 | + | // RepoSettings are the settings of a repository that govern its merge | |||
| 24 | + | // requests. | |||
| 25 | + | message RepoSettings { | |||
| 26 | + | // AllowedMergeModes are the modes with which a merge request of the | |||
| 27 | + | // repository may be merged. It is never empty in a response and has no | |||
| 28 | + | // duplicate. Both MERGE_MODE_FAST_FORWARD and MERGE_MODE_SQUASH are allowed | |||
| 29 | + | // by default. MERGE_MODE_UNSPECIFIED is rejected. | |||
| 30 | + | repeated MergeMode allowed_merge_modes = 1; | |||
| 31 | + | // FailingChecksBlock says whether a merge request whose checks fail cannot be | |||
| 32 | + | // merged. It is true at creation of the repository and always stored | |||
| 33 | + | // explicitly, so a later change of the server default never alters an | |||
| 34 | + | // existing repository. | |||
| 35 | + | bool failing_checks_block = 2; | |||
| 36 | + | } | |||
| 37 | + | ||||
| 22 | // Repo is the metadata of a repository. Git-owned state (refs, trees, history) | 38 | // Repo is the metadata of a repository. Git-owned state (refs, trees, history) | ||
| 23 | // is read through GitService. | 39 | // is read through GitService. | ||
| 24 | message Repo { | 40 | message Repo { | ||
| @@ -37,6 +53,9 @@ message Repo { | |||||
| 37 | google.protobuf.Timestamp created_at = 5; | 53 | google.protobuf.Timestamp created_at = 5; | ||
| 38 | // PushedAt is the time of the last push. It is unset until the first push. | 54 | // PushedAt is the time of the last push. It is unset until the first push. | ||
| 39 | google.protobuf.Timestamp pushed_at = 6; | 55 | google.protobuf.Timestamp pushed_at = 6; | ||
| 56 | + | // Settings are the merge settings of the repository. Always set in a | |||
| 57 | + | // response, with the defaults for a repository that never changed them. | |||
| 58 | + | RepoSettings settings = 7; | |||
| 40 | } | 59 | } | ||
| 41 | 60 | ||||
| 42 | // RepoService manages repositories and their metadata. | 61 | // RepoService manages repositories and their metadata. | ||
| @@ -49,12 +68,13 @@ service RepoService { | |||||
| 49 | // GetRepo returns one repository. Fails with not_found if it does not exist | 68 | // GetRepo returns one repository. Fails with not_found if it does not exist | ||
| 50 | // or is private and not readable by the caller. | 69 | // or is private and not readable by the caller. | ||
| 51 | rpc GetRepo(GetRepoRequest) returns (GetRepoResponse); | 70 | rpc GetRepo(GetRepoRequest) returns (GetRepoResponse); | ||
| 52 | - | // CreateRepo creates an empty repository. Needs the repo:write scope. Fails | 71 | + | // CreateRepo creates an empty repository with the default settings. Needs |
| 72 | + | // the repo:write scope. Fails | |||
| 53 | // with already_exists if the name is taken and invalid_argument if the name | 73 | // with already_exists if the name is taken and invalid_argument if the name | ||
| 54 | // is not valid. | 74 | // is not valid. | ||
| 55 | rpc CreateRepo(CreateRepoRequest) returns (CreateRepoResponse); | 75 | rpc CreateRepo(CreateRepoRequest) returns (CreateRepoResponse); | ||
| 56 | - | // UpdateRepo changes the fields named in update_mask. Needs the repo:admin | 76 | + | // UpdateRepo changes the fields named in update_mask, including the merge |
| 57 | - | // scope. | 77 | + | // settings. Needs the repo:admin scope. |
| 58 | rpc UpdateRepo(UpdateRepoRequest) returns (UpdateRepoResponse); | 78 | rpc UpdateRepo(UpdateRepoRequest) returns (UpdateRepoResponse); | ||
| 59 | // DeleteRepo deletes a repository. Needs the repo:admin scope. The server | 79 | // DeleteRepo deletes a repository. Needs the repo:admin scope. The server | ||
| 60 | // moves the data aside rather than destroying it; there is no undelete RPC. | 80 | // moves the data aside rather than destroying it; there is no undelete RPC. | ||
| @@ -124,9 +144,17 @@ message UpdateRepoRequest { | |||||
| 124 | // update_mask contains "default_branch". The branch must exist, otherwise | 144 | // update_mask contains "default_branch". The branch must exist, otherwise | ||
| 125 | // the call fails with failed_precondition. | 145 | // the call fails with failed_precondition. | ||
| 126 | string default_branch = 4; | 146 | string default_branch = 4; | ||
| 127 | - | // UpdateMask lists the fields to change: "description", "visibility" and/or | 147 | + | // UpdateMask lists the fields to change: "description", "visibility", |
| 128 | - | // "default_branch". It must not be empty. Other paths are invalid_argument. | 148 | + | // "default_branch", "settings.allowed_merge_modes" and/or |
| 149 | + | // "settings.failing_checks_block". "settings" stands for both settings | |||
| 150 | + | // paths. It must not be empty. Other paths are invalid_argument. | |||
| 129 | google.protobuf.FieldMask update_mask = 5; | 151 | google.protobuf.FieldMask update_mask = 5; | ||
| 152 | + | // Settings holds the new merge settings. Only the fields named in | |||
| 153 | + | // update_mask are used. allowed_merge_modes must then not be empty nor | |||
| 154 | + | // contain MERGE_MODE_UNSPECIFIED, otherwise the call fails with | |||
| 155 | + | // invalid_argument. Changing settings needs the repo:admin scope, like any | |||
| 156 | + | // other field. | |||
| 157 | + | RepoSettings settings = 6; | |||
| 130 | } | 158 | } | ||
| 131 | 159 | ||||
| 132 | // UpdateRepoResponse holds the repository after the update. | 160 | // UpdateRepoResponse holds the repository after the update. | ||
M proto/ermite/server.proto +30 -0
| @@ -10,6 +10,12 @@ service ServerService { | |||
| 10 | 10 | // contract it implements. It needs no authentication, so a client can call | |
| 11 | 11 | // it first to check compatibility. | |
| 12 | 12 | rpc GetVersion(GetVersionRequest) returns (GetVersionResponse); | |
| 13 | + | // GetSigningKey returns the public key with which the server signs the | |
| 14 | + | // commits it creates (squash merges, see MergeMode). It needs no | |
| 15 | + | // authentication: the key is public, and anyone verifying a commit needs it. | |
| 16 | + | // Servers that implement it list "signing_key" in | |
| 17 | + | // GetVersionResponse.features. | |
| 18 | + | rpc GetSigningKey(GetSigningKeyRequest) returns (GetSigningKeyResponse); | |
| 13 | 19 | } | |
| 14 | 20 | ||
| 15 | 21 | // GetVersionRequest is empty. | |
| @@ -28,3 +34,27 @@ message GetVersionResponse { | |||
| 28 | 34 | // Identifiers are lowercase, dot-separated and never reused. | |
| 29 | 35 | repeated string features = 2; | |
| 30 | 36 | } | |
| 37 | + | ||
| 38 | + | // GetSigningKeyRequest is empty. | |
| 39 | + | message GetSigningKeyRequest {} | |
| 40 | + | ||
| 41 | + | // GetSigningKeyResponse describes the commit signing key of the server. | |
| 42 | + | message GetSigningKeyResponse { | |
| 43 | + | // PublicKey is the public key as one OpenSSH authorized_keys line, for | |
| 44 | + | // example "ssh-ed25519 AAAA...". Commits are signed in the SSH signature | |
| 45 | + | // format (SSHSIG). | |
| 46 | + | string public_key = 1; | |
| 47 | + | // Fingerprint is the SHA-256 fingerprint of the key, in the form | |
| 48 | + | // "SHA256:<base64>" that ssh-keygen prints. | |
| 49 | + | string fingerprint = 2; | |
| 50 | + | // CommitterName is the name the server records as the committer of the | |
| 51 | + | // commits it creates. | |
| 52 | + | string committer_name = 3; | |
| 53 | + | // CommitterEmail is the email address the server records as the committer of | |
| 54 | + | // the commits it creates. It is the principal of allowed_signers. | |
| 55 | + | string committer_email = 4; | |
| 56 | + | // AllowedSigners is a ready-to-use line for an allowed signers file | |
| 57 | + | // ("<committer_email> <public_key>"), to verify these commits with | |
| 58 | + | // "git config gpg.ssh.allowedSignersFile". | |
| 59 | + | string allowed_signers = 5; | |
| 60 | + | } | |
| @@ -10,6 +10,12 @@ service ServerService { | |||||
| 10 | // contract it implements. It needs no authentication, so a client can call | 10 | // contract it implements. It needs no authentication, so a client can call | ||
| 11 | // it first to check compatibility. | 11 | // it first to check compatibility. | ||
| 12 | rpc GetVersion(GetVersionRequest) returns (GetVersionResponse); | 12 | rpc GetVersion(GetVersionRequest) returns (GetVersionResponse); | ||
| 13 | + | // GetSigningKey returns the public key with which the server signs the | |||
| 14 | + | // commits it creates (squash merges, see MergeMode). It needs no | |||
| 15 | + | // authentication: the key is public, and anyone verifying a commit needs it. | |||
| 16 | + | // Servers that implement it list "signing_key" in | |||
| 17 | + | // GetVersionResponse.features. | |||
| 18 | + | rpc GetSigningKey(GetSigningKeyRequest) returns (GetSigningKeyResponse); | |||
| 13 | } | 19 | } | ||
| 14 | 20 | ||||
| 15 | // GetVersionRequest is empty. | 21 | // GetVersionRequest is empty. | ||
| @@ -28,3 +34,27 @@ message GetVersionResponse { | |||||
| 28 | // Identifiers are lowercase, dot-separated and never reused. | 34 | // Identifiers are lowercase, dot-separated and never reused. | ||
| 29 | repeated string features = 2; | 35 | repeated string features = 2; | ||
| 30 | } | 36 | } | ||
| 37 | + | ||||
| 38 | + | // GetSigningKeyRequest is empty. | |||
| 39 | + | message GetSigningKeyRequest {} | |||
| 40 | + | ||||
| 41 | + | // GetSigningKeyResponse describes the commit signing key of the server. | |||
| 42 | + | message GetSigningKeyResponse { | |||
| 43 | + | // PublicKey is the public key as one OpenSSH authorized_keys line, for | |||
| 44 | + | // example "ssh-ed25519 AAAA...". Commits are signed in the SSH signature | |||
| 45 | + | // format (SSHSIG). | |||
| 46 | + | string public_key = 1; | |||
| 47 | + | // Fingerprint is the SHA-256 fingerprint of the key, in the form | |||
| 48 | + | // "SHA256:<base64>" that ssh-keygen prints. | |||
| 49 | + | string fingerprint = 2; | |||
| 50 | + | // CommitterName is the name the server records as the committer of the | |||
| 51 | + | // commits it creates. | |||
| 52 | + | string committer_name = 3; | |||
| 53 | + | // CommitterEmail is the email address the server records as the committer of | |||
| 54 | + | // the commits it creates. It is the principal of allowed_signers. | |||
| 55 | + | string committer_email = 4; | |||
| 56 | + | // AllowedSigners is a ready-to-use line for an allowed signers file | |||
| 57 | + | // ("<committer_email> <public_key>"), to verify these commits with | |||
| 58 | + | // "git config gpg.ssh.allowedSignersFile". | |||
| 59 | + | string allowed_signers = 5; | |||
| 60 | + | } | |||
A proto/ermite/session.proto +51 -0
| @@ -0,0 +1,51 @@ | |||
| 1 | + | // SPDX-License-Identifier: MIT | |
| 2 | + | ||
| 3 | + | syntax = "proto3"; | |
| 4 | + | ||
| 5 | + | package ermite; | |
| 6 | + | ||
| 7 | + | import "google/protobuf/timestamp.proto"; | |
| 8 | + | ||
| 9 | + | // SessionService manages the owner's browser sessions. The browser itself | |
| 10 | + | // never calls it: it signs in by opening the link that CreateLoginLink | |
| 11 | + | // returns, and signs out by posting to the web's logout route. | |
| 12 | + | // | |
| 13 | + | // Every RPC is owner-only: it needs the root token, or a stored token that | |
| 14 | + | // holds every scope and is not restricted to repositories. Any other caller | |
| 15 | + | // gets permission_denied. Sessions do not go through this API: the Connect | |
| 16 | + | // API accepts bearer tokens only and ignores cookies. | |
| 17 | + | // | |
| 18 | + | // Servers that implement this service list "session" in | |
| 19 | + | // GetVersionResponse.features. | |
| 20 | + | service SessionService { | |
| 21 | + | // CreateLoginLink creates a one-time link that signs the owner's browser | |
| 22 | + | // in. The link is valid for a short time (about a minute), can be used | |
| 23 | + | // once, and is kept in memory only: a server restart voids it. Opening it | |
| 24 | + | // shows a confirmation page; only confirming it consumes the link and sets | |
| 25 | + | // the session. Creating a new link does not void an earlier one. Fails with | |
| 26 | + | // resource_exhausted when too many links are pending. | |
| 27 | + | rpc CreateLoginLink(CreateLoginLinkRequest) returns (CreateLoginLinkResponse); | |
| 28 | + | // SignOutEverywhere ends every browser session at once, including those on | |
| 29 | + | // other devices. Pending login links are not affected. Tokens are not | |
| 30 | + | // affected either: revoke them with TokenService. | |
| 31 | + | rpc SignOutEverywhere(SignOutEverywhereRequest) returns (SignOutEverywhereResponse); | |
| 32 | + | } | |
| 33 | + | ||
| 34 | + | // CreateLoginLinkRequest is empty. | |
| 35 | + | message CreateLoginLinkRequest {} | |
| 36 | + | ||
| 37 | + | // CreateLoginLinkResponse holds the link. | |
| 38 | + | message CreateLoginLinkResponse { | |
| 39 | + | // Url is the absolute link to open in a browser, on the public URL of the | |
| 40 | + | // server. It holds a secret: clients print it to the terminal and nowhere | |
| 41 | + | // else, and never log it. | |
| 42 | + | string url = 1; | |
| 43 | + | // ExpiresAt is when the link stops working if it is not used. | |
| 44 | + | google.protobuf.Timestamp expires_at = 2; | |
| 45 | + | } | |
| 46 | + | ||
| 47 | + | // SignOutEverywhereRequest is empty. | |
| 48 | + | message SignOutEverywhereRequest {} | |
| 49 | + | ||
| 50 | + | // SignOutEverywhereResponse is empty. | |
| 51 | + | message SignOutEverywhereResponse {} | |
| @@ -0,0 +1,51 @@ | |||||
| 1 | + | // SPDX-License-Identifier: MIT | |||
| 2 | + | ||||
| 3 | + | syntax = "proto3"; | |||
| 4 | + | ||||
| 5 | + | package ermite; | |||
| 6 | + | ||||
| 7 | + | import "google/protobuf/timestamp.proto"; | |||
| 8 | + | ||||
| 9 | + | // SessionService manages the owner's browser sessions. The browser itself | |||
| 10 | + | // never calls it: it signs in by opening the link that CreateLoginLink | |||
| 11 | + | // returns, and signs out by posting to the web's logout route. | |||
| 12 | + | // | |||
| 13 | + | // Every RPC is owner-only: it needs the root token, or a stored token that | |||
| 14 | + | // holds every scope and is not restricted to repositories. Any other caller | |||
| 15 | + | // gets permission_denied. Sessions do not go through this API: the Connect | |||
| 16 | + | // API accepts bearer tokens only and ignores cookies. | |||
| 17 | + | // | |||
| 18 | + | // Servers that implement this service list "session" in | |||
| 19 | + | // GetVersionResponse.features. | |||
| 20 | + | service SessionService { | |||
| 21 | + | // CreateLoginLink creates a one-time link that signs the owner's browser | |||
| 22 | + | // in. The link is valid for a short time (about a minute), can be used | |||
| 23 | + | // once, and is kept in memory only: a server restart voids it. Opening it | |||
| 24 | + | // shows a confirmation page; only confirming it consumes the link and sets | |||
| 25 | + | // the session. Creating a new link does not void an earlier one. Fails with | |||
| 26 | + | // resource_exhausted when too many links are pending. | |||
| 27 | + | rpc CreateLoginLink(CreateLoginLinkRequest) returns (CreateLoginLinkResponse); | |||
| 28 | + | // SignOutEverywhere ends every browser session at once, including those on | |||
| 29 | + | // other devices. Pending login links are not affected. Tokens are not | |||
| 30 | + | // affected either: revoke them with TokenService. | |||
| 31 | + | rpc SignOutEverywhere(SignOutEverywhereRequest) returns (SignOutEverywhereResponse); | |||
| 32 | + | } | |||
| 33 | + | ||||
| 34 | + | // CreateLoginLinkRequest is empty. | |||
| 35 | + | message CreateLoginLinkRequest {} | |||
| 36 | + | ||||
| 37 | + | // CreateLoginLinkResponse holds the link. | |||
| 38 | + | message CreateLoginLinkResponse { | |||
| 39 | + | // Url is the absolute link to open in a browser, on the public URL of the | |||
| 40 | + | // server. It holds a secret: clients print it to the terminal and nowhere | |||
| 41 | + | // else, and never log it. | |||
| 42 | + | string url = 1; | |||
| 43 | + | // ExpiresAt is when the link stops working if it is not used. | |||
| 44 | + | google.protobuf.Timestamp expires_at = 2; | |||
| 45 | + | } | |||
| 46 | + | ||||
| 47 | + | // SignOutEverywhereRequest is empty. | |||
| 48 | + | message SignOutEverywhereRequest {} | |||
| 49 | + | ||||
| 50 | + | // SignOutEverywhereResponse is empty. | |||
| 51 | + | message SignOutEverywhereResponse {} | |||
M proto/ermite/types.proto +20 -0
| @@ -35,3 +35,23 @@ message Commit { | |||
| 35 | 35 | // not valid UTF-8 is converted with the replacement character. | |
| 36 | 36 | string message = 6; | |
| 37 | 37 | } | |
| 38 | + | ||
| 39 | + | // MergeMode is how a merge request is merged. Both modes need the target to | |
| 40 | + | // be an ancestor of the head: a branch behind its target is rebased by its | |
| 41 | + | // author and pushed again, the server never rebases nor creates merge commits. | |
| 42 | + | enum MergeMode { | |
| 43 | + | // Not set. In MergeMergeRequestRequest.mode it means fast-forward. Rejected | |
| 44 | + | // in RepoSettings.allowed_merge_modes. Returned on a merge request that was | |
| 45 | + | // not merged. | |
| 46 | + | MERGE_MODE_UNSPECIFIED = 0; | |
| 47 | + | // The target branch moves to the head. No commit is created and the | |
| 48 | + | // signatures of the branch's commits are kept. | |
| 49 | + | MERGE_MODE_FAST_FORWARD = 1; | |
| 50 | + | // One new commit is created with the tree of the head and the target as | |
| 51 | + | // only parent, signed by the server's key (see ServerService.GetSigningKey). | |
| 52 | + | // Its author is the author of the first commit of the branch, the other | |
| 53 | + | // authors are added as "Co-authored-by:" trailers, and its message is the | |
| 54 | + | // title, " (!<number>)", a blank line and the list of the squashed commits' | |
| 55 | + | // summaries. | |
| 56 | + | MERGE_MODE_SQUASH = 2; | |
| 57 | + | } | |
| @@ -35,3 +35,23 @@ message Commit { | |||||
| 35 | // not valid UTF-8 is converted with the replacement character. | 35 | // not valid UTF-8 is converted with the replacement character. | ||
| 36 | string message = 6; | 36 | string message = 6; | ||
| 37 | } | 37 | } | ||
| 38 | + | ||||
| 39 | + | // MergeMode is how a merge request is merged. Both modes need the target to | |||
| 40 | + | // be an ancestor of the head: a branch behind its target is rebased by its | |||
| 41 | + | // author and pushed again, the server never rebases nor creates merge commits. | |||
| 42 | + | enum MergeMode { | |||
| 43 | + | // Not set. In MergeMergeRequestRequest.mode it means fast-forward. Rejected | |||
| 44 | + | // in RepoSettings.allowed_merge_modes. Returned on a merge request that was | |||
| 45 | + | // not merged. | |||
| 46 | + | MERGE_MODE_UNSPECIFIED = 0; | |||
| 47 | + | // The target branch moves to the head. No commit is created and the | |||
| 48 | + | // signatures of the branch's commits are kept. | |||
| 49 | + | MERGE_MODE_FAST_FORWARD = 1; | |||
| 50 | + | // One new commit is created with the tree of the head and the target as | |||
| 51 | + | // only parent, signed by the server's key (see ServerService.GetSigningKey). | |||
| 52 | + | // Its author is the author of the first commit of the branch, the other | |||
| 53 | + | // authors are added as "Co-authored-by:" trailers, and its message is the | |||
| 54 | + | // title, " (!<number>)", a blank line and the list of the squashed commits' | |||
| 55 | + | // summaries. | |||
| 56 | + | MERGE_MODE_SQUASH = 2; | |||
| 57 | + | } | |||