diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..5fb6c58 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,161 @@ +name: kernel gateway tests + +on: + push: + branches: ["main"] + pull_request: + schedule: + - cron: "0 0 * * *" + +defaults: + run: + shell: bash -eux {0} + +jobs: + build: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, macos-latest] + python-version: ["3.8", "3.11"] + include: + - os: macos-latest + python-version: "3.9" + - os: ubuntu-latest + python-version: "3.12" + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Base Setup + uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 + + - name: Run the tests + timeout-minutes: 15 + run: | + hatch run cov:test --cov-fail-under 50 || hatch run test:test --lf + + - name: Show help + run: | + pip install . + cd $HOME + jupyter kernelgateway --help + + - uses: jupyterlab/maintainer-tools/.github/actions/upload-coverage@v1 + + coverage: + runs-on: ubuntu-latest + needs: + - build + steps: + - uses: actions/checkout@v4 + - uses: jupyterlab/maintainer-tools/.github/actions/report-coverage@v1 + with: + fail_under: 80 + + test_lint: + name: Test Lint + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 + - name: Run Linters + run: | + #hatch run typing:test + hatch run lint:build + pipx run interrogate -vv . + pipx run doc8 --max-line-length=200 + + check_release: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 + - uses: jupyter-server/jupyter_releaser/.github/actions/check-release@v2 + with: + token: ${{ secrets.GITHUB_TOKEN }} + + test_docs: + runs-on: windows-latest + steps: + - uses: actions/checkout@v4 + - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 + - run: hatch run docs:build + + test_miniumum_versions: + name: Test Minimum Versions + timeout-minutes: 20 + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Base Setup + uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 + with: + dependency_type: minimum + + - name: List installed packages + run: | + hatch run test:list + + - name: Run the unit tests + run: | + hatch run test:nowarn || hatch run test:nowarn --lf + + test_prereleases: + name: Test Prereleases + runs-on: ubuntu-latest + timeout-minutes: 20 + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Base Setup + uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 + with: + dependency_type: pre + - name: Run the tests + run: | + hatch run test:nowarn || hatch run test:nowarn --lf + + make_sdist: + name: Make SDist + runs-on: ubuntu-latest + timeout-minutes: 20 + steps: + - uses: actions/checkout@v4 + - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 + - uses: jupyterlab/maintainer-tools/.github/actions/make-sdist@v1 + + test_sdist: + runs-on: ubuntu-latest + needs: [make_sdist] + name: Install from SDist and Test + timeout-minutes: 20 + steps: + - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 + - uses: jupyterlab/maintainer-tools/.github/actions/test-sdist@v1 + + link_check: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 + - uses: jupyterlab/maintainer-tools/.github/actions/check-links@v1 + + tests_check: # This job does nothing and is only used for the branch protection + if: always() + needs: + - coverage + - test_docs + - test_miniumum_versions + - test_lint + - test_prereleases + - check_release + - link_check + - test_sdist + runs-on: ubuntu-latest + steps: + - name: Decide whether the needed jobs succeeded or failed + uses: re-actors/alls-green@release/v1 + with: + jobs: ${{ toJSON(needs) }} diff --git a/.github/workflows/enforce-label.yml b/.github/workflows/enforce-label.yml new file mode 100644 index 0000000..75432d5 --- /dev/null +++ b/.github/workflows/enforce-label.yml @@ -0,0 +1,17 @@ +name: Enforce PR label + +concurrency: + group: label-${{ github.ref }} + cancel-in-progress: true + +on: + pull_request: + types: [labeled, unlabeled, opened, edited, synchronize] +jobs: + enforce-label: + runs-on: ubuntu-latest + permissions: + pull-requests: write + steps: + - name: enforce-triage-label + uses: jupyterlab/maintainer-tools/.github/actions/enforce-label@v1 diff --git a/.github/workflows/prep-release.yml b/.github/workflows/prep-release.yml new file mode 100644 index 0000000..7a2a18d --- /dev/null +++ b/.github/workflows/prep-release.yml @@ -0,0 +1,42 @@ +name: "Step 1: Prep Release" +on: + workflow_dispatch: + inputs: + version_spec: + description: "New Version Specifier" + default: "next" + required: false + branch: + description: "The branch to target" + required: false + post_version_spec: + description: "Post Version Specifier" + required: false + since: + description: "Use PRs with activity since this date or git reference" + required: false + since_last_stable: + description: "Use PRs with activity since the last stable git tag" + required: false + type: boolean +jobs: + prep_release: + runs-on: ubuntu-latest + steps: + - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 + + - name: Prep Release + id: prep-release + uses: jupyter-server/jupyter_releaser/.github/actions/prep-release@v2 + with: + token: ${{ secrets.ADMIN_GITHUB_TOKEN }} + version_spec: ${{ github.event.inputs.version_spec }} + post_version_spec: ${{ github.event.inputs.post_version_spec }} + target: ${{ github.event.inputs.target }} + branch: ${{ github.event.inputs.branch }} + since: ${{ github.event.inputs.since }} + since_last_stable: ${{ github.event.inputs.since_last_stable }} + + - name: "** Next Step **" + run: | + echo "Optional): Review Draft Release: ${{ steps.prep-release.outputs.release_url }}" diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml new file mode 100644 index 0000000..91cdcec --- /dev/null +++ b/.github/workflows/publish-release.yml @@ -0,0 +1,53 @@ +name: "Step 2: Publish Release" +on: + workflow_dispatch: + inputs: + branch: + description: "The target branch" + required: false + release_url: + description: "The URL of the draft GitHub release" + required: false + steps_to_skip: + description: "Comma separated list of steps to skip" + required: false + +jobs: + publish_release: + runs-on: ubuntu-latest + environment: release + steps: + - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 + + - name: Populate Release + id: populate-release + uses: jupyter-server/jupyter_releaser/.github/actions/populate-release@v2 + with: + token: ${{ secrets.ADMIN_GITHUB_TOKEN }} + target: ${{ github.event.inputs.target }} + branch: ${{ github.event.inputs.branch }} + release_url: ${{ github.event.inputs.release_url }} + steps_to_skip: ${{ github.event.inputs.steps_to_skip }} + + - name: Finalize Release + id: finalize-release + env: + TWINE_USERNAME: __token__ + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + uses: jupyter-server/jupyter-releaser/.github/actions/finalize-release@v2 + with: + token: ${{ secrets.ADMIN_GITHUB_TOKEN }} + target: ${{ github.event.inputs.target }} + release_url: ${{ steps.populate-release.outputs.release_url }} + + - name: "** Next Step **" + if: ${{ success() }} + run: | + echo "Verify the final release" + echo ${{ steps.finalize-release.outputs.release_url }} + + - name: "** Failure Message **" + if: ${{ failure() }} + run: | + echo "Failed to Publish the Draft Release Url:" + echo ${{ steps.populate-release.outputs.release_url }} diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml deleted file mode 100644 index 902ce52..0000000 --- a/.github/workflows/tests.yml +++ /dev/null @@ -1,45 +0,0 @@ -name: Tests - -on: - workflow_dispatch: - push: - pull_request: - branches: - - main - -jobs: - tests: - name: Run tests (Python ${{matrix.python}}) - - strategy: - matrix: - python: - - "3.8" - - "3.9" - - "3.10" - - "3.11" - - "3.12" - - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Base Setup - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 - - - name: Install dependencies - run: | - pip install -e . - pip freeze - - - name: Show help - run: jupyter kernelgateway --help - - - name: Run tests - run: hatch run cov:test - env: - ASYNC_TEST_TIMEOUT: 10 - - - name: Build docs - run: hatch run docs:build diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 32991c1..eb76474 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -65,10 +65,10 @@ repos: - id: ruff types_or: [python, jupyter] args: ["--fix", "--show-fixes"] - exclude: ^kernel_gateway/tests/resources/ + exclude: ^tests/resources/ - id: ruff-format types_or: [python, jupyter] - exclude: ^kernel_gateway/tests/resources/ + exclude: ^tests/resources/ - repo: https://github.com/scientific-python/cookie rev: "2023.12.21" diff --git a/CHANGELOG.md b/CHANGELOG.md index 803b36d..48d3b55 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # Changelog + + ## 2.5.0 (2020-04-19) ([Full Changelog](https://github.com/jupyter/kernel_gateway/compare/2.4.3...50b26c553d7eaf6556b1ea9fd8f424388ebb2e94)) @@ -19,6 +21,8 @@ [@bgerrity](https://github.com/search?q=repo%3Ajupyter%2Fkernel_gateway+involves%3Abgerrity+updated%3A2020-08-18..2021-04-19&type=Issues) | [@dolfinus](https://github.com/search?q=repo%3Ajupyter%2Fkernel_gateway+involves%3Adolfinus+updated%3A2020-08-18..2021-04-19&type=Issues) | [@kevin-bates](https://github.com/search?q=repo%3Ajupyter%2Fkernel_gateway+involves%3Akevin-bates+updated%3A2020-08-18..2021-04-19&type=Issues) | [@mwouts](https://github.com/search?q=repo%3Ajupyter%2Fkernel_gateway+involves%3Amwouts+updated%3A2020-08-18..2021-04-19&type=Issues) | [@willingc](https://github.com/search?q=repo%3Ajupyter%2Fkernel_gateway+involves%3Awillingc+updated%3A2020-08-18..2021-04-19&type=Issues) + + ## 2.4.3 (2020-08-18) - [PR-340](https://github.com/jupyter/kernel_gateway/pull/340) enable ssl_version as a JKG config option diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index 5abbd92..0000000 --- a/MANIFEST.in +++ /dev/null @@ -1,2 +0,0 @@ -include kernel_gateway/jupyter_websocket/swagger.* -include LICENSE.md diff --git a/RELEASE.md b/RELEASE.md new file mode 100644 index 0000000..3370c6c --- /dev/null +++ b/RELEASE.md @@ -0,0 +1,25 @@ +# Release Guide + +## Using `jupyter_releaser` + +The recommended way to make a release is to use [`jupyter_releaser`](https://jupyter-releaser.readthedocs.io/en/latest/get_started/making_release_from_repo.html). + +## Manual Release + +- Update `CHANGELOG` + +- Run the following: + +```bash +export VERSION= +pip install pipx +pipx run hatch version $VERSION +git commit -a -m "Release $VERSION" +git tag $VERSION; true; +git push --all +git push --tags +rm -rf dist build +pipx run build . +pipx run twine check dist/* +pipx run twine upload dist/* +``` diff --git a/pyproject.toml b/pyproject.toml index dda23ad..3682fc7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -33,12 +33,12 @@ classifiers = [ "Programming Language :: Python :: 3.11", ] dependencies = [ - "jupyter_client>=7.4.4", - "jupyter_core>=4.12,!=5.0.*", - "jupyter_server>=2.0", - "requests>=2.7,<3.0", - "tornado>=6.2.0", - "traitlets>=5.6.0", + "jupyter_client>=8.6", + "jupyter_core>=5.7", + "jupyter_server>=2.12", + "requests>=2.31", + "tornado>=6.4", + "traitlets>=5.14.1", ] [project.scripts] @@ -64,10 +64,12 @@ docs = [ [tool.hatch.version] path = "kernel_gateway/_version.py" +validate-bump = false [tool.hatch.build.targets.sdist] include = [ "/kernel_gateway", + "/tests" ] [tool.hatch.build.targets.wheel] @@ -81,13 +83,31 @@ build = "make -C docs html SPHINXOPTS='-W'" [tool.hatch.envs.test] features = ["test"] [tool.hatch.envs.test.scripts] +list = "python -m pip freeze" test = "python -m pytest -vv {args}" +nowarn = "test -W default {args}" [tool.hatch.envs.cov] features = ["test"] dependencies = ["coverage[toml]", "pytest-cov"] [tool.hatch.envs.cov.scripts] test = "python -m pytest -vv --cov kernel_gateway --cov-branch --cov-report term-missing:skip-covered {args}" +nowarn = "test -W default {args}" + +[tool.hatch.envs.typing] +dependencies = ["pre-commit"] +detached = true +[tool.hatch.envs.typing.scripts] +test = "pre-commit run --all-files --hook-stage manual mypy" + +[tool.hatch.envs.lint] +dependencies = ["pre-commit"] +detached = true +[tool.hatch.envs.lint.scripts] +build = [ + "pre-commit run --all-files ruff", + "pre-commit run --all-files ruff-format" +] [tool.ruff.lint] extend-select = [ @@ -142,7 +162,7 @@ disable_error_code = ["no-untyped-def", "no-untyped-call"] enable_error_code = ["ignore-without-code", "redundant-expr", "truthy-bool"] [tool.ruff.lint.per-file-ignores] -"kernel_gateway/tests/*" = ["T201", "S", "RET", "EM"] +"tests/*" = ["T201", "S", "RET", "EM"] "etc/*" = ["T201", "S", "RET"] [tool.pytest.ini_options] @@ -154,12 +174,40 @@ addopts = [ "--showlocals", "--strict-markers", "--strict-config" ] testpaths = [ - "kernel_gateway/tests/" + "tests/" ] filterwarnings = [ "error", "module:datetime.datetime.utc:DeprecationWarning", ] +[tool.coverage.report] +exclude_lines = [ + "pragma: no cover", + "def __repr__", + "if self.debug:", + "if settings.DEBUG", + "raise AssertionError", + "raise NotImplementedError", + "if 0:", + "if __name__ == .__main__.:", + "class .*\bProtocol\\):", + "@(abc\\.)?abstractmethod", +] + +[tool.coverage.run] +relative_files = true +source = ["kernel_gateway"] + +[tool.interrogate] +ignore-init-module=true +ignore-private=true +ignore-semiprivate=true +ignore-property-decorators=true +ignore-nested-functions=true +ignore-nested-classes=true +fail-under=70 +exclude = ["docs", "etc", "scripts", "tests"] + [tool.repo-review] ignore = ["GH102", "PC111"] diff --git a/kernel_gateway/tests/__init__.py b/tests/__init__.py similarity index 100% rename from kernel_gateway/tests/__init__.py rename to tests/__init__.py diff --git a/conftest.py b/tests/conftest.py similarity index 100% rename from conftest.py rename to tests/conftest.py diff --git a/kernel_gateway/tests/notebook_http/__init__.py b/tests/notebook_http/__init__.py similarity index 100% rename from kernel_gateway/tests/notebook_http/__init__.py rename to tests/notebook_http/__init__.py diff --git a/kernel_gateway/tests/notebook_http/cell/__init__.py b/tests/notebook_http/cell/__init__.py similarity index 100% rename from kernel_gateway/tests/notebook_http/cell/__init__.py rename to tests/notebook_http/cell/__init__.py diff --git a/kernel_gateway/tests/notebook_http/cell/test_parser.py b/tests/notebook_http/cell/test_parser.py similarity index 100% rename from kernel_gateway/tests/notebook_http/cell/test_parser.py rename to tests/notebook_http/cell/test_parser.py diff --git a/kernel_gateway/tests/notebook_http/swagger/__init__.py b/tests/notebook_http/swagger/__init__.py similarity index 100% rename from kernel_gateway/tests/notebook_http/swagger/__init__.py rename to tests/notebook_http/swagger/__init__.py diff --git a/kernel_gateway/tests/notebook_http/swagger/test_builders.py b/tests/notebook_http/swagger/test_builders.py similarity index 100% rename from kernel_gateway/tests/notebook_http/swagger/test_builders.py rename to tests/notebook_http/swagger/test_builders.py diff --git a/kernel_gateway/tests/notebook_http/swagger/test_parser.py b/tests/notebook_http/swagger/test_parser.py similarity index 100% rename from kernel_gateway/tests/notebook_http/swagger/test_parser.py rename to tests/notebook_http/swagger/test_parser.py diff --git a/kernel_gateway/tests/notebook_http/test_request_utils.py b/tests/notebook_http/test_request_utils.py similarity index 100% rename from kernel_gateway/tests/notebook_http/test_request_utils.py rename to tests/notebook_http/test_request_utils.py diff --git a/kernel_gateway/tests/resources/failing_code.ipynb b/tests/resources/failing_code.ipynb similarity index 100% rename from kernel_gateway/tests/resources/failing_code.ipynb rename to tests/resources/failing_code.ipynb diff --git a/kernel_gateway/tests/resources/kernel_api.ipynb b/tests/resources/kernel_api.ipynb similarity index 100% rename from kernel_gateway/tests/resources/kernel_api.ipynb rename to tests/resources/kernel_api.ipynb diff --git a/kernel_gateway/tests/resources/public/index.html b/tests/resources/public/index.html similarity index 100% rename from kernel_gateway/tests/resources/public/index.html rename to tests/resources/public/index.html diff --git a/kernel_gateway/tests/resources/responses.ipynb b/tests/resources/responses.ipynb similarity index 100% rename from kernel_gateway/tests/resources/responses.ipynb rename to tests/resources/responses.ipynb diff --git a/kernel_gateway/tests/resources/simple_api.ipynb b/tests/resources/simple_api.ipynb similarity index 100% rename from kernel_gateway/tests/resources/simple_api.ipynb rename to tests/resources/simple_api.ipynb diff --git a/kernel_gateway/tests/resources/unknown_kernel.ipynb b/tests/resources/unknown_kernel.ipynb similarity index 100% rename from kernel_gateway/tests/resources/unknown_kernel.ipynb rename to tests/resources/unknown_kernel.ipynb diff --git a/kernel_gateway/tests/resources/weirdly%20named#notebook.ipynb b/tests/resources/weirdly%20named#notebook.ipynb similarity index 100% rename from kernel_gateway/tests/resources/weirdly%20named#notebook.ipynb rename to tests/resources/weirdly%20named#notebook.ipynb diff --git a/kernel_gateway/tests/resources/zen.ipynb b/tests/resources/zen.ipynb similarity index 100% rename from kernel_gateway/tests/resources/zen.ipynb rename to tests/resources/zen.ipynb diff --git a/kernel_gateway/tests/test_gatewayapp.py b/tests/test_gatewayapp.py similarity index 100% rename from kernel_gateway/tests/test_gatewayapp.py rename to tests/test_gatewayapp.py diff --git a/kernel_gateway/tests/test_jupyter_websocket.py b/tests/test_jupyter_websocket.py similarity index 100% rename from kernel_gateway/tests/test_jupyter_websocket.py rename to tests/test_jupyter_websocket.py diff --git a/kernel_gateway/tests/test_mixins.py b/tests/test_mixins.py similarity index 100% rename from kernel_gateway/tests/test_mixins.py rename to tests/test_mixins.py diff --git a/kernel_gateway/tests/test_notebook_http.py b/tests/test_notebook_http.py similarity index 99% rename from kernel_gateway/tests/test_notebook_http.py rename to tests/test_notebook_http.py index 1393ff1..e4df4af 100644 --- a/kernel_gateway/tests/test_notebook_http.py +++ b/tests/test_notebook_http.py @@ -10,7 +10,8 @@ from tornado.httpclient import HTTPClientError from traitlets.config import Config -from ..notebook_http.swagger.handlers import SwaggerSpecHandler +from kernel_gateway.notebook_http.swagger.handlers import SwaggerSpecHandler + from .test_gatewayapp import RESOURCES