diff --git a/README.md b/README.md index a66117b..3798725 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,19 @@ You can always change the settings back after the migration manually or edit the * Add link to new location in source project description * Archive source projects after migration +## User mapping ## + +Gitlab use email to match users between instances. If the username are not the same between instances but emails are the same, then all user associations are preserved. However, if users email changed, associations are lost after import. You can fix this issue by supplying a user mapping file to make the correspondance. + +First, create a `user-mapping.txt` file containing the old and new email address, one record per line, like this: + +``` +alice@example.com alice.foo@example.com +bob@example.com bob.bar@example.com +``` + +To enable user mapping, set the variables `USER_MAPPING=true` and `USER_MAPPING_FILE=user-mapping.txt`. After downloading the export archive, the file `project_members.ndjson` inside it is modified with the new emails. The case is non-sensitive. The importation proceeds as usual. + # License # Copyright (c) 2020 K - Mail Order GmbH & Co. KG diff --git a/migrate.sh b/migrate.sh old mode 100644 new mode 100755 index d432fca..dbaa960 --- a/migrate.sh +++ b/migrate.sh @@ -21,6 +21,12 @@ printf "Migrate badges? (yes/no): " read -r MIGRATE_BADGES printf "Migrate hooks? (yes/no): " read -r MIGRATE_HOOKS +printf "Apply user mapping? (yes/no): " +read -r USER_MAPPING +if [[ "$USER_MAPPING" == "yes" ]]; then + printf "User mapping file: " + read -r USER_MAPPING_FILE +fi #SOURCE_PATH="" #TARGET_PATH="" #ARCHIVE_AFTER_MIGRATION="no" @@ -30,6 +36,8 @@ read -r MIGRATE_HOOKS #MIGRATE_PROJECT_VARIABLES="no" #MIGRATE_BADGES="no" #MIGRATE_HOOKS="no" +#USER_MAPPING="no" +#USER_MAPPING_FILE="user-mapping.txt" CURL_PARAMS="" unset -v sourceGitlabPrivateAccessToken targetGitlabPrivateAccessToken @@ -288,6 +296,11 @@ function migrateProject() { echo " Done ${exportStatus[1]}" local fileName fileName=$(downloadFile "${exportStatus[1]}") + + if [[ "$USER_MAPPING" == "yes" ]]; then + modifyUserMapping "${USER_MAPPING_FILE}" "${fileName}" + fi + importProject "${project}" "${fileName}" break fi @@ -314,6 +327,31 @@ function downloadFile () { echo "$tempPath" } +function modifyUserMapping () { + local userMappingFile=$1 + local archiveFile=$2 + local workDir="work" + + mapfile -t userMap < ${userMappingFile} + + mkdir -p ${workDir} + tar -C ${workDir} -xzf "$archiveFile" + + projectMembersFile=${workDir}/tree/project/project_members.ndjson + tmpFile="$(basename ${projectMembersFile}).tmp" + + for item in "${userMap[@]}"; do + read -r search replace <<< "$item" + jq -c --arg search ${search} --arg replace ${replace} \ + '. | if (.user.email | test($search; "i")) then .user.email |= $replace else . end' \ + ${projectMembersFile} > ${tmpFile} && \ + mv ${tmpFile} ${projectMembersFile} + done + + tar -C ${workDir} -czf "${archiveFile}" . + rm -rf ${workDir} +} + function importProject () { local project=$1 local fileName=$2