diff --git a/.checks/pre-push b/.checks/pre-push new file mode 100755 index 0000000..73c6e3c --- /dev/null +++ b/.checks/pre-push @@ -0,0 +1,96 @@ +#!/usr/bin/env bash +# PRE-PUSH +# Check the repo for dependency, language, vulnerability, and build issues + +set -euo pipefail + +# Setting log colours +RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; NC='\033[0m' + +echo -e "${GREEN}Running pre-push checks...${NC}" + +# Start time tracking +START_TIME=$(date +%s) + +# Setting paths +REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)" +CONTENT_DIR="$REPO_ROOT/content" +ZENSICAL_CFG_PATH="$REPO_ROOT/zensical.toml" +SITE_DIR="$REPO_ROOT/deploy" +LOG_DIR="$REPO_ROOT/.checks/logs" +mkdir -p "$LOG_DIR" + +# Cleanup old logs +rm -f "$LOG_DIR/*" + +# Cleanup function +cleanup() { + trap - EXIT INT TERM + if [[ -n "${SERVER_PID:-}" ]] && ps -p "$SERVER_PID" >/dev/null 2>&1; then + kill "$SERVER_PID" >/dev/null 2>&1 || true + for _ in {1..30}; do ps -p "$SERVER_PID" >/dev/null 2>&1 || break; sleep 0.1; done + fi +} +trap cleanup EXIT INT TERM + +# Function to run commands and log output +run_command() { + local cmd="$1" + local logfile="$2" + echo -e "${GREEN}Running ${cmd}...${NC}" + $cmd >"$logfile" 2>&1 || { echo -e "${RED}${cmd} failed. See $logfile${NC}"; exit 1; } +} + +# Running independent checks in parallel +{ + # Trivy check for vulnerabilities + if command -v trivy &>/dev/null; then + run_command "trivy fs . --exit-code 1 --severity CRITICAL,HIGH,MEDIUM,LOW,UNKNOWN --no-progress --scanners vuln" "$LOG_DIR/trivy.log" + else + echo -e "${YELLOW}Trivy not installed. Skipping vulnerability scan.${NC}" + fi +} & + +{ + # Trufflehog check for passwords and secrets + if command -v trufflehog &>/dev/null && command -v jq &>/dev/null; then + TMPF="$(mktemp)" + trufflehog filesystem . --json >"$TMPF" 2>"$LOG_DIR/trufflehog.log" || true + if jq -e 'select(.verified==true)' "$TMPF" | grep -q .; then + cp "$TMPF" "$LOG_DIR/trufflehog-findings.json" + echo -e "${RED}Verified secrets found. See $LOG_DIR/trufflehog-findings.json${NC}" + rm -f "$TMPF"; exit 1 + fi + rm -f "$TMPF" + else + echo -e "${YELLOW}TruffleHog or jq not installed. Skipping secrets scan.${NC}" + fi +} & + +{ + # Dependabot dependency vulnerability check + if command -v npm &>/dev/null && [[ -f package.json ]]; then + run_command "npm audit --audit-level=high" "$LOG_DIR/npm-audit.log" + elif command -v pip &>/dev/null && [[ -f requirements.txt ]]; then + run_command "pip list --outdated" "$LOG_DIR/pip-outdated.log" + if grep -q "upgradable" "$LOG_DIR/pip-outdated.log"; then + echo -e "${YELLOW}Outdated Python dependencies found. See $LOG_DIR/pip-outdated.log${NC}" + fi + else + echo -e "${YELLOW}No dependency management files found. Skipping dependency checks.${NC}" + fi +} & + +# Wait for all background jobs to finish +wait + +# # Build the site using Zensical to check for build errors +# if ! command -v zensical >/dev/null 2>&1; then +# echo -e "${RED}Zensical not installed; cannot build docs.${NC}"; exit 1 +# fi +# run_command "zensical build --clean" "$LOG_DIR/zensical-build.log" + +# End time tracking and calculate duration +END_TIME=$(date +%s) +DURATION=$((END_TIME - START_TIME)) +echo -e "${GREEN}Push checks completed in $DURATION seconds.${NC}" diff --git a/.envrc b/.envrc new file mode 100755 index 0000000..c45df50 --- /dev/null +++ b/.envrc @@ -0,0 +1,34 @@ +#!/bin/bash + +# Check if .venv exists +if [[ -d ".venv" ]]; then + # Activate the virtual environment + export VIRTUAL_ENV="$PWD/.venv" + export PATH="$VIRTUAL_ENV/bin:$PATH" + + # Verify we're using the right Python + if [[ -x "$VIRTUAL_ENV/bin/python3.14" ]]; then + export PYTHONPATH="$PWD/src:$PYTHONPATH" + echo "Activated virtual environment: $VIRTUAL_ENV" + else + echo "Warning: Virtual environment Python not found" + fi + +else + echo "Warning: No .venv directory found" +fi + +# Run pip to update packages inside the venv +echo "Running pip update..." +"$VIRTUAL_ENV/bin/python3.14" -m pip install --upgrade pip +"$VIRTUAL_ENV/bin/python3.14" -m pip install --no-cache-dir --upgrade $(pip list --format=freeze | grep -v '^\-e' | cut -d = -f 1 | tr '\n' ' ') + +# Update requirements.txt with pinned versions only if installs succeeded +if [[ $? -eq 0 ]]; then + "$VIRTUAL_ENV/bin/python3.14" -m pip freeze > requirements.txt + echo "Packages updated successfully" +else + echo "pip install failed; requirements.txt not updated" +fi + +echo "Environment configured with direnv" diff --git a/readme.md b/readme.md index af9cde1..5b8aa7e 100644 --- a/readme.md +++ b/readme.md @@ -1,5 +1,3 @@ - - # Reviews API ![FastAPI](https://img.shields.io/badge/FastAPI-009688?style=flat&logo=FastAPI&logoColor=white) ![Scalar](https://img.shields.io/badge/Scalar-1A1A1A?style=flat&logo=Scalar&logoColor=white) diff --git a/requirements.txt b/requirements.txt index 8a5e498..5d6285f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,14 @@ -fastapi==0.115.0 -uvicorn==0.30.0 -scalar-fastapi==1.8.1 +annotated-doc==0.0.4 +annotated-types==0.7.0 +anyio==4.13.0 +click==8.3.2 +fastapi==0.135.3 +h11==0.16.0 +idna==3.11 +pydantic==2.12.5 +pydantic_core==2.41.5 +scalar_fastapi==1.8.1 +starlette==1.0.0 +typing-inspection==0.4.2 +typing_extensions==4.15.0 +uvicorn==0.44.0