Skip to content

Commit cbf8809

Browse files
committed
add support for private source repositories
- checks if a source repository is private and authenticates if necessary - private forks are skipped as we cannot access them - see #189 for the github equivalent implementation
1 parent b0e78ae commit cbf8809

File tree

1 file changed

+36
-4
lines changed

1 file changed

+36
-4
lines changed

src/hubcast/web/gitlab/routes.py

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,14 +63,21 @@ async def sync_branch(event, gl_src, gl_dest, dest_user, *args, **kwargs):
6363

6464
src_repo_url = event.data["repository"]["git_http_url"]
6565
src_fullname = event.data["project"]["path_with_namespace"]
66+
private_src_repo = event.data["project"]["visibility_level"] != 20
6667
repo_id = event.data["project_id"]
6768
# after represents the new HEAD of the ref
6869
want_sha = event.data["after"]
6970
target_ref = event.data["ref"]
7071

72+
src_creds = {}
73+
if private_src_repo:
74+
src_creds = {
75+
"username": gl_src.requester,
76+
"password": await gl_src.auth.authenticate_installation(gl_src.requester),
77+
}
78+
7179
# skip branches from push events that are also merge requests
72-
# TODO this needs the src creds if necessary
73-
src_refs = await ls_remote(src_repo_url)
80+
src_refs = await ls_remote(src_repo_url, **src_creds)
7481
pull_refs = [
7582
src_refs[ref] for ref in src_refs if ref.startswith("refs/merge-requests/")
7683
]
@@ -101,7 +108,7 @@ async def sync_branch(event, gl_src, gl_dest, dest_user, *args, **kwargs):
101108
log.info(f"[{src_fullname}]: {target_ref} already up-to-date")
102109
return
103110

104-
packfile = await fetch_pack(src_repo_url, want_sha, have_shas)
111+
packfile = await fetch_pack(src_repo_url, want_sha, have_shas, **src_creds)
105112

106113
log.info(f"[{src_fullname}]: mirroring {from_sha} -> {want_sha}")
107114
await send_pack(
@@ -159,6 +166,17 @@ async def sync_mr(event, gl_src, gl_dest, dest_user, *args, **kwawrgs):
159166
src_repo_url = event.data["object_attributes"]["source"]["git_http_url"]
160167
src_fullname = event.data["object_attributes"]["source"]["path_with_namespace"]
161168
want_sha = event.data["object_attributes"]["last_commit"]["id"]
169+
# https://docs.gitlab.com/development/permissions/predefined_roles/#general-permissions
170+
private_src_repo = (
171+
event.data["object_attributes"]["source"]["visibility_level"] != 20
172+
)
173+
174+
src_creds = {}
175+
if private_src_repo:
176+
src_creds = {
177+
"username": gl_src.requester,
178+
"password": await gl_src.auth.authenticate_installation(gl_src.requester),
179+
}
162180

163181
# merge requests coming from forks are pushed as branches in the form of
164182
# mr-<mr-number> instead of as their branch name as conflicts could occur
@@ -172,6 +190,20 @@ async def sync_mr(event, gl_src, gl_dest, dest_user, *args, **kwawrgs):
172190
else:
173191
target_ref = f"refs/heads/{event.data['object_attributes']['source_branch']}"
174192

193+
if is_from_fork and private_src_repo:
194+
# we can't access private forks
195+
log.warning(
196+
"cannot sync merge request from private fork",
197+
extra={
198+
"target_fullname": event.data["object_attributes"]["target"][
199+
"path_with_namespace"
200+
],
201+
"mr_id": merge_request_id,
202+
"fork_fullname": src_fullname,
203+
},
204+
)
205+
return
206+
175207
repo_config = await get_repo_config(gl_src, src_fullname, refresh=True)
176208

177209
dest_fullname = f"{repo_config.dest_org}/{repo_config.dest_name}"
@@ -189,7 +221,7 @@ async def sync_mr(event, gl_src, gl_dest, dest_user, *args, **kwawrgs):
189221
log.info(f"[{src_fullname}]: {target_ref} already up-to-date")
190222
return
191223

192-
packfile = await fetch_pack(src_repo_url, want_sha, have_shas)
224+
packfile = await fetch_pack(src_repo_url, want_sha, have_shas, **src_creds)
193225

194226
log.info(f"[{src_fullname}]: mirroring {from_sha} -> {want_sha}")
195227
await send_pack(

0 commit comments

Comments
 (0)