Add review-versions.sh helper script

This commit is contained in:
Leendert de Borst
2025-12-01 11:51:21 +01:00
parent fd9eb9d653
commit ca85c04c75
4 changed files with 117 additions and 415 deletions

View File

@@ -1,288 +0,0 @@
#!/usr/bin/env bash
# Check if running with bash
if [ -z "$BASH_VERSION" ]; then
echo "Error: This script must be run with bash"
echo "Usage: bash $0"
exit 1
fi
# Script to export all existing translation files from AliasVault
# Based on the paths defined in crowdin.yml
# Excludes English source files and preserves full directory structure
set -e # Exit on any error
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Function to print colored output
print_status() {
echo -e "${BLUE}[INFO]${NC} $1"
}
print_success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
print_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# Function to create directory if it doesn't exist
ensure_dir() {
local dir="$1"
if [ ! -d "$dir" ]; then
mkdir -p "$dir"
print_status "Created directory: $dir"
fi
}
# Function to copy file if it exists
copy_if_exists() {
local src="$1"
local dest="$2"
if [ -f "$src" ]; then
ensure_dir "$(dirname "$dest")"
cp "$src" "$dest"
print_success "Copied: $src -> $dest"
return 0
else
print_warning "File not found: $src"
return 1
fi
}
# Get script directory
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
# Change to project root
cd "$PROJECT_ROOT"
print_status "Starting translation export from: $PROJECT_ROOT"
# Define target directory for export
EXPORT_DIR="translation_export_$(date +%Y%m%d_%H%M%S)"
print_status "Export directory: $EXPORT_DIR"
# Create export directory
ensure_dir "$EXPORT_DIR"
# Languages to export (from crowdin.yml)
LANGUAGES=("nl" "de" "fr" "es" "it" "pt" "uk" "zh" "ja" "ko")
# Counter for statistics
TOTAL_FILES=0
COPIED_FILES=0
MISSING_FILES=0
print_status "Exporting translations for languages: ${LANGUAGES[*]}"
# ============================================================================
# Export translation files based on crowdin.yml paths
# ============================================================================
print_status "Processing Web App (Blazor WASM) translations..."
# Blazor WASM Client JSON localization files
for lang in "${LANGUAGES[@]}"; do
src="apps/server/AliasVault.Client/wwwroot/locales/$lang.json"
dest="$EXPORT_DIR/apps/server/AliasVault.Client/wwwroot/locales/$lang.json"
if copy_if_exists "$src" "$dest"; then
((COPIED_FILES++))
else
((MISSING_FILES++))
fi
((TOTAL_FILES++))
done
# .NET Resource files (RESX) for Blazor components
for lang in "${LANGUAGES[@]}"; do
src="apps/server/AliasVault.Client/Resources/SharedResources.$lang.resx"
dest="$EXPORT_DIR/apps/server/AliasVault.Client/Resources/SharedResources.$lang.resx"
if copy_if_exists "$src" "$dest"; then
((COPIED_FILES++))
else
((MISSING_FILES++))
fi
((TOTAL_FILES++))
done
# Blazor component resource files (find all .en.resx files and copy their translations)
while IFS= read -r -d '' en_file; do
for lang in "${LANGUAGES[@]}"; do
# Replace .en.resx with .$lang.resx
src="${en_file%.en.resx}.$lang.resx"
# Create destination path maintaining structure
rel_path="${src#apps/server/AliasVault.Client/Resources/}"
dest="$EXPORT_DIR/apps/server/AliasVault.Client/Resources/$rel_path"
if copy_if_exists "$src" "$dest"; then
((COPIED_FILES++))
else
((MISSING_FILES++))
fi
((TOTAL_FILES++))
done
done < <(find apps/server/AliasVault.Client/Resources -name "*.en.resx" -type f -print0)
# ============================================================================
# Browser Extension
# ============================================================================
print_status "Processing Browser Extension translations..."
# Browser Extension JSON translation files (nested structure)
# Find all English JSON files and copy their translations
while IFS= read -r -d '' en_file; do
for lang in "${LANGUAGES[@]}"; do
# Get relative path from en directory
rel_path="${en_file#apps/browser-extension/src/locales/en/}"
src="apps/browser-extension/src/locales/$lang/$rel_path"
dest="$EXPORT_DIR/apps/browser-extension/src/locales/$lang/$rel_path"
if copy_if_exists "$src" "$dest"; then
((COPIED_FILES++))
else
((MISSING_FILES++))
fi
((TOTAL_FILES++))
done
done < <(find apps/browser-extension/src/locales/en -name "*.json" -type f -print0)
# ============================================================================
# Mobile App (React Native + Native iOS/Android)
# ============================================================================
print_status "Processing Mobile App translations..."
# React Native JSON translation files
for lang in "${LANGUAGES[@]}"; do
src="apps/mobile-app/i18n/locales/$lang.json"
dest="$EXPORT_DIR/apps/mobile-app/i18n/locales/$lang.json"
if copy_if_exists "$src" "$dest"; then
((COPIED_FILES++))
else
((MISSING_FILES++))
fi
((TOTAL_FILES++))
done
# iOS native localization files
for lang in "${LANGUAGES[@]}"; do
# AliasVault main app
src="apps/mobile-app/ios/AliasVault/$lang.lproj/Localizable.strings"
dest="$EXPORT_DIR/apps/mobile-app/ios/AliasVault/$lang.lproj/Localizable.strings"
if copy_if_exists "$src" "$dest"; then
((COPIED_FILES++))
else
((MISSING_FILES++))
fi
((TOTAL_FILES++))
src="apps/mobile-app/ios/AliasVault/$lang.lproj/InfoPlist.strings"
dest="$EXPORT_DIR/apps/mobile-app/ios/AliasVault/$lang.lproj/InfoPlist.strings"
if copy_if_exists "$src" "$dest"; then
((COPIED_FILES++))
else
((MISSING_FILES++))
fi
((TOTAL_FILES++))
# iOS Autofill extension
src="apps/mobile-app/ios/Autofill/$lang.lproj/Localizable.strings"
dest="$EXPORT_DIR/apps/mobile-app/ios/Autofill/$lang.lproj/Localizable.strings"
if copy_if_exists "$src" "$dest"; then
((COPIED_FILES++))
else
((MISSING_FILES++))
fi
((TOTAL_FILES++))
# iOS VaultUI framework
src="apps/mobile-app/ios/VaultUI/$lang.lproj/Localizable.strings"
dest="$EXPORT_DIR/apps/mobile-app/ios/VaultUI/$lang.lproj/Localizable.strings"
if copy_if_exists "$src" "$dest"; then
((COPIED_FILES++))
else
((MISSING_FILES++))
fi
((TOTAL_FILES++))
done
# Android native localization files
for lang in "${LANGUAGES[@]}"; do
src="apps/mobile-app/android/app/src/main/res/values-$lang/strings.xml"
dest="$EXPORT_DIR/apps/mobile-app/android/app/src/main/res/values-$lang/strings.xml"
if copy_if_exists "$src" "$dest"; then
((COPIED_FILES++))
else
((MISSING_FILES++))
fi
((TOTAL_FILES++))
done
# ============================================================================
# Summary and cleanup
# ============================================================================
print_status "Export completed!"
print_success "Export directory: $EXPORT_DIR"
print_status "Statistics:"
print_status " Total files processed: $TOTAL_FILES"
print_status " Translation files copied: $COPIED_FILES"
print_status " Translation files missing: $MISSING_FILES"
if [ $MISSING_FILES -gt 0 ]; then
print_warning "Some translation files were not found. This is normal if translations are not complete for all languages."
fi
print_status "Export structure:"
print_status " - Only translation files copied (as defined in crowdin.yml)"
print_status " - Full directory hierarchy preserved for translation files"
print_status " - Ready for distribution or archiving"
# Create zip archive in scripts folder
ZIP_NAME="translation_export_$(date +%Y%m%d_%H%M%S).zip"
ZIP_PATH="$SCRIPT_DIR/$ZIP_NAME"
print_status "Creating zip archive..."
if command -v zip >/dev/null 2>&1; then
cd "$EXPORT_DIR"
zip -r "$ZIP_PATH" . >/dev/null 2>&1
cd "$PROJECT_ROOT"
print_success "Zip archive created: $ZIP_PATH"
else
print_warning "zip command not available. Please install zip or manually create archive."
fi
print_status "Export completed!"
print_success "Export directory: $EXPORT_DIR"
print_success "Zip archive: $ZIP_PATH"
print_status "Statistics:"
print_status " Total files processed: $TOTAL_FILES"
print_status " Translation files copied: $COPIED_FILES"
print_status " Translation files missing: $MISSING_FILES"
if [ $MISSING_FILES -gt 0 ]; then
print_warning "Some translation files were not found. This is normal if translations are not complete for all languages."
fi
print_status "Export structure:"
print_status " - Only translation files copied (as defined in crowdin.yml)"
print_status " - Full directory hierarchy preserved for translation files"
print_status " - Ready for distribution or archiving"
print_status "You can now upload the zip file: $ZIP_PATH"

