diff --git a/translations-app/handleAppTranslations.sh b/translations-app/handleAppTranslations.sh index debf85b6..2f5c38ff 100755 --- a/translations-app/handleAppTranslations.sh +++ b/translations-app/handleAppTranslations.sh @@ -3,6 +3,9 @@ # verbose and exit on error set -xe +# Load the string freeze helpers +. /stringFreeze.sh + # Print tooling information php -v tx -v @@ -74,6 +77,18 @@ if [ -f '.tx/backport' ]; then versions="main master $(cat .tx/backport)" fi +# During a string freeze no new strings may enter the translation system. +# This only affects apps that are shipped with the server, all other apps keep +# syncing their strings. For shipped apps the branch with the new strings is +# skipped completely and the newest stable branch defines the source strings. +STRING_FREEZE='false' +TEMPLATE_BRANCHES='master main' +if is_string_freeze "$versions" && is_shipped_app "$APP_ID"; then + STRING_FREEZE='true' + TEMPLATE_BRANCHES=$(newest_stable_branch "$versions") + echo "String freeze is active and $APP_ID is shipped: not syncing new strings from main and master, using $TEMPLATE_BRANCHES instead" +fi + mkdir stable-templates mkdir -p translationfiles/templates/ @@ -98,6 +113,13 @@ do continue fi + if [ "$STRING_FREEZE" = 'true' ] && { [ "$version" = 'master' ] || [ "$version" = 'main' ]; }; then + # during the string freeze the new strings of the development branch + # must not be added to the translation system + echo "Skipping templates of $version during the string freeze" + continue + fi + cd /app/$version # build POT files @@ -119,23 +141,28 @@ done cd /app/default # merge POT files into one -for file in $(ls stable-templates/master.*) +# the last branch of the list wins, so main takes precedence over master +HAS_TEMPLATES='false' +for template_branch in $TEMPLATE_BRANCHES do - name=$(echo $file | cut -b 25- ) - msgcat --use-first stable-templates/*.$name > $SOURCE_FILE -done -# alternative merge of main branch -for file in $(ls stable-templates/main.*) -do - name=$(echo $file | cut -b 23- ) - msgcat --use-first stable-templates/*.$name > $SOURCE_FILE + for file in $(ls stable-templates/$template_branch.* 2>/dev/null) + do + HAS_TEMPLATES='true' + name=${file#stable-templates/$template_branch.} + # the template branch comes first, so duplicated strings keep its comments + msgcat --use-first $file $(ls stable-templates/*.$name | grep -vxF "$file") > $SOURCE_FILE + done done # remove intermediate POT files rm -rf stable-templates # push sources -tx push -s +if [ "$HAS_TEMPLATES" = 'true' ]; then + tx push -s +else + echo "No source templates found for branch $TEMPLATE_BRANCHES, not pushing sources" +fi # pull translations - force pull because a fresh clone has newer time stamps tx pull -f -a --minimum-perc=5 diff --git a/translations/Dockerfile b/translations/Dockerfile index 4f827aad..a0acf09f 100644 --- a/translations/Dockerfile +++ b/translations/Dockerfile @@ -42,6 +42,7 @@ RUN mkdir -p /app ADD gitconfig /root/.gitconfig ADD known_hosts /root/.ssh/known_hosts ADD handleTranslations.sh /handleTranslations.sh +ADD stringFreeze.sh /stringFreeze.sh ADD validateTranslationFiles.sh /validateTranslationFiles.sh ADD translationtool/translationtool.phar /translationtool.phar diff --git a/translations/handleTranslations.sh b/translations/handleTranslations.sh index ea71ca3c..479e2bd3 100755 --- a/translations/handleTranslations.sh +++ b/translations/handleTranslations.sh @@ -3,6 +3,9 @@ # verbose and exit on error set -xe +# Load the string freeze helpers +. /stringFreeze.sh + # Print tooling information php -v tx -v @@ -31,6 +34,18 @@ git push ################################## versions='master stable35 stable34 stable33 stable32' +# During a string freeze no new strings may enter the translation system. +# Everything in the server repository is shipped, so the branch with the new +# strings is skipped completely and the newest stable branch defines the +# resources and source strings instead. +STRING_FREEZE='false' +TEMPLATE_BRANCH='master' +if is_string_freeze "$versions"; then + STRING_FREEZE='true' + TEMPLATE_BRANCH=$(newest_stable_branch "$versions") + echo "String freeze is active: not syncing new strings from master, using $TEMPLATE_BRANCH instead" +fi + mkdir stable-templates mkdir -p translationfiles/templates/ @@ -55,6 +70,13 @@ do continue fi + if [ "$STRING_FREEZE" = 'true' ] && { [ "$version" = 'master' ] || [ "$version" = 'main' ]; }; then + # during the string freeze the new strings of the development branch + # must not be added to the translation system + echo "Skipping templates of $version during the string freeze" + continue + fi + cd /app/$version # build POT files @@ -74,11 +96,13 @@ done cd /app/default # merge POT files into one -for file in $(ls stable-templates/master.*) +HAS_TEMPLATES='false' +for file in $(ls stable-templates/$TEMPLATE_BRANCH.* 2>/dev/null) do - # Change below to 23 when server switches to main - name=$(echo $file | cut -b 25- ) - msgcat --use-first stable-templates/*.$name > translationfiles/templates/$name + HAS_TEMPLATES='true' + name=${file#stable-templates/$TEMPLATE_BRANCH.} + # the template branch comes first, so duplicated strings keep its comments + msgcat --use-first $file $(ls stable-templates/*.$name | grep -vxF "$file") > translationfiles/templates/$name done # remove intermediate POT files @@ -88,7 +112,11 @@ rm -rf stable-templates git checkout master # push sources -tx push -s +if [ "$HAS_TEMPLATES" = 'true' ]; then + tx push -s +else + echo "No source templates found for branch $TEMPLATE_BRANCH, not pushing sources" +fi # pull translations - force pull because a fresh clone has newer time stamps tx pull -f -a --minimum-perc=50 diff --git a/translations/stringFreeze.sh b/translations/stringFreeze.sh new file mode 100755 index 00000000..613f24ec --- /dev/null +++ b/translations/stringFreeze.sh @@ -0,0 +1,69 @@ +#!/bin/sh + +################################## +# Helpers to handle the translation string freeze +# +# Between the first release candidate of a new major Nextcloud release and its +# final release no new source strings may enter the translation system. +# The freeze is active while the newest stable branch of nextcloud/server has an +# OC_VersionString like "35.0.0 RC3". Outside of the freeze the newest stable +# branch is on a maintenance version like "35.0.4 RC1" or "35.0.3". +################################## + +SERVER_RAW_URL='https://raw.githubusercontent.com/nextcloud/server' + +# Print the newest stable branch of a space separated branch list, +# e.g. "main master stable35 stable33" prints "stable35" +newest_stable_branch() { + FREEZE_MAJOR=$(echo "$1" | tr ' ' '\n' | grep -E '^stable[0-9]+$' | sed -E 's/^stable//' | sort -n | tail -n 1) + + if [ -n "$FREEZE_MAJOR" ]; then + echo "stable$FREEZE_MAJOR" + fi +} + +# Check whether the string freeze is active, based on the newest stable branch +# of the given space separated branch list. Returns 0 (true) when it is active. +is_string_freeze() { + FREEZE_BRANCH=$(newest_stable_branch "$1") + + if [ -z "$FREEZE_BRANCH" ]; then + echo 'No stable branch in the branch list, so there is no string freeze to respect' + return 1 + fi + + FREEZE_VERSION_PHP=$(curl --silent --show-error --fail --location --retry 3 "$SERVER_RAW_URL/$FREEZE_BRANCH/version.php") || { + echo "Could not read version.php of nextcloud/server branch $FREEZE_BRANCH" + # Acting like freeze and trying tomorrow again + return 0 + } + + FREEZE_VERSION_STRING=$(echo "$FREEZE_VERSION_PHP" | grep -oE "OC_VersionString *= *'[^']*'" | sed -E "s/.*'(.*)'/\1/") + echo "Newest stable branch $FREEZE_BRANCH is at version \"$FREEZE_VERSION_STRING\"" + + if [ -z "$FREEZE_VERSION_STRING" ]; then + echo "Could not read the OC_VersionString of nextcloud/server branch $FREEZE_BRANCH" + # Acting like freeze and trying tomorrow again + return 0 + fi + + case "$FREEZE_VERSION_STRING" in + *.0.0\ RC*) + return 0 + ;; + esac + + return 1 +} + +# Check whether the given app id is shipped with Nextcloud server. +# Returns 0 (true) when the app is listed in core/shipped.json +is_shipped_app() { + FREEZE_SHIPPED_JSON=$(curl --silent --show-error --fail --location --retry 3 "$SERVER_RAW_URL/master/core/shipped.json") || { + echo 'Could not read core/shipped.json of nextcloud/server' + # Acting like freeze and trying tomorrow again + return 0 + } + + echo "$FREEZE_SHIPPED_JSON" | jq --exit-status --arg app "$1" '(.shippedApps + .defaultEnabled + .alwaysEnabled) | index($app) != null' > /dev/null +}