Skip to content

Commit 268f003

Browse files
authored
fix: BOMS-235 Create script to set up remotes for devstack (#184)
Ticket: https://2u-internal.atlassian.net/browse/BOMS-235
1 parent 4483bcb commit 268f003

4 files changed

Lines changed: 500 additions & 22 deletions

File tree

.github/workflows/cli-tests.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,6 @@ jobs:
7070

7171
- name: CLI tests
7272
run: pytest -s ./tests/*.py
73+
74+
- name: Repo setup-remotes tests
75+
run: ./tests/test_repo.sh

Makefile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,13 +143,18 @@ dev.status: ## Prints the status of all git repositories.
143143
dev.checkout: ## Check out "openedx-release/$OPENEDX_RELEASE" in each repo if set, use default branch otherwise.
144144
./repo.sh checkout
145145

146+
dev.setup-remotes: ## Set up edx and openedx remotes for all forked repositories.
147+
./repo.sh setup-remotes
148+
146149
dev.clone: dev.clone.ssh ## Clone service repos to the parent directory.
147150

148151
dev.clone.https: ## Clone service repos using HTTPS method to the parent directory.
149152
./repo.sh clone
153+
make dev.setup-remotes
150154

151155
dev.clone.ssh: ## Clone service repos using SSH method to the parent directory.
152156
./repo.sh clone_ssh
157+
make dev.setup-remotes
153158

154159
########################################################################################
155160
# Developer interface: Docker image management.

repo.sh

Lines changed: 284 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,14 @@ repos=(
2626
"https://github.com/openedx/cs_comments_service.git"
2727
"https://github.com/edx/ecommerce.git"
2828
"https://github.com/openedx/edx-notes-api.git"
29-
"https://github.com/openedx/edx-platform.git"
29+
"https://github.com/edx/edx-platform.git"
3030
"https://github.com/openedx/xqueue.git"
3131
"https://github.com/edx/edx-analytics-dashboard.git"
32-
"https://github.com/openedx/frontend-app-gradebook.git"
33-
"https://github.com/openedx/frontend-app-learner-dashboard.git"
34-
"https://github.com/openedx/frontend-app-learner-record.git"
32+
"https://github.com/edx/frontend-app-gradebook.git"
33+
"https://github.com/edx/frontend-app-learner-dashboard.git"
34+
"https://github.com/edx/frontend-app-learner-record.git"
3535
"https://github.com/edx/frontend-app-payment.git"
36-
"https://github.com/openedx/frontend-app-publisher.git"
37-
"https://github.com/edx/edx-analytics-dashboard.git"
36+
"https://github.com/edx/frontend-app-publisher.git"
3837
"https://github.com/edx/edx-analytics-data-api.git"
3938
"https://github.com/openedx/enterprise-catalog.git"
4039
"https://github.com/edx/portal-designer.git"
@@ -46,17 +45,29 @@ repos=(
4645
non_release_repos=(
4746
"https://github.com/openedx/frontend-app-authn.git"
4847
"https://github.com/openedx/frontend-app-course-authoring.git"
49-
"https://github.com/openedx/frontend-app-learning.git"
48+
"https://github.com/edx/frontend-app-learning.git"
5049
"https://github.com/edx/registrar.git"
5150
"https://github.com/edx/frontend-app-program-console.git"
5251
"https://github.com/openedx/frontend-app-account.git"
53-
"https://github.com/openedx/frontend-app-profile.git"
54-
"https://github.com/openedx/frontend-app-ora-grading.git"
52+
"https://github.com/edx/frontend-app-profile.git"
53+
"https://github.com/edx/frontend-app-ora-grading.git"
5554
"https://github.com/openedx/enterprise-subsidy.git"
56-
"https://github.com/openedx/frontend-app-admin-portal.git"
57-
"https://github.com/openedx/frontend-app-learner-portal-enterprise.git"
55+
"https://github.com/edx/frontend-app-admin-portal.git"
56+
"https://github.com/edx/frontend-app-learner-portal-enterprise.git"
5857
"https://github.com/edx/frontend-app-enterprise-checkout.git"
5958
"https://github.com/edx/edx-exams.git"
59+
"https://github.com/edx/frontend-app-skills.git"
60+
"https://github.com/edx/frontend-app-ora.git"
61+
"https://github.com/edx/frontend-app-exams-dashboard.git"
62+
"https://github.com/edx/frontend-app-learner-portal-programs.git"
63+
"https://github.com/edx/frontend-app-communications.git"
64+
"https://github.com/edx/frontend-app-discussions.git"
65+
"https://github.com/edx/frontend-app-enterprise-public-catalog.git"
66+
"https://github.com/edx/frontend-app-support-tools.git"
67+
"https://github.com/edx/frontend-app-authoring.git"
68+
"https://github.com/edx/frontend-app-instruct.git"
69+
"https://github.com/edx/frontend-app-catalog.git"
70+
"https://github.com/edx/openedx-translations.git"
6071
)
6172

6273
ssh_repos=(
@@ -66,15 +77,14 @@ ssh_repos=(
6677
"git@github.com:edx/ecommerce.git"
6778
"git@github.com:openedx/edx-notes-api.git"
6879
"git@github.com:openedx/enterprise-catalog.git"
69-
"git@github.com:openedx/edx-platform.git"
80+
"git@github.com:edx/edx-platform.git"
7081
"git@github.com:openedx/xqueue.git"
7182
"git@github.com:edx/edx-analytics-dashboard.git"
72-
"git@github.com:openedx/frontend-app-gradebook.git"
73-
"git@github.com:openedx/frontend-app-learner-dashboard.git"
74-
"git@github.com:openedx/frontend-app-learner-record.git"
83+
"git@github.com:edx/frontend-app-gradebook.git"
84+
"git@github.com:edx/frontend-app-learner-dashboard.git"
85+
"git@github.com:edx/frontend-app-learner-record.git"
7586
"git@github.com:edx/frontend-app-payment.git"
76-
"git@github.com:openedx/frontend-app-publisher.git"
77-
"git@github.com:edx/edx-analytics-dashboard.git"
87+
"git@github.com:edx/frontend-app-publisher.git"
7888
"git@github.com:edx/edx-analytics-data-api.git"
7989
"git@github.com:edx/portal-designer.git"
8090
"git@github.com:openedx/license-manager.git"
@@ -85,17 +95,29 @@ ssh_repos=(
8595
non_release_ssh_repos=(
8696
"git@github.com:openedx/frontend-app-authn.git"
8797
"git@github.com:openedx/frontend-app-course-authoring.git"
88-
"git@github.com:openedx/frontend-app-learning.git"
98+
"git@github.com:edx/frontend-app-learning.git"
8999
"git@github.com:edx/registrar.git"
90100
"git@github.com:edx/frontend-app-program-console.git"
91101
"git@github.com:openedx/frontend-app-account.git"
92-
"git@github.com:openedx/frontend-app-profile.git"
93-
"git@github.com:openedx/frontend-app-ora-grading.git"
102+
"git@github.com:edx/frontend-app-profile.git"
103+
"git@github.com:edx/frontend-app-ora-grading.git"
94104
"git@github.com:openedx/enterprise-subsidy.git"
95-
"git@github.com:openedx/frontend-app-admin-portal.git"
96-
"git@github.com:openedx/frontend-app-learner-portal-enterprise.git"
105+
"git@github.com:edx/frontend-app-admin-portal.git"
106+
"git@github.com:edx/frontend-app-learner-portal-enterprise.git"
97107
"git@github.com:edx/frontend-app-enterprise-checkout.git"
98108
"git@github.com:edx/edx-exams.git"
109+
"git@github.com:edx/frontend-app-skills.git"
110+
"git@github.com:edx/frontend-app-ora.git"
111+
"git@github.com:edx/frontend-app-exams-dashboard.git"
112+
"git@github.com:edx/frontend-app-learner-portal-programs.git"
113+
"git@github.com:edx/frontend-app-communications.git"
114+
"git@github.com:edx/frontend-app-discussions.git"
115+
"git@github.com:edx/frontend-app-enterprise-public-catalog.git"
116+
"git@github.com:edx/frontend-app-support-tools.git"
117+
"git@github.com:edx/frontend-app-authoring.git"
118+
"git@github.com:edx/frontend-app-instruct.git"
119+
"git@github.com:edx/frontend-app-catalog.git"
120+
"git@github.com:edx/openedx-translations.git"
99121
)
100122

101123
if [ -n "${OPENEDX_RELEASE}" ]; then
@@ -287,6 +309,244 @@ status ()
287309
cd - &> /dev/null
288310
}
289311

312+
# Define repositories that exist in both edx and openedx organizations
313+
# These are the ones that need remote setup for forked repositories
314+
FORKED_REPOS=(
315+
"course-discovery"
316+
"credentials"
317+
"cs_comments_service"
318+
"ecommerce"
319+
"edx-notes-api"
320+
"edx-platform"
321+
"xqueue"
322+
"edx-analytics-dashboard"
323+
"frontend-app-gradebook"
324+
"frontend-app-learner-dashboard"
325+
"frontend-app-learner-record"
326+
"frontend-app-skills"
327+
"frontend-app-learning"
328+
"frontend-app-ora"
329+
"frontend-app-ora-grading"
330+
"frontend-app-exams-dashboard"
331+
"frontend-app-learner-portal-programs"
332+
"frontend-app-program-console"
333+
"frontend-app-communications"
334+
"frontend-app-discussions"
335+
"frontend-app-profile"
336+
"frontend-app-enterprise-public-catalog"
337+
"frontend-app-publisher"
338+
"frontend-app-support-tools"
339+
"frontend-app-admin-portal"
340+
"frontend-app-learner-portal-enterprise"
341+
"frontend-app-enterprise-checkout"
342+
"frontend-app-authoring"
343+
"frontend-app-instruct"
344+
"frontend-app-catalog"
345+
"openedx-translations"
346+
"frontend-app-payment"
347+
"edx-analytics-data-api"
348+
"enterprise-catalog"
349+
"portal-designer"
350+
"license-manager"
351+
"codejail-service"
352+
"enterprise-access"
353+
"frontend-app-authn"
354+
"frontend-app-course-authoring"
355+
"registrar"
356+
"frontend-app-account"
357+
"enterprise-subsidy"
358+
"edx-exams"
359+
)
360+
361+
setup_forked_repo_remotes ()
362+
{
363+
local repo_name=$1
364+
local edx_remote_exists
365+
local openedx_remote_exists
366+
local origin_exists
367+
local existing_url=""
368+
local existing_org=""
369+
local other_org
370+
local other_remote_exists
371+
local other_url
372+
373+
# Check if we're in a git repository
374+
if [ ! -d ".git" ]; then
375+
echo "ERROR: $repo_name is not a git repository"
376+
return 1
377+
fi
378+
379+
# Check if both remotes already exist (idempotency check)
380+
edx_remote_exists=$(git remote | grep "^edx$" || true)
381+
openedx_remote_exists=$(git remote | grep "^openedx$" || true)
382+
origin_exists=$(git remote | grep "^origin$" || true)
383+
384+
if [ -n "$edx_remote_exists" ] && [ -n "$openedx_remote_exists" ] && [ -z "$origin_exists" ]; then
385+
echo "Both edx and openedx remotes already exist in $repo_name. No changes needed."
386+
return 0
387+
fi
388+
389+
echo "Setting up remotes for forked repository: $repo_name"
390+
391+
# First, try to find an existing remote and its URL
392+
if [ -n "$origin_exists" ]; then
393+
# We have an 'origin' remote - determine its organization
394+
existing_url=$(git remote get-url origin 2>/dev/null || true)
395+
396+
if [[ $existing_url =~ github\.com[:/]edx/ ]]; then
397+
existing_org="edx"
398+
elif [[ $existing_url =~ github\.com[:/]openedx/ ]]; then
399+
existing_org="openedx"
400+
else
401+
echo "ERROR: Unexpected origin URL in $repo_name: $existing_url"
402+
echo "Expected URL to be from either edx or openedx organization"
403+
return 1
404+
fi
405+
406+
# Rename origin to the correct organization name if not already done
407+
if ! git remote | grep -q "^${existing_org}$"; then
408+
echo "Renaming origin to '$existing_org' in $repo_name"
409+
if ! git remote rename origin "$existing_org"; then
410+
echo "ERROR: Failed to rename origin to $existing_org in $repo_name"
411+
return 1
412+
fi
413+
else
414+
echo "Remote '$existing_org' already exists, removing origin"
415+
git remote remove origin 2>/dev/null || true
416+
fi
417+
elif [ -n "$edx_remote_exists" ]; then
418+
# No origin, but we have an 'edx' remote - use it as reference
419+
existing_url=$(git remote get-url edx)
420+
existing_org="edx"
421+
elif [ -n "$openedx_remote_exists" ]; then
422+
# No origin or edx, but we have an 'openedx' remote - use it as reference
423+
existing_url=$(git remote get-url openedx)
424+
existing_org="openedx"
425+
else
426+
echo "ERROR: No remotes found in $repo_name"
427+
return 1
428+
fi
429+
430+
# Determine the other organization and add its remote if missing
431+
if [ "$existing_org" = "edx" ]; then
432+
other_org="openedx"
433+
else
434+
other_org="edx"
435+
fi
436+
437+
# Check if the other remote exists
438+
other_remote_exists=$(git remote | grep "^${other_org}$" || true)
439+
440+
if [ -z "$other_remote_exists" ]; then
441+
# Construct the URL for the other organization
442+
if [[ $existing_url =~ ^git@ ]]; then
443+
# SSH URL format
444+
other_url="git@github.com:${other_org}/${repo_name}.git"
445+
else
446+
# HTTPS URL format
447+
other_url="https://github.com/${other_org}/${repo_name}.git"
448+
fi
449+
450+
echo "Adding $other_org remote: $other_url"
451+
if ! git remote add "$other_org" "$other_url"; then
452+
echo "ERROR: Failed to add $other_org remote in $repo_name"
453+
return 1
454+
fi
455+
else
456+
echo "Remote '$other_org' already exists in $repo_name"
457+
fi
458+
459+
echo "Successfully configured remotes for $repo_name"
460+
return 0
461+
}
462+
463+
setup_all_forked_repo_remotes ()
464+
{
465+
local successful_repos=()
466+
local failed_repos=()
467+
local skipped_repos=()
468+
local repo
469+
local name
470+
local is_forked
471+
local forked_repo
472+
473+
echo "Setting up remotes for all forked repositories..."
474+
echo "========================================"
475+
476+
for repo in "${repos[@]}" "${non_release_repos[@]}"
477+
do
478+
# Extract repo name from URL
479+
if [[ ! $repo =~ $name_pattern ]]; then
480+
echo "Cannot setup remotes for repo; URL did not match expected pattern: $repo"
481+
continue
482+
fi
483+
name="${BASH_REMATCH[1]}"
484+
485+
# Check if directory exists
486+
if [ ! -d "$name" ]; then
487+
echo "Repository $name is not cloned. Skipping."
488+
skipped_repos+=("$name")
489+
continue
490+
fi
491+
492+
# Check if this repo is configured as a forked repo
493+
is_forked=false
494+
for forked_repo in "${FORKED_REPOS[@]}"; do
495+
if [[ "$forked_repo" == "$name" ]]; then
496+
is_forked=true
497+
break
498+
fi
499+
done
500+
501+
if [[ "$is_forked" == false ]]; then
502+
echo "Repository $name is not configured as a forked repo. Skipping."
503+
skipped_repos+=("$name")
504+
continue
505+
fi
506+
507+
# Change to repo directory and setup remotes
508+
cd "$name"
509+
if setup_forked_repo_remotes "$name"; then
510+
successful_repos+=("$name")
511+
else
512+
failed_repos+=("$name")
513+
fi
514+
cd "$DEVSTACK_WORKSPACE"
515+
echo ""
516+
done
517+
518+
# Print summary report
519+
echo "========================================"
520+
echo "Remote Setup Summary:"
521+
echo "========================================"
522+
523+
if [ ${#successful_repos[@]} -gt 0 ]; then
524+
echo "✓ Successfully configured remotes for ${#successful_repos[@]} repositories:"
525+
printf " - %s\n" "${successful_repos[@]}"
526+
echo ""
527+
fi
528+
529+
if [ ${#failed_repos[@]} -gt 0 ]; then
530+
echo "✗ Failed to configure remotes for ${#failed_repos[@]} repositories:"
531+
printf " - %s\n" "${failed_repos[@]}"
532+
echo ""
533+
fi
534+
535+
if [ ${#skipped_repos[@]} -gt 0 ]; then
536+
echo "◦ Skipped ${#skipped_repos[@]} repositories (not cloned or not forked):"
537+
printf " - %s\n" "${skipped_repos[@]}"
538+
echo ""
539+
fi
540+
541+
echo "Total repositories processed: $((${#successful_repos[@]} + ${#failed_repos[@]} + ${#skipped_repos[@]}))"
542+
543+
if [ ${#failed_repos[@]} -gt 0 ]; then
544+
return 1
545+
else
546+
return 0
547+
fi
548+
}
549+
290550
if [ "$1" == "checkout" ]; then
291551
checkout
292552
elif [ "$1" == "clone" ]; then
@@ -297,4 +557,6 @@ elif [ "$1" == "reset" ]; then
297557
reset
298558
elif [ "$1" == "status" ]; then
299559
status
560+
elif [ "$1" == "setup-remotes" ]; then
561+
setup_all_forked_repo_remotes
300562
fi

0 commit comments

Comments
 (0)