Skip to content
Merged
3 changes: 3 additions & 0 deletions .github/workflows/cli-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,6 @@ jobs:

- name: CLI tests
run: pytest -s ./tests/*.py

- name: Repo setup-remotes tests
run: ./tests/test_repo.sh
5 changes: 5 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -143,13 +143,18 @@ dev.status: ## Prints the status of all git repositories.
dev.checkout: ## Check out "openedx-release/$OPENEDX_RELEASE" in each repo if set, use default branch otherwise.
./repo.sh checkout

dev.setup-remotes: ## Set up edx and openedx remotes for all forked repositories.
./repo.sh setup-remotes

dev.clone: dev.clone.ssh ## Clone service repos to the parent directory.

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

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

########################################################################################
# Developer interface: Docker image management.
Expand Down
306 changes: 284 additions & 22 deletions repo.sh
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,14 @@ repos=(
"https://github.com/openedx/cs_comments_service.git"
"https://github.com/edx/ecommerce.git"
"https://github.com/openedx/edx-notes-api.git"
"https://github.com/openedx/edx-platform.git"
"https://github.com/edx/edx-platform.git"
"https://github.com/openedx/xqueue.git"
"https://github.com/edx/edx-analytics-dashboard.git"
"https://github.com/openedx/frontend-app-gradebook.git"
"https://github.com/openedx/frontend-app-learner-dashboard.git"
"https://github.com/openedx/frontend-app-learner-record.git"
"https://github.com/edx/frontend-app-gradebook.git"
"https://github.com/edx/frontend-app-learner-dashboard.git"
"https://github.com/edx/frontend-app-learner-record.git"
"https://github.com/edx/frontend-app-payment.git"
"https://github.com/openedx/frontend-app-publisher.git"
"https://github.com/edx/edx-analytics-dashboard.git"
"https://github.com/edx/frontend-app-publisher.git"
"https://github.com/edx/edx-analytics-data-api.git"
"https://github.com/openedx/enterprise-catalog.git"
"https://github.com/edx/portal-designer.git"
Expand All @@ -46,17 +45,29 @@ repos=(
non_release_repos=(
"https://github.com/openedx/frontend-app-authn.git"
"https://github.com/openedx/frontend-app-course-authoring.git"
"https://github.com/openedx/frontend-app-learning.git"
"https://github.com/edx/frontend-app-learning.git"
"https://github.com/edx/registrar.git"
"https://github.com/edx/frontend-app-program-console.git"
"https://github.com/openedx/frontend-app-account.git"
"https://github.com/openedx/frontend-app-profile.git"
"https://github.com/openedx/frontend-app-ora-grading.git"
"https://github.com/edx/frontend-app-profile.git"
"https://github.com/edx/frontend-app-ora-grading.git"
"https://github.com/openedx/enterprise-subsidy.git"
"https://github.com/openedx/frontend-app-admin-portal.git"
"https://github.com/openedx/frontend-app-learner-portal-enterprise.git"
"https://github.com/edx/frontend-app-admin-portal.git"
"https://github.com/edx/frontend-app-learner-portal-enterprise.git"
"https://github.com/edx/frontend-app-enterprise-checkout.git"
"https://github.com/edx/edx-exams.git"
"https://github.com/edx/frontend-app-skills.git"
"https://github.com/edx/frontend-app-ora.git"
"https://github.com/edx/frontend-app-exams-dashboard.git"
"https://github.com/edx/frontend-app-learner-portal-programs.git"
"https://github.com/edx/frontend-app-communications.git"
"https://github.com/edx/frontend-app-discussions.git"
"https://github.com/edx/frontend-app-enterprise-public-catalog.git"
"https://github.com/edx/frontend-app-support-tools.git"
"https://github.com/edx/frontend-app-authoring.git"
"https://github.com/edx/frontend-app-instruct.git"
"https://github.com/edx/frontend-app-catalog.git"
"https://github.com/edx/openedx-translations.git"
)

ssh_repos=(
Expand All @@ -66,15 +77,14 @@ ssh_repos=(
"git@github.com:edx/ecommerce.git"
"git@github.com:openedx/edx-notes-api.git"
"git@github.com:openedx/enterprise-catalog.git"
"git@github.com:openedx/edx-platform.git"
"git@github.com:edx/edx-platform.git"
"git@github.com:openedx/xqueue.git"
"git@github.com:edx/edx-analytics-dashboard.git"
"git@github.com:openedx/frontend-app-gradebook.git"
"git@github.com:openedx/frontend-app-learner-dashboard.git"
"git@github.com:openedx/frontend-app-learner-record.git"
"git@github.com:edx/frontend-app-gradebook.git"
"git@github.com:edx/frontend-app-learner-dashboard.git"
"git@github.com:edx/frontend-app-learner-record.git"
"git@github.com:edx/frontend-app-payment.git"
"git@github.com:openedx/frontend-app-publisher.git"
"git@github.com:edx/edx-analytics-dashboard.git"
"git@github.com:edx/frontend-app-publisher.git"
"git@github.com:edx/edx-analytics-data-api.git"
"git@github.com:edx/portal-designer.git"
"git@github.com:openedx/license-manager.git"
Expand All @@ -85,17 +95,29 @@ ssh_repos=(
non_release_ssh_repos=(
"git@github.com:openedx/frontend-app-authn.git"
"git@github.com:openedx/frontend-app-course-authoring.git"
"git@github.com:openedx/frontend-app-learning.git"
"git@github.com:edx/frontend-app-learning.git"
"git@github.com:edx/registrar.git"
"git@github.com:edx/frontend-app-program-console.git"
"git@github.com:openedx/frontend-app-account.git"
"git@github.com:openedx/frontend-app-profile.git"
"git@github.com:openedx/frontend-app-ora-grading.git"
"git@github.com:edx/frontend-app-profile.git"
"git@github.com:edx/frontend-app-ora-grading.git"
"git@github.com:openedx/enterprise-subsidy.git"
"git@github.com:openedx/frontend-app-admin-portal.git"
"git@github.com:openedx/frontend-app-learner-portal-enterprise.git"
"git@github.com:edx/frontend-app-admin-portal.git"
"git@github.com:edx/frontend-app-learner-portal-enterprise.git"
"git@github.com:edx/frontend-app-enterprise-checkout.git"
"git@github.com:edx/edx-exams.git"
"git@github.com:edx/frontend-app-skills.git"
"git@github.com:edx/frontend-app-ora.git"
"git@github.com:edx/frontend-app-exams-dashboard.git"
"git@github.com:edx/frontend-app-learner-portal-programs.git"
"git@github.com:edx/frontend-app-communications.git"
"git@github.com:edx/frontend-app-discussions.git"
"git@github.com:edx/frontend-app-enterprise-public-catalog.git"
"git@github.com:edx/frontend-app-support-tools.git"
"git@github.com:edx/frontend-app-authoring.git"
"git@github.com:edx/frontend-app-instruct.git"
"git@github.com:edx/frontend-app-catalog.git"
"git@github.com:edx/openedx-translations.git"
)

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

# Define repositories that exist in both edx and openedx organizations
# These are the ones that need remote setup for forked repositories
FORKED_REPOS=(
"course-discovery"
"credentials"
"cs_comments_service"
"ecommerce"
"edx-notes-api"
"edx-platform"
"xqueue"
"edx-analytics-dashboard"
"frontend-app-gradebook"
"frontend-app-learner-dashboard"
"frontend-app-learner-record"
"frontend-app-skills"
"frontend-app-learning"
"frontend-app-ora"
"frontend-app-ora-grading"
"frontend-app-exams-dashboard"
"frontend-app-learner-portal-programs"
"frontend-app-program-console"
"frontend-app-communications"
"frontend-app-discussions"
"frontend-app-profile"
"frontend-app-enterprise-public-catalog"
"frontend-app-publisher"
"frontend-app-support-tools"
"frontend-app-admin-portal"
"frontend-app-learner-portal-enterprise"
"frontend-app-enterprise-checkout"
"frontend-app-authoring"
"frontend-app-instruct"
"frontend-app-catalog"
"openedx-translations"
"frontend-app-payment"
"edx-analytics-data-api"
"enterprise-catalog"
"portal-designer"
"license-manager"
"codejail-service"
"enterprise-access"
"frontend-app-authn"
"frontend-app-course-authoring"
"registrar"
"frontend-app-account"
"enterprise-subsidy"
"edx-exams"
)

setup_forked_repo_remotes ()
{
local repo_name=$1
local edx_remote_exists
local openedx_remote_exists
local origin_exists
local existing_url=""
local existing_org=""
local other_org
local other_remote_exists
local other_url

# Check if we're in a git repository
if [ ! -d ".git" ]; then
echo "ERROR: $repo_name is not a git repository"
return 1
fi

# Check if both remotes already exist (idempotency check)
edx_remote_exists=$(git remote | grep "^edx$" || true)
openedx_remote_exists=$(git remote | grep "^openedx$" || true)
origin_exists=$(git remote | grep "^origin$" || true)

if [ -n "$edx_remote_exists" ] && [ -n "$openedx_remote_exists" ] && [ -z "$origin_exists" ]; then
echo "Both edx and openedx remotes already exist in $repo_name. No changes needed."
return 0
fi

echo "Setting up remotes for forked repository: $repo_name"

# First, try to find an existing remote and its URL
if [ -n "$origin_exists" ]; then
# We have an 'origin' remote - determine its organization
existing_url=$(git remote get-url origin 2>/dev/null || true)

if [[ $existing_url =~ github\.com[:/]edx/ ]]; then
existing_org="edx"
elif [[ $existing_url =~ github\.com[:/]openedx/ ]]; then
existing_org="openedx"
else
echo "ERROR: Unexpected origin URL in $repo_name: $existing_url"
echo "Expected URL to be from either edx or openedx organization"
return 1
fi

# Rename origin to the correct organization name if not already done
if ! git remote | grep -q "^${existing_org}$"; then
echo "Renaming origin to '$existing_org' in $repo_name"
if ! git remote rename origin "$existing_org"; then
echo "ERROR: Failed to rename origin to $existing_org in $repo_name"
return 1
fi
else
echo "Remote '$existing_org' already exists, removing origin"
git remote remove origin 2>/dev/null || true
fi
elif [ -n "$edx_remote_exists" ]; then
# No origin, but we have an 'edx' remote - use it as reference
existing_url=$(git remote get-url edx)
existing_org="edx"
elif [ -n "$openedx_remote_exists" ]; then
# No origin or edx, but we have an 'openedx' remote - use it as reference
existing_url=$(git remote get-url openedx)
existing_org="openedx"
else
echo "ERROR: No remotes found in $repo_name"
return 1
fi

# Determine the other organization and add its remote if missing
if [ "$existing_org" = "edx" ]; then
other_org="openedx"
else
other_org="edx"
fi

# Check if the other remote exists
other_remote_exists=$(git remote | grep "^${other_org}$" || true)

if [ -z "$other_remote_exists" ]; then
# Construct the URL for the other organization
if [[ $existing_url =~ ^git@ ]]; then
# SSH URL format
other_url="git@github.com:${other_org}/${repo_name}.git"
else
# HTTPS URL format
other_url="https://github.com/${other_org}/${repo_name}.git"
fi

echo "Adding $other_org remote: $other_url"
if ! git remote add "$other_org" "$other_url"; then
echo "ERROR: Failed to add $other_org remote in $repo_name"
return 1
fi
else
echo "Remote '$other_org' already exists in $repo_name"
fi

echo "Successfully configured remotes for $repo_name"
return 0
}

setup_all_forked_repo_remotes ()
{
local successful_repos=()
local failed_repos=()
local skipped_repos=()
local repo
local name
local is_forked
local forked_repo

echo "Setting up remotes for all forked repositories..."
echo "========================================"

for repo in "${repos[@]}" "${non_release_repos[@]}"
do
# Extract repo name from URL
if [[ ! $repo =~ $name_pattern ]]; then
echo "Cannot setup remotes for repo; URL did not match expected pattern: $repo"
continue
fi
name="${BASH_REMATCH[1]}"

# Check if directory exists
if [ ! -d "$name" ]; then
echo "Repository $name is not cloned. Skipping."
skipped_repos+=("$name")
continue
fi

# Check if this repo is configured as a forked repo
is_forked=false
for forked_repo in "${FORKED_REPOS[@]}"; do
if [[ "$forked_repo" == "$name" ]]; then
is_forked=true
break
fi
done

if [[ "$is_forked" == false ]]; then
echo "Repository $name is not configured as a forked repo. Skipping."
skipped_repos+=("$name")
continue
fi

# Change to repo directory and setup remotes
cd "$name"
if setup_forked_repo_remotes "$name"; then
successful_repos+=("$name")
else
failed_repos+=("$name")
fi
cd "$DEVSTACK_WORKSPACE"
echo ""
done

# Print summary report
echo "========================================"
echo "Remote Setup Summary:"
echo "========================================"

if [ ${#successful_repos[@]} -gt 0 ]; then
echo "✓ Successfully configured remotes for ${#successful_repos[@]} repositories:"
printf " - %s\n" "${successful_repos[@]}"
echo ""
fi

if [ ${#failed_repos[@]} -gt 0 ]; then
echo "✗ Failed to configure remotes for ${#failed_repos[@]} repositories:"
printf " - %s\n" "${failed_repos[@]}"
echo ""
fi

if [ ${#skipped_repos[@]} -gt 0 ]; then
echo "◦ Skipped ${#skipped_repos[@]} repositories (not cloned or not forked):"
printf " - %s\n" "${skipped_repos[@]}"
echo ""
fi

echo "Total repositories processed: $((${#successful_repos[@]} + ${#failed_repos[@]} + ${#skipped_repos[@]}))"

if [ ${#failed_repos[@]} -gt 0 ]; then
return 1
else
return 0
fi
}

if [ "$1" == "checkout" ]; then
checkout
elif [ "$1" == "clone" ]; then
Expand All @@ -297,4 +557,6 @@ elif [ "$1" == "reset" ]; then
reset
elif [ "$1" == "status" ]; then
status
elif [ "$1" == "setup-remotes" ]; then
setup_all_forked_repo_remotes
fi
Loading