feat: add repository_dispatch trigger for cross-repo CI #35
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: | ||
| repository_dispatch: | ||
| types: [dependency-update] | ||
| push: | ||
| branches: [master] | ||
| pull_request: | ||
| branches: [master] | ||
| permissions: | ||
| contents: read | ||
| env: | ||
| PYTEST_VERSION: ">=7.0,<9.0" | ||
| PYYAML_VERSION: ">=6.0,<7.0" | ||
| CLICK_VERSION: ">=8.0,<9.0" | ||
| jobs: | ||
| # ──────────────────────────────────────────────────────────── | ||
| # Unit tests — ebuild only, no sibling repos needed | ||
| # ──────────────────────────────────────────────────────────── | ||
| unit: | ||
| name: Unit (${{ matrix.os }} / Python ${{ matrix.python }}) | ||
| runs-on: ${{ matrix.os }} | ||
| strategy: | ||
| fail-fast: false | ||
| matrix: | ||
| os: [ubuntu-latest, windows-latest, macos-latest] | ||
| python: ["3.11", "3.12"] | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - uses: actions/setup-python@v5 | ||
| with: | ||
| python-version: ${{ matrix.python }} | ||
| - name: Install dependencies | ||
| run: pip install "pytest${{ env.PYTEST_VERSION }}" "pyyaml${{ env.PYYAML_VERSION }}" "click${{ env.CLICK_VERSION }}" | ||
| - name: Run unit tests | ||
| run: python -m pytest tests/test_eos_ai.py -v --tb=short --junitxml=results-unit.xml | ||
| - name: Upload test results | ||
| if: always() | ||
| uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: unit-results-${{ matrix.os }}-py${{ matrix.python }} | ||
| path: results-unit.xml | ||
| # ──────────────────────────────────────────────────────────── | ||
| # Integration tests — checks out eos + eboot alongside ebuild | ||
| # ──────────────────────────────────────────────────────────── | ||
| integration: | ||
| repository_dispatch: | ||
| types: [dependency-update] | ||
| name: Integration (${{ matrix.os }} / Python ${{ matrix.python }}) | ||
| runs-on: ${{ matrix.os }} | ||
| strategy: | ||
| fail-fast: false | ||
| matrix: | ||
| os: [ubuntu-latest, windows-latest, macos-latest] | ||
| python: ["3.11", "3.12"] | ||
| steps: | ||
| # Check out all three repos side-by-side: | ||
| # workspace/ | ||
| # ├── ebuild/ ← this repo | ||
| # ├── eos/ ← sibling | ||
| # └── eboot/ ← sibling | ||
| - name: Checkout ebuild | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| path: ebuild | ||
| - name: Checkout eos | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| repository: ${{ github.repository_owner }}/eos | ||
| path: eos | ||
| continue-on-error: true | ||
| - name: Checkout eboot | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| repository: ${{ github.repository_owner }}/eboot | ||
| path: eboot | ||
| continue-on-error: true | ||
| - uses: actions/setup-python@v5 | ||
| with: | ||
| python-version: ${{ matrix.python }} | ||
| - name: Install dependencies | ||
| run: pip install "pytest${{ env.PYTEST_VERSION }}" "pyyaml${{ env.PYYAML_VERSION }}" "click${{ env.CLICK_VERSION }}" | ||
| - name: Verify sibling repos | ||
| shell: bash | ||
| run: | | ||
| echo "── Repo layout ──" | ||
| ls -d */ 2>/dev/null || echo "(no subdirectories found)" | ||
| if [ ! -d "eos" ] || [ ! -d "eboot" ]; then | ||
| echo "::warning::Sibling repos not available — integration tests will be skipped" | ||
| fi | ||
| - name: Run integration tests | ||
| if: hashFiles('eos/README.md') != '' && hashFiles('eboot/README.md') != '' | ||
| working-directory: ebuild | ||
| run: python -m pytest tests/test_cortex_r5_integration.py -v --tb=short --junitxml=results-integration.xml | ||
| - name: Verify integration tests ran | ||
| if: hashFiles('eos/README.md') != '' && hashFiles('eboot/README.md') != '' | ||
| shell: bash | ||
| working-directory: ebuild | ||
| run: | | ||
| if [ ! -f results-integration.xml ]; then | ||
| echo "::error::Integration test results not found" | ||
| exit 1 | ||
| fi | ||
| if grep -q 'tests="0"' results-integration.xml; then | ||
| echo "::error::Integration tests collected 0 tests" | ||
| exit 1 | ||
| fi | ||
| - name: Upload test results | ||
| if: always() | ||
| uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: integration-results-${{ matrix.os }}-py${{ matrix.python }} | ||
| path: ebuild/results-integration.xml | ||
| if-no-files-found: ignore | ||
| # ──────────────────────────────────────────────────────────── | ||
| # Full test suite — all tests via pytest discovery | ||
| # ──────────────────────────────────────────────────────────── | ||
| full-suite: | ||
| name: Full Suite (Python ${{ matrix.python }}) | ||
| runs-on: ubuntu-latest | ||
| strategy: | ||
| fail-fast: false | ||
| matrix: | ||
| python: ["3.11", "3.12"] | ||
| steps: | ||
| - name: Checkout ebuild | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| path: ebuild | ||
| - name: Checkout eos | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| repository: ${{ github.repository_owner }}/eos | ||
| path: eos | ||
| continue-on-error: true | ||
| - name: Checkout eboot | ||
| uses: actions/checkout@v4 | ||
| with: | ||
| repository: ${{ github.repository_owner }}/eboot | ||
| path: eboot | ||
| continue-on-error: true | ||
| - uses: actions/setup-python@v5 | ||
| with: | ||
| python-version: ${{ matrix.python }} | ||
| - name: Install dependencies | ||
| run: pip install "pytest${{ env.PYTEST_VERSION }}" pytest-cov "pyyaml${{ env.PYYAML_VERSION }}" "click${{ env.CLICK_VERSION }}" | ||
| - name: Check sibling repos | ||
| id: siblings | ||
| shell: bash | ||
| run: | | ||
| if [ -d "eos" ] && [ -d "eboot" ]; then | ||
| echo "available=true" >> $GITHUB_OUTPUT | ||
| else | ||
| echo "available=false" >> $GITHUB_OUTPUT | ||
| echo "::warning::Sibling repos not available — running unit tests only" | ||
| fi | ||
| - name: Run full test suite with coverage | ||
| if: steps.siblings.outputs.available == 'true' | ||
| working-directory: ebuild | ||
| run: | | ||
| python -m pytest tests/ \ | ||
| -v --tb=short \ | ||
| --junitxml=results-full.xml \ | ||
| --cov=ebuild --cov-report=term-missing --cov-report=xml:coverage.xml | ||
| - name: Run unit tests only (no sibling repos) | ||
| if: steps.siblings.outputs.available != 'true' | ||
| working-directory: ebuild | ||
| run: | | ||
| python -m pytest tests/test_eos_ai.py \ | ||
| -v --tb=short \ | ||
| --junitxml=results-full.xml \ | ||
| --cov=ebuild --cov-report=term-missing --cov-report=xml:coverage.xml | ||
| - name: Run standalone pipeline test | ||
| working-directory: ebuild | ||
| run: python test_full_pipeline.py | ||
| - name: Verify generated files | ||
| working-directory: ebuild | ||
| run: | | ||
| test -f _generated_test/board.yaml | ||
| test -f _generated_test/boot.yaml | ||
| test -f _generated_test/eos_product_config.h | ||
| test -f _generated_test/eboot_flash_layout.h | ||
| - name: Upload test results | ||
| if: always() | ||
| uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: full-results-py${{ matrix.python }} | ||
| path: | | ||
| ebuild/results-full.xml | ||
| ebuild/coverage.xml | ||
| # ──────────────────────────────────────────────────────────── | ||
| # Gate — single status check for branch protection | ||
| # ──────────────────────────────────────────────────────────── | ||
| ci-pass: | ||
| name: CI Pass | ||
| runs-on: ubuntu-latest | ||
| needs: [unit, integration, full-suite] | ||
| if: always() | ||
| steps: | ||
| - name: Check results | ||
| env: | ||
| UNIT_RESULT: ${{ needs.unit.result }} | ||
| FULL_RESULT: ${{ needs.full-suite.result }} | ||
| INTEG_RESULT: ${{ needs.integration.result }} | ||
| run: | | ||
| if [ "$UNIT_RESULT" != "success" ]; then | ||
| echo "::error::Unit tests failed" | ||
| exit 1 | ||
| fi | ||
| if [ "$FULL_RESULT" != "success" ]; then | ||
| echo "::error::Full test suite failed" | ||
| exit 1 | ||
| fi | ||
| if [ "$INTEG_RESULT" = "failure" ]; then | ||
| echo "::warning::Integration tests failed — review results" | ||
| fi | ||
| echo "All required checks passed" | ||