feat(README): update the format #14
Workflow file for this run
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
| name: Tests | |
| on: | |
| push: | |
| branches: [ master, main ] | |
| pull_request: | |
| branches: [ master, main ] | |
| jobs: | |
| lint: | |
| runs-on: ubuntu-latest | |
| strategy: | |
| matrix: | |
| python-version: ['3.9', '3.10', '3.11', '3.12', '3.13'] | |
| steps: | |
| - 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 | |
| pip install -e ".[dev]" | |
| - name: Run flake8 | |
| run: | | |
| flake8 ioc/ tests/ | |
| - name: Run mypy (optional) | |
| run: | | |
| mypy ioc/ || true | |
| continue-on-error: true | |
| test-core: | |
| runs-on: ubuntu-latest | |
| strategy: | |
| matrix: | |
| python-version: ['3.9', '3.10', '3.11', '3.12', '3.13'] | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Python ${{ matrix.python-version }} | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| - name: Install core dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -e . | |
| - name: Run core tests (excluding extras) | |
| run: | | |
| # Run only core tests, excluding extra package tests | |
| python -m unittest discover -s tests -p "test_*.py" -v 2>&1 | grep -v "extra\." | tee test_output.txt | |
| # Check results | |
| if grep -q "FAILED" test_output.txt; then | |
| echo "Core tests failed" | |
| exit 1 | |
| fi | |
| test-with-specific-extras: | |
| runs-on: ubuntu-latest | |
| strategy: | |
| matrix: | |
| python-version: ['3.9', '3.11'] | |
| include: | |
| - extras: 'flask' | |
| test_module: 'tests.ioc_test.extra.flask' | |
| - extras: 'jinja2' | |
| test_module: 'tests.ioc_test.extra.jinja' | |
| - extras: 'redis' | |
| test_module: 'tests.ioc_test.extra.redis' | |
| steps: | |
| - 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 with ${{ matrix.extras }} | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -e ".[${{ matrix.extras }}]" | |
| - name: Check if extras tests exist and dependencies are available | |
| id: check_tests | |
| run: | | |
| # Check if test module exists and can be imported | |
| python -c " | |
| import os | |
| import sys | |
| import importlib.util | |
| test_path = '${{ matrix.test_module }}'.replace('.', '/') | |
| test_exists = os.path.exists(f'{test_path}') | |
| # Check if the extra package is available | |
| extras = '${{ matrix.extras }}'.split(',') | |
| missing = [] | |
| for extra in extras: | |
| try: | |
| if extra == 'flask': | |
| import flask | |
| elif extra == 'jinja2': | |
| import jinja2 | |
| elif extra == 'redis': | |
| import redis | |
| except ImportError: | |
| missing.append(extra) | |
| if test_exists and not missing: | |
| with open(os.environ['GITHUB_OUTPUT'], 'a') as f: | |
| f.write('should_run=true\\n') | |
| else: | |
| with open(os.environ['GITHUB_OUTPUT'], 'a') as f: | |
| f.write('should_run=false\\n') | |
| if missing: | |
| print(f'Missing dependencies: {missing}') | |
| if not test_exists: | |
| print(f'Test module {test_path} does not exist') | |
| " | |
| - name: Run tests for ${{ matrix.extras }} | |
| if: steps.check_tests.outputs.should_run == 'true' | |
| run: | | |
| python -m unittest discover -s $(echo "${{ matrix.test_module }}" | tr '.' '/') -p "test_*.py" -v | |
| continue-on-error: true | |
| test-all-extras: | |
| runs-on: ubuntu-latest | |
| strategy: | |
| matrix: | |
| python-version: ['3.9', '3.13'] | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Python ${{ matrix.python-version }} | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| - name: Install all dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -e ".[flask,jinja2,redis,dev]" | |
| - name: Create smart test runner | |
| run: | | |
| cat > smart_test_runner.py << 'EOF' | |
| import unittest | |
| import sys | |
| import importlib | |
| # Map test modules to their requirements | |
| OPTIONAL_DEPS = { | |
| 'flask': ['flask'], | |
| 'jinja2': ['jinja2'], | |
| 'redis': ['redis'], | |
| } | |
| def is_module_available(module_name): | |
| try: | |
| importlib.import_module(module_name) | |
| return True | |
| except ImportError: | |
| return False | |
| def main(): | |
| # Check which optional dependencies are available | |
| available_extras = [] | |
| for extra, deps in OPTIONAL_DEPS.items(): | |
| if all(is_module_available(dep) for dep in deps): | |
| available_extras.append(extra) | |
| print(f"Available extras: {', '.join(available_extras) if available_extras else 'None'}") | |
| # Run all tests | |
| loader = unittest.TestLoader() | |
| suite = loader.discover('tests', pattern='test_*.py') | |
| runner = unittest.TextTestRunner(verbosity=2, stream=sys.stdout, buffer=True) | |
| result = runner.run(suite) | |
| # Analyze failures | |
| if not result.wasSuccessful(): | |
| import_errors = 0 | |
| other_errors = 0 | |
| for error in result.errors + result.failures: | |
| error_text = str(error[1]) | |
| if 'ModuleNotFoundError' in error_text or 'ImportError' in error_text: | |
| import_errors += 1 | |
| else: | |
| other_errors += 1 | |
| print(f"\nTest Summary:") | |
| print(f" Import errors (expected): {import_errors}") | |
| print(f" Other errors: {other_errors}") | |
| # Only fail if there are non-import errors | |
| if other_errors > 0: | |
| sys.exit(1) | |
| else: | |
| print("\nAll failures were due to missing optional dependencies - this is expected") | |
| sys.exit(0) | |
| else: | |
| sys.exit(0) | |
| if __name__ == '__main__': | |
| main() | |
| EOF | |
| - name: Run all tests with smart error handling | |
| run: | | |
| python smart_test_runner.py | |
| docs: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.11' | |
| - name: Install dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -e . | |
| pip install sphinx | |
| - name: Build documentation | |
| run: | | |
| sphinx-build -nW -b html -d docs/_build/doctrees docs docs/_build/html | |
| - name: Upload documentation artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: documentation | |
| path: docs/_build/html/ | |
| if: always() | |
| package: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.11' | |
| - name: Install build dependencies | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install build twine | |
| - name: Build package | |
| run: | | |
| python -m build | |
| - name: Check package | |
| run: | | |
| twine check dist/* |