deps(libraries): add upper bound specifiers and sync package versions (fixes #693) #1269
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
| # Main CI workflow: runs on every push and pull request targeting main or develop. | |
| # Job order: lint -> (test + test-ui) in parallel -> build | |
| name: CI | |
| on: | |
| push: | |
| branches: [main, develop] | |
| pull_request: | |
| branches: [main, develop] | |
| jobs: | |
| lint: | |
| name: Lint | |
| runs-on: ubuntu-latest | |
| steps: | |
| # Check out the full repository so subsequent steps can access all files. | |
| - uses: actions/checkout@v6 | |
| - name: Check workflow security invariants | |
| run: python .github/scripts/check_opencode_workflow.py | |
| # Install uv (fast Python package/project manager) with dependency caching enabled | |
| # so repeated runs reuse cached packages and finish faster. | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v8.1.0 | |
| with: | |
| enable-cache: true | |
| # Pin to Python 3.12 for lint checks; consistent with the test matrix default. | |
| - name: Set up Python | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: '3.12' | |
| # Install ruff and mypy via uv for linting, formatting, and type checking. | |
| - name: Install lint tools | |
| run: | | |
| uv lock --check | |
| uv pip install --system ruff mypy | |
| # Run Ruff linter across both Python packages. | |
| # --output-format=github annotates pull requests with inline lint errors. | |
| - name: Run Ruff | |
| run: ruff check packages/ --output-format=github | |
| # Verify code is formatted according to Ruff's formatter rules. | |
| # --check exits with a non-zero code if any file would be reformatted, | |
| # failing the job without actually writing changes. | |
| - name: Check Ruff formatting | |
| run: ruff format --check packages/ | |
| # Run mypy type checking across both source trees. | |
| # mypy is configured via pyproject.toml at the repo root. | |
| # continue-on-error: pre-existing type errors exist across the codebase; | |
| # mypy runs for visibility but does not block CI until they are resolved. | |
| - name: Run mypy | |
| continue-on-error: true | |
| run: mypy packages/core/src packages/libraries/src | |
| test: | |
| # Matrix strategy tests every supported Python version on every supported OS, | |
| # giving early signal on platform-specific or version-specific regressions. | |
| name: Test (Python ${{ matrix.python-version }}, ${{ matrix.os }}) | |
| runs-on: ${{ matrix.os }} | |
| # Lint must pass before spending runner time on tests. | |
| needs: lint | |
| strategy: | |
| # Keep running remaining matrix legs even if one fails, so we get a full | |
| # picture of failures across all platforms in a single CI run. | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, windows-latest, macos-latest] | |
| python-version: ["3.10", "3.11", "3.12"] | |
| exclude: | |
| # Python 3.10 on macOS is excluded because the macOS-latest runner | |
| # ships with an arm64 (M1) image where 3.10 builds are not available. | |
| - os: macos-latest | |
| python-version: "3.10" | |
| steps: | |
| # Full checkout required for test discovery and package builds. | |
| - uses: actions/checkout@v6 | |
| # uv replaces pip + virtualenv with a single, faster tool. | |
| # Caching is enabled so dependencies don't re-download on every run. | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v8.1.0 | |
| with: | |
| enable-cache: true | |
| # Install the exact Python version specified by the matrix cell. | |
| - name: Set up Python ${{ matrix.python-version }} | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| # Install all test dependencies plus both packages in editable mode (-e) | |
| # so import paths resolve to the source tree. | |
| # pytest-asyncio is required for async test cases in core. | |
| # pytest-cov enables coverage collection. | |
| - name: Install dependencies | |
| run: | | |
| uv lock --check | |
| uv venv | |
| uv pip install -r requirements-dev.txt | |
| uv pip install -e packages/core | |
| uv pip install -e packages/libraries | |
| uv pip install pytest pytest-asyncio pytest-cov | |
| # Run pytest for core package with coverage. | |
| # --tb=short keeps failure output concise. | |
| # --cov=packages/core/src generates a per-package coverage report. | |
| - name: Run core tests | |
| run: uv run --no-project python -m pytest packages/core/tests -v --tb=short --cov=packages/core/src --cov-report=xml --cov-report=term-missing | |
| # Run pytest for libraries package with coverage appended to the same report. | |
| - name: Run libraries tests | |
| run: uv run --no-project python -m pytest packages/libraries/tests -v --tb=short --cov=packages/libraries/src --cov-report=xml --cov-append | |
| # Upload the XML coverage report to Codecov. | |
| # Restricted to one matrix leg (ubuntu + 3.11) to avoid duplicate uploads | |
| # that would skew the coverage percentage. | |
| # fail_ci_if_error=false prevents a Codecov outage from breaking the build. | |
| - name: Upload coverage | |
| uses: codecov/codecov-action@v7 | |
| if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.11' | |
| with: | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| files: ./coverage.xml | |
| fail_ci_if_error: false | |
| test-ui: | |
| name: Test Studio UI | |
| runs-on: ubuntu-latest | |
| # Lint must pass before spending runner time on UI tests. | |
| needs: lint | |
| steps: | |
| # Full checkout needed to access packages/studio source. | |
| - uses: actions/checkout@v6 | |
| # The Studio package targets Node 22 LTS; using setup-node ensures the correct | |
| # version is available regardless of what the runner ships with. | |
| - name: Set up Node.js | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: "22" | |
| # pnpm is the package manager for the monorepo workspace. Version 11 is | |
| # pinned because pnpm-workspace.yaml's `overrides`/`allowBuilds`/ | |
| # `onlyBuiltDependencies` keys are only understood by pnpm >=10. | |
| - name: Install pnpm | |
| uses: pnpm/action-setup@v6 | |
| with: | |
| version: 11 | |
| # Install all JS/TS dependencies declared in packages/studio/package.json | |
| # and the workspace root. | |
| - name: Install dependencies | |
| working-directory: packages/studio | |
| run: pnpm install --frozen-lockfile | |
| - name: Run Studio ESLint | |
| working-directory: packages/studio | |
| run: pnpm lint | |
| # Run the Vitest/Jest suite for the React frontend. | |
| - name: Run tests | |
| working-directory: packages/studio | |
| run: pnpm test | |
| # TypeScript compiler check with --noEmit: validates types without producing | |
| # output files. Catches type errors that unit tests alone may miss. | |
| - name: Type check | |
| working-directory: packages/studio | |
| run: pnpm exec tsc --noEmit | |
| build-electron: | |
| name: Build Electron Installer (Windows) | |
| runs-on: windows-latest | |
| needs: [test, test-ui] | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Set up Node.js | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: "22" | |
| - name: Install pnpm | |
| uses: pnpm/action-setup@v6 | |
| with: | |
| version: 11 | |
| - name: Set up Python | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: "3.11" | |
| - name: Install engine build tools | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install pyinstaller | |
| pip install ./packages/core | |
| pip install "./packages/libraries[desktop,web,excel,database,keystore,dataframes]" | |
| - name: Install dependencies | |
| working-directory: packages/studio | |
| run: pnpm install --frozen-lockfile | |
| - name: Build Python bridge | |
| working-directory: packages/studio | |
| run: pnpm build:bridge | |
| - name: Build Electron app | |
| working-directory: packages/studio | |
| run: pnpm build | |
| - name: Run packaged Electron E2E smoke suite | |
| working-directory: packages/studio | |
| run: pnpm test:e2e | |
| - name: Upload Electron E2E artifacts on failure | |
| if: failure() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: electron-e2e-failure-artifacts | |
| path: | | |
| packages/studio/test-results | |
| packages/studio/playwright-report | |
| - name: Upload installer artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: windows-installer | |
| path: packages/studio/dist-electron/*.exe | |
| build: | |
| name: Build Packages | |
| runs-on: ubuntu-latest | |
| # Both test jobs must succeed before attempting a build to avoid wasting | |
| # runner time packaging broken code. | |
| needs: [test, test-ui] | |
| steps: | |
| # Full checkout required so python -m build can locate pyproject.toml. | |
| - uses: actions/checkout@v6 | |
| - name: Install uv | |
| uses: astral-sh/setup-uv@v8.1.0 | |
| with: | |
| enable-cache: true | |
| # Use a stable, non-EOL Python for the build step. | |
| - name: Set up Python | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: '3.11' | |
| - name: Verify Python lockfile | |
| run: uv lock --check | |
| # Install the PEP 517 build frontend; no other runtime deps needed here. | |
| - name: Install build tools | |
| run: uv venv && uv pip install build | |
| # Build source distribution and wheel for the root project. | |
| # Artifacts land in dist/ for the upload step. | |
| - name: Build packages | |
| run: uv run --no-project python -m build | |
| # Persist the built distributions as a downloadable workflow artifact. | |
| # Other workflows (e.g. release.yml) or manual inspection can use these | |
| # without re-running the build. | |
| - name: Upload artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: dist | |
| path: dist/ |