diff --git a/scripts/bump-version.sh b/scripts/bump-versions.sh similarity index 100% rename from scripts/bump-version.sh rename to scripts/bump-versions.sh diff --git a/scripts/export-translations.sh b/scripts/export-translations.sh deleted file mode 100755 index 8467ca73c..000000000 --- a/scripts/export-translations.sh +++ /dev/null @@ -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" diff --git a/scripts/migrate-images.sh b/scripts/migrate-images.sh deleted file mode 100755 index 1091f4a1a..000000000 --- a/scripts/migrate-images.sh +++ /dev/null @@ -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." diff --git a/scripts/review-versions.sh b/scripts/review-versions.sh new file mode 100755 index 000000000..d445c0f3e --- /dev/null +++ b/scripts/review-versions.sh @@ -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 "────────────────────────────────────────────────────────────────────────────────────" \ No newline at end of file