diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 2027d97..90b273a 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -29,7 +29,7 @@ concurrency: jobs: conda-python-build: secrets: inherit - uses: rapidsai/shared-workflows/.github/workflows/conda-python-build.yaml@branch-24.02 + uses: rapidsai/shared-workflows/.github/workflows/conda-python-build.yaml@branch-24.10 with: build_type: ${{ inputs.build_type || 'branch' }} branch: ${{ inputs.branch }} @@ -40,7 +40,7 @@ jobs: upload-conda: needs: conda-python-build secrets: inherit - uses: rapidsai/shared-workflows/.github/workflows/conda-upload-packages.yaml@branch-24.02 + uses: rapidsai/shared-workflows/.github/workflows/conda-upload-packages.yaml@branch-24.10 with: build_type: ${{ inputs.build_type || 'branch' }} branch: ${{ inputs.branch }} @@ -48,7 +48,7 @@ jobs: sha: ${{ inputs.sha }} wheel-build: secrets: inherit - uses: rapidsai/shared-workflows/.github/workflows/wheels-build.yaml@branch-24.02 + uses: rapidsai/shared-workflows/.github/workflows/wheels-build.yaml@branch-24.10 with: build_type: ${{ inputs.build_type || 'branch' }} branch: ${{ inputs.branch }} @@ -60,7 +60,7 @@ jobs: wheel-publish: needs: wheel-build secrets: inherit - uses: rapidsai/shared-workflows/.github/workflows/wheels-publish.yaml@branch-24.02 + uses: rapidsai/shared-workflows/.github/workflows/wheels-publish.yaml@branch-24.10 with: build_type: ${{ inputs.build_type || 'branch' }} branch: ${{ inputs.branch }} diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index 74b53e3..8e536da 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -18,41 +18,41 @@ jobs: - wheel-build - wheel-tests secrets: inherit - uses: rapidsai/shared-workflows/.github/workflows/pr-builder.yaml@branch-24.02 + uses: rapidsai/shared-workflows/.github/workflows/pr-builder.yaml@branch-24.10 checks: secrets: inherit - uses: rapidsai/shared-workflows/.github/workflows/checks.yaml@branch-24.02 + uses: rapidsai/shared-workflows/.github/workflows/checks.yaml@branch-24.10 conda-python-build: needs: checks secrets: inherit - uses: rapidsai/shared-workflows/.github/workflows/conda-python-build.yaml@branch-24.02 + uses: rapidsai/shared-workflows/.github/workflows/conda-python-build.yaml@branch-24.10 with: build_type: pull-request - # Package is pure Python and only ever requires one build. - matrix_filter: 'map(select(.ARCH == "amd64" and (.LINUX_VER | test("centos")|not))) | sort_by(.PY_VER | split(".") | map(tonumber)) | [.[-1]]' + # This selects "ARCH=amd64 + the latest supported Python + CUDA". + matrix_filter: map(select(.ARCH == "amd64")) | max_by([(.PY_VER|split(".")|map(tonumber)), (.CUDA_VER|split(".")|map(tonumber))]) | [.] conda-python-tests: needs: conda-python-build secrets: inherit - uses: rapidsai/shared-workflows/.github/workflows/conda-python-tests.yaml@branch-24.02 + uses: rapidsai/shared-workflows/.github/workflows/conda-python-tests.yaml@branch-24.10 with: build_type: pull-request - # Package is pure Python and only ever requires one build. - matrix_filter: 'map(select(.ARCH == "amd64" and (.LINUX_VER | test("centos")|not))) | sort_by(.PY_VER | split(".") | map(tonumber)) | [.[-1]]' + # This selects "ARCH=amd64 + the latest supported Python + CUDA". + matrix_filter: map(select(.ARCH == "amd64")) | max_by([(.PY_VER|split(".")|map(tonumber)), (.CUDA_VER|split(".")|map(tonumber))]) | [.] wheel-build: needs: checks secrets: inherit - uses: rapidsai/shared-workflows/.github/workflows/wheels-build.yaml@branch-24.02 + uses: rapidsai/shared-workflows/.github/workflows/wheels-build.yaml@branch-24.10 with: build_type: pull-request - # Package is pure Python and only ever requires one build. - matrix_filter: 'map(select((.LINUX_VER | test("centos")|not))) | sort_by((.PY_VER | split(".") | map(tonumber))) | [.[-1] + {ARCH: "amd64"}]' + # This selects the latest supported Python + CUDA + matrix_filter: max_by([(.PY_VER|split(".")|map(tonumber)), (.CUDA_VER|split(".")|map(tonumber))]) | [.] script: "ci/build_wheel.sh" wheel-tests: needs: wheel-build secrets: inherit - uses: rapidsai/shared-workflows/.github/workflows/wheels-test.yaml@branch-24.02 + uses: rapidsai/shared-workflows/.github/workflows/wheels-test.yaml@branch-24.10 with: build_type: pull-request - # Package is pure Python and only ever requires one build. - matrix_filter: 'map(select(.ARCH == "amd64" and (.LINUX_VER | test("centos")|not))) | sort_by(.PY_VER | split(".") | map(tonumber)) | [.[-1]]' - script: "ci/test_wheel.sh" \ No newline at end of file + # This selects the latest supported Python + CUDA + matrix_filter: max_by([(.PY_VER|split(".")|map(tonumber)), (.CUDA_VER|split(".")|map(tonumber))]) | [.] + script: "ci/test_wheel.sh" diff --git a/.github/workflows/trigger-breaking-change-alert.yaml b/.github/workflows/trigger-breaking-change-alert.yaml new file mode 100644 index 0000000..3b972f3 --- /dev/null +++ b/.github/workflows/trigger-breaking-change-alert.yaml @@ -0,0 +1,26 @@ +name: Trigger Breaking Change Notifications + +on: + pull_request_target: + types: + - closed + - reopened + - labeled + - unlabeled + +jobs: + trigger-notifier: + if: contains(github.event.pull_request.labels.*.name, 'breaking') + secrets: inherit + uses: rapidsai/shared-workflows/.github/workflows/breaking-change-alert.yaml@branch-24.12 + with: + sender_login: ${{ github.event.sender.login }} + sender_avatar: ${{ github.event.sender.avatar_url }} + repo: ${{ github.repository }} + pr_number: ${{ github.event.pull_request.number }} + pr_title: "${{ github.event.pull_request.title }}" + pr_body: "${{ github.event.pull_request.body || '_Empty PR description_' }}" + pr_base_ref: ${{ github.event.pull_request.base.ref }} + pr_author: ${{ github.event.pull_request.user.login }} + event_action: ${{ github.event.action }} + pr_merged: ${{ github.event.pull_request.merged }} diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 469e3f1..45227a8 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -2,20 +2,20 @@ repos: - repo: https://github.com/psf/black - rev: 23.11.0 + rev: 24.8.0 hooks: - id: black files: jupyterlab_nvdashboard/.* # Explicitly specify the pyproject.toml at the repo root, not per-project. args: ['--config', 'pyproject.toml'] - repo: https://github.com/PyCQA/flake8 - rev: 6.1.0 + rev: 7.1.1 hooks: - id: flake8 args: ['--config=.flake8'] files: jupyterlab_nvdashboard/.*$ - repo: https://github.com/rapidsai/dependency-file-generator - rev: v1.7.1 + rev: v1.14.0 hooks: - id: rapids-dependency-file-generator args: ['--clean'] diff --git a/ci/build_wheel.sh b/ci/build_wheel.sh index 5a765f1..dd552c4 100755 --- a/ci/build_wheel.sh +++ b/ci/build_wheel.sh @@ -38,6 +38,8 @@ python -m pip install build # Build the Python package python -m build -s -w +ci/validate_wheel.sh dist + rapids-logger "Uploading JupyterLab NVDashboard wheels to S3" # Upload Python wheels to S3 -RAPIDS_PY_WHEEL_NAME="${package_name}" rapids-upload-wheels-to-s3 dist +RAPIDS_PY_WHEEL_NAME="${package_name}" RAPIDS_PY_WHEEL_PURE="1" rapids-upload-wheels-to-s3 dist diff --git a/ci/check_style.sh b/ci/check_style.sh index 32900f6..4ad78d9 100755 --- a/ci/check_style.sh +++ b/ci/check_style.sh @@ -8,7 +8,7 @@ rapids-logger "Create checks conda environment" rapids-dependency-file-generator \ --output conda \ - --file_key checks \ + --file-key checks \ --matrix "cuda=${RAPIDS_CUDA_VERSION%.*};arch=$(arch);py=${RAPIDS_PY_VERSION}" | tee env.yaml rapids-mamba-retry env create --yes -f env.yaml -n checks diff --git a/ci/test_python.sh b/ci/test_python.sh index 92f9a7d..a7ac3b8 100755 --- a/ci/test_python.sh +++ b/ci/test_python.sh @@ -8,7 +8,7 @@ set -euo pipefail rapids-logger "Generate Python testing dependencies" rapids-dependency-file-generator \ --output conda \ - --file_key test_python \ + --file-key test_python \ --matrix "cuda=${RAPIDS_CUDA_VERSION%.*};arch=$(arch);py=${RAPIDS_PY_VERSION}" | tee env.yaml rapids-mamba-retry env create --yes -f env.yaml -n test diff --git a/ci/test_wheel.sh b/ci/test_wheel.sh index 8497bd5..e9bc4fc 100755 --- a/ci/test_wheel.sh +++ b/ci/test_wheel.sh @@ -7,7 +7,7 @@ set -eou pipefail package_name="jupyterlab-nvdashboard" rapids-logger "Downloading artifacts from previous jobs" -RAPIDS_PY_WHEEL_NAME="${package_name}" rapids-download-wheels-from-s3 ./dist +RAPIDS_PY_WHEEL_NAME="${package_name}" RAPIDS_PY_WHEEL_PURE="1" rapids-download-wheels-from-s3 ./dist # echo to expand wildcard before adding `[extra]` required for pip python -m pip install $(echo ./dist/jupyterlab_nvdashboard*.whl)[test] diff --git a/ci/validate_wheel.sh b/ci/validate_wheel.sh new file mode 100755 index 0000000..60a80fc --- /dev/null +++ b/ci/validate_wheel.sh @@ -0,0 +1,18 @@ +#!/bin/bash +# Copyright (c) 2024, NVIDIA CORPORATION. + +set -euo pipefail + +wheel_dir_relative_path=$1 + +rapids-logger "validate packages with 'pydistcheck'" + +pydistcheck \ + --inspect \ + "$(echo ${wheel_dir_relative_path}/*.whl)" + +rapids-logger "validate packages with 'twine'" + +twine check \ + --strict \ + "$(echo ${wheel_dir_relative_path}/*.whl)" diff --git a/conda/environments/all_arch-any.yaml b/conda/environments/all_arch-any.yaml index e96db4f..5762fa1 100644 --- a/conda/environments/all_arch-any.yaml +++ b/conda/environments/all_arch-any.yaml @@ -10,7 +10,7 @@ dependencies: - nodejs=18 - pre-commit - psutil -- pynvml +- pynvml>=11.0.0,<12.0.0a0 - pytest - pytest-asyncio - pytest-jupyter[server]>=0.6.0 diff --git a/conda/recipes/jupyterlab-nvdashboard/meta.yaml b/conda/recipes/jupyterlab-nvdashboard/meta.yaml index 0bf73c2..f6960b6 100644 --- a/conda/recipes/jupyterlab-nvdashboard/meta.yaml +++ b/conda/recipes/jupyterlab-nvdashboard/meta.yaml @@ -26,7 +26,7 @@ requirements: run: - python >=3.8 - jupyterlab >=4 - - pynvml + - pynvml >=11.0.0,<12.0.0a0 - psutil diff --git a/dependencies.yaml b/dependencies.yaml index 59c226a..38a889e 100644 --- a/dependencies.yaml +++ b/dependencies.yaml @@ -72,7 +72,7 @@ dependencies: - output_types: [conda, requirements, pyproject] packages: - jupyterlab>=4 - - pynvml + - pynvml>=11.0.0,<12.0.0a0 - psutil test_python: common: diff --git a/jupyterlab_nvdashboard/apps/gpu.py b/jupyterlab_nvdashboard/apps/gpu.py index 6ba8eee..f8db278 100644 --- a/jupyterlab_nvdashboard/apps/gpu.py +++ b/jupyterlab_nvdashboard/apps/gpu.py @@ -26,9 +26,7 @@ # Maximum bandwidth is bidirectional, divide by 2 for separate RX & TX max_bw = ( - max( - sum(i.value.ullVal for i in bw) * 1024**2 for bw in bandwidth - ) + max(sum(i.value.ullVal for i in bw) * 1024**2 for bw in bandwidth) / 2 ) except (IndexError, pynvml.nvml.NVMLError_NotSupported): diff --git a/jupyterlab_nvdashboard/tests/test_cpu_handlers.py b/jupyterlab_nvdashboard/tests/test_cpu_handlers.py index a67f068..f967453 100644 --- a/jupyterlab_nvdashboard/tests/test_cpu_handlers.py +++ b/jupyterlab_nvdashboard/tests/test_cpu_handlers.py @@ -17,9 +17,10 @@ def mock_handler(monkeypatch): @pytest.fixture def handler_args(): - with patch("tornado.web.Application") as mock_application, patch( - "tornado.httputil.HTTPServerRequest" - ) as mock_request: + with ( + patch("tornado.web.Application") as mock_application, + patch("tornado.httputil.HTTPServerRequest") as mock_request, + ): # Mock the settings to return appropriate values mock_settings = { "base_url": "/", diff --git a/jupyterlab_nvdashboard/tests/test_gpu_handlers.py b/jupyterlab_nvdashboard/tests/test_gpu_handlers.py index 97752a0..7e997ca 100644 --- a/jupyterlab_nvdashboard/tests/test_gpu_handlers.py +++ b/jupyterlab_nvdashboard/tests/test_gpu_handlers.py @@ -23,9 +23,10 @@ def mock_handler(monkeypatch): @pytest.fixture def handler_args(): - with patch("tornado.web.Application") as mock_application, patch( - "tornado.httputil.HTTPServerRequest" - ) as mock_request: + with ( + patch("tornado.web.Application") as mock_application, + patch("tornado.httputil.HTTPServerRequest") as mock_request, + ): # Mock the settings to return appropriate values mock_settings = { "base_url": "/", diff --git a/package.json b/package.json index 054fdc2..cd574c9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jupyterlab-nvdashboard", - "version": "0.11.0", + "version": "0.12.0", "description": "A JupyterLab extension for displaying GPU usage dashboards", "keywords": [ "jupyter", diff --git a/pyproject.toml b/pyproject.toml index dfdf6c8..39b2c3d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,7 +31,7 @@ classifiers = [ dependencies = [ "jupyterlab>=4", "psutil", - "pynvml", + "pynvml>=11.0.0,<12.0.0a0", ] # This list was generated by `rapids-dependency-file-generator`. To make changes, edit dependencies.yaml and run `rapids-dependency-file-generator`. dynamic = ["version", "description", "authors", "urls", "keywords"] @@ -114,3 +114,11 @@ force-exclude = ''' package.json )/ ''' + +[tool.pydistcheck] +select = [ + "distro-too-large-compressed", +] + +# PyPI limit is 100 MiB, fail CI before we get too close to that +max_allowed_size_compressed = '75M' diff --git a/schema/config.json b/schema/config.json index e190eea..49d12da 100644 --- a/schema/config.json +++ b/schema/config.json @@ -1,6 +1,7 @@ { - "title": "jupyterlab-nvdashboard", + "title": "NVDashboard", "description": "Settings for the jupyterlab-nvdashboard extension.", + "jupyter.lab.setting-icon": "launcher:gpu-icon", "type": "object", "properties": { "updateFrequency": { diff --git a/style/icons/expansion-card.svg b/style/icons/expansion-card.svg index b8a85e5..82ead84 100644 --- a/style/icons/expansion-card.svg +++ b/style/icons/expansion-card.svg @@ -1,4 +1,4 @@ - - + +