www: эволюция дизайна лендинга (taste-redesign + taste-frontend) #34
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: Deploy WWW to Main Bucket | |
| on: | |
| push: | |
| branches: | |
| - main | |
| paths: | |
| - 'www/**' | |
| workflow_dispatch: | |
| # Общая группа с release-full.yml: оба workflow пишут index.html в MAIN bucket | |
| concurrency: | |
| group: site-deploy | |
| cancel-in-progress: false | |
| jobs: | |
| deploy: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| # Skip if commit message contains [skip ci] | |
| if: "!contains(github.event.head_commit.message, '[skip ci]')" | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6 | |
| with: | |
| fetch-depth: 0 | |
| # AWS CLI v2 предустановлен на ubuntu-latest | |
| - name: Verify AWS CLI | |
| run: aws --version | |
| - name: Configure AWS CLI for Yandex Cloud | |
| env: | |
| AWS_ACCESS_KEY_ID: ${{ secrets.YANDEX_STORAGE_KEY_ID }} | |
| AWS_SECRET_ACCESS_KEY: ${{ secrets.YANDEX_STORAGE_SECRET_KEY }} | |
| run: | | |
| aws configure set aws_access_key_id $AWS_ACCESS_KEY_ID | |
| aws configure set aws_secret_access_key $AWS_SECRET_ACCESS_KEY | |
| aws configure set default.region ru-central1 | |
| - name: Show changed files | |
| run: | | |
| echo "📁 Files in www/:" | |
| ls -la www/ | |
| - name: Minify index.html for deploy | |
| run: | | |
| echo "🔨 Minifying www/index.html for deploy..." | |
| # Размер до минификации | |
| BEFORE=$(stat -c%s www/index.html) | |
| echo "📄 Before: $BEFORE bytes" | |
| # Минификация HTML (только для загрузки, не коммитим) | |
| npx --yes html-minifier-terser \ | |
| --collapse-whitespace \ | |
| --preserve-line-breaks \ | |
| --remove-comments \ | |
| --remove-redundant-attributes \ | |
| --remove-script-type-attributes \ | |
| --remove-style-link-type-attributes \ | |
| --minify-css true \ | |
| --minify-js true \ | |
| --input-dir www \ | |
| --output-dir www \ | |
| --file-ext html | |
| # Размер после минификации | |
| AFTER=$(stat -c%s www/index.html) | |
| SAVED=$((BEFORE - AFTER)) | |
| PERCENT=$((SAVED * 100 / BEFORE)) | |
| echo "📄 After: $AFTER bytes" | |
| echo "✅ Saved: $SAVED bytes ($PERCENT%)" | |
| # ВАЖНО: deploy-www.yml НЕ коммитит изменения, | |
| # поэтому минифицированная версия НЕ попадёт в репо | |
| - name: Update sitemap.xml dates for changed files | |
| env: | |
| BEFORE_SHA: ${{ github.event.before }} | |
| CURRENT_SHA: ${{ github.sha }} | |
| run: | | |
| echo "📝 Updating sitemap.xml for changed files..." | |
| TODAY=$(date -u +"%Y-%m-%d") | |
| # Get changed files | |
| CHANGED=$(git diff --name-only "$BEFORE_SHA" "$CURRENT_SHA" -- www/ 2>/dev/null || git diff --name-only HEAD~1 HEAD -- www/ 2>/dev/null || true) | |
| for file in $CHANGED; do | |
| # Skip sitemap.xml itself | |
| [ "$file" = "www/sitemap.xml" ] && continue | |
| # Get URL path (e.g., www/llm-prompt.md -> llm-prompt.md, www/index.html -> /) | |
| URL_PATH="${file#www/}" | |
| if [ "$URL_PATH" = "index.html" ]; then | |
| URL_PATH="" | |
| fi | |
| # Update lastmod for this URL in sitemap if exists | |
| if grep -q "https://prefetch.ru/${URL_PATH}" www/sitemap.xml 2>/dev/null; then | |
| echo " 📅 Updating date for: ${URL_PATH:-/}" | |
| # Update the lastmod after the matching loc | |
| sed -i "/<loc>https:\/\/prefetch\.ru\/${URL_PATH//\//\\/}<\/loc>/,/<\/url>/ s|<lastmod>[0-9-]*</lastmod>|<lastmod>${TODAY}</lastmod>|" www/sitemap.xml | |
| fi | |
| done | |
| echo "✅ Sitemap updated" | |
| cat www/sitemap.xml | |
| - name: Find changed files in www/ | |
| id: changes | |
| env: | |
| BEFORE_SHA: ${{ github.event.before }} | |
| CURRENT_SHA: ${{ github.sha }} | |
| run: | | |
| echo "🔍 Finding changed files in www/..." | |
| # Get changed files (added, modified) | |
| CHANGED=$(git diff --name-only "$BEFORE_SHA" "$CURRENT_SHA" -- www/ 2>/dev/null | grep -v '^$' || true) | |
| # Get deleted files | |
| DELETED=$(git diff --name-only --diff-filter=D "$BEFORE_SHA" "$CURRENT_SHA" -- www/ 2>/dev/null | grep -v '^$' || true) | |
| # Fallback: if before is empty (first push), compare with HEAD~1 | |
| if [ -z "$CHANGED" ] && [ -z "$DELETED" ]; then | |
| CHANGED=$(git diff --name-only HEAD~1 HEAD -- www/ 2>/dev/null | grep -v '^$' || true) | |
| DELETED=$(git diff --name-only --diff-filter=D HEAD~1 HEAD -- www/ 2>/dev/null | grep -v '^$' || true) | |
| fi | |
| # Save to files for next step | |
| echo "$CHANGED" > /tmp/changed_files.txt | |
| echo "$DELETED" > /tmp/deleted_files.txt | |
| echo "📝 Changed files:" | |
| cat /tmp/changed_files.txt | |
| echo "" | |
| echo "🗑️ Deleted files:" | |
| cat /tmp/deleted_files.txt | |
| # Count files | |
| if [ -n "$CHANGED" ]; then | |
| CHANGED_COUNT=$(echo "$CHANGED" | wc -l | tr -d ' ') | |
| else | |
| CHANGED_COUNT=0 | |
| fi | |
| if [ -n "$DELETED" ]; then | |
| DELETED_COUNT=$(echo "$DELETED" | wc -l | tr -d ' ') | |
| else | |
| DELETED_COUNT=0 | |
| fi | |
| echo "changed_count=$CHANGED_COUNT" >> $GITHUB_OUTPUT | |
| echo "deleted_count=$DELETED_COUNT" >> $GITHUB_OUTPUT | |
| - name: Deploy changed files to MAIN bucket | |
| env: | |
| BUCKET: ${{ secrets.YANDEX_STORAGE_BUCKET_MAIN }} | |
| ENDPOINT: ${{ secrets.YANDEX_STORAGE_ENDPOINT }} | |
| EVENT_NAME: ${{ github.event_name }} | |
| run: | | |
| # Ручной запуск - полная синхронизация: diff последнего коммита не догоняет | |
| # файлы, потерянные упавшими деплоями, и bucket тихо расходится с репо | |
| if [ "$EVENT_NAME" = "workflow_dispatch" ]; then | |
| echo "📤 Ручной запуск - полная синхронизация www/ с bucket" | |
| aws s3 sync www/ "s3://${BUCKET}/" \ | |
| --endpoint-url ${ENDPOINT} \ | |
| --delete | |
| echo "✅ Полная синхронизация завершена" | |
| exit 0 | |
| fi | |
| echo "📤 Deploying changed files to MAIN bucket: $BUCKET" | |
| # Upload changed/added files | |
| while IFS= read -r file; do | |
| [ -z "$file" ] && continue | |
| if [ -f "$file" ]; then | |
| S3_PATH="${file#www/}" | |
| echo " 📄 Uploading: $file → $S3_PATH" | |
| aws s3 cp "$file" "s3://${BUCKET}/${S3_PATH}" \ | |
| --endpoint-url ${ENDPOINT} | |
| fi | |
| done < /tmp/changed_files.txt | |
| # Delete removed files | |
| while IFS= read -r file; do | |
| [ -z "$file" ] && continue | |
| S3_PATH="${file#www/}" | |
| echo " 🗑️ Deleting: $S3_PATH" | |
| aws s3 rm "s3://${BUCKET}/${S3_PATH}" \ | |
| --endpoint-url ${ENDPOINT} || true | |
| done < /tmp/deleted_files.txt | |
| echo "✅ Deployment complete" | |
| - name: Upload updated sitemap.xml | |
| env: | |
| BUCKET: ${{ secrets.YANDEX_STORAGE_BUCKET_MAIN }} | |
| ENDPOINT: ${{ secrets.YANDEX_STORAGE_ENDPOINT }} | |
| run: | | |
| echo "📤 Uploading updated sitemap.xml..." | |
| aws s3 cp www/sitemap.xml "s3://${BUCKET}/sitemap.xml" \ | |
| --endpoint-url ${ENDPOINT} | |
| echo "✅ Sitemap uploaded" | |
| - name: Verify deployment | |
| env: | |
| BUCKET: ${{ secrets.YANDEX_STORAGE_BUCKET_MAIN }} | |
| ENDPOINT: ${{ secrets.YANDEX_STORAGE_ENDPOINT }} | |
| run: | | |
| echo "📊 Deployment summary:" | |
| echo " - Changed files uploaded: ${{ steps.changes.outputs.changed_count }}" | |
| echo " - Deleted files removed: ${{ steps.changes.outputs.deleted_count }}" | |
| echo "" | |
| echo "📁 Contents of MAIN bucket:" | |
| aws s3 ls s3://${BUCKET}/ \ | |
| --endpoint-url ${ENDPOINT} \ | |
| --recursive \ | |
| --human-readable | |
| - name: Deployment Summary | |
| env: | |
| BUCKET: ${{ secrets.YANDEX_STORAGE_BUCKET_MAIN }} | |
| run: | | |
| echo "" | |
| echo "==========================================" | |
| echo "🎉 WWW Deployment Complete!" | |
| echo "==========================================" | |
| echo "Bucket: $BUCKET" | |
| echo "Commit: ${{ github.sha }}" | |
| echo "Date: $(date -u +%Y-%m-%d\ %H:%M:%S\ UTC)" | |
| echo "==========================================" |