Merge pull request #338 from Gfermoto/dev #164
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
| # Автодеплой при push в main. | |
| # Требует: self-hosted runner на сервере BirdLense (см. scripts/setup-auto-deploy.sh). | |
| # Если workflow «висит» в Queued: runner offline или не зарегистрирован с метками self-hosted + birdlense. | |
| name: Deploy | |
| on: | |
| push: | |
| branches: [main] | |
| workflow_dispatch: | |
| concurrency: | |
| group: deploy-main | |
| cancel-in-progress: true | |
| permissions: | |
| contents: read | |
| jobs: | |
| deploy: | |
| runs-on: [self-hosted, birdlense] | |
| timeout-minutes: 45 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| - name: Sync to deploy dir | |
| run: | | |
| DEPLOY_DIR="${DEPLOY_DIR:-/root/BirdLense}" | |
| mkdir -p "$DEPLOY_DIR"/app/data/recordings "$DEPLOY_DIR"/app/data/db "$DEPLOY_DIR"/app/app_config | |
| UC="$DEPLOY_DIR/app/app_config/user_config.yaml" | |
| if [ -f "$UC" ]; then cp "$UC" "${UC}.bak.deploy-$(date +%Y%m%d%H%M%S)"; fi | |
| rsync -a --delete \ | |
| --exclude='.git' \ | |
| --exclude='app/data' \ | |
| --exclude='app/.env' \ | |
| --exclude='app/app_config/user_config.yaml' \ | |
| --filter='P app/app_config/user_config.yaml' \ | |
| --exclude='node_modules' \ | |
| --exclude='__pycache__' \ | |
| --exclude='.venv-docs-tmp' \ | |
| --exclude='.venv-docs' \ | |
| --exclude='site' \ | |
| --exclude='app/.venv' \ | |
| --exclude='.venv-datasets' \ | |
| ./ "$DEPLOY_DIR"/ | |
| - name: Intel GPU compose override | |
| run: | | |
| cd "${DEPLOY_DIR:-/root/BirdLense}/app" | |
| bash scripts/docker-compose-intel-override-gen.sh | |
| - name: Intel GPU perf (PMU / intel_gpu_top) | |
| run: | | |
| cd "${DEPLOY_DIR:-/root/BirdLense}/app" | |
| if [ -f docker-compose.override.yml ]; then | |
| printf '%s\n' 'kernel.perf_event_paranoid=0' | tee /etc/sysctl.d/99-birdlense-perf.conf | |
| sysctl -p /etc/sysctl.d/99-birdlense-perf.conf || true | |
| fi | |
| - name: Build and restart | |
| run: | | |
| cd "${DEPLOY_DIR:-/root/BirdLense}/app" | |
| make stop 2>/dev/null || true | |
| make build | |
| make start | |
| # Optional repo secret: same value as server app/.env BIRDLENSE_UI_API_KEY when strict UI auth is on. | |
| # Enables verify-stack --check-domain-health and verify-release with REQUIRE_SETTINGS_HEALTH=1. | |
| - name: Verify | |
| env: | |
| BIRDLENSE_UI_API_KEY: ${{ secrets.BIRDLENSE_UI_API_KEY }} | |
| run: | | |
| set -euo pipefail | |
| DEPLOY_DIR="${DEPLOY_DIR:-/root/BirdLense}" | |
| ENV_FILE="$DEPLOY_DIR/app/.env" | |
| PORT=8085 | |
| if [ -f "$ENV_FILE" ]; then | |
| V=$(grep -E '^[[:space:]]*BIRDLENSE_PORT=' "$ENV_FILE" | tail -1 || true) | |
| if [ -n "$V" ]; then | |
| PORT="${V#*=}" | |
| PORT="${PORT//\"/}" | |
| PORT="${PORT//\'/}" | |
| fi | |
| fi | |
| BASE_URL="http://127.0.0.1:${PORT}" | |
| echo "Verify stack: ${BASE_URL}" | |
| sleep 10 | |
| VERIFY_ARGS=(--base-url "$BASE_URL") | |
| if [ -n "${BIRDLENSE_UI_API_KEY:-}" ]; then | |
| VERIFY_ARGS+=(--check-domain-health) | |
| fi | |
| cd "$DEPLOY_DIR" | |
| BIRDLENSE_UI_API_KEY="${BIRDLENSE_UI_API_KEY:-}" scripts/verify-stack.sh "${VERIFY_ARGS[@]}" | |
| if [ -n "${BIRDLENSE_UI_API_KEY:-}" ]; then | |
| REQUIRE_SETTINGS_HEALTH=1 BIRDLENSE_UI_API_KEY="${BIRDLENSE_UI_API_KEY}" BASE_URL="${BASE_URL}" \ | |
| scripts/verify-release.sh | |
| fi | |
| - name: Test recognition (optional) | |
| if: success() | |
| continue-on-error: true | |
| run: | | |
| VIDEO=$(find "${DEPLOY_DIR:-/root/BirdLense}/app/data/recordings" -name "video.mp4" -printf "%T@ %p\n" 2>/dev/null | sort -rn | head -1 | cut -d' ' -f2) | |
| [ -n "$VIDEO" ] || exit 0 | |
| CONTAINER_VIDEO="/app/data/recordings/${VIDEO#*recordings/}" | |
| docker exec birdlense python /app/processor/src/main.py "$CONTAINER_VIDEO" --fake-motion true |