refactor(api): resolve_config carries lifecycle config fields [LTV-Po.2a] #394
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: CI | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| concurrency: | |
| group: ci-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| lint: | |
| name: Lint & format | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.12" | |
| # Pin ruff so notebook .ipynb formatting (which the lint job is | |
| # strict about) doesn't drift between contributor laptops and CI | |
| # the moment a new ruff release ships. Bump in lock-step with | |
| # any local re-runs of ``scripts/build_release_notebook_*.py``. | |
| - run: pip install 'ruff==0.15.12' | |
| - run: ruff check . | |
| - run: ruff format --check . | |
| typecheck: | |
| name: Type check | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.12" | |
| - run: pip install -e ".[dev]" | |
| - run: mypy leadforge/ | |
| test: | |
| name: Tests (Python ${{ matrix.python-version }}) | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| python-version: ["3.11", "3.12"] | |
| env: | |
| COVERAGE_FILE: .coverage.${{ matrix.python-version }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| - run: pip install -e ".[dev]" pytest-cov | |
| - run: pytest --cov=leadforge --cov-report=term-missing | |
| - name: Upload coverage artifact | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: pr-agent-context-coverage-py${{ matrix.python-version }} | |
| path: .coverage.${{ matrix.python-version }} | |
| include-hidden-files: true | |
| if-no-files-found: ignore | |
| release-artifacts-sync: | |
| name: Release artifacts in sync (PR 7.2.1) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.12" | |
| - run: pip install -e ".[dev]" | |
| # Each script's --check mode reports drift as exit-code-1 without | |
| # touching disk; the verifier is exit-code-1 on a real claim drift. | |
| # Running them in CI is the only way the audit-sync guarantee | |
| # actually holds — without this job, a stale metrics.json / | |
| # claims_register / docs/ copy could land on main unnoticed. | |
| - name: docs/ vendored copies are in sync | |
| run: python scripts/sync_release_docs.py --check | |
| - name: release/metrics.json + per-tier metrics.json are in sync | |
| run: python scripts/build_release_metrics.py --check | |
| - name: release/claims_register.{md,json} are in sync with source.yaml | |
| run: python scripts/build_claims_register.py --check | |
| - name: every claim in claims_register_source.yaml resolves & values match | |
| run: python scripts/verify_claims_register.py | |
| - name: Kaggle and Hugging Face metadata agree with release preview contract | |
| run: python scripts/lint_platform_metadata.py | |
| validate-dataset: | |
| name: Validate lead scoring dataset | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.12" | |
| - run: pip install -e ".[dev,scripts]" | |
| - name: Check for v5 dataset | |
| id: check-v5 | |
| run: | | |
| if [ -f "lead_scoring_intro_v5.csv" ]; then | |
| echo "found=true" >> "$GITHUB_OUTPUT" | |
| echo "csv=lead_scoring_intro_v5.csv" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "found=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Run v5 validator | |
| if: steps.check-v5.outputs.found == 'true' | |
| run: python scripts/validate_lead_scoring_dataset.py --csv "${{ steps.check-v5.outputs.csv }}" --enforce-1000 | |
| - name: Skip v5 (no dataset) | |
| if: steps.check-v5.outputs.found != 'true' | |
| run: echo "No lead_scoring_intro_v5.csv found in repo root — skipping v5 validation" | |
| validate-dataset-v6: | |
| name: Validate v6 lead scoring dataset | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.12" | |
| - run: pip install -e ".[dev,scripts]" | |
| - name: Check for v6 datasets | |
| id: check-v6 | |
| run: | | |
| STUDENT="lead_scoring_intro/lead_scoring_intro_v6.csv" | |
| INSTRUCTOR="lead_scoring_intro/lead_scoring_intro_v6_instructor.csv" | |
| if [ -f "$STUDENT" ] && [ -f "$INSTRUCTOR" ]; then | |
| echo "found=true" >> "$GITHUB_OUTPUT" | |
| echo "student=$STUDENT" >> "$GITHUB_OUTPUT" | |
| echo "instructor=$INSTRUCTOR" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "found=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Run v6 validator | |
| if: steps.check-v6.outputs.found == 'true' | |
| run: python scripts/validate_v6_dataset.py "${{ steps.check-v6.outputs.student }}" "${{ steps.check-v6.outputs.instructor }}" | |
| - name: Skip v6 (no dataset) | |
| if: steps.check-v6.outputs.found != 'true' | |
| run: echo "No v6 datasets found — skipping v6 validation" | |
| validate-dataset-v7: | |
| name: Validate v7 lead scoring dataset | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.12" | |
| - run: pip install -e ".[dev,scripts]" | |
| - name: Check for v7 datasets | |
| id: check-v7 | |
| run: | | |
| STUDENT="lead_scoring_intro/lead_scoring_intro_v7.csv" | |
| INSTRUCTOR="lead_scoring_intro/lead_scoring_intro_v7_instructor.csv" | |
| if [ -f "$STUDENT" ] && [ -f "$INSTRUCTOR" ]; then | |
| echo "found=true" >> "$GITHUB_OUTPUT" | |
| echo "student=$STUDENT" >> "$GITHUB_OUTPUT" | |
| echo "instructor=$INSTRUCTOR" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "found=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Run v7 validator | |
| if: steps.check-v7.outputs.found == 'true' | |
| run: python scripts/validate_v7_dataset.py "${{ steps.check-v7.outputs.student }}" "${{ steps.check-v7.outputs.instructor }}" | |
| - name: Skip v7 (no dataset) | |
| if: steps.check-v7.outputs.found != 'true' | |
| run: echo "No v7 datasets found — skipping v7 validation" | |
| notebooks: | |
| name: Execute release notebooks (G13.1) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.12" | |
| - run: pip install -e ".[dev,scripts,notebooks]" | |
| - name: Register python3 kernelspec for nbclient | |
| run: python -m ipykernel install --user --name python3 | |
| - name: Build intermediate and advanced public bundles (needed by nb04 §4) | |
| run: | | |
| python scripts/build_public_release.py release --tier intermediate | |
| python scripts/build_public_release.py release --tier advanced | |
| - name: Execute release notebooks end-to-end + builder byte-stability | |
| run: | | |
| pytest tests/release/notebooks/test_execute_notebooks.py \ | |
| tests/scripts/test_release_notebook_builders.py \ | |
| -v |