name: 🧱 openbb-core on: pull_request: branches: - develop - v5 paths: - 'openbb_platform/core/**' - 'openbb_platform/extensions/devtools/**' - '.github/workflows/test-openbb-core.yml' push: branches: - develop - v5 paths: - 'openbb_platform/core/**' - 'openbb_platform/extensions/devtools/**' - '.github/workflows/test-openbb-core.yml' merge_group: types: [checks_requested] workflow_dispatch: concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: true defaults: run: shell: bash working-directory: openbb_platform/core jobs: test: name: Test (${{ matrix.os }} / Python ${{ matrix.python_version }}) runs-on: ${{ matrix.os }} env: OPENBB_ALLOW_ON_COMMAND_OUTPUT: "True" OPENBB_ALLOW_MUTABLE_EXTENSIONS: "True" permissions: contents: read strategy: fail-fast: false matrix: include: # Linux: full sweep across every supported Python. - { os: ubuntu-latest, python_version: "3.11" } - { os: ubuntu-latest, python_version: "3.12" } - { os: ubuntu-latest, python_version: "3.13" } - { os: ubuntu-latest, python_version: "3.14" } # macOS and Windows: min and max supported. - { os: macos-latest, python_version: "3.11" } - { os: macos-latest, python_version: "3.14" } - { os: windows-latest, python_version: "3.11" } - { os: windows-latest, python_version: "3.14" } steps: - name: Checkout code uses: actions/checkout@v6 with: ref: ${{ github.event.pull_request.head.sha || github.sha }} - name: Install Python ${{ matrix.python_version }} uses: actions/setup-python@v6 with: python-version: ${{ matrix.python_version }} allow-prereleases: true cache: "pip" - name: Install openbb-core (with pandas and flask extras) and test deps run: | python -m pip install --upgrade pip pip install -e ".[pandas,flask]" pip install pytest pytest-cov pytest-asyncio httpx2 coverage[toml] - name: Run unit tests run: | pytest tests \ --cov=openbb_core \ --cov-config=.coveragerc \ --cov-report=term-missing \ --cov-report=xml:coverage-unit.xml - name: Upload unit-test coverage artifact if: always() uses: actions/upload-artifact@v4 with: name: openbb-core-coverage-unit-${{ matrix.os }}-py${{ matrix.python_version }} path: openbb_platform/core/coverage-unit.xml if-no-files-found: ignore integration: name: Integration (ubuntu / py3.13) runs-on: ubuntu-latest needs: test env: OPENBB_ALLOW_ON_COMMAND_OUTPUT: "True" OPENBB_ALLOW_MUTABLE_EXTENSIONS: "True" permissions: contents: read steps: - name: Checkout code uses: actions/checkout@v6 with: ref: ${{ github.event.pull_request.head.sha || github.sha }} - name: Install Python 3.13 uses: actions/setup-python@v6 with: python-version: "3.13" cache: "pip" - name: Install openbb-core (with pandas and flask extras) and test deps run: | python -m pip install --upgrade pip pip install -e ".[pandas,flask]" pip install pytest pytest-cov pytest-asyncio httpx2 coverage[toml] - name: Enable subprocess coverage (sitecustomize shim) run: | # `coverage.process_startup()` only fires in child interpreters when # both COVERAGE_PROCESS_START is set AND a sitecustomize.py on # sys.path calls it. Drop the shim into site-packages so every # `python` subprocess spawned by the integration suite (including # the one that runs `openbb-build`) is instrumented. python -c "import sysconfig, pathlib; \ p = pathlib.Path(sysconfig.get_paths()['purelib']) / 'sitecustomize.py'; \ p.write_text('import coverage\ncoverage.process_startup()\n'); \ print('wrote', p)" - name: Run integration tests with subprocess coverage env: COVERAGE_PROCESS_START: ${{ github.workspace }}/openbb_platform/core/.coveragerc COVERAGE_FILE: .coverage.integration run: | # Run pytest directly. Child interpreters are instrumented via # COVERAGE_PROCESS_START + sitecustomize and write parallel # `.coverage.*` files in CWD. pytest integration -m integration -v coverage combine coverage report --rcfile=.coveragerc coverage xml --rcfile=.coveragerc -o coverage-integration.xml - name: Upload integration coverage artifact if: always() uses: actions/upload-artifact@v4 with: name: openbb-core-coverage-integration path: openbb_platform/core/coverage-integration.xml if-no-files-found: ignore