View File

@@ -1,127 +0,0 @@
#!/usr/bin/env bash
#
# This script is used to migrate Docker images from one host/namespace to another.
# Was used for migrating from lanedirt/aliasvault to aliasvault/aliasvault, kept for reference.
#
# mirror-multiarch.sh — copy ALL platforms from OLD_NS to NEW_NS using skopeo.
# Edit OLD_NS, NEW_NS, TAGS below.
# ----------------------- EDIT THESE -----------------------
OLD_NS="ghcr.io/lanedirt/aliasvault"
NEW_NS="ghcr.io/aliasvault/aliasvault"
TAGS=(
0.7.0
0.8.0
0.8.1
0.8.2
0.8.3
0.9.0
0.9.1
0.9.2
0.9.3
0.9.4
0.10.0
0.10.1
0.10.2
0.10.3
0.11.0
0.11.1
0.12.0
0.12.1
0.12.2
0.12.3
0.13.0
0.14.0
0.15.0
0.15.1
0.16.0
0.16.1
0.16.2
0.17.0
0.17.1
0.17.2
0.17.3
0.18.0
0.18.1
0.19.0
0.19.1
0.19.2
0.20.0
0.20.1
0.20.2
0.21.0
0.21.1
0.21.2
0.22.0
latest
)
# Optional auth (leave empty to use `skopeo login ghcr.io`)
SRC_CREDS="" # "username:token" with read:packages for lanedirt
DST_CREDS="" # "username:token" with write:packages for aliasvault
# -----------------------
set -euo pipefail
RETRIES=3
DRY_RUN=0 # set to 1 to print commands only
need() { command -v "$1" >/dev/null 2>&1 || { echo "Missing dependency: $1"; exit 1; }; }
need skopeo
src_args=()
dst_args=()
[[ -n "$SRC_CREDS" ]] && src_args+=( --src-creds "$SRC_CREDS" )
[[ -n "$DST_CREDS" ]] && dst_args+=( --dest-creds "$DST_CREDS" )
probe_exists() {
local ref="$1"
# Use --raw so skopeo doesn't try to pick darwin/arm64; works for manifest lists and single-manifest images.
skopeo inspect --raw --retry-times "${RETRIES}" "${src_args[@]}" "docker://${ref}" >/dev/null 2>&1
}
copy_multiarch() {
local src="$1" dst="$2"
local cmd=(skopeo copy --all --retry-times "${RETRIES}" "${src_args[@]}" "${dst_args[@]}"
"docker://${src}" "docker://${dst}")
if [[ "$DRY_RUN" -eq 1 ]]; then
echo "[DRY-RUN] ${cmd[*]}"
else
"${cmd[@]}"
fi
}
echo "Source: ${OLD_NS}"
echo "Dest : ${NEW_NS}"
[[ "$DRY_RUN" -eq 1 ]] && echo "(dry-run mode)"
for TAG in "${TAGS[@]}"; do
SRC="${OLD_NS}:${TAG}"
DST="${NEW_NS}:${TAG}"
echo
echo "Processing ${SRC}${DST}"
if ! probe_exists "${SRC}"; then
echo "Tag ${SRC} not found or not accessible; skipping"
continue
fi
copy_multiarch "${SRC}" "${DST}"
echo "Verified destination (manifest digest + platforms):"
# Use --raw to avoid host-platform selection; then summarize platforms with jq if available.
if command -v jq >/dev/null 2>&1; then
man="$(skopeo inspect --raw "docker://${DST}")"
mt="$(echo "$man" | jq -r '.mediaType // ""')"
if [[ "$mt" == "application/vnd.docker.distribution.manifest.list.v2+json" || "$mt" == "application/vnd.oci.image.index.v1+json" ]]; then
echo "$man" | jq -r '.manifests | map(.platform) | .[] | "\(.os)/\(.architecture)\(if .variant then "/\(.variant)" else "" end)"' | sort -u
else
echo "$man" | jq -r '.config.digest'
fi
else
skopeo inspect --raw "docker://${DST}" >/dev/null && echo "(raw manifest retrieved)"
fi
done
echo
echo "Done."

