Files
TimeTracker/scripts/validate-setup.py
T
Dries Peeters 4a8607f400 feat: Add major feature updates - integrations, services, and utilities
- Add Google Calendar integration with OAuth 2.0 support
- Implement integration service and workflow engine
- Add new routes: auth, clients, custom_reports, integrations, invoices, team_chat
- Add utility modules: config_manager, email, excel_export, file_upload, permissions_seed
- Add integration view template
- Add Docker permission fixes and enhanced start scripts
- Add migration management utilities and legacy schema migration
- Add validation and version management scripts
- Update setup.py version to 4.9.16

This release significantly expands the application's integration capabilities,
adds new business logic services, and improves infrastructure tooling.
2026-01-09 22:42:53 +01:00

284 lines
8.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
"""
TimeTracker CI/CD Setup Validation Script
Validates that all CI/CD components are properly configured
"""
import os
import sys
import subprocess
from pathlib import Path
class Colors:
"""ANSI color codes for terminal output"""
GREEN = '\033[92m'
RED = '\033[91m'
YELLOW = '\033[93m'
BLUE = '\033[94m'
ENDC = '\033[0m'
BOLD = '\033[1m'
def print_header(text):
"""Print a formatted header"""
print(f"\n{Colors.BOLD}{Colors.BLUE}{'=' * 60}{Colors.ENDC}")
print(f"{Colors.BOLD}{Colors.BLUE}{text:^60}{Colors.ENDC}")
print(f"{Colors.BOLD}{Colors.BLUE}{'=' * 60}{Colors.ENDC}\n")
def print_success(text):
"""Print success message"""
print(f"{Colors.GREEN}{Colors.ENDC} {text}")
def print_error(text):
"""Print error message"""
print(f"{Colors.RED}{Colors.ENDC} {text}")
def print_warning(text):
"""Print warning message"""
print(f"{Colors.YELLOW}{Colors.ENDC} {text}")
def print_info(text):
"""Print info message"""
print(f"{Colors.BLUE}{Colors.ENDC} {text}")
def check_file_exists(filepath, required=True):
"""Check if a file exists"""
path = Path(filepath)
if path.exists():
print_success(f"Found: {filepath}")
return True
else:
if required:
print_error(f"Missing required file: {filepath}")
else:
print_warning(f"Optional file not found: {filepath}")
return False
def check_python_package(package_name):
"""Check if a Python package is installed"""
try:
__import__(package_name)
print_success(f"Python package '{package_name}' is installed")
return True
except ImportError:
print_error(f"Python package '{package_name}' is NOT installed")
return False
def run_command(command, description):
"""Run a command and check if it succeeds
Args:
command: Command string or list of command arguments
description: Human-readable description
"""
import shlex
try:
# If command is a string, split it safely
if isinstance(command, str):
try:
cmd_list = shlex.split(command)
except ValueError:
# Fallback to simple split
cmd_list = command.split()
else:
cmd_list = command
result = subprocess.run(
cmd_list,
capture_output=True,
text=True,
timeout=30
)
if result.returncode == 0:
print_success(f"{description}: OK")
return True
else:
print_error(f"{description}: FAILED")
if result.stderr:
print(f" Error: {result.stderr[:200]}")
return False
except subprocess.TimeoutExpired:
print_error(f"{description}: TIMEOUT")
return False
except Exception as e:
print_error(f"{description}: ERROR ({str(e)})")
return False
def main():
"""Main validation function"""
print_header("TimeTracker CI/CD Setup Validation")
# Track results
checks = {
'workflows': [],
'tests': [],
'config': [],
'docs': [],
'python': []
}
# 1. Check GitHub Actions workflows
print_header("1. GitHub Actions Workflows")
workflows = [
'.github/workflows/ci-comprehensive.yml',
'.github/workflows/cd-development.yml',
'.github/workflows/cd-release.yml',
'.github/workflows/docker-publish.yml',
'.github/workflows/migration-check.yml',
]
for workflow in workflows:
checks['workflows'].append(check_file_exists(workflow))
# 2. Check test files
print_header("2. Test Files")
test_files = [
'tests/conftest.py',
'tests/test_basic.py',
'tests/test_routes.py',
'tests/test_models_comprehensive.py',
'tests/test_security.py',
'tests/test_analytics.py',
'tests/test_invoices.py',
]
for test_file in test_files:
checks['tests'].append(check_file_exists(test_file))
# 3. Check configuration files
print_header("3. Configuration Files")
config_files = [
('pytest.ini', True),
('requirements-test.txt', True),
('.pre-commit-config.yaml', False),
('Makefile', False),
('.gitignore', True),
]
for config_file, required in config_files:
checks['config'].append(check_file_exists(config_file, required))
# 4. Check documentation
print_header("4. Documentation")
docs = [
'CI_CD_DOCUMENTATION.md',
'CI_CD_QUICK_START.md',
'CI_CD_IMPLEMENTATION_SUMMARY.md',
]
for doc in docs:
checks['docs'].append(check_file_exists(doc))
# 5. Check Python dependencies
print_header("5. Python Dependencies")
packages = [
'pytest',
'flask',
'sqlalchemy',
]
for package in packages:
checks['python'].append(check_python_package(package))
# 6. Check Python test dependencies
print_header("6. Test Dependencies")
test_packages = [
'pytest',
'pytest_cov',
'pytest_flask',
'black',
'flake8',
'bandit',
]
test_deps_ok = True
for package in test_packages:
if not check_python_package(package.replace('_', '-')):
test_deps_ok = False
if not test_deps_ok:
print_info("Install test dependencies: pip install -r requirements-test.txt")
# 7. Run quick tests
print_header("7. Quick Test Validation")
# Check if pytest can discover tests
if run_command(['pytest', '--collect-only', '-q'], 'Test discovery'):
print_info("Tests can be discovered successfully")
# Try to run smoke tests (if they exist)
if run_command(['pytest', '-m', 'smoke', '--co', '-q'], 'Smoke test discovery'):
print_info("Smoke tests are properly marked")
# 8. Check Docker setup
print_header("8. Docker Configuration")
docker_files = [
('Dockerfile', True),
('docker-compose.yml', True),
('.dockerignore', False),
]
for docker_file, required in docker_files:
check_file_exists(docker_file, required)
# 9. Check helper scripts
print_header("9. Helper Scripts")
scripts = [
'scripts/run-tests.sh',
'scripts/run-tests.bat',
]
for script in scripts:
check_file_exists(script, required=False)
# 10. Summary
print_header("Validation Summary")
total_checks = sum(len(v) for v in checks.values())
passed_checks = sum(sum(v) for v in checks.values())
print(f"\n{Colors.BOLD}Results:{Colors.ENDC}")
print(f" Workflows: {sum(checks['workflows'])}/{len(checks['workflows'])}")
print(f" Tests: {sum(checks['tests'])}/{len(checks['tests'])}")
print(f" Configuration: {sum(checks['config'])}/{len(checks['config'])}")
print(f" Documentation: {sum(checks['docs'])}/{len(checks['docs'])}")
print(f" Python deps: {sum(checks['python'])}/{len(checks['python'])}")
print(f"\n{Colors.BOLD}Total: {passed_checks}/{total_checks}{Colors.ENDC}")
if passed_checks == total_checks:
print(f"\n{Colors.GREEN}{Colors.BOLD}✓ All checks passed! CI/CD setup is complete.{Colors.ENDC}")
print(f"\n{Colors.BOLD}Next steps:{Colors.ENDC}")
print(" 1. Run smoke tests: pytest -m smoke")
print(" 2. Create a test PR to verify CI works")
print(" 3. Review documentation: CI_CD_QUICK_START.md")
return 0
else:
failed = total_checks - passed_checks
print(f"\n{Colors.YELLOW}{Colors.BOLD}⚠ Setup incomplete: {failed} checks failed{Colors.ENDC}")
print(f"\n{Colors.BOLD}Action required:{Colors.ENDC}")
print(" 1. Review errors above")
print(" 2. Install missing dependencies: pip install -r requirements-test.txt")
print(" 3. Check documentation: CI_CD_DOCUMENTATION.md")
return 1
if __name__ == '__main__':
try:
sys.exit(main())
except KeyboardInterrupt:
print(f"\n\n{Colors.YELLOW}Validation interrupted by user{Colors.ENDC}")
sys.exit(130)
except Exception as e:
print(f"\n{Colors.RED}Validation failed with error: {e}{Colors.ENDC}")
sys.exit(1)