Skip to content

fix:meliisearch api, added in config file, readme for getting/creatin… #286

fix:meliisearch api, added in config file, readme for getting/creatin…

fix:meliisearch api, added in config file, readme for getting/creatin… #286

Workflow file for this run

name: Build and Deploy
on:
push:
branches: [main]
workflow_dispatch: # Allows manual triggering
jobs:
build-and-deploy:
# Prod
# runs-on: ubuntu-latest
# Self hosted
runs-on: self-hosted
environment: production # This tells GitHub to use the production environment secrets
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
# fetch-depth: 0 is recommended for a more reliable diff across multiple commits in a push
fetch-depth: 0
lfs: true
- name: Verify LFS and database file
run: |
echo "🔎 Verifying Git LFS and SQLite DB presence..."
git lfs version || true
echo "LFS-tracked files:"
git lfs ls-files || true
echo "Listing DB directories:"
ls -l ./db || true
ls -l ./frontend/db || true
echo "File type of DB files (if present):"
for f in ./db/*.db ./frontend/db/*.db; do
if [ -f "$f" ]; then file "$f" || true; fi
done
- name: Pull LFS objects explicitly (workaround)
run: |
echo "⬇️ Pulling LFS objects explicitly..."
git lfs pull --include="db/**,frontend/db/**" || git lfs pull || true
- name: Detect changed sections
id: detect-changes
run: |
echo "🔍 Detecting changes based on custom build rules..."
# Use a more robust diff command that covers all commits in a push
all_changed=$(git diff --name-only ${{ github.event.before }} ${{ github.event.after }} || git diff --name-only HEAD~1 HEAD)
if [ -z "$all_changed" ]; then
echo "❌ No changes detected. Skipping build and deploy."
echo "should_deploy=false" >> $GITHUB_OUTPUT
exit 0
fi
echo "📁 All changed files:"
echo "$all_changed" | sed 's/^/ - /'
changed_dirs=""
requires_full_rebuild=false
# Helper function to add a directory to the list if it's not already there
add_dir() {
if [[ ! "$changed_dirs" =~ (^|[[:space:]])$1($|[[:space:]]) ]]; then
changed_dirs="$changed_dirs $1"
fi
}
for file in $all_changed; do
case "$file" in
frontend/src/pages/t/*)
add_dir "t"
;;
frontend/src/pages/markdown_pages/tldr/*|frontend/src/pages/tldr/*)
add_dir "markdown_pages"
add_dir "tldr"
;;
frontend/src/pages/html_pages/cheatsheets/*|frontend/src/pages/c/*)
add_dir "html_pages"
add_dir "c"
;;
frontend/src/pages/svg_icons/*)
add_dir "svg_icons"
;;
frontend/src/pages/png_icons/*)
# If png_icons changes, we build both png_icons and svg_icons
add_dir "png_icons"
add_dir "svg_icons"
;;
frontend/src/pages/emojies/*)
add_dir "emojies"
;;
frontend/src/pages/cars/*)
add_dir "cars"
;;
frontend/src/pages/mcp/*)
add_dir "mcp"
;;
frontend/public/mcp/*)
add_dir "mcp"
;;
frontend/src/pages/index.astro)
# Index page changes only need to rebuild the index page
add_dir "index_only"
;;
frontend/public/*)
# Public assets are served directly, just sync without rebuild
add_dir "public_assets_only"
;;
frontend/src/*)
# Other src changes (components, layouts, styles, etc.) need full rebuild
requires_full_rebuild=true
;;
*)
# You can add a default case here if needed, for example, to build everything
# echo "Change detected in unhandled path: $file"
;;
esac
done
# Clean up leading/trailing whitespace
changed_dirs=$(echo "$changed_dirs" | xargs)
# Determine final build strategy
if [ "$requires_full_rebuild" = true ]; then
echo "🔧 Components/layouts/styles changed - requires full rebuild"
echo "📦 Build strategy: full_rebuild"
echo "should_deploy=true" >> $GITHUB_OUTPUT
echo "changed_sections=full_rebuild" >> $GITHUB_OUTPUT
elif [ -n "$changed_dirs" ]; then
echo "📦 Changed sections to build: $changed_dirs"
echo "should_deploy=true" >> $GITHUB_OUTPUT
echo "changed_sections=$changed_dirs" >> $GITHUB_OUTPUT
else
echo "❌ No changes matched the build rules. Skipping deployment."
echo "should_deploy=false" >> $GITHUB_OUTPUT
fi
# - name: Setup Bun
# if: steps.detect-changes.outputs.should_deploy == 'true'
# uses: oven-sh/setup-bun@v1
# with:
# bun-version: "1.1.34"
# - name: Cache Bun dependencies
# if: steps.detect-changes.outputs.should_deploy == 'true'
# uses: actions/cache@v4
# with:
# path: ~/.bun
# key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lockb') }}
# restore-keys: |
# ${{ runner.os }}-bun-
- name: Setup Node.js
if: steps.detect-changes.outputs.should_deploy == 'true'
uses: actions/setup-node@v4
with:
node-version: "22.17.0"
- name: Exclude unchanged sections from build
if: steps.detect-changes.outputs.should_deploy == 'true'
run: |
echo "🔧 Excluding unchanged sections from build..."
cd frontend/src/pages
changed_sections="${{ steps.detect-changes.outputs.changed_sections }}"
echo "Building strategy: $changed_sections"
# Only exclude sections if we're doing selective page builds
if [[ "$changed_sections" != "full_rebuild" && "$changed_sections" != "public_assets_only" && "$changed_sections" != "index_only" ]]; then
echo "🎯 Selective build mode"
for dir in */; do
if [ -d "$dir" ]; then
dir_name=${dir%/}
if [[ "$changed_sections" =~ (^|[[:space:]])$dir_name($|[[:space:]]) ]] || [[ "$dir_name" == _* ]]; then
echo "✅ Including: $dir_name"
else
echo "❌ Excluding: $dir_name -> _$dir_name"
mv "$dir" "_$dir"
fi
fi
done
elif [[ "$changed_sections" == "full_rebuild" ]]; then
echo "🔧 Full rebuild mode - building all sections"
for dir in */; do
if [ -d "$dir" ]; then
dir_name=${dir%/}
echo "✅ Including: $dir_name"
fi
done
elif [[ "$changed_sections" == "index_only" ]]; then
echo "🏠 Index page only mode - excluding all other pages"
for dir in */; do
if [ -d "$dir" ]; then
dir_name=${dir%/}
if [[ "$dir_name" == _* ]]; then
echo "✅ Keeping excluded: $dir_name"
else
echo "❌ Excluding: $dir_name -> _$dir_name"
mv "$dir" "_$dir"
fi
fi
done
else
echo "🔧 Public assets only mode - no page exclusions needed"
fi
# - name: Install dependencies
# if: steps.detect-changes.outputs.should_deploy == 'true' && steps.detect-changes.outputs.changed_sections != 'public_assets_only'
# run: |
# echo "📦 Installing dependencies with Bun..."
# cd frontend
# bun install
- name: Install dependencies
if: steps.detect-changes.outputs.should_deploy == 'true' && steps.detect-changes.outputs.changed_sections != 'public_assets_only'
run: |
echo "📦 Installing dependencies..."
cd frontend
npm install
- name: Clean dist directory
if: steps.detect-changes.outputs.should_deploy == 'true' && steps.detect-changes.outputs.changed_sections != 'public_assets_only'
run: |
echo "🧹 Cleaning dist directory before build..."
cd frontend
rm -rf dist
mkdir -p dist
# - name: Build project
# if: steps.detect-changes.outputs.should_deploy == 'true' && steps.detect-changes.outputs.changed_sections != 'public_assets_only'
# run: |
# echo "🔨 Building project with Bun..."
# cd frontend
# bun run astro build
- name: Build project
if: steps.detect-changes.outputs.should_deploy == 'true' && steps.detect-changes.outputs.changed_sections != 'public_assets_only'
run: |
echo "🔨 Building project..."
cd frontend
npx astro build
env:
NODE_OPTIONS: "--max-old-space-size=16384"
UV_THREADPOOL_SIZE: "16"
PUBLIC_GA_ID: ${{ secrets.PUBLIC_GA_ID }}
MEILISEARCH_API_KEY: ${{ secrets.MEILISEARCH_API_KEY }}
- name: Restore original folder structure
if: always() && steps.detect-changes.outputs.should_deploy == 'true'
run: |
echo "🔄 Restoring original folder structure..."
cd frontend/src/pages
for dir in _*/; do
if [ -d "$dir" ]; then
original_name=${dir#_}
original_name=${original_name%/}
echo "Restoring _$original_name to $original_name"
mv "$dir" "$original_name/"
fi
done
- name: Setup SSH
if: steps.detect-changes.outputs.should_deploy == 'true'
uses: webfactory/ssh-agent@v0.8.0
with:
ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}
- name: Add server to known hosts
if: steps.detect-changes.outputs.should_deploy == 'true'
run: |
ssh-keyscan -H ${{ secrets.SSH_HOST }} >> ~/.ssh/known_hosts
- name: Deploy to server
if: steps.detect-changes.outputs.should_deploy == 'true'
run: |
echo "🚀 Deploying to server..."
echo "Deployed sections: ${{ steps.detect-changes.outputs.changed_sections }}"
changed_sections="${{ steps.detect-changes.outputs.changed_sections }}"
if [[ "$changed_sections" == "public_assets_only" ]]; then
echo "📁 Only public assets changed - syncing files only"
rsync -rvz --delete --no-perms --no-owner --no-group --no-times --progress ./frontend/public/ ${{ secrets.SSH_USERNAME }}@${{ secrets.SSH_HOST }}:/tools/
elif [[ "$changed_sections" == "full_rebuild" ]]; then
echo "📦 Full deployment - deleting old files on server"
rsync -rvz --delete --no-perms --no-owner --no-group --no-times --progress ./frontend/dist/ ${{ secrets.SSH_USERNAME }}@${{ secrets.SSH_HOST }}:/tools/
else
echo "📦 Partial deployment - keeping existing files on server"
rsync -rvz --no-perms --no-owner --no-group --no-times --progress ./frontend/dist/ ${{ secrets.SSH_USERNAME }}@${{ secrets.SSH_HOST }}:/tools/
fi
- name: Purge entire Cloudflare cache
if: steps.detect-changes.outputs.should_deploy == 'true'
run: |
echo "Purging entire Cloudflare cache..."
RESPONSE=$(curl -s -X POST "https://api.cloudflare.com/client/v4/zones/${{ secrets.CLOUDFLARE_ZONE_ID }}/purge_cache" \
-H "Authorization: Bearer ${{ secrets.CLOUDFLARE_CACHE_PURGE_API_KEY }}" \
-H "Content-Type: application/json" \
--data '{"purge_everything":true}')
echo "Response:"
echo "$RESPONSE"
- name: Generate search index data and deploy to server
run: |
echo "🔍 Generating search index data..."
cd search-index
make sync-search-index
echo "✅ Search index generation completed"
- name: Skip deployment message
if: steps.detect-changes.outputs.should_deploy == 'false'
run: |
echo "⏭️ Skipping deployment - no changes matched the build rules."