chore: Bump version to 0.8.5 for development #19
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Test Dev Build Upgrade | |
| on: | |
| push: | |
| branches: [dev] | |
| pull_request: | |
| branches: [dev] | |
| workflow_dispatch: | |
| inputs: | |
| from_version: | |
| description: 'Upgrade from version (default: latest production)' | |
| required: false | |
| default: 'latest' | |
| to_version: | |
| description: 'Upgrade to dev version (leave empty for auto-detect from VERSION file)' | |
| required: false | |
| default: '' | |
| jobs: | |
| test-dev-upgrade: | |
| name: Dev Upgrade Test (latest → dev-${{ github.event.inputs.to_version || 'VERSION' }}) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v4 | |
| - name: Determine dev version | |
| id: versions | |
| run: | | |
| # Read current version from VERSION file | |
| CURRENT_VERSION=$(cat VERSION | tr -d '\n\r') | |
| echo "Current version: $CURRENT_VERSION" | |
| # Determine FROM version (default to latest production) | |
| FROM_VERSION="${{ github.event.inputs.from_version || 'latest' }}" | |
| echo "Upgrade FROM version: $FROM_VERSION" | |
| # Determine TO version (dev tag) | |
| if [[ -n "${{ github.event.inputs.to_version }}" ]]; then | |
| TO_VERSION="dev-${{ github.event.inputs.to_version }}" | |
| echo "Using manually specified to_version: $TO_VERSION" | |
| else | |
| TO_VERSION="dev-${CURRENT_VERSION}" | |
| echo "Auto-detected to_version: $TO_VERSION (from VERSION file)" | |
| fi | |
| # Export for later steps | |
| echo "from_version=$FROM_VERSION" >> $GITHUB_OUTPUT | |
| echo "to_version=$TO_VERSION" >> $GITHUB_OUTPUT | |
| echo "current_version=$CURRENT_VERSION" >> $GITHUB_OUTPUT | |
| - name: Create test .env file | |
| run: | | |
| # Generate secrets first | |
| ENCRYPTION_KEY=$(openssl rand -base64 32) | |
| JWT_SECRET=$(openssl rand -base64 64) | |
| JWT_REFRESH_SECRET=$(openssl rand -base64 64) | |
| SHARE_TOKEN_SECRET=$(openssl rand -base64 64) | |
| # Create .env file with proper escaping | |
| cat > .env << 'EOF' | |
| # Database Configuration | |
| POSTGRES_USER=vitransfer | |
| POSTGRES_PASSWORD=test_postgres_password | |
| POSTGRES_DB=vitransfer | |
| # Redis Configuration | |
| REDIS_PASSWORD=test_redis_password | |
| # Application Configuration | |
| APP_PORT=4321 | |
| TZ=UTC | |
| PUID=1000 | |
| PGID=1000 | |
| # Admin Account | |
| ADMIN_EMAIL=admin@test.local | |
| ADMIN_PASSWORD=TestPassword123! | |
| ADMIN_NAME=Test Admin | |
| # Application URL | |
| NEXT_PUBLIC_APP_URL=http://localhost:4321 | |
| # HTTPS | |
| HTTPS_ENABLED=false | |
| EOF | |
| # Append secrets separately with quotes to handle special characters | |
| echo "ENCRYPTION_KEY=\"$ENCRYPTION_KEY\"" >> .env | |
| echo "JWT_SECRET=\"$JWT_SECRET\"" >> .env | |
| echo "JWT_REFRESH_SECRET=\"$JWT_REFRESH_SECRET\"" >> .env | |
| echo "SHARE_TOKEN_SECRET=\"$SHARE_TOKEN_SECRET\"" >> .env | |
| - name: Deploy production version | |
| run: | | |
| FROM_VERSION="${{ steps.versions.outputs.from_version }}" | |
| echo "[DEPLOY] Deploying production version: $FROM_VERSION" | |
| # Backup original compose file | |
| cp docker-compose.yml docker-compose.yml.new | |
| # Modify compose to use production version (likely already :latest) | |
| if [[ "$FROM_VERSION" != "latest" ]]; then | |
| sed -i "s/image: crypt010\/vitransfer:latest/image: crypt010\/vitransfer:$FROM_VERSION/g" docker-compose.yml | |
| fi | |
| # Start production version | |
| docker compose up -d | |
| echo "[WAIT] Waiting for production version to be ready..." | |
| sleep 40 | |
| # Verify production version is running | |
| docker compose ps | |
| - name: Verify production version started | |
| run: | | |
| echo "Checking if production version is healthy..." | |
| # Wait for health checks | |
| for i in {1..10}; do | |
| APP_HEALTH=$(docker inspect vitransfer-app --format='{{.State.Health.Status}}' 2>/dev/null || echo "starting") | |
| echo "Attempt $i: App health = $APP_HEALTH" | |
| if [[ "$APP_HEALTH" == "healthy" ]]; then | |
| break | |
| fi | |
| sleep 5 | |
| done | |
| # Final health check | |
| APP_HEALTH=$(docker inspect vitransfer-app --format='{{.State.Health.Status}}') | |
| if [[ "$APP_HEALTH" != "healthy" ]]; then | |
| echo "[ERROR] Production version failed to start" | |
| docker logs vitransfer-app --tail 100 | |
| exit 1 | |
| fi | |
| echo "[OK] Production version is running" | |
| - name: Seed test data | |
| run: | | |
| echo "[SEED] Seeding test data..." | |
| # Login and get auth token | |
| echo "Logging in to get auth token..." | |
| LOGIN_RESPONSE=$(curl -s -X POST http://localhost:4321/api/auth/login \ | |
| -H "Content-Type: application/json" \ | |
| -d '{"email":"admin@test.local","password":"TestPassword123!"}') | |
| AUTH_TOKEN=$(echo "$LOGIN_RESPONSE" | grep -o '"accessToken":"[^"]*"' | sed 's/"accessToken":"//;s/"$//') | |
| if [[ -z "$AUTH_TOKEN" ]]; then | |
| echo "[ERROR] Failed to get auth token" | |
| echo "$LOGIN_RESPONSE" | |
| exit 1 | |
| fi | |
| # Create test project via API | |
| echo "Creating seed test project..." | |
| CREATE_PROJECT=$(curl -s -X POST http://localhost:4321/api/projects \ | |
| -H "Authorization: Bearer $AUTH_TOKEN" \ | |
| -H "Content-Type: application/json" \ | |
| -d '{ | |
| "title": "CI Test Project", | |
| "description": "Pre-upgrade seed project", | |
| "recipientName": "Seed Client", | |
| "recipientEmail": "seed@test.local", | |
| "sharePassword": "SeedPass123", | |
| "authMode": "PASSWORD" | |
| }') | |
| if [[ "$CREATE_PROJECT" == *"error"* ]]; then | |
| echo "[ERROR] Failed to create seed project" | |
| echo "$CREATE_PROJECT" | |
| exit 1 | |
| fi | |
| SEED_PROJECT_ID=$(echo "$CREATE_PROJECT" | grep -o '"id":"[^"]*"' | head -1 | sed 's/"id":"//;s/"$//') | |
| echo "Seed project created with ID: $SEED_PROJECT_ID" | |
| echo "$SEED_PROJECT_ID" > /tmp/seed_project_id.txt | |
| # Get current data count | |
| BEFORE_PROJECTS=$(docker exec vitransfer-postgres psql -U vitransfer -d vitransfer -t -c "SELECT COUNT(*) FROM \"Project\";" | tr -d ' ') | |
| BEFORE_USERS=$(docker exec vitransfer-postgres psql -U vitransfer -d vitransfer -t -c "SELECT COUNT(*) FROM \"User\";" | tr -d ' ') | |
| echo "Before upgrade:" | |
| echo " Projects: $BEFORE_PROJECTS" | |
| echo " Users: $BEFORE_USERS" | |
| # Store counts for later verification | |
| echo "$BEFORE_PROJECTS" > /tmp/before_projects.txt | |
| echo "$BEFORE_USERS" > /tmp/before_users.txt | |
| echo "[OK] Test data seeded successfully" | |
| - name: Backup database | |
| run: | | |
| echo "[BACKUP] Creating database backup..." | |
| docker exec vitransfer-postgres pg_dump -U vitransfer vitransfer > /tmp/backup_before_upgrade.sql | |
| echo "[OK] Database backed up to /tmp/backup_before_upgrade.sql" | |
| - name: Stop production version | |
| run: | | |
| echo "[STOP] Stopping production version..." | |
| docker compose stop app worker | |
| docker compose rm -f app worker | |
| - name: Upgrade to dev version | |
| run: | | |
| TO_VERSION="${{ steps.versions.outputs.to_version }}" | |
| echo "[UPGRADE] Upgrading to dev version: $TO_VERSION" | |
| # Restore new compose file | |
| mv docker-compose.yml.new docker-compose.yml | |
| # Update compose to use dev tag | |
| sed -i "s/image: crypt010\/vitransfer:latest/image: crypt010\/vitransfer:$TO_VERSION/g" docker-compose.yml | |
| # Show what we're deploying | |
| echo "Docker images to be used:" | |
| grep "image: crypt010/vitransfer" docker-compose.yml | |
| # Pull dev version | |
| docker compose pull app worker | |
| # Start dev version (database and redis are still running) | |
| docker compose up -d app worker | |
| echo "[WAIT] Waiting for dev version to be ready..." | |
| sleep 40 | |
| - name: Verify dev upgrade succeeded | |
| run: | | |
| echo "Checking if dev version is healthy..." | |
| # Wait for health checks | |
| for i in {1..10}; do | |
| APP_HEALTH=$(docker inspect vitransfer-app --format='{{.State.Health.Status}}' 2>/dev/null || echo "starting") | |
| echo "Attempt $i: App health = $APP_HEALTH" | |
| if [[ "$APP_HEALTH" == "healthy" ]]; then | |
| break | |
| fi | |
| sleep 5 | |
| done | |
| # Final health check | |
| APP_HEALTH=$(docker inspect vitransfer-app --format='{{.State.Health.Status}}') | |
| if [[ "$APP_HEALTH" != "healthy" ]]; then | |
| echo "[ERROR] Dev version failed to start" | |
| docker logs vitransfer-app --tail 100 | |
| exit 1 | |
| fi | |
| echo "[OK] Dev version is running" | |
| - name: Verify migrations ran | |
| run: | | |
| echo "Checking if migrations ran successfully..." | |
| docker logs vitransfer-app 2>&1 | grep -i "migration" || true | |
| # Check for migration errors | |
| MIGRATION_ERRORS=$(docker logs vitransfer-app 2>&1 | grep -i "migration.*error" || echo "") | |
| if [[ -n "$MIGRATION_ERRORS" ]]; then | |
| echo "[ERROR] Migration errors detected:" | |
| echo "$MIGRATION_ERRORS" | |
| exit 1 | |
| fi | |
| echo "[OK] No migration errors detected" | |
| - name: Verify data integrity | |
| run: | | |
| echo "[VERIFY] Verifying data integrity after upgrade..." | |
| # Get counts after upgrade | |
| AFTER_PROJECTS=$(docker exec vitransfer-postgres psql -U vitransfer -d vitransfer -t -c "SELECT COUNT(*) FROM \"Project\";" | tr -d ' ') | |
| AFTER_USERS=$(docker exec vitransfer-postgres psql -U vitransfer -d vitransfer -t -c "SELECT COUNT(*) FROM \"User\";" | tr -d ' ') | |
| BEFORE_PROJECTS=$(cat /tmp/before_projects.txt) | |
| BEFORE_USERS=$(cat /tmp/before_users.txt) | |
| echo "After upgrade:" | |
| echo " Projects: $AFTER_PROJECTS (was $BEFORE_PROJECTS)" | |
| echo " Users: $AFTER_USERS (was $BEFORE_USERS)" | |
| # Verify counts match | |
| if [[ "$AFTER_PROJECTS" != "$BEFORE_PROJECTS" ]]; then | |
| echo "[ERROR] Project count mismatch!" | |
| exit 1 | |
| fi | |
| if [[ "$AFTER_USERS" != "$BEFORE_USERS" ]]; then | |
| echo "[ERROR] User count mismatch!" | |
| exit 1 | |
| fi | |
| echo "[OK] Data integrity verified - all counts match" | |
| # Store verified counts for summary (before creating more test data) | |
| echo "$AFTER_PROJECTS" > /tmp/after_projects_verified.txt | |
| echo "$AFTER_USERS" > /tmp/after_users_verified.txt | |
| exit 1 | |
| fi | |
| if [[ "$AFTER_USERS" != "$BEFORE_USERS" ]]; then | |
| echo "[ERROR] User count mismatch!" | |
| exit 1 | |
| fi | |
| echo "[OK] Data integrity verified - all counts match" | |
| - name: Test functionality after upgrade | |
| run: | | |
| echo "[TEST] Testing functionality after upgrade..." | |
| # Test health endpoint | |
| RESPONSE=$(curl -s http://localhost:4321/api/health) | |
| if [[ "$RESPONSE" != *"ok"* ]]; then | |
| echo "[ERROR] Health check failed" | |
| exit 1 | |
| fi | |
| echo "[OK] Health check passed" | |
| # Test login and save token | |
| LOGIN_RESPONSE=$(curl -s -X POST http://localhost:4321/api/auth/login \ | |
| -H "Content-Type: application/json" \ | |
| -d '{"email":"admin@test.local","password":"TestPassword123!"}') | |
| if [[ "$LOGIN_RESPONSE" == *"error"* ]]; then | |
| echo "[ERROR] Login failed after upgrade" | |
| echo "$LOGIN_RESPONSE" | |
| exit 1 | |
| fi | |
| echo "[OK] Login still works" | |
| # Extract accessToken from the tokens object in the response | |
| AUTH_TOKEN=$(echo "$LOGIN_RESPONSE" | grep -o '"accessToken":"[^"]*"' | head -1 | sed 's/"accessToken":"//;s/"$//') | |
| if [[ -z "$AUTH_TOKEN" ]]; then | |
| echo "[ERROR] Failed to extract access token" | |
| exit 1 | |
| fi | |
| echo "$AUTH_TOKEN" > /tmp/auth_token.txt | |
| - name: Test API endpoints after upgrade | |
| run: | | |
| echo "[TEST] Testing API endpoints after upgrade to dev build..." | |
| AUTH_TOKEN=$(cat /tmp/auth_token.txt) | |
| # Test session endpoint | |
| echo "Testing session endpoint..." | |
| SESSION_RESPONSE=$(curl -s http://localhost:4321/api/auth/session \ | |
| -H "Authorization: Bearer $AUTH_TOKEN") | |
| echo "Session response: $SESSION_RESPONSE" | |
| if [[ "$SESSION_RESPONSE" != *"admin@test.local"* ]] || [[ "$SESSION_RESPONSE" == *'"authenticated":false'* ]]; then | |
| echo "[ERROR] Session endpoint failed" | |
| echo "Full session response: $SESSION_RESPONSE" | |
| exit 1 | |
| fi | |
| echo "[OK] Session endpoint working" | |
| # Test projects list endpoint | |
| echo "Testing projects list..." | |
| PROJECTS_RESPONSE=$(curl -s http://localhost:4321/api/projects \ | |
| -H "Authorization: Bearer $AUTH_TOKEN") | |
| if [[ "$PROJECTS_RESPONSE" == *"error"* ]]; then | |
| echo "[ERROR] Projects endpoint failed" | |
| echo "$PROJECTS_RESPONSE" | |
| exit 1 | |
| fi | |
| echo "[OK] Projects endpoint working" | |
| # Verify seeded projects are still there | |
| if [[ "$PROJECTS_RESPONSE" != *"CI Test Project"* ]]; then | |
| echo "[ERROR] Seeded project not found after upgrade!" | |
| exit 1 | |
| fi | |
| echo "[OK] Seeded projects preserved" | |
| # Test users list endpoint | |
| echo "Testing users list..." | |
| USERS_RESPONSE=$(curl -s http://localhost:4321/api/users \ | |
| -H "Authorization: Bearer $AUTH_TOKEN") | |
| if [[ "$USERS_RESPONSE" == *"error"* ]] || [[ "$USERS_RESPONSE" != *"admin@test.local"* ]]; then | |
| echo "[ERROR] Users endpoint failed" | |
| echo "$USERS_RESPONSE" | |
| exit 1 | |
| fi | |
| echo "[OK] Users endpoint working" | |
| # Test settings endpoint | |
| echo "Testing settings endpoint..." | |
| SETTINGS_RESPONSE=$(curl -s http://localhost:4321/api/settings \ | |
| -H "Authorization: Bearer $AUTH_TOKEN") | |
| if [[ "$SETTINGS_RESPONSE" == *"error"* ]]; then | |
| echo "[ERROR] Settings endpoint failed" | |
| echo "$SETTINGS_RESPONSE" | |
| exit 1 | |
| fi | |
| echo "[OK] Settings endpoint working" | |
| # Test analytics endpoint | |
| echo "Testing analytics endpoint..." | |
| ANALYTICS_RESPONSE=$(curl -s http://localhost:4321/api/analytics \ | |
| -H "Authorization: Bearer $AUTH_TOKEN") | |
| if [[ "$ANALYTICS_RESPONSE" == *"error"* ]]; then | |
| echo "[ERROR] Analytics endpoint failed" | |
| echo "$ANALYTICS_RESPONSE" | |
| exit 1 | |
| fi | |
| echo "[OK] Analytics endpoint working" | |
| - name: Test creating new project after upgrade | |
| run: | | |
| echo "[TEST] Testing project creation after upgrade to dev build..." | |
| AUTH_TOKEN=$(cat /tmp/auth_token.txt) | |
| CREATE_PROJECT=$(curl -s -X POST http://localhost:4321/api/projects \ | |
| -H "Authorization: Bearer $AUTH_TOKEN" \ | |
| -H "Content-Type: application/json" \ | |
| -d '{ | |
| "title": "Post-Upgrade Dev Test Project", | |
| "description": "Created after dev upgrade", | |
| "recipientName": "Dev Upgrade Test Client", | |
| "recipientEmail": "devupgrade@test.local", | |
| "sharePassword": "DevPass789", | |
| "authMode": "PASSWORD" | |
| }') | |
| if [[ "$CREATE_PROJECT" == *"error"* ]]; then | |
| echo "[ERROR] Project creation failed after dev upgrade" | |
| echo "$CREATE_PROJECT" | |
| exit 1 | |
| fi | |
| PROJECT_ID=$(echo "$CREATE_PROJECT" | grep -o '"id":"[^"]*"' | head -1 | sed 's/"id":"//;s/"$//') | |
| echo "New project created after dev upgrade with ID: $PROJECT_ID" | |
| echo "$PROJECT_ID" > /tmp/new_project_id.txt | |
| echo "[OK] Project creation still works after dev upgrade" | |
| - name: Test recipient management after upgrade | |
| run: | | |
| echo "[TEST] Testing recipient management after dev upgrade..." | |
| AUTH_TOKEN=$(cat /tmp/auth_token.txt) | |
| PROJECT_ID=$(cat /tmp/new_project_id.txt) | |
| # Test adding recipient | |
| echo "Adding recipient to project..." | |
| ADD_RECIPIENT=$(curl -s -X POST "http://localhost:4321/api/projects/$PROJECT_ID/recipients" \ | |
| -H "Authorization: Bearer $AUTH_TOKEN" \ | |
| -H "Content-Type: application/json" \ | |
| -d '{ | |
| "email": "devrecipient2@test.local", | |
| "name": "Dev Second Recipient", | |
| "isPrimary": false | |
| }') | |
| if [[ "$ADD_RECIPIENT" == *"error"* ]]; then | |
| echo "[ERROR] Failed to add recipient" | |
| echo "$ADD_RECIPIENT" | |
| exit 1 | |
| fi | |
| echo "[OK] Recipient added successfully" | |
| # Test listing recipients | |
| echo "Listing recipients..." | |
| RECIPIENTS=$(curl -s "http://localhost:4321/api/projects/$PROJECT_ID/recipients" \ | |
| -H "Authorization: Bearer $AUTH_TOKEN") | |
| if [[ "$RECIPIENTS" != *"devrecipient2@test.local"* ]]; then | |
| echo "[ERROR] Failed to retrieve recipient" | |
| echo "$RECIPIENTS" | |
| exit 1 | |
| fi | |
| echo "[OK] Recipients list working" | |
| - name: Test user creation after upgrade | |
| run: | | |
| echo "[TEST] Testing user creation after dev upgrade..." | |
| AUTH_TOKEN=$(cat /tmp/auth_token.txt) | |
| # Create new user | |
| CREATE_USER=$(curl -s -X POST http://localhost:4321/api/users \ | |
| -H "Authorization: Bearer $AUTH_TOKEN" \ | |
| -H "Content-Type: application/json" \ | |
| -d '{ | |
| "email": "devnewuser@test.local", | |
| "password": "DevUserPass456!", | |
| "name": "Dev New Test User", | |
| "role": "ADMIN" | |
| }') | |
| if [[ "$CREATE_USER" == *"error"* ]]; then | |
| echo "[ERROR] Failed to create user" | |
| echo "$CREATE_USER" | |
| exit 1 | |
| fi | |
| echo "[OK] User creation working" | |
| # Verify user appears in users list | |
| USERS_LIST=$(curl -s http://localhost:4321/api/users \ | |
| -H "Authorization: Bearer $AUTH_TOKEN") | |
| if [[ "$USERS_LIST" != *"devnewuser@test.local"* ]]; then | |
| echo "[ERROR] New user not found in users list" | |
| exit 1 | |
| fi | |
| echo "[OK] New user verified in database" | |
| - name: Test notification tables after upgrade | |
| run: | | |
| echo "[TEST] Testing notification system tables..." | |
| AUTH_TOKEN=$(cat /tmp/auth_token.txt) | |
| # Query database to verify NotificationQueue table exists | |
| QUEUE_CHECK=$(docker compose -f docker-compose.yml exec -T postgres \ | |
| psql -U vitransfer -d vitransfer -t -c \ | |
| "SELECT EXISTS ( | |
| SELECT FROM information_schema.tables | |
| WHERE table_schema = 'public' | |
| AND table_name = 'NotificationQueue' | |
| );") | |
| if [[ "$QUEUE_CHECK" != *"t"* ]]; then | |
| echo "[ERROR] NotificationQueue table missing" | |
| exit 1 | |
| fi | |
| echo "[OK] NotificationQueue table exists" | |
| # Verify NotificationSchedule table exists | |
| SCHEDULE_CHECK=$(docker compose -f docker-compose.yml exec -T postgres \ | |
| psql -U vitransfer -d vitransfer -t -c \ | |
| "SELECT EXISTS ( | |
| SELECT FROM information_schema.tables | |
| WHERE table_schema = 'public' | |
| AND table_name = 'NotificationSchedule' | |
| );") | |
| if [[ "$SCHEDULE_CHECK" != *"t"* ]]; then | |
| echo "[ERROR] NotificationSchedule table missing" | |
| exit 1 | |
| fi | |
| echo "[OK] NotificationSchedule table exists" | |
| - name: Test project update after upgrade | |
| run: | | |
| echo "[TEST] Testing project update (PATCH) after dev upgrade..." | |
| AUTH_TOKEN=$(cat /tmp/auth_token.txt) | |
| PROJECT_ID=$(cat /tmp/new_project_id.txt) | |
| # Update project properties | |
| UPDATE_PROJECT=$(curl -s -X PATCH "http://localhost:4321/api/projects/$PROJECT_ID" \ | |
| -H "Authorization: Bearer $AUTH_TOKEN" \ | |
| -H "Content-Type: application/json" \ | |
| -d '{ | |
| "title": "Updated Dev Post-Upgrade Project", | |
| "description": "Description updated after dev upgrade test", | |
| "status": "IN_REVIEW" | |
| }') | |
| if [[ "$UPDATE_PROJECT" == *"error"* ]]; then | |
| echo "[ERROR] Failed to update project" | |
| echo "$UPDATE_PROJECT" | |
| exit 1 | |
| fi | |
| echo "[OK] Project update working" | |
| # Verify the update worked | |
| GET_PROJECT=$(curl -s "http://localhost:4321/api/projects/$PROJECT_ID" \ | |
| -H "Authorization: Bearer $AUTH_TOKEN") | |
| if [[ "$GET_PROJECT" != *"Updated Dev Post-Upgrade Project"* ]]; then | |
| echo "[ERROR] Project update not reflected in database" | |
| exit 1 | |
| fi | |
| echo "[OK] Project update verified in database" | |
| - name: Test settings update after upgrade | |
| run: | | |
| echo "[TEST] Testing settings update (PATCH) after dev upgrade..." | |
| AUTH_TOKEN=$(cat /tmp/auth_token.txt) | |
| # Update global settings | |
| UPDATE_SETTINGS=$(curl -s -X PATCH "http://localhost:4321/api/settings" \ | |
| -H "Authorization: Bearer $AUTH_TOKEN" \ | |
| -H "Content-Type: application/json" \ | |
| -d '{ | |
| "companyName": "Dev Upgrade Test Studio", | |
| "defaultPreviewResolution": "1080p", | |
| "defaultWatermarkEnabled": true | |
| }') | |
| if [[ "$UPDATE_SETTINGS" == *"error"* ]]; then | |
| echo "[ERROR] Failed to update settings" | |
| echo "$UPDATE_SETTINGS" | |
| exit 1 | |
| fi | |
| echo "[OK] Settings update working" | |
| # Verify the settings were updated | |
| GET_SETTINGS=$(curl -s "http://localhost:4321/api/settings" \ | |
| -H "Authorization: Bearer $AUTH_TOKEN") | |
| if [[ "$GET_SETTINGS" != *"Dev Upgrade Test Studio"* ]]; then | |
| echo "[ERROR] Settings update not reflected" | |
| exit 1 | |
| fi | |
| echo "[OK] Settings update verified" | |
| - name: Test project-specific analytics after upgrade | |
| run: | | |
| echo "[TEST] Testing project-specific analytics endpoint..." | |
| AUTH_TOKEN=$(cat /tmp/auth_token.txt) | |
| PROJECT_ID=$(cat /tmp/new_project_id.txt) | |
| # Test project-specific analytics endpoint | |
| PROJ_ANALYTICS=$(curl -s "http://localhost:4321/api/analytics/$PROJECT_ID" \ | |
| -H "Authorization: Bearer $AUTH_TOKEN") | |
| if [[ "$PROJ_ANALYTICS" == *"error"* ]]; then | |
| echo "[ERROR] Project analytics endpoint failed" | |
| echo "$PROJ_ANALYTICS" | |
| exit 1 | |
| fi | |
| if [[ "$PROJ_ANALYTICS" != *"stats"* ]] || [[ "$PROJ_ANALYTICS" != *"videoStats"* ]]; then | |
| echo "[ERROR] Project analytics response missing required fields" | |
| exit 1 | |
| fi | |
| echo "[OK] Project-specific analytics working" | |
| - name: Test worker after upgrade | |
| run: | | |
| echo "[TEST] Testing worker after upgrade..." | |
| WORKER_LOGS=$(docker logs vitransfer-worker 2>&1) | |
| if [[ "$WORKER_LOGS" != *"Video processing worker started"* ]]; then | |
| echo "[ERROR] Worker did not start properly after upgrade" | |
| exit 1 | |
| fi | |
| echo "[OK] Worker operational" | |
| - name: Compare database schemas | |
| run: | | |
| echo "[SCHEMA] Comparing database schemas..." | |
| # Get current schema | |
| docker exec vitransfer-postgres pg_dump -U vitransfer --schema-only vitransfer > /tmp/schema_after_upgrade.sql | |
| echo "Schema dump created. Tables present:" | |
| docker exec vitransfer-postgres psql -U vitransfer -d vitransfer -c "\dt" | |
| - name: Generate upgrade summary | |
| if: always() | |
| run: | | |
| # Get data counts for preservation check | |
| PROJECTS_BEFORE=$(cat /tmp/before_projects.txt 2>/dev/null || echo "0") | |
| USERS_BEFORE=$(cat /tmp/before_users.txt 2>/dev/null || echo "0") | |
| PROJECTS_PRESERVED=$(cat /tmp/after_projects_verified.txt 2>/dev/null || echo "0") | |
| USERS_PRESERVED=$(cat /tmp/after_users_verified.txt 2>/dev/null || echo "0") | |
| # Get final counts (after testing new data creation) | |
| PROJECTS_FINAL=$(docker exec vitransfer-postgres psql -U vitransfer -d vitransfer -t -c "SELECT COUNT(*) FROM \"Project\";" 2>/dev/null | tr -d ' ' || echo "0") | |
| USERS_FINAL=$(docker exec vitransfer-postgres psql -U vitransfer -d vitransfer -t -c "SELECT COUNT(*) FROM \"User\";" 2>/dev/null | tr -d ' ' || echo "0") | |
| # Determine data preservation status | |
| if [[ "$PROJECTS_BEFORE" == "$PROJECTS_PRESERVED" ]] && [[ "$USERS_BEFORE" == "$USERS_PRESERVED" ]]; then | |
| DATA_PRESERVATION="[OK] All seeded data preserved" | |
| else | |
| DATA_PRESERVATION="[ERROR] Data loss detected" | |
| fi | |
| # Determine new data creation status | |
| if [[ "$PROJECTS_FINAL" -gt "$PROJECTS_PRESERVED" ]]; then | |
| NEW_DATA_STATUS="[OK] Successfully created new project after upgrade" | |
| else | |
| NEW_DATA_STATUS="[WARN] No new data created in post-upgrade tests" | |
| fi | |
| # Pre-calculate status for preservation table | |
| if [[ "$PROJECTS_BEFORE" == "$PROJECTS_PRESERVED" ]]; then | |
| PROJECTS_STATUS="[OK]" | |
| else | |
| PROJECTS_STATUS="[ERROR]" | |
| fi | |
| if [[ "$USERS_BEFORE" == "$USERS_PRESERVED" ]]; then | |
| USERS_STATUS="[OK]" | |
| else | |
| USERS_STATUS="[ERROR]" | |
| fi | |
| cat >> $GITHUB_STEP_SUMMARY << EOF | |
| # Dev Build Upgrade Test Results | |
| ## Upgrade Path | |
| - **From Version**: \`${{ steps.versions.outputs.from_version }}\` (production) | |
| - **To Version**: \`${{ steps.versions.outputs.to_version }}\` (development) | |
| - **PostgreSQL**: \`${{ steps.versions.outputs.postgres_version }}\` | |
| - **Redis**: \`${{ steps.versions.outputs.redis_version }}\` | |
| ## Data Preservation (Existing Data Survived Upgrade) | |
| | Resource | Before Upgrade | After Upgrade | Status | | |
| |----------|----------------|---------------|--------| | |
| | Projects | ${PROJECTS_BEFORE} | ${PROJECTS_PRESERVED} | ${PROJECTS_STATUS} | | |
| | Users | ${USERS_BEFORE} | ${USERS_PRESERVED} | ${USERS_STATUS} | | |
| **Data Preservation**: ${DATA_PRESERVATION} | |
| ## Post-Upgrade Functionality | |
| | Check | Result | | |
| |-------|--------| | |
| | Final Project Count | ${PROJECTS_FINAL} (started with ${PROJECTS_BEFORE}, created +$((PROJECTS_FINAL - PROJECTS_BEFORE)) in tests) | | |
| | New Data Creation | ${NEW_DATA_STATUS} | | |
| ## Test Results | |
| | Test | Status | | |
| |------|--------| | |
| | Production Deployment | ${{ job.status == 'success' && '[OK] Passed' || '[ERROR] Failed' }} | | |
| | Data Seeding | ${{ job.status == 'success' && '[OK] Passed' || '[ERROR] Failed' }} | | |
| | Database Backup | ${{ job.status == 'success' && '[OK] Passed' || '[ERROR] Failed' }} | | |
| | Upgrade to Dev Build | ${{ job.status == 'success' && '[OK] Passed' || '[ERROR] Failed' }} | | |
| | Database Migrations | ${{ job.status == 'success' && '[OK] Passed' || '[ERROR] Failed' }} | | |
| | Data Verification | ${{ job.status == 'success' && '[OK] Passed' || '[ERROR] Failed' }} | | |
| | API Health Endpoint | ${{ job.status == 'success' && '[OK] Passed' || '[ERROR] Failed' }} | | |
| | Admin Login | ${{ job.status == 'success' && '[OK] Passed' || '[ERROR] Failed' }} | | |
| | Session API | ${{ job.status == 'success' && '[OK] Passed' || '[ERROR] Failed' }} | | |
| | Projects API | ${{ job.status == 'success' && '[OK] Passed' || '[ERROR] Failed' }} | | |
| | Seeded Data Preserved | ${{ job.status == 'success' && '[OK] Passed' || '[ERROR] Failed' }} | | |
| | Users API | ${{ job.status == 'success' && '[OK] Passed' || '[ERROR] Failed' }} | | |
| | Settings API | ${{ job.status == 'success' && '[OK] Passed' || '[ERROR] Failed' }} | | |
| | Analytics API | ${{ job.status == 'success' && '[OK] Passed' || '[ERROR] Failed' }} | | |
| | Project Creation | ${{ job.status == 'success' && '[OK] Passed' || '[ERROR] Failed' }} | | |
| | Recipient Management | ${{ job.status == 'success' && '[OK] Passed' || '[ERROR] Failed' }} | | |
| | User Creation | ${{ job.status == 'success' && '[OK] Passed' || '[ERROR] Failed' }} | | |
| | Notification Tables | ${{ job.status == 'success' && '[OK] Passed' || '[ERROR] Failed' }} | | |
| | Project Update (PATCH) | ${{ job.status == 'success' && '[OK] Passed' || '[ERROR] Failed' }} | | |
| | Settings Update (PATCH) | ${{ job.status == 'success' && '[OK] Passed' || '[ERROR] Failed' }} | | |
| | Project-Specific Analytics | ${{ job.status == 'success' && '[OK] Passed' || '[ERROR] Failed' }} | | |
| | Worker Service | ${{ job.status == 'success' && '[OK] Passed' || '[ERROR] Failed' }} | | |
| EOF | |
| - name: Show upgrade logs on failure | |
| if: failure() | |
| run: | | |
| echo "=== Application Logs (Last 200 lines) ===" | |
| docker logs vitransfer-app --tail 200 | |
| echo "" | |
| echo "=== Worker Logs ===" | |
| docker logs vitransfer-worker --tail 100 | |
| echo "" | |
| echo "=== PostgreSQL Logs ===" | |
| docker logs vitransfer-postgres --tail 50 | |
| echo "" | |
| echo "=== Database Backup (First 50 lines) ===" | |
| head -n 50 /tmp/backup_before_upgrade.sql | |
| - name: Upload backup on failure | |
| if: failure() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: database-backup-before-dev-upgrade | |
| path: /tmp/backup_before_upgrade.sql | |
| retention-days: 7 | |
| - name: Cleanup | |
| if: always() | |
| run: | | |
| docker compose down -v | |
| rm -f .env cookies.txt | |
| rm -f /tmp/before_projects.txt /tmp/before_users.txt | |
| rm -f /tmp/backup_before_upgrade.sql /tmp/schema_after_upgrade.sql |