117
scripts/review-versions.sh Executable file
View File

@@ -0,0 +1,117 @@
#!/usr/bin/env bash
# Check if running with bash
if [ -z "$BASH_VERSION" ]; then
echo "Error: This script must be run with bash"
echo "Usage: bash $0"
exit 1
fi
# Function to extract version from server AppInfo.cs
get_server_version() {
local major=$(grep "public const int VersionMajor = " ../apps/server/Shared/AliasVault.Shared.Core/AppInfo.cs | tr -d ';' | tr -d ' ' | cut -d'=' -f2)
local minor=$(grep "public const int VersionMinor = " ../apps/server/Shared/AliasVault.Shared.Core/AppInfo.cs | tr -d ';' | tr -d ' ' | cut -d'=' -f2)
local patch=$(grep "public const int VersionPatch = " ../apps/server/Shared/AliasVault.Shared.Core/AppInfo.cs | tr -d ';' | tr -d ' ' | cut -d'=' -f2)
local stage=$(grep "public const string VersionStage = " ../apps/server/Shared/AliasVault.Shared.Core/AppInfo.cs | cut -d'"' -f2)
echo "$major.$minor.$patch$stage"
}
# Function to extract version from browser extension config
get_browser_extension_version() {
grep "version: " ../apps/browser-extension/wxt.config.ts | head -n1 | tr -d '"' | tr -d ',' | tr -d ' ' | cut -d':' -f2
}
# Function to extract version from browser extension package.json
get_browser_extension_package_json_version() {
grep "\"version\": " ../apps/browser-extension/package.json | tr -d '"' | tr -d ',' | tr -d ' ' | cut -d':' -f2
}
# Function to extract version from browser extension AppInfo.ts
get_browser_extension_ts_version() {
grep "public static readonly VERSION = " ../apps/browser-extension/src/utils/AppInfo.ts | tr -d "'" | tr -d ';' | tr -d ' ' | cut -d'=' -f2
}
# Function to extract version from mobile app
get_mobile_app_version() {
grep "\"version\": " ../apps/mobile-app/app.json | tr -d '"' | tr -d ',' | tr -d ' ' | cut -d':' -f2
}
get_mobile_app_ts_version() {
grep "public static readonly VERSION = " ../apps/mobile-app/utils/AppInfo.ts | tr -d "'" | tr -d ';' | tr -d ' ' | cut -d'=' -f2
}
# Function to extract version from iOS app
get_ios_version() {
grep "MARKETING_VERSION = " ../apps/mobile-app/ios/AliasVault.xcodeproj/project.pbxproj | head -n1 | tr -d '"' | tr -d ';' | tr -d ' ' | cut -d'=' -f2
}
# Function to extract iOS build number
get_ios_build() {
grep -A1 "CURRENT_PROJECT_VERSION" ../apps/mobile-app/ios/AliasVault.xcodeproj/project.pbxproj | grep "CURRENT_PROJECT_VERSION = [0-9]\+;" | head -n1 | tr -d ';' | tr -d ' ' | cut -d'=' -f2
}
# Function to extract version from Android app
get_android_version() {
grep "versionName " ../apps/mobile-app/android/app/build.gradle | head -n1 | tr -d '"' | tr -d ' ' | cut -d'=' -f2 | sed 's/versionName//'
}
# Function to extract Android build number
get_android_build() {
grep "versionCode" ../apps/mobile-app/android/app/build.gradle | grep -E "versionCode [0-9]+" | head -n1 | awk '{print $2}'
}
# Function to extract version from Safari extension
get_safari_version() {
grep "MARKETING_VERSION = " ../apps/browser-extension/safari-xcode/AliasVault/AliasVault.xcodeproj/project.pbxproj | head -n1 | tr -d '"' | tr -d ';' | tr -d ' ' | cut -d'=' -f2
}
# Function to extract Safari build number
get_safari_build() {
grep -A1 "CURRENT_PROJECT_VERSION" ../apps/browser-extension/safari-xcode/AliasVault/AliasVault.xcodeproj/project.pbxproj | grep "CURRENT_PROJECT_VERSION = [0-9]\+;" | head -n1 | tr -d ';' | tr -d ' ' | cut -d'=' -f2
}
# Collect all versions
server_version=$(get_server_version)
browser_wxt_version=$(get_browser_extension_version)
browser_package_version=$(get_browser_extension_package_json_version)
browser_ts_version=$(get_browser_extension_ts_version)
mobile_version=$(get_mobile_app_version)
mobile_ts_version=$(get_mobile_app_ts_version)
ios_version=$(get_ios_version)
ios_build=$(get_ios_build)
android_version=$(get_android_version)
android_build=$(get_android_build)
safari_version=$(get_safari_version)
safari_build=$(get_safari_build)
# Print table header
printf "%-50s %-20s %-15s\n" "Component" "Version" "Build Number"
echo "─────────────────────────────────────────────────────────────────────────────────"
# Server
printf "%-50s %-20s %-15s\n" "Server (AppInfo.cs)" "$server_version" "N/A"
# Browser Extension
echo ""
printf "%-50s %-20s %-15s\n" "Browser Extension (wxt.config.ts)" "$browser_wxt_version" "N/A"
printf "%-50s %-20s %-15s\n" "Browser Extension (package.json)" "$browser_package_version" "N/A"
printf "%-50s %-20s %-15s\n" "Browser Extension (AppInfo.ts)" "$browser_ts_version" "N/A"
# Safari Extension
echo ""
printf "%-50s %-20s %-15s\n" "Safari Extension (Xcode)" "$safari_version" "$safari_build"
# Mobile App
echo ""
printf "%-50s %-20s %-15s\n" "Mobile App (app.json)" "$mobile_version" "N/A"
printf "%-50s %-20s %-15s\n" "Mobile App (AppInfo.ts)" "$mobile_ts_version" "N/A"
# iOS
echo ""
printf "%-50s %-20s %-15s\n" "iOS App (Xcode)" "$ios_version" "$ios_build"
# Android
echo ""
printf "%-50s %-20s %-15s\n" "Android App (build.gradle)" "$android_version" "$android_build"
echo "────────────────────────────────────────────────────────────────────────────────────"