Skip to content

Refine summary stats backend RPCs for data explorer, add Python implementation and basic scaffolding #47

Refine summary stats backend RPCs for data explorer, add Python implementation and basic scaffolding

Refine summary stats backend RPCs for data explorer, add Python implementation and basic scaffolding #47

name: 'Positron Python CI'
on:
push:
branches:
- main
paths:
- '.github/workflows/positron-python-ci.yml'
- 'extensions/positron-python/**'
pull_request:
branches:
- main
paths:
- '.github/workflows/positron-python-ci.yml'
- 'extensions/positron-python/**'
defaults:
run:
working-directory: 'extensions/positron-python'
env:
NODE_VERSION: '18.17.1'
PYTHON_VERSION: '3.10'
PROJECT_DIR: 'extensions/positron-python'
PYTHON_SRC_DIR: 'extensions/positron-python/pythonFiles'
# Force a path with spaces and to test extension works in these scenarios
# Unicode characters are causing 2.7 failures so skip that for now.
special-working-directory: './path with spaces'
special-working-directory-relative: 'path with spaces'
jobs:
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install Node ${{ env.NODE_VERSION }}
uses: actions/setup-node@v3
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'yarn'
- name: Install Yarn
run: npm install -g yarn
- name: Install Python ${{ env.PYTHON_VERSION }}
uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
cache: 'pip'
- name: Install Node dependencies
run: yarn install --immutable --network-timeout 120000 --prefer-offline
- name: Run `gulp prePublishNonBundle`
run: yarn prePublish
- name: Check dependencies
run: yarn checkDependencies
- name: Lint TypeScript code
run: yarn lint
- name: Check TypeScript format
run: yarn format-check
- name: Check Python format
run: |
python -m pip install -U black
python -m black . --check
working-directory: ${{ env.PYTHON_SRC_DIR }}
- name: Run Ruff
run: |
python -m pip install -U ruff
python -m ruff check .
working-directory: ${{ env.PYTHON_SRC_DIR }}
check-types:
name: Check Python types
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Use Python ${{ env.PYTHON_VERSION }}
uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
cache: 'pip'
- name: Install base Python requirements
run: 'python -m pip install --no-deps --require-hashes --only-binary :all: -t ./pythonFiles/lib/python --no-cache-dir --implementation py -r requirements.txt'
- name: Install Positron IPyKernel requirements
run: python scripts/vendor.py
- name: Install other Python requirements
run: |
python -m pip --disable-pip-version-check install -t ./pythonFiles/lib/python --no-cache-dir --implementation py --no-deps --upgrade --pre debugpy
python -m pip install --upgrade -r build/test-requirements.txt
python -m pip install --upgrade -r ./pythonFiles/positron/pinned-test-requirements.txt
- name: Run Pyright
uses: jakebailey/pyright-action@v2
with:
version: 1.1.308
working-directory: ${{ env.PYTHON_SRC_DIR }}
python-tests:
name: Python Tests
# The value of runs-on is the OS of the current job (specified in the strategy matrix below) instead of being hardcoded.
runs-on: ${{ matrix.os }}
defaults:
run:
working-directory: ${{ env.special-working-directory }}/${{ env.PROJECT_DIR}}
strategy:
fail-fast: false
matrix:
# TODO: Decide whether we want to match upstream matrix.
# # We're not running CI on macOS for now because it's one less matrix entry to lower the number of runners used,
# # macOS runners are expensive, and we assume that Ubuntu is enough to cover the Unix case.
# os: [ubuntu-latest, windows-latest]
# # Run the tests on the oldest and most recent versions of Python.
# python: ['3.8', '3.x'] # run for 3 pytest versions, most recent stable, oldest version supported and pre-release
# pytest-version: ['pytest', 'pytest@pre-release', 'pytest==6.2.0']
include:
- os: 'ubuntu-latest'
python: '3.8'
pytest-version: 'pytest<8.1.1'
- os: 'macos-latest'
python: '3.9'
pytest-version: 'pytest<8.1.1'
- os: 'windows-latest'
python: '3.10'
pytest-version: 'pytest<8.1.1'
- os: 'ubuntu-latest'
python: '3.11'
pytest-version: 'pytest<8.1.1'
- os: 'ubuntu-latest'
python: '3.12'
pytest-version: 'pytest<8.1.1'
steps:
- name: Checkout
uses: actions/checkout@v4
with:
path: ${{ env.special-working-directory-relative }}
- name: Use Python ${{ matrix.python }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python }}
- name: Install specific pytest version
if: matrix.pytest-version == 'pytest@pre-release'
run: |
python -m pip install --pre pytest
- name: Install specific pytest version
if: matrix.pytest-version != 'pytest@pre-release'
run: |
python -m pip install "${{ matrix.pytest-version }}"
- name: Install specific pytest version
run: python -m pytest --version
- name: Install base Python requirements
run: 'python -m pip install --no-deps --require-hashes --only-binary :all: -t ./pythonFiles/lib/python --no-cache-dir --implementation py -r requirements.txt'
- name: Install test requirements
run: python -m pip install -r build/test-requirements.txt
- name: Run Python unit tests
run: python pythonFiles/tests/run_all.py
positron-ipykernel-tests:
name: Test Positron IPyKernel
runs-on: ${{ matrix.os }}
strategy:
matrix:
include:
- os: 'ubuntu-latest'
python: '3.8'
time-elapsed: ''
- os: 'macos-latest'
python: '3.9'
time-elapsed: ''
- os: 'windows-latest'
python: '3.10'
time-elapsed: ''
- os: 'ubuntu-latest'
python: '3.11'
time-elapsed: ''
- os: 'ubuntu-latest'
python: '3.12'
time-elapsed: ''
# - os: 'ubuntu-latest'
# python: '3.10'
# time-elapsed: '3 months'
# - os: 'ubuntu-latest'
# python: '3.10'
# time-elapsed: '6 months'
# - os: 'ubuntu-latest'
# python: '3.10'
# time-elapsed: '9 months'
# - os: 'ubuntu-latest'
# python: '3.10'
# time-elapsed: '1 year'
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Use Python ${{ matrix.python }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python }}
cache: 'pip'
- name: Install Positron IPyKernel requirements
run: python scripts/vendor.py
- name: Install Positron IPyKernel test requirements
run: python -m pip install --prefer-binary --upgrade -r pythonFiles/positron/pinned-test-requirements.txt
- name: Get date for older dependencies
if: ${{ matrix.time-elapsed != '' }}
run: |
echo "SNAPSHOT_DATE=$(date -d '-${{ matrix.time-elapsed }}' --iso-8601)" >> $GITHUB_ENV
- name: Get older PyPI snapshot
if: ${{ matrix.time-elapsed != '' }}
run: |
python -m pip config set global.index-url https://packagemanager.posit.co/pypi/${{ env.SNAPSHOT_DATE }}/simple
python -m pip config set global.trusted-host packagemanager.posit.co
python -m pip install --prefer-binary --force-reinstall -r pythonFiles/positron/data-science-requirements.txt
- name: Run Positron IPyKernel unit tests
run: pytest pythonFiles/positron
typescript-tests:
name: Test TypeScript
runs-on: ${{ matrix.os }}
defaults:
run:
working-directory: ${{ env.special-working-directory }}/${{ env.PROJECT_DIR}}
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python: ['3.x']
test-suite: [ts-unit, venv, single-workspace, debugger, functional, smoke]
# TODO: Add integration tests on windows and ubuntu. This requires updating
# src/test/positron/testElectron.ts to support installing Positron on these platforms.
exclude:
- os: windows-latest
test-suite: venv
- os: windows-latest
test-suite: debugger
- os: windows-latest
test-suite: single-workspace
- os: windows-latest
test-suite: smoke
- os: ubuntu-latest
test-suite: venv
- os: ubuntu-latest
test-suite: debugger
- os: ubuntu-latest
test-suite: single-workspace
- os: ubuntu-latest
test-suite: smoke
steps:
- name: Checkout
uses: actions/checkout@v4
with:
path: ${{ env.special-working-directory-relative }}
- name: Install Node ${{ env.NODE_VERSION }}
uses: actions/setup-node@v3
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'yarn'
cache-dependency-path: ${{ env.special-working-directory-relative }}/${{ env.PROJECT_DIR }}/yarn.lock
- name: Install Yarn
run: npm install -g yarn
- name: Use Python ${{ matrix.python }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python }}
cache: 'pip'
- name: Install Node dependencies
run: yarn install --immutable --network-timeout 120000 --prefer-offline
- name: Run `gulp prePublishNonBundle`
run: yarn prePublish
- name: Localization
run: npx @vscode/l10n-dev@latest export ./src
- name: Install test requirements
run: python -m pip install --upgrade -r ./build/test-requirements.txt
- name: Install functional test requirements
run: python -m pip install --upgrade -r ./build/functional-test-requirements.txt
if: matrix.test-suite == 'functional'
- name: Prepare pipenv for venv tests
env:
TEST_FILES_SUFFIX: testvirtualenvs
PYTHON_VIRTUAL_ENVS_LOCATION: './src/tmp/envPaths.json'
shell: pwsh
if: matrix.test-suite == 'venv'
run: |
python -m pip install pipenv
python -m pipenv run python ./build/ci/addEnvPath.py ${{ env.PYTHON_VIRTUAL_ENVS_LOCATION }} pipenvPath
- name: Prepare poetry for venv tests
env:
TEST_FILES_SUFFIX: testvirtualenvs
shell: pwsh
if: matrix.test-suite == 'venv'
run: |
python -m pip install poetry
Move-Item -Path ".\build\ci\pyproject.toml" -Destination .
poetry env use python
- name: Prepare virtualenv for venv tests
env:
TEST_FILES_SUFFIX: testvirtualenvs
PYTHON_VIRTUAL_ENVS_LOCATION: './src/tmp/envPaths.json'
shell: pwsh
if: matrix.test-suite == 'venv'
run: |
python -m pip install virtualenv
python -m virtualenv .virtualenv/
if ('${{ matrix.os }}' -match 'windows-latest') {
& ".virtualenv/Scripts/python.exe" ./build/ci/addEnvPath.py ${{ env.PYTHON_VIRTUAL_ENVS_LOCATION }} virtualEnvPath
} else {
& ".virtualenv/bin/python" ./build/ci/addEnvPath.py ${{ env.PYTHON_VIRTUAL_ENVS_LOCATION }} virtualEnvPath
}
- name: Prepare venv for venv tests
env:
TEST_FILES_SUFFIX: testvirtualenvs
PYTHON_VIRTUAL_ENVS_LOCATION: './src/tmp/envPaths.json'
shell: pwsh
if: matrix.test-suite == 'venv' && startsWith(matrix.python, 3.)
run: |
python -m venv .venv
if ('${{ matrix.os }}' -match 'windows-latest') {
& ".venv/Scripts/python.exe" ./build/ci/addEnvPath.py ${{ env.PYTHON_VIRTUAL_ENVS_LOCATION }} venvPath
} else {
& ".venv/bin/python" ./build/ci/addEnvPath.py ${{ env.PYTHON_VIRTUAL_ENVS_LOCATION }} venvPath
}
- name: Prepare conda for venv tests
env:
TEST_FILES_SUFFIX: testvirtualenvs
PYTHON_VIRTUAL_ENVS_LOCATION: './src/tmp/envPaths.json'
shell: pwsh
if: matrix.test-suite == 'venv'
run: |
# 1. For `*.testvirtualenvs.test.ts`
if ('${{ matrix.os }}' -match 'windows-latest') {
$condaPythonPath = Join-Path -Path $Env:CONDA -ChildPath python.exe
$condaExecPath = Join-Path -Path $Env:CONDA -ChildPath Scripts | Join-Path -ChildPath conda
} else{
$condaPythonPath = Join-Path -Path $Env:CONDA -ChildPath bin | Join-Path -ChildPath python
$condaExecPath = Join-Path -Path $Env:CONDA -ChildPath bin | Join-Path -ChildPath conda
}
& $condaPythonPath ./build/ci/addEnvPath.py ${{ env.PYTHON_VIRTUAL_ENVS_LOCATION }} condaExecPath $condaExecPath
& $condaPythonPath ./build/ci/addEnvPath.py ${{ env.PYTHON_VIRTUAL_ENVS_LOCATION }} condaPath
& $condaExecPath init --all
- name: Prepare VSIX for smoke tests
run: yarn package --allow-star-activation
if: matrix.test-suite == 'smoke'
- name: Set CI_PYTHON_PATH and CI_DISABLE_AUTO_SELECTION
run: |
echo "CI_PYTHON_PATH=$(which python)" >> $GITHUB_ENV
echo "CI_DISABLE_AUTO_SELECTION=1" >> $GITHUB_ENV
shell: bash
if: matrix.test-suite != 'ts-unit'
# Run TypeScript unit tests only for Python 3.X.
- name: Run TypeScript unit tests
run: yarn test:unittests
if: matrix.test-suite == 'ts-unit' && startsWith(matrix.python, 3.)
# The virtual environment based tests use the `testSingleWorkspace` set of tests
# with the environment variable `TEST_FILES_SUFFIX` set to `testvirtualenvs`,
# which is set in the "Prepare environment for venv tests" step.
# We also use a third-party GitHub Action to install xvfb on Linux,
# run tests and then clean up the process once the tests ran.
# See https://github.com/GabrielBB/xvfb-action
- name: Run venv tests
env:
TEST_FILES_SUFFIX: testvirtualenvs
CI_PYTHON_VERSION: ${{ matrix.python }}
POSITRON_GITHUB_PAT: ${{ secrets.POSITRON_GITHUB_PAT }}
uses: GabrielBB/xvfb-action@v1.6
with:
run: yarn testSingleWorkspace
working-directory: ${{ env.special-working-directory }}/${{ env.PROJECT_DIR }}
if: matrix.test-suite == 'venv'
- name: Run single-workspace tests
env:
CI_PYTHON_VERSION: ${{ matrix.python }}
POSITRON_GITHUB_PAT: ${{ secrets.POSITRON_GITHUB_PAT }}
uses: GabrielBB/xvfb-action@v1.6
with:
run: yarn testSingleWorkspace
working-directory: ${{ env.special-working-directory }}/${{ env.PROJECT_DIR }}
if: matrix.test-suite == 'single-workspace'
- name: Run debugger tests
env:
CI_PYTHON_VERSION: ${{ matrix.python }}
POSITRON_GITHUB_PAT: ${{ secrets.POSITRON_GITHUB_PAT }}
uses: GabrielBB/xvfb-action@v1.6
with:
run: yarn testDebugger
working-directory: ${{ env.special-working-directory }}/${{ env.PROJECT_DIR }}
if: matrix.test-suite == 'debugger'
- name: Run TypeScript functional tests
run: yarn test:functional
if: matrix.test-suite == 'functional'
- name: Run smoke tests
env:
POSITRON_GITHUB_PAT: ${{ secrets.POSITRON_GITHUB_PAT }}
run: yarn tsc && node ./out/test/smokeTest.js
if: matrix.test-suite == 'smoke'