Spaces:
Sleeping
Sleeping
| name: CI — UVM TB Generator | |
| on: | |
| push: | |
| branches: [main, develop] | |
| paths-ignore: ["docs/**", "README.md"] | |
| pull_request: | |
| branches: [main] | |
| workflow_dispatch: | |
| env: | |
| PYTHON_VERSION: "3.11" | |
| jobs: | |
| lint: | |
| name: Lint & Format Check | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ env.PYTHON_VERSION }} | |
| - name: Install dependencies | |
| run: | | |
| pip install flake8 black yamllint | |
| pip install -r requirements.txt | |
| - name: Run flake8 | |
| run: flake8 src/ tests/ --max-line-length=120 --extend-ignore=E203 | |
| - name: Run yamllint on configs and protocols | |
| run: yamllint configs/ protocols/ | |
| test: | |
| name: Tests (Python ${{ matrix.python-version }}) | |
| runs-on: ubuntu-latest | |
| strategy: | |
| matrix: | |
| python-version: ["3.10", "3.11", "3.12"] | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| - name: Install dependencies | |
| run: | | |
| pip install pytest pytest-cov | |
| pip install -r requirements.txt | |
| - name: Run tests with coverage | |
| run: | | |
| python -m pytest tests/ -v --cov=src --cov-report=xml --cov-report=term-missing | |
| - name: Upload coverage | |
| uses: codecov/codecov-action@v5 | |
| with: | |
| file: ./coverage.xml | |
| fail_ci_if_error: false | |
| generate: | |
| name: Generation Smoke Test | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ env.PYTHON_VERSION }} | |
| - name: Install dependencies | |
| run: | | |
| pip install -r requirements.txt | |
| - name: Generate from YAML spec | |
| run: | | |
| python -m src.main --spec configs/uart_demo.yaml --json | |
| - name: Generate from .core file | |
| run: | | |
| python -m src.main --spec configs/uart16550-1.5.core --json | |
| - name: Verify output files exist | |
| run: | | |
| test -d output/uart_tb | |
| test -f output/uart_tb/testbench.sv | |
| test -f output/uart_tb/interface_uart.sv | |
| test -d output/uart16550_tb | |
| test -f output/uart16550_tb/testbench.sv | |
| echo "All output files verified" | |
| - name: Verify API server imports | |
| run: | | |
| python -c "from src.api.server import app; print('API server OK')" | |
| regression: | |
| name: Multi-Seed Regression Test | |
| runs-on: ubuntu-latest | |
| needs: [generate] | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ env.PYTHON_VERSION }} | |
| - name: Install dependencies | |
| run: | | |
| pip install -r requirements.txt | |
| - name: Run auto-training with 3 seeds | |
| run: | | |
| python -m src.main --spec configs/uart16550-1.5.core --auto-train \ | |
| --max-iterations 3 --coverage-target 75 --simulator stub | |
| - name: Export coverage trend | |
| run: | | |
| python -c " | |
| import json | |
| from pathlib import Path | |
| trend_file = next(Path('output').rglob('*coverage_trend*'), None) | |
| if trend_file: | |
| print('Coverage trend:') | |
| print(trend_file.read_text()) | |
| else: | |
| # Show registry content | |
| reg_dir = Path('output') / 'model_registry' | |
| if reg_dir.exists(): | |
| versions = sorted(reg_dir.iterdir()) | |
| print(f'Versions: {[v.name for v in versions]}') | |
| " || true | |
| - name: Verify FuseSoC .core file generated | |
| run: | | |
| test -f output/uart16550_tb/uart16550.core && echo "FuseSoC .core found" || echo "No FuseSoC core" | |
| schema: | |
| name: Schema Validation | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ env.PYTHON_VERSION }} | |
| - name: Install deps | |
| run: pip install pyyaml jsonschema | |
| - name: Validate demo specs against schema | |
| run: | | |
| python -c " | |
| import json, yaml, sys | |
| from jsonschema import validate | |
| with open('configs/schema/master_schema.json') as f: | |
| schema = json.load(f) | |
| for spec_file in ['configs/uart_demo.yaml', 'configs/uart16550-1.5.core']: | |
| with open(spec_file) as f: | |
| if spec_file.endswith('.core'): | |
| # .core files wrap spec in a different format; validate the relevant parts | |
| data = yaml.safe_load(f) | |
| else: | |
| data = yaml.safe_load(f) | |
| try: | |
| validate(instance=data, schema=schema) | |
| print(f'OK: {spec_file} passes schema') | |
| except Exception as e: | |
| print(f'FAIL: {spec_file} — {e}') | |
| sys.exit(1) | |
| " | |