Development & Release¶
Prerequisites¶
- Node.js 22 (the version CI uses) and npm
- VS Code 1.100 or newer to run the extension
- For the documentation: Python 3 and
pip install -r requirements-docs.txt
Set up¶
Commands¶
| Command | What it does |
|---|---|
npm run build |
Bundles src/extension.ts with Vite into dist/extension.js (CommonJS, minified, Node 18 target; vscode and Node built-ins external) |
npm run watch |
The same in watch mode |
npm test |
Unit tests in src/test/ with Jest |
npm run test:e2e |
End-to-end tests in src/e2e/ that spawn real Jest and Vitest processes (--runInBand) |
npm run typecheck |
tsc --noEmit for the sources and, with tsconfig.test.json, for the tests |
npm run lint / npm run lint:fix |
Biome: lint and import organization, with --write to fix |
npm run format:fix |
Biome formatter (tabs, single quotes) |
npm run package |
vsce package → a .vsix to install locally |
npm run release:patch\|minor\|major |
npm version, which pushes the tag and starts the release workflow |
mkdocs serve |
The documentation at http://127.0.0.1:8000 with live reload |
Debug the extension¶
Press F5 (Run Extension): the npm: build task runs and a second VS Code window opens with the
extension loaded from dist/. Run Extension (Watch) rebuilds on every change; reload the window
(Developer: Reload Window) to pick it up. Extension examples opens the examples/ folder with a test
file so you have something to click.
The Jest Runner output channel in the development window shows the extension's own logs; set
"jestrunner.enableDebugLogs": true in that window for the verbose version.
Tests¶
Unit tests (src/test/)¶
Jest with babel-jest (TypeScript preset, CommonJS modules). The vscode module is replaced by
src/test/__mocks__/vscode.ts, a hand-written mock of the API the extension uses (workspace, window,
commands, tests, debug, Uri, Range, TestItem collections, configuration). The reporter templates'
?raw imports are mapped to the files via moduleNameMapper and a transform that returns the source as a
string.
Conventions:
- one
*.test.tsper behavior area, named after the module (testRunnerConfig.*.test.ts,TestController.*.test.ts,testDetection/*.test.ts), - the file system is mocked where detection is tested; real temp directories where parsing is tested,
src/test/testControllerSetup.tsbuilds a controller with mocked dependencies for the Test Explorer tests,- framework-specific behavior (arguments, config resolution, detection heuristics, Windows quoting) always has a test of its own; a bug fix comes with a regression test.
End-to-end tests (src/e2e/)¶
runners.e2e.test.ts installs nothing extra: it uses the Jest and Vitest of this repository's
node_modules, writes small test projects to a temp directory and runs them through TestRunExecutor and
TestRunner with the real spawn. It covers what mocks cannot: quoting of special test names in cmd.exe,
PowerShell and Git Bash, reporters loaded from the temp directory, result matching of real output, killing
the process tree on cancel. CI runs it on Ubuntu, Windows and macOS.
Continuous integration¶
.github/workflows/:
| Workflow | Trigger | What it does |
|---|---|---|
ci.yml |
push to master, pull requests (not drafts), called by release.yml; skipped for documentation-only changes |
matrix Ubuntu / Windows / macOS with Node 22: npm ci; on Ubuntu lint, typecheck and unit tests with coverage (uploaded to Codecov on master); unit tests on the others; e2e tests everywhere; then a build job that packages the .vsix and uploads it as an artifact |
release.yml |
a v* tag, or by hand |
runs ci.yml, creates the GitHub release with the .vsix and publishes to the Visual Studio Marketplace and Open VSX through the shared workflows in firsttris/workflows |
bump.yml |
by hand, choose patch / minor / major | bumps package.json, tags, and thereby starts release.yml |
docs.yml |
push to master touching docs/, mkdocs.yml, requirements-docs.txt or the workflow; pull requests (build only); by hand |
mkdocs build --strict and deployment to GitHub Pages |
Release¶
- Make sure
masteris green. - Either run Bump version in the Actions tab and pick the increment, or locally
npm run release:patch(orminor/major), which runsnpm versionand pushes the tag. - The tag starts
release.yml: checks, GitHub release with the.vsix, publish to both marketplaces. Versions already published are skipped, so re-running on an existing tag is safe.
The version in package.json is the single source of truth; CHANGELOG.md is maintained by hand for
notable releases.
Documentation¶
The site is built from docs/ with MkDocs Material:
pip install -r requirements-docs.txt
mkdocs serve # live preview
mkdocs build --strict # what CI runs; fails on broken links and missing pages
mkdocs.yml holds the navigation; add a page there when you add a file. Pages use plain Markdown with
admonitions (!!! tip), tabs (=== "Title"), Mermaid diagrams and key labels (++ctrl+shift+p++). Relative
links between pages ([x](usage.md)) work both on GitHub and on the site, which is why use_directory_urls
is off. Documentation-only changes do not trigger the CI build.
Adding a framework¶
The order that keeps the layers consistent:
testDetection/frameworkDefinitions.ts: name, config files, binary name.testDetection/frameworkDetection.ts: a content check (import or call pattern) if the framework can be recognized from the file;isFrameworkUsedInanddetectTestFrameworkpick up the definition.testDetection/configParsers/<name>Parser.tsandtestFileDetection.ts: which patterns the config contributes.frameworkAdapters.ts: the single-file arguments, including the name filter flag.testRunnerConfig.tsandconfig/Settings.ts(pluspackage.jsoncontributes.configuration): command, run options and debug options settings.execution/TestArgumentBuilder.ts: the batched strategy with the reporter or output format the Test Explorer will read, andtestResultProcessor.tsif a new parser is needed.debug/DebugConfigurationProvider.ts: the launch configuration.coverageProvider.ts: how its coverage report is found.- Tests for each step, a row in Supported Test Frameworks and the settings in the Settings Reference.
Conventions¶
- TypeScript strict mode; tabs and single quotes (Biome enforces both).
- Pure functions where possible (adapters, parsers, matchers); classes for things with lifecycle (terminal, controller, watchers).
- Every
vscodedependency behind a seam that the mock can serve; no partial real API in tests. - Log through
utils/Logger.ts, neverconsole. - Commit messages describe the change for the changelog reader (
fix: ...,CI: ...,feat: ...).