tenseleyflow/shithub / c79d6a0

Browse files

docs/api: document README + topics + merge-upstream surface

Authored by mfwolffe <wolffemf@dukes.jmu.edu>
SHA
c79d6a0ae11d4564e83c7e6601fa759b87ae75f9
Parents
c8f60aa
Tree
21f7fd8

2 changed files

StatusFile+-
M docs/public/SUMMARY.md 1 0
A docs/public/api/repos-followups.md 134 0
docs/public/SUMMARY.mdmodified
@@ -27,6 +27,7 @@
2727
 - [Users](./api/users.md)
2828
 - [Organizations](./api/orgs.md)
2929
 - [Repositories](./api/repos.md)
30
+- [Repository follow-ups (README/topics/merge-upstream)](./api/repos-followups.md)
3031
 - [Branches and tags](./api/branches.md)
3132
 - [Repo collaborators](./api/collaborators.md)
3233
 - [Commits](./api/commits.md)
docs/public/api/repos-followups.mdadded
@@ -0,0 +1,134 @@
1
+# Repository follow-ups — README + topics + merge-upstream
2
+
3
+Three additive endpoints that round out the §2 repos surface. The
4
+core repos CRUD (list/single/create/patch/delete) lives in
5
+[Repositories](./repos.md); this page covers the three that arrived
6
+later: rendering-free README fetch, topic replacement, and fork
7
+sync.
8
+
9
+Scopes:
10
+
11
+- `repo:read` on README.
12
+- `repo:write` on topics replace/clear and merge-upstream.
13
+
14
+## Endpoints
15
+
16
+```
17
+GET    /api/v1/repos/{o}/{r}/readme[?ref=]
18
+PUT    /api/v1/repos/{o}/{r}/topics
19
+DELETE /api/v1/repos/{o}/{r}/topics
20
+POST   /api/v1/repos/{o}/{r}/merge-upstream
21
+```
22
+
23
+## README
24
+
25
+`GET /api/v1/repos/{o}/{r}/readme` returns the repo's README at
26
+`ref` (default branch when omitted). The handler walks the root
27
+tree, picks the first entry whose name starts with `readme`
28
+(case-insensitive), and prefers `.md` / `.markdown` over plain
29
+text so a repo with both `README.md` and `README.rst` returns the
30
+markdown variant — matching the HTML code-view's choice.
31
+
32
+Response shape:
33
+
34
+```json
35
+{
36
+  "name":         "README.md",
37
+  "path":         "README.md",
38
+  "size":         312,
39
+  "encoding":     "base64",
40
+  "content":      "IyBEZW1vIHJlcG8K...",
41
+  "download_url": "http://shithub.local/alice/demo/raw/trunk/README.md"
42
+}
43
+```
44
+
45
+`content` is base64-encoded so binary or UTF-16 READMEs round-trip
46
+cleanly. `size` matches the decoded byte count. The handler caps
47
+reads at 1 MiB (matching the HTML render cap); larger READMEs are
48
+truncated to that cap but the response still succeeds. Use
49
+`download_url` to stream the full blob when the cap matters.
50
+
51
+Errors:
52
+
53
+| Status | Cause                                                    |
54
+|------:|-----------------------------------------------------------|
55
+| 404   | Repo missing, caller lacks read, ref absent, or no README |
56
+
57
+The 404 is existence-leak-safe: a private repo the caller can't
58
+read returns the same 404 as a public repo with no README.
59
+
60
+## Topics
61
+
62
+`PUT /api/v1/repos/{o}/{r}/topics` replaces the full topic set
63
+atomically. Body:
64
+
65
+```json
66
+{ "names": ["go", "rest-api", "shithub"] }
67
+```
68
+
69
+Response (200):
70
+
71
+```json
72
+{ "names": ["go", "rest-api", "shithub"] }
73
+```
74
+
75
+Topics are normalized server-side (lowercased, deduped) and
76
+validated:
77
+
78
+- Max 20 per repo.
79
+- Each name 1–50 chars, lowercase letters / digits / hyphens
80
+  only.
81
+
82
+Invalid input returns `422` with a JSON error describing the
83
+violated constraint.
84
+
85
+`DELETE /api/v1/repos/{o}/{r}/topics` clears all topics. Returns
86
+`204 No Content`. Idempotent — clearing an empty set still
87
+returns 204.
88
+
89
+## Merge-upstream (fork sync)
90
+
91
+`POST /api/v1/repos/{o}/{r}/merge-upstream` fast-forwards a fork's
92
+default branch to its upstream. Mirrors GitHub's "Sync fork"
93
+button.
94
+
95
+The handler refuses non-forks with `422`. For a real fork it
96
+calls the shared `fork.Sync` orchestrator, which only proceeds
97
+when the merge is a clean fast-forward — divergent forks return
98
+`409` and must be reconciled by the user via their git client.
99
+
100
+Successful response:
101
+
102
+```json
103
+{
104
+  "merged":      true,
105
+  "old_oid":     "a1b2...",
106
+  "new_oid":     "c3d4...",
107
+  "base_branch": "trunk",
108
+  "message":     "fast-forwarded to upstream"
109
+}
110
+```
111
+
112
+Already-up-to-date (200, not an error):
113
+
114
+```json
115
+{
116
+  "merged":  false,
117
+  "message": "already up to date"
118
+}
119
+```
120
+
121
+Errors:
122
+
123
+| Status | Cause                                                    |
124
+|------:|-----------------------------------------------------------|
125
+| 409   | Fork has diverged from upstream — sync via your client.  |
126
+| 409   | Ref changed concurrently — retry.                        |
127
+| 409   | Fork still being initialized — retry shortly.            |
128
+| 422   | Repo is not a fork.                                      |
129
+| 422   | Source or fork default branch is empty.                  |
130
+
131
+The endpoint is intentionally narrower than GitHub's: we only
132
+fast-forward. A "fork sync with merge commit" mode would require
133
+the runner to pick an author identity and resolve conflicts, both
134
+of which we'd rather the caller do locally.