name: Code Check - Quality and Syntax on: push: branches: ["**"] pull_request: branches: ["**"] jobs: syntax-lint: runs-on: ubuntu-latest strategy: matrix: python-version: ["3.11", "3.13", "3.14"] fail-fast: false steps: - name: Checkout uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - name: Install dependencies run: | python -m pip install --upgrade pip if [ -f requirements.txt ]; then pip install -r requirements.txt; fi pip install flake8 - name: Run Python syntax check run: | set -e files=$(git ls-files '*.py') if [ -z "$files" ]; then echo "No Python files to check"; exit 0; fi python -m py_compile $files - name: Run flake8 lint run: | files=$(git ls-files '*.py') if [ -z "$files" ]; then echo "No Python files to lint"; exit 0; fi flake8 $files - name: Check execution (Smoke Test) run: | files=$(git ls-files '*.py') for file in $files; do echo "Testing execution of $file..." # Special-case: run `batch.py` and watch its output for the marker if [ "$file" = "batch.py" ]; then tmp=$(mktemp) # Run the script with line-buffered output to a temp file stdbuf -oL python "$file" >"$tmp" 2>&1 & pid=$! # Start a monitor that follows the temp file and kills the process when pattern seen ( stdbuf -oL tail -F "$tmp" 2>/dev/null | stdbuf -oL grep -m1 --line-buffered ' yt-dlp batch' && kill $pid ) & monitor_pid=$! # Wait up to 5s for the process to exit (or be killed by the monitor) if timeout 5s bash -c 'while kill -0 "$1" 2>/dev/null; do sleep 0.1; done' _ "$pid"; then status=0 else status=$? fi # Stop the monitor and cleanup kill $monitor_pid 2>/dev/null || true wait $monitor_pid 2>/dev/null || true # If the marker was seen in the temp output, treat as success if grep -q ' yt-dlp batch' "$tmp"; then echo "Marker seen in $file output — considered working" rm -f "$tmp" continue fi rm -f "$tmp" # If process exited successfully, continue; otherwise fall back to compile check if [ $status -eq 0 ]; then continue fi if [ $status -eq 124 ]; then echo "Timed out without marker for $file" fi python -m py_compile "$file" status2=$? if [ $status2 -ne 0 ]; then echo "Execution or compile failed for $file (exit $status or $status2)" exit $status2 fi continue fi # Default behavior for other files: try --version with a 5s timeout if timeout 5s python "$file" --version; then status=0 else status=$? fi # If it ran successfully, continue if [ $status -eq 0 ]; then continue fi # If the run timed out (timeout returns 124) and this is with_ui.py, allow it if [ $status -eq 124 ] && [ "$file" = "with_ui.py" ]; then echo "Timed out after 5s for $file — allowed for with_ui.py" continue fi # Otherwise, fall back to a compile check python -m py_compile "$file" status2=$? if [ $status2 -ne 0 ]; then echo "Execution or compile failed for $file (exit $status or $status2)" exit $status2 fi done