@@ -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=(
4645non_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
6273ssh_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=(
8595non_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
101123if [ -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+
290550if [ " $1 " == " checkout" ]; then
291551 checkout
292552elif [ " $1 " == " clone" ]; then
@@ -297,4 +557,6 @@ elif [ "$1" == "reset" ]; then
297557 reset
298558elif [ " $1 " == " status" ]; then
299559 status
560+ elif [ " $1 " == " setup-remotes" ]; then
561+ setup_all_forked_repo_remotes
300562fi
0 commit comments