detached 9390908

docs(api): document issue access, errors, the owner topic and the issues setting

commit
939090845b49b704c717b205b10b702abcd9a833
author
brice · · 2026-10-19 08:50 UTC
parent
bfc173e
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
9 files · +108 -39
M README.md +1 -0
@@ -33,6 +33,7 @@ Status: early development.
3333 | `GitService` | refs, trees, blobs, commits and diffs |
3434 | `TokenService` | API tokens |
3535 | `MergeRequestService` | merge requests, comments, merge |
36+| `IssueService` | issues, comments, owner moderation of public submissions |
3637 | `SessionService` | web sign-in links (owner only) |
3738 | `EventService` | live event stream, resumable |
3839 | `ServerService` | version, features, signing key, OIDC key rotation |
@@ -33,6 +33,7 @@ Status: early development.
33 | `GitService` | refs, trees, blobs, commits and diffs |33 | `GitService` | refs, trees, blobs, commits and diffs |
34 | `TokenService` | API tokens |34 | `TokenService` | API tokens |
35 | `MergeRequestService` | merge requests, comments, merge |35 | `MergeRequestService` | merge requests, comments, merge |
36+| `IssueService` | issues, comments, owner moderation of public submissions |
36 | `SessionService` | web sign-in links (owner only) |37 | `SessionService` | web sign-in links (owner only) |
37 | `EventService` | live event stream, resumable |38 | `EventService` | live event stream, resumable |
38 | `ServerService` | version, features, signing key, OIDC key rotation |39 | `ServerService` | version, features, signing key, OIDC key rotation |
M docs/services.md +2 -1
@@ -6,8 +6,9 @@
66 | `GitService` | `ListRefs`, `GetTree`, `ListPaths`, `GetBlob` (streamed), `ListCommits`, `GetCommit` (structured diff), `ResolveRevision` |
77 | `TokenService` | `CreateToken` (secret shown once), `ListTokens`, `RevokeToken` |
88 | `MergeRequestService` | `CreateMergeRequest`, `ListMergeRequests`, `GetMergeRequest` (commits, diff, comments), `AddComment`, `EditComment`, `DeleteComment`, `ResolveComment`, `CloseMergeRequest`, `MergeMergeRequest`, `MarkRead` |
9+| `IssueService` | `CreateIssue`, `ListIssues`, `GetIssue` (comments), `AddIssueComment`, `CloseIssue`, `ReopenIssue`; owner only: `ListPendingIssues`, `ApproveIssue`, `RejectIssue`. Feature `issues`. Issues share numbers with merge requests |
910 | `SessionService` | `CreateLoginLink`, `SignOutEverywhere` (owner only) |
10-| `EventService` | `Watch` (streamed, resumable) |
11+| `EventService` | `Watch` (streamed, resumable). Topics `home`, `repo:<name>` and `owner` (owner rights only). Events 17–21: `issue_opened`, `issue_closed`, `issue_reopened`, `issue_commented`, and `issue_submitted` (only on `owner`, no content) |
1112 | `ServerService` | `GetVersion` (version and features), `GetSigningKey`, `RotateOIDCKey` (owner only) |
1213 | `TrustedKeyService` | `ListTrustedKeys`, `AddTrustedKey` and `RemoveTrustedKey` (owner only). `Commit.verification` carries the result of the check (feature `commit_signatures`) |
1314 | `RunService` | `ListRuns`, `GetRun`, `GetJob`, `GetJobLog` (streamed, follow), `ListAnnotations`, `GetStepSummaries`, `CancelRun`, `RerunRun`, `DispatchWorkflow`, `ListWorkflows`, `DisableWorkflow`, `EnableWorkflow`, `ListChecks`, `ListRunners`, `RemoveRunner` |
@@ -6,8 +6,9 @@
6 | `GitService` | `ListRefs`, `GetTree`, `ListPaths`, `GetBlob` (streamed), `ListCommits`, `GetCommit` (structured diff), `ResolveRevision` |6 | `GitService` | `ListRefs`, `GetTree`, `ListPaths`, `GetBlob` (streamed), `ListCommits`, `GetCommit` (structured diff), `ResolveRevision` |
7 | `TokenService` | `CreateToken` (secret shown once), `ListTokens`, `RevokeToken` |7 | `TokenService` | `CreateToken` (secret shown once), `ListTokens`, `RevokeToken` |
8 | `MergeRequestService` | `CreateMergeRequest`, `ListMergeRequests`, `GetMergeRequest` (commits, diff, comments), `AddComment`, `EditComment`, `DeleteComment`, `ResolveComment`, `CloseMergeRequest`, `MergeMergeRequest`, `MarkRead` |8 | `MergeRequestService` | `CreateMergeRequest`, `ListMergeRequests`, `GetMergeRequest` (commits, diff, comments), `AddComment`, `EditComment`, `DeleteComment`, `ResolveComment`, `CloseMergeRequest`, `MergeMergeRequest`, `MarkRead` |
9+| `IssueService` | `CreateIssue`, `ListIssues`, `GetIssue` (comments), `AddIssueComment`, `CloseIssue`, `ReopenIssue`; owner only: `ListPendingIssues`, `ApproveIssue`, `RejectIssue`. Feature `issues`. Issues share numbers with merge requests |
9 | `SessionService` | `CreateLoginLink`, `SignOutEverywhere` (owner only) |10 | `SessionService` | `CreateLoginLink`, `SignOutEverywhere` (owner only) |
10-| `EventService` | `Watch` (streamed, resumable) |11+| `EventService` | `Watch` (streamed, resumable). Topics `home`, `repo:<name>` and `owner` (owner rights only). Events 17–21: `issue_opened`, `issue_closed`, `issue_reopened`, `issue_commented`, and `issue_submitted` (only on `owner`, no content) |
11 | `ServerService` | `GetVersion` (version and features), `GetSigningKey`, `RotateOIDCKey` (owner only) |12 | `ServerService` | `GetVersion` (version and features), `GetSigningKey`, `RotateOIDCKey` (owner only) |
12 | `TrustedKeyService` | `ListTrustedKeys`, `AddTrustedKey` and `RemoveTrustedKey` (owner only). `Commit.verification` carries the result of the check (feature `commit_signatures`) |13 | `TrustedKeyService` | `ListTrustedKeys`, `AddTrustedKey` and `RemoveTrustedKey` (owner only). `Commit.verification` carries the result of the check (feature `commit_signatures`) |
13 | `RunService` | `ListRuns`, `GetRun`, `GetJob`, `GetJobLog` (streamed, follow), `ListAnnotations`, `GetStepSummaries`, `CancelRun`, `RerunRun`, `DispatchWorkflow`, `ListWorkflows`, `DisableWorkflow`, `EnableWorkflow`, `ListChecks`, `ListRunners`, `RemoveRunner` |14 | `RunService` | `ListRuns`, `GetRun`, `GetJob`, `GetJobLog` (streamed, follow), `ListAnnotations`, `GetStepSummaries`, `CancelRun`, `RerunRun`, `DispatchWorkflow`, `ListWorkflows`, `DisableWorkflow`, `EnableWorkflow`, `ListChecks`, `ListRunners`, `RemoveRunner` |
M gen/ermite/ermiteconnect/event.connect.go +10 -8
@@ -49,10 +49,11 @@ type EventServiceClient interface {
4949 // for merge requests, merge_request_opened, merge_request_merged,
5050 // merge_request_closed, comment_added, comment_edited, comment_deleted and
5151 // comment_resolved (a thread resolved or reopened); for issues, issue_opened,
52- // issue_closed, issue_reopened and issue_commented (and issue_submitted, to
53- // owner watchers only). Each one is delivered on the
54- // "repo:<name>" topic of its repository and on "home", subject to the
55- // visibility of the repository.
52+ // issue_closed, issue_reopened and issue_commented, and issue_submitted. Each
53+ // one is delivered on the "repo:<name>" topic of its repository and on
54+ // "home", subject to the visibility of the repository, except
55+ // issue_submitted: it is delivered only on the "owner" topic, never on
56+ // "home" or "repo:<name>", and carries no content (see IssueSubmitted).
5657 //
5758 // Servers with the feature "ci.runs" also publish run_updated and
5859 // job_updated, only on the "repo:<name>" topic of their repository (never on
@@ -124,10 +125,11 @@ type EventServiceHandler interface {
124125 // for merge requests, merge_request_opened, merge_request_merged,
125126 // merge_request_closed, comment_added, comment_edited, comment_deleted and
126127 // comment_resolved (a thread resolved or reopened); for issues, issue_opened,
127- // issue_closed, issue_reopened and issue_commented (and issue_submitted, to
128- // owner watchers only). Each one is delivered on the
129- // "repo:<name>" topic of its repository and on "home", subject to the
130- // visibility of the repository.
128+ // issue_closed, issue_reopened and issue_commented, and issue_submitted. Each
129+ // one is delivered on the "repo:<name>" topic of its repository and on
130+ // "home", subject to the visibility of the repository, except
131+ // issue_submitted: it is delivered only on the "owner" topic, never on
132+ // "home" or "repo:<name>", and carries no content (see IssueSubmitted).
131133 //
132134 // Servers with the feature "ci.runs" also publish run_updated and
133135 // job_updated, only on the "repo:<name>" topic of their repository (never on
@@ -49,10 +49,11 @@ type EventServiceClient interface {
49 // for merge requests, merge_request_opened, merge_request_merged,49 // for merge requests, merge_request_opened, merge_request_merged,
50 // merge_request_closed, comment_added, comment_edited, comment_deleted and50 // merge_request_closed, comment_added, comment_edited, comment_deleted and
51 // comment_resolved (a thread resolved or reopened); for issues, issue_opened,51 // comment_resolved (a thread resolved or reopened); for issues, issue_opened,
52- // issue_closed, issue_reopened and issue_commented (and issue_submitted, to52+ // issue_closed, issue_reopened and issue_commented, and issue_submitted. Each
53- // owner watchers only). Each one is delivered on the53+ // one is delivered on the "repo:<name>" topic of its repository and on
54- // "repo:<name>" topic of its repository and on "home", subject to the54+ // "home", subject to the visibility of the repository, except
55- // visibility of the repository.55+ // issue_submitted: it is delivered only on the "owner" topic, never on
56+ // "home" or "repo:<name>", and carries no content (see IssueSubmitted).
56 //57 //
57 // Servers with the feature "ci.runs" also publish run_updated and58 // Servers with the feature "ci.runs" also publish run_updated and
58 // job_updated, only on the "repo:<name>" topic of their repository (never on59 // job_updated, only on the "repo:<name>" topic of their repository (never on
@@ -124,10 +125,11 @@ type EventServiceHandler interface {
124 // for merge requests, merge_request_opened, merge_request_merged,125 // for merge requests, merge_request_opened, merge_request_merged,
125 // merge_request_closed, comment_added, comment_edited, comment_deleted and126 // merge_request_closed, comment_added, comment_edited, comment_deleted and
126 // comment_resolved (a thread resolved or reopened); for issues, issue_opened,127 // comment_resolved (a thread resolved or reopened); for issues, issue_opened,
127- // issue_closed, issue_reopened and issue_commented (and issue_submitted, to128+ // issue_closed, issue_reopened and issue_commented, and issue_submitted. Each
128- // owner watchers only). Each one is delivered on the129+ // one is delivered on the "repo:<name>" topic of its repository and on
129- // "repo:<name>" topic of its repository and on "home", subject to the130+ // "home", subject to the visibility of the repository, except
130- // visibility of the repository.131+ // issue_submitted: it is delivered only on the "owner" topic, never on
132+ // "home" or "repo:<name>", and carries no content (see IssueSubmitted).
131 //133 //
132 // Servers with the feature "ci.runs" also publish run_updated and134 // Servers with the feature "ci.runs" also publish run_updated and
133 // job_updated, only on the "repo:<name>" topic of their repository (never on135 // job_updated, only on the "repo:<name>" topic of their repository (never on
M gen/ermite/event.pb.go +15 -7 generated file: collapsed
M gen/ermite/issue.pb.go +8 -4
@@ -95,9 +95,12 @@ type Issue struct {
9595 Body string `protobuf:"bytes,4,opt,name=body,proto3" json:"body,omitempty"`
9696 // State is where the issue is in its life.
9797 State IssueState `protobuf:"varint,5,opt,name=state,proto3,enum=ermite.IssueState" json:"state,omitempty"`
98- // Author names who created the issue: the label of the token that was used,
99- // "root" for the root token, or "owner" for a web session. It is
100- // informational: labels are not unique and the token may be gone.
98+ // Author names who created the issue: the label of the token or session
99+ // that was used ("root" for the root token, "owner" for a web session), or,
100+ // for an issue approved from the public form, the unverified display name
101+ // the visitor typed (or "anonymous"). It is informational and never proves
102+ // identity: labels are not unique, the token may be gone, and a visitor can
103+ // type "owner".
101104 Author string `protobuf:"bytes,6,opt,name=author,proto3" json:"author,omitempty"`
102105 // CreatedAt is when the issue was created.
103106 CreatedAt *timestamppb.Timestamp `protobuf:"bytes,7,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`
@@ -951,7 +954,8 @@ type PendingIssue struct {
951954 // Body is the content. It may be empty.
952955 Body string `protobuf:"bytes,4,opt,name=body,proto3" json:"body,omitempty"`
953956 // Author is the optional display name given by the anonymous submitter. It
954- // may be empty and is not verified.
957+ // may be empty or "anonymous", and is not verified: it never proves
958+ // identity (a visitor can type "owner"). It becomes Issue.author on approval.
955959 Author string `protobuf:"bytes,5,opt,name=author,proto3" json:"author,omitempty"`
956960 // CreatedAt is when the issue was submitted.
957961 CreatedAt *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`
@@ -95,9 +95,12 @@ type Issue struct {
95 Body string `protobuf:"bytes,4,opt,name=body,proto3" json:"body,omitempty"`95 Body string `protobuf:"bytes,4,opt,name=body,proto3" json:"body,omitempty"`
96 // State is where the issue is in its life.96 // State is where the issue is in its life.
97 State IssueState `protobuf:"varint,5,opt,name=state,proto3,enum=ermite.IssueState" json:"state,omitempty"`97 State IssueState `protobuf:"varint,5,opt,name=state,proto3,enum=ermite.IssueState" json:"state,omitempty"`
98- // Author names who created the issue: the label of the token that was used,98+ // Author names who created the issue: the label of the token or session
99- // "root" for the root token, or "owner" for a web session. It is99+ // that was used ("root" for the root token, "owner" for a web session), or,
100- // informational: labels are not unique and the token may be gone.100+ // for an issue approved from the public form, the unverified display name
101+ // the visitor typed (or "anonymous"). It is informational and never proves
102+ // identity: labels are not unique, the token may be gone, and a visitor can
103+ // type "owner".
101 Author string `protobuf:"bytes,6,opt,name=author,proto3" json:"author,omitempty"`104 Author string `protobuf:"bytes,6,opt,name=author,proto3" json:"author,omitempty"`
102 // CreatedAt is when the issue was created.105 // CreatedAt is when the issue was created.
103 CreatedAt *timestamppb.Timestamp `protobuf:"bytes,7,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`106 CreatedAt *timestamppb.Timestamp `protobuf:"bytes,7,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`
@@ -951,7 +954,8 @@ type PendingIssue struct {
951 // Body is the content. It may be empty.954 // Body is the content. It may be empty.
952 Body string `protobuf:"bytes,4,opt,name=body,proto3" json:"body,omitempty"`955 Body string `protobuf:"bytes,4,opt,name=body,proto3" json:"body,omitempty"`
953 // Author is the optional display name given by the anonymous submitter. It956 // Author is the optional display name given by the anonymous submitter. It
954- // may be empty and is not verified.957+ // may be empty or "anonymous", and is not verified: it never proves
958+ // identity (a visitor can type "owner"). It becomes Issue.author on approval.
955 Author string `protobuf:"bytes,5,opt,name=author,proto3" json:"author,omitempty"`959 Author string `protobuf:"bytes,5,opt,name=author,proto3" json:"author,omitempty"`
956 // CreatedAt is when the issue was submitted.960 // CreatedAt is when the issue was submitted.
957 CreatedAt *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`961 CreatedAt *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`
M gen/ermite/repo.pb.go +7 -2 generated file: collapsed
M proto/ermite/event.proto +20 -11
@@ -20,10 +20,11 @@ service EventService {
2020 // for merge requests, merge_request_opened, merge_request_merged,
2121 // merge_request_closed, comment_added, comment_edited, comment_deleted and
2222 // comment_resolved (a thread resolved or reopened); for issues, issue_opened,
23- // issue_closed, issue_reopened and issue_commented (and issue_submitted, to
24- // owner watchers only). Each one is delivered on the
25- // "repo:<name>" topic of its repository and on "home", subject to the
26- // visibility of the repository.
23+ // issue_closed, issue_reopened and issue_commented, and issue_submitted. Each
24+ // one is delivered on the "repo:<name>" topic of its repository and on
25+ // "home", subject to the visibility of the repository, except
26+ // issue_submitted: it is delivered only on the "owner" topic, never on
27+ // "home" or "repo:<name>", and carries no content (see IssueSubmitted).
2728 //
2829 // Servers with the feature "ci.runs" also publish run_updated and
2930 // job_updated, only on the "repo:<name>" topic of their repository (never on
@@ -58,9 +59,17 @@ service EventService {
5859 // WatchRequest selects the events to receive.
5960 message WatchRequest {
6061 // Topics are the subjects to follow: "home" for every repository visible to
61- // the caller, or "repo:<name>" for one repository. Empty means "home".
62- // Unknown topics are invalid_argument. A "repo:<name>" topic for a repository
63- // that does not exist or is not visible is not_found.
62+ // the caller, "repo:<name>" for one repository, or "owner". Empty means
63+ // "home". Unknown topics are invalid_argument. A "repo:<name>" topic for a
64+ // repository that does not exist or is not visible is not_found.
65+ //
66+ // The "owner" topic needs owner rights: root, an owner session, or a token
67+ // that holds every scope with no repository or branch limit. Anyone else
68+ // gets the same invalid_argument as for an unknown topic, so the topic is
69+ // not revealed. It carries the merge request and issue events of every
70+ // repository (merge_request_opened, merge_request_merged,
71+ // merge_request_closed, comment_added, and the issue events), repo_updated
72+ // and repo_deleted, plus issue_submitted, which is delivered nowhere else.
6473 repeated string topics = 1;
6574 // ResumeAfter is the Event.id of the last event the client has seen. Empty
6675 // to receive only new events.
@@ -120,8 +129,8 @@ message Event {
120129 IssueReopened issue_reopened = 19;
121130 // IssueCommented: a comment was added to an issue.
122131 IssueCommented issue_commented = 20;
123- // IssueSubmitted: an issue is awaiting moderation. Delivered to owner
124- // watchers only.
132+ // IssueSubmitted: an issue is awaiting moderation. Delivered only on the
133+ // "owner" topic, never on "home" or "repo:<name>", and carries no content.
125134 IssueSubmitted issue_submitted = 21;
126135 }
127136 }
@@ -251,8 +260,8 @@ message IssueCommented {
251260 IssueComment comment = 3;
252261 }
253262
254-// IssueSubmitted reports an issue awaiting moderation. It is delivered to
255-// owner watchers only. It carries no title or body: content never travels in
263+// IssueSubmitted reports an issue awaiting moderation. It is delivered only
264+// on the "owner" topic, never on "home" or "repo:<name>". It carries no title or body: content never travels in
256265 // events, read it with IssueService.ListPendingIssues.
257266 message IssueSubmitted {
258267 // Repo is the name of the repository.
@@ -20,10 +20,11 @@ service EventService {
20 // for merge requests, merge_request_opened, merge_request_merged,20 // for merge requests, merge_request_opened, merge_request_merged,
21 // merge_request_closed, comment_added, comment_edited, comment_deleted and21 // merge_request_closed, comment_added, comment_edited, comment_deleted and
22 // comment_resolved (a thread resolved or reopened); for issues, issue_opened,22 // comment_resolved (a thread resolved or reopened); for issues, issue_opened,
23- // issue_closed, issue_reopened and issue_commented (and issue_submitted, to23+ // issue_closed, issue_reopened and issue_commented, and issue_submitted. Each
24- // owner watchers only). Each one is delivered on the24+ // one is delivered on the "repo:<name>" topic of its repository and on
25- // "repo:<name>" topic of its repository and on "home", subject to the25+ // "home", subject to the visibility of the repository, except
26- // visibility of the repository.26+ // issue_submitted: it is delivered only on the "owner" topic, never on
27+ // "home" or "repo:<name>", and carries no content (see IssueSubmitted).
27 //28 //
28 // Servers with the feature "ci.runs" also publish run_updated and29 // Servers with the feature "ci.runs" also publish run_updated and
29 // job_updated, only on the "repo:<name>" topic of their repository (never on30 // job_updated, only on the "repo:<name>" topic of their repository (never on
@@ -58,9 +59,17 @@ service EventService {
58 // WatchRequest selects the events to receive.59 // WatchRequest selects the events to receive.
59 message WatchRequest {60 message WatchRequest {
60 // Topics are the subjects to follow: "home" for every repository visible to61 // Topics are the subjects to follow: "home" for every repository visible to
61- // the caller, or "repo:<name>" for one repository. Empty means "home".62+ // the caller, "repo:<name>" for one repository, or "owner". Empty means
62- // Unknown topics are invalid_argument. A "repo:<name>" topic for a repository63+ // "home". Unknown topics are invalid_argument. A "repo:<name>" topic for a
63- // that does not exist or is not visible is not_found.64+ // repository that does not exist or is not visible is not_found.
65+ //
66+ // The "owner" topic needs owner rights: root, an owner session, or a token
67+ // that holds every scope with no repository or branch limit. Anyone else
68+ // gets the same invalid_argument as for an unknown topic, so the topic is
69+ // not revealed. It carries the merge request and issue events of every
70+ // repository (merge_request_opened, merge_request_merged,
71+ // merge_request_closed, comment_added, and the issue events), repo_updated
72+ // and repo_deleted, plus issue_submitted, which is delivered nowhere else.
64 repeated string topics = 1;73 repeated string topics = 1;
65 // ResumeAfter is the Event.id of the last event the client has seen. Empty74 // ResumeAfter is the Event.id of the last event the client has seen. Empty
66 // to receive only new events.75 // to receive only new events.
@@ -120,8 +129,8 @@ message Event {
120 IssueReopened issue_reopened = 19;129 IssueReopened issue_reopened = 19;
121 // IssueCommented: a comment was added to an issue.130 // IssueCommented: a comment was added to an issue.
122 IssueCommented issue_commented = 20;131 IssueCommented issue_commented = 20;
123- // IssueSubmitted: an issue is awaiting moderation. Delivered to owner132+ // IssueSubmitted: an issue is awaiting moderation. Delivered only on the
124- // watchers only.133+ // "owner" topic, never on "home" or "repo:<name>", and carries no content.
125 IssueSubmitted issue_submitted = 21;134 IssueSubmitted issue_submitted = 21;
126 }135 }
127 }136 }
@@ -251,8 +260,8 @@ message IssueCommented {
251 IssueComment comment = 3;260 IssueComment comment = 3;
252 }261 }
253 262
254-// IssueSubmitted reports an issue awaiting moderation. It is delivered to263+// IssueSubmitted reports an issue awaiting moderation. It is delivered only
255-// owner watchers only. It carries no title or body: content never travels in264+// on the "owner" topic, never on "home" or "repo:<name>". It carries no title or body: content never travels in
256 // events, read it with IssueService.ListPendingIssues.265 // events, read it with IssueService.ListPendingIssues.
257 message IssueSubmitted {266 message IssueSubmitted {
258 // Repo is the name of the repository.267 // Repo is the name of the repository.
M proto/ermite/issue.proto +38 -4
@@ -31,9 +31,12 @@ message Issue {
3131 string body = 4;
3232 // State is where the issue is in its life.
3333 IssueState state = 5;
34- // Author names who created the issue: the label of the token that was used,
35- // "root" for the root token, or "owner" for a web session. It is
36- // informational: labels are not unique and the token may be gone.
34+ // Author names who created the issue: the label of the token or session
35+ // that was used ("root" for the root token, "owner" for a web session), or,
36+ // for an issue approved from the public form, the unverified display name
37+ // the visitor typed (or "anonymous"). It is informational and never proves
38+ // identity: labels are not unique, the token may be gone, and a visitor can
39+ // type "owner".
3740 string author = 6;
3841 // CreatedAt is when the issue was created.
3942 google.protobuf.Timestamp created_at = 7;
@@ -56,6 +59,36 @@ message IssueComment {
5659 }
5760
5861 // IssueService manages issues and their comments.
62+//
63+// Servers that implement this service list "issues" in
64+// GetVersionResponse.features. Issues and merge requests of a repository share
65+// one number sequence. When the issues mode of the repository is off, every
66+// call answers not_found, as for a repository that does not exist.
67+//
68+// Reading (ListIssues, GetIssue) needs the same access as reading the
69+// repository: nothing for a public one, the repo:read scope for a private one.
70+// Writing (CreateIssue, AddIssueComment, CloseIssue, ReopenIssue) needs the
71+// owner or a token with the issue:write scope on the repository; branch
72+// prefixes do not restrict it. A caller without credentials gets
73+// unauthenticated, one with an insufficient scope gets permission_denied, and
74+// one that cannot read the repository gets not_found.
75+//
76+// Text fields are normalized to NFC and stripped of control and Unicode
77+// bidirectional characters (line breaks and tabs stay in bodies and comments).
78+// The title is one line of 1 to 120 code points; body and comment text are at
79+// most 10,000 code points and a comment must not be blank. A text that breaks
80+// a rule is rejected with invalid_argument. A comment on an issue that already
81+// holds 1,000 comments gives resource_exhausted. Closing an issue that is not
82+// open, or reopening one that is not closed, gives failed_precondition.
83+//
84+// The ordinary RPCs only return issues in state OPEN or CLOSED, and
85+// ListIssues with state ISSUE_STATE_PENDING is invalid_argument. Submissions
86+// from the public form wait as PendingIssue records, reachable only through
87+// the three moderation RPCs (ListPendingIssues, ApproveIssue, RejectIssue).
88+// These need owner rights (root, an owner session, or a token holding every
89+// scope with no repository or branch limit); anyone else gets not_found, and
90+// so does a malformed pending issue id. A malformed repository name is
91+// invalid_argument whoever asks.
5992 service IssueService {
6093 // CreateIssue opens an issue. Needs the issue:write scope.
6194 rpc CreateIssue(CreateIssueRequest) returns (CreateIssueResponse);
@@ -191,7 +224,8 @@ message PendingIssue {
191224 // Body is the content. It may be empty.
192225 string body = 4;
193226 // Author is the optional display name given by the anonymous submitter. It
194- // may be empty and is not verified.
227+ // may be empty or "anonymous", and is not verified: it never proves
228+ // identity (a visitor can type "owner"). It becomes Issue.author on approval.
195229 string author = 5;
196230 // CreatedAt is when the issue was submitted.
197231 google.protobuf.Timestamp created_at = 6;
@@ -31,9 +31,12 @@ message Issue {
31 string body = 4;31 string body = 4;
32 // State is where the issue is in its life.32 // State is where the issue is in its life.
33 IssueState state = 5;33 IssueState state = 5;
34- // Author names who created the issue: the label of the token that was used,34+ // Author names who created the issue: the label of the token or session
35- // "root" for the root token, or "owner" for a web session. It is35+ // that was used ("root" for the root token, "owner" for a web session), or,
36- // informational: labels are not unique and the token may be gone.36+ // for an issue approved from the public form, the unverified display name
37+ // the visitor typed (or "anonymous"). It is informational and never proves
38+ // identity: labels are not unique, the token may be gone, and a visitor can
39+ // type "owner".
37 string author = 6;40 string author = 6;
38 // CreatedAt is when the issue was created.41 // CreatedAt is when the issue was created.
39 google.protobuf.Timestamp created_at = 7;42 google.protobuf.Timestamp created_at = 7;
@@ -56,6 +59,36 @@ message IssueComment {
56 }59 }
57 60
58 // IssueService manages issues and their comments.61 // IssueService manages issues and their comments.
62+//
63+// Servers that implement this service list "issues" in
64+// GetVersionResponse.features. Issues and merge requests of a repository share
65+// one number sequence. When the issues mode of the repository is off, every
66+// call answers not_found, as for a repository that does not exist.
67+//
68+// Reading (ListIssues, GetIssue) needs the same access as reading the
69+// repository: nothing for a public one, the repo:read scope for a private one.
70+// Writing (CreateIssue, AddIssueComment, CloseIssue, ReopenIssue) needs the
71+// owner or a token with the issue:write scope on the repository; branch
72+// prefixes do not restrict it. A caller without credentials gets
73+// unauthenticated, one with an insufficient scope gets permission_denied, and
74+// one that cannot read the repository gets not_found.
75+//
76+// Text fields are normalized to NFC and stripped of control and Unicode
77+// bidirectional characters (line breaks and tabs stay in bodies and comments).
78+// The title is one line of 1 to 120 code points; body and comment text are at
79+// most 10,000 code points and a comment must not be blank. A text that breaks
80+// a rule is rejected with invalid_argument. A comment on an issue that already
81+// holds 1,000 comments gives resource_exhausted. Closing an issue that is not
82+// open, or reopening one that is not closed, gives failed_precondition.
83+//
84+// The ordinary RPCs only return issues in state OPEN or CLOSED, and
85+// ListIssues with state ISSUE_STATE_PENDING is invalid_argument. Submissions
86+// from the public form wait as PendingIssue records, reachable only through
87+// the three moderation RPCs (ListPendingIssues, ApproveIssue, RejectIssue).
88+// These need owner rights (root, an owner session, or a token holding every
89+// scope with no repository or branch limit); anyone else gets not_found, and
90+// so does a malformed pending issue id. A malformed repository name is
91+// invalid_argument whoever asks.
59 service IssueService {92 service IssueService {
60 // CreateIssue opens an issue. Needs the issue:write scope.93 // CreateIssue opens an issue. Needs the issue:write scope.
61 rpc CreateIssue(CreateIssueRequest) returns (CreateIssueResponse);94 rpc CreateIssue(CreateIssueRequest) returns (CreateIssueResponse);
@@ -191,7 +224,8 @@ message PendingIssue {
191 // Body is the content. It may be empty.224 // Body is the content. It may be empty.
192 string body = 4;225 string body = 4;
193 // Author is the optional display name given by the anonymous submitter. It226 // Author is the optional display name given by the anonymous submitter. It
194- // may be empty and is not verified.227+ // may be empty or "anonymous", and is not verified: it never proves
228+ // identity (a visitor can type "owner"). It becomes Issue.author on approval.
195 string author = 5;229 string author = 5;
196 // CreatedAt is when the issue was submitted.230 // CreatedAt is when the issue was submitted.
197 google.protobuf.Timestamp created_at = 6;231 google.protobuf.Timestamp created_at = 6;
M proto/ermite/repo.proto +7 -2
@@ -168,8 +168,9 @@ message UpdateRepoRequest {
168168 // UpdateMask lists the fields to change: "description", "visibility",
169169 // "default_branch", "topics", "settings.allowed_merge_modes" and/or
170170 // "settings.failing_checks_block". "settings" stands for both merge settings
171- // paths. The optional issues field changes the issue mode separately.
172- // It must not be empty. Other paths are invalid_argument.
171+ // paths. It must not be empty unless issues is set. Other paths are
172+ // invalid_argument, including "settings.issues" and "issues": the issues
173+ // field is applied outside the mask.
173174 google.protobuf.FieldMask update_mask = 5;
174175 // Settings holds the new merge settings. Only the fields named in
175176 // update_mask are used. allowed_merge_modes must then not be empty nor
@@ -181,6 +182,10 @@ message UpdateRepoRequest {
181182 // if update_mask contains "topics"; an empty list then clears them.
182183 repeated string topics = 7;
183184 // Issues is the new issue participation mode. When absent it is unchanged.
185+ // It is applied whatever update_mask contains, and may be the only change
186+ // (an empty update_mask is then valid). When present it must not be
187+ // ISSUES_MODE_UNSPECIFIED: that is invalid_argument. Changing it needs the
188+ // repo:admin scope and a token with no branch limit, like any other field.
184189 optional IssuesMode issues = 8;
185190 }
186191
@@ -168,8 +168,9 @@ message UpdateRepoRequest {
168 // UpdateMask lists the fields to change: "description", "visibility",168 // UpdateMask lists the fields to change: "description", "visibility",
169 // "default_branch", "topics", "settings.allowed_merge_modes" and/or169 // "default_branch", "topics", "settings.allowed_merge_modes" and/or
170 // "settings.failing_checks_block". "settings" stands for both merge settings170 // "settings.failing_checks_block". "settings" stands for both merge settings
171- // paths. The optional issues field changes the issue mode separately.171+ // paths. It must not be empty unless issues is set. Other paths are
172- // It must not be empty. Other paths are invalid_argument.172+ // invalid_argument, including "settings.issues" and "issues": the issues
173+ // field is applied outside the mask.
173 google.protobuf.FieldMask update_mask = 5;174 google.protobuf.FieldMask update_mask = 5;
174 // Settings holds the new merge settings. Only the fields named in175 // Settings holds the new merge settings. Only the fields named in
175 // update_mask are used. allowed_merge_modes must then not be empty nor176 // update_mask are used. allowed_merge_modes must then not be empty nor
@@ -181,6 +182,10 @@ message UpdateRepoRequest {
181 // if update_mask contains "topics"; an empty list then clears them.182 // if update_mask contains "topics"; an empty list then clears them.
182 repeated string topics = 7;183 repeated string topics = 7;
183 // Issues is the new issue participation mode. When absent it is unchanged.184 // Issues is the new issue participation mode. When absent it is unchanged.
185+ // It is applied whatever update_mask contains, and may be the only change
186+ // (an empty update_mask is then valid). When present it must not be
187+ // ISSUES_MODE_UNSPECIFIED: that is invalid_argument. Changing it needs the
188+ // repo:admin scope and a token with no branch limit, like any other field.
184 optional IssuesMode issues = 8;189 optional IssuesMode issues = 8;
185 }190 }
186 191

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 2

Tags 18

↑↓ moveenter openesc close