You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(vcs): discover private repositories of personal accounts (#42)
git-sync listed a GitHub personal account through GET /users/{owner}/repos,
which returns public repositories only whatever token is presented, so private
repositories were silently missing from every run with no error to point at.
When the token belongs to the configured owner, list through
GET /user/repos?visibility=all&affiliation=owner instead, which reports them.
Mirroring another account still sees its public repositories only, since no
credential can see further.
A GitLab source in a user namespace failed outright at the discover stage,
because only GET /groups/{owner}/projects was tried and it 404s for a personal
namespace. A 404 on the first page now falls back to
GET /users/{owner}/projects.
A mirror whose discovery succeeds but reports nothing now warns and names the
likely cause, since an empty run was otherwise indistinguishable from a mirror
that is up to date.
Co-authored-by: Anmol Nagpal <ianmolnagpal@gmail.com>
Copy file name to clipboardExpand all lines: CHANGELOG.md
+7Lines changed: 7 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
8
8
## [Unreleased]
9
9
10
+
### Fixed
11
+
-`git-sync` discovered only the public repositories of a GitHub personal account. The listing fell back to `GET /users/{owner}/repos` when the owner was not an organisation, and that endpoint returns public repositories only, whatever token is presented, so private repositories were silently missing from every run with no error to point at. When the token belongs to the configured owner, SyncerD now lists through `GET /user/repos?visibility=all&affiliation=owner`, which reports private repositories. Mirroring another account still sees its public repositories only, since no credential can see further
12
+
-`git-sync` failed outright at the `discover` stage when a GitLab source was a user namespace rather than a group: only `GET /groups/{owner}/projects` was tried, and it 404s for a personal namespace. A 404 on the first page now falls back to `GET /users/{owner}/projects`, which lists private projects the token can see
13
+
14
+
### Changed
15
+
- A `git-sync` mirror whose source discovery succeeds but reports no repositories at all now logs a warning naming the likely cause (a token that cannot read the source's private repositories), because an empty run was otherwise indistinguishable from a mirror that is up to date
Copy file name to clipboardExpand all lines: docs/git-sync-runbook.md
+12-1Lines changed: 12 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -210,7 +210,7 @@ query and the one-file-per-command note.
210
210
211
211
| Provider | Token | Scopes |
212
212
|---|---|---|
213
-
| GitHub | fine-grained PAT | Metadata read, Contents read, Administration write (only if `create_missing`) |
213
+
| GitHub | fine-grained PAT | Metadata read, Contents read, Administration write (only if `create_missing`); a fine grained token must also grant access to each private repository you expect to be mirrored, or discovery reports fewer repositories than the source holds|
214
214
| GitLab | group access token |`api` to create projects, plus `write_repository`|
215
215
216
216
Environment variable names derive from the **provider name** in your config,
@@ -576,6 +576,17 @@ config that looks valid can still fail at the credential or network step:
576
576
Bitbucket also has no archived concept, so `skip_archived` has no effect
577
577
for a Bitbucket source.
578
578
579
+
**A personal account source needs a token belonging to that account.**
580
+
GitHub's `GET /users/{owner}/repos` returns public repositories only, whatever
581
+
token is presented, so SyncerD lists a personal account through
582
+
`GET /user/repos`instead, which reports private repositories too. That
583
+
endpoint only ever describes the account the token belongs to. Mirroring
584
+
someone else's personal account therefore discovers its public repositories
585
+
and nothing more, because no credential can see further. Organisation owners
586
+
are unaffected: `GET /orgs/{org}/repos`reports private repositories to any
587
+
token with access. The same shape applies to GitLab, where a user namespace
588
+
falls back to `GET /users/{owner}/projects`.
589
+
579
590
**Released binaries need git on PATH.** goreleaser ships a bare binary with
580
591
no bundled git; install git 2.30 or newer on any host that runs a release
// Discovery that succeeds but reports nothing is the shape a
218
+
// under scoped token takes: the API answers, and answers with the
219
+
// public half of an account, or with nothing at all. Say so, since
220
+
// an empty run is otherwise indistinguishable from a mirror that
221
+
// is genuinely up to date.
222
+
iflen(repos) ==0 {
223
+
logging.Warn(fmt.Sprintf("mirror %s: source provider reported no repositories at all; if the source holds private repositories, check that the token can read them (a GitHub token needs the repo scope, or repository access on a fine grained token; a GitLab token needs read_api)", m.Name),
0 commit comments