Thank you for your interest in contributing to the Deepnote VS Code extension! This guide will help you set up your development environment and understand the contribution workflow.
main branch |
|---|
- Node.js 22.15.1
- npm 10.9.2
- Python Minimum supported version as defined here
- Windows, macOS, or Linux
- Visual Studio Code
- The following VS Code extensions:
git clone https://github.com/deepnote/vscode-deepnote
cd vscode-deepnoteFirst, install all the recommended VS Code extensions. Open the Command Palette (Ctrl+Shift+P or Cmd+Shift+P) and run:
Extensions: Show Recommended Extensions
Then install all the extensions listed under "Workspace Recommendations".
On Apple Silicon, you will have to use system versions of libsodium and libzmq instead of the bundled ones. Also, you'll need to use Python 3.11 or older.
brew update
brew install cmake pkg-config libsodium zeromq
export CMAKE_POLICY_VERSION_MINIMUM=3.5
export PKG_CONFIG_PATH="$(brew --prefix)/lib/pkgconfig"
export CPPFLAGS="-I$(brew --prefix libsodium)/include -I$(brew --prefix zeromq)/include"
export LDFLAGS="-L$(brew --prefix libsodium)/lib -L$(brew --prefix zeromq)/lib"
npm_config_build_from_source=true npm install zeromq@
Install the dependecies:
npm install
# Run this to setup the necessary pre-commit hooks.
npm run setup-precommit-hook
python3 -m venv .venv
# Activate the virtual environment as appropriate for your shell, For example, on bash it's ...
source .venv/bin/activate
# and in Windows cmd or PowerShell
.venv\Scripts\activate
# The Python code in the extension is formatted using Black.
python -m pip install black
Run the watch build Tasks from the Run Build Task... command picker (short cut CTRL+SHIFT+B or ⇧⌘B). This will leave build tasks running in the background and which will re-run as files are edited and saved. You can see the output from either task in the Terminal panel (use the selector to choose which output to look at).
You can also compile from the command-line. For a full compile you can use:
npm run compile
For incremental builds it is recommended you use the watch build task (for better integration with VS Code).
Optionally you can use the following commands depending on your needs:
# This will compile everything, but only watch for changes to the desktop bundle.
# Note: Its advisable to use the `watch` task instead of this one (for integration with VS Code, e.g. view errors in problems window).
npm run watch
# This watches changes to all files, webviews, web version of extension, node version of extension, etc
# This can be resource intensive, as there are a number of bundles created, thus requiring monitoring of files for each of these numerous bundles.
npm run watch-allSometimes you will need to run npm run clean and even rm -r out dist.
This is especially true if you have added or removed files.
After completing the setup steps, you can run the Deepnote extension in development mode:
-
Open the project in VS Code
code . -
Start the watch task (for automatic recompilation)
- Press
Ctrl+Shift+B(Windows/Linux) or⇧⌘B(macOS) - Select
watchfrom the task list - This will continuously compile your changes in the background
- Press
-
Launch the Extension Development Host
- Press
F5or click the Run and Debug icon in the sidebar - Select
Extensionfrom the dropdown menu - Click the green play button
- A new VS Code window will open with
[Extension Development Host]in the title
- Press
-
Test your changes
- The Extension Development Host has the Deepnote extension loaded
- Open a Deepnote project or notebook file (
.deepnote) - Test the functionality you're working on
- Check the Debug Console in your main VS Code window for logs
-
Reload after making changes
- The watch task automatically recompiles when you save files
- In the Extension Development Host window, press
Ctrl+R(Windows/Linux) orCmd+R(macOS) to reload - Or restart the debug session with
Ctrl+Shift+F5/Cmd+Shift+F5
The project includes several launch configurations in .vscode/launch.json:
- Extension - Run the extension in a new VS Code window (most common for development)
- Extension (web) - Test the web version of the extension
- Extension inside container - Test in a containerized environment
- Unit Tests - Run unit tests without VS Code
- Tests (Jupyter+Python Extension installed) - Run integration tests
Click to expand debugging tips
Enable detailed logging:
Edit .vscode/launch.json and add environment variables:
"env": {
"VSC_JUPYTER_FORCE_LOGGING": "1",
"VSC_JUPYTER_LOG_TELEMETRY": "1",
"VSC_JUPYTER_LOG_IPYWIDGETS": "1"
}Set breakpoints:
- Click in the gutter next to line numbers in your TypeScript code
- Breakpoints will pause execution in the Extension Development Host
- Inspect variables in the Debug sidebar
View logs:
- Debug Console: Shows console.log output and errors
- Output panel: Select "Deepnote" from the dropdown to see extension-specific logs
- Terminal: Shows build output from the watch task
Common issues:
- If changes don't appear, try
npm run cleanand restart the watch task - If breakpoints don't work, ensure source maps are enabled (they are by default)
- If the extension doesn't load, check the Debug Console for errors
TypeScript errors and warnings will be displayed in the Problems window of Visual Studio Code.
To test changes, open the vscode-jupyter folder in VSCode, and select the workspace titled vscode-jupyter.
Then, open the debug panel by clicking the Run and Debug icon on the sidebar, select the Extension
option from the top menu, and click start. A new window will launch with the title
[Extension Development Host].
Note: Unit tests are those in files with extension .unit.test.ts.
- Make sure you have compiled all code (done automatically when using incremental building)
- Ensure you have disabled breaking into 'Uncaught Exceptions' when running the Unit Tests
- For the linters and formatters tests to pass successfully, you will need to have those corresponding Python libraries installed locally
- Run the Tests via the
Unit Testslaunch option.
You can also run them from the command-line (after compiling):
npm run test:unittests # runs all unit tests
npm run test:unittests -- --grep='<NAME-OF-SUITE>'To run only a specific test suite for unit tests:
Alter the launch.json file in the "Debug Unit Tests" section by setting the grep field:
"args": [
"--timeout=60000",
"--grep", "<suite name>"
],...this will only run the suite with the tests you care about during a test run (be sure to set the debugger to run the Debug Unit Tests launcher).
Note: Integration tests are those in files with extension *.vscode.test*.ts.
- Make sure you have compiled all code (done automatically when using incremental building)
- Some of the tests require specific virtual environments. Run the 'src/test/datascience/setupTestEnvs.cmd` (or equivalent) to create them.
- For the linters and formatters tests to pass successfully, you will need to have those corresponding Python libraries installed locally by using the
build/test-requirements.txtfile - Run the tests via
npm runor the Debugger launch options (you can "Start Without Debugging").
You can also run the tests from the command-line (after compiling):
npm run testVSCode # will launch the VSC UIIf you want to change which tests are run or which version of Python is used, you can do this by setting environment variables. The same variables work when running from the command line or launching from within VSCode, though the mechanism used to specify them changes a little.
- Setting
CI_PYTHON_PATHlets you change the version of python the tests are executed with - Setting
VSC_JUPYTER_CI_TEST_GREPlets you filter the tests by name
CI_PYTHON_PATH
In some tests a Python executable is actually run. The default executable is
python (for now). Unless you've run the tests inside a virtual environment,
this will almost always mean Python 2 is used, which probably isn't what you
want.
By setting the CI_PYTHON_PATH environment variable you can
control the exact Python executable that gets used. If the executable
you specify isn't on $PATH then be sure to use an absolute path.
This is also the mechanism for testing against other versions of Python.
VSC_JUPYTER_CI_TEST_GREP
This environment variable allows providing a regular expression which will be matched against suite and test "names" to be run. By default all tests are run.
For example, to run only the tests in the DataScience - Kernels Finder suite (from
src/test/datascience/kernel-launcher/kernelFinder.vscode.test.ts)
you would set the value to Kernels Finder.
Be sure to escape any grep-sensitive characters in your suite name.
In some rare cases in the "system" tests the VSC_JUPYTER_CI_TEST_GREP
environment variable is ignored. If that happens then you will need to
temporarily modify the const defaultGrep = line in
src/test/index.ts.
Launching from VSCode
In order to set environment variables when launching the tests from VSCode you
should edit the launch.json file. For example you can add the following to the
appropriate configuration you want to run to change the interpreter used during
testing:
"env": {
"CI_PYTHON_PATH": "/absolute/path/to/interpreter/of/choice/python"
}On the command line
The mechanism to set environment variables on the command line will vary based on your system, however most systems support a syntax like the following for setting a single variable for a subprocess:
VSC_JUPYTER_CI_TEST_GREP=Sorting npm run testVSCodeThe extension has a number of scripts in ./pythonFiles. Tests for these scripts are found in ./pythonFiles/tests. To run those tests:
python2.7 pythonFiles/tests/run_all.pypython3 -m pythonFiles.tests
By default, functional tests are included. To exclude them:
python3 -m pythonFiles.tests --no-functional
To run only the functional tests:
python3 -m pythonFiles.tests --functional
Clone the repo into any directory, open that directory in VSCode, and use the Extension launch option within VSCode.
Messages displayed to the user must be localized using/created constants from/in the localize.ts file.
To effectively contribute to this extension, it helps to know how its development process works. That way you know not only why the project maintainers do what they do to keep this project running smoothly, but it allows you to help out by noticing when a step is missed or to learn in case someday you become a project maintainer as well!
Here's an example of a typical workflow:
- Sync to main (get your fork's main to match vscode-jupyter's main)
- Create branch
npm installnpm run clean- Start VS code Insiders root
- CTRL+SHIFT+B (run the task
compile) - Make code changes
- Write and run unit tests if appropriate
- Test with
Extensionlaunch task - Repeat until works in normal extension
- Test with
Extension (web)launch task - Run jupyter notebook server to use in web testing
- Repeat until works in web extension
- Write integration tests and run locally.
- Submit PR
- Check PR output to make sure tests don't fail.
- Debug CI test failures
First and foremost, we try to be helpful to users of the extension. We monitor Stack Overflow questions to see where people might need help. We also try to respond to all issues in some way in a timely manner (typically in less than one business day, definitely no more than a week). We also answer questions that reach us in other ways, e.g. Twitter.
For pull requests, we aim to review any externally contributed PR no later than the next sprint from when it was submitted (see Release Cycle below for our sprint schedule).
Planning is done as monthly releases.
The extension aims to do a new release once a month. A release plan is created for each release to help track anything that requires a person to do (long-term this project aims to automate as much of the development process as possible).
All development is actively done in the main branch of the
repository. This allows us to have a
development build which is expected to be stable at
all times. Once we reach a release candidate, it becomes
our release branch.
At that point only what is in the release branch will make it into the next
release.
Key details that all pull requests are expected to handle should be in the pull request template. We do expect CI to be passing for a pull request before we will consider merging it.
The extension sets the major version be the year of release, the minor version the
release count for that year, and the build number is a number that increments
for every build.
For example the first release in 2021 is 2021.1.<build number>.
Overall steps for releasing are covered in the release plan (template).
To create a release build, follow the steps outlined in the release plan (which has a template).
Steps to build the extension on your machine once you've cloned the repo:
> npm install -g @vscode/vsce
# Perform the next steps in the vscode-jupyter folder.
> npm install
> npm run clean
> npm run package # This step takes around 10 minutes.Resulting in a ms-toolsai-jupyter-insiders.vsix file in your vscode-jupyter folder.
package.json, run npm install (instead of npm ci) to update package-lock.json and install dependencies all at once.