Skill v1.0.0
currentTrusted Publisher100/100version: "1.0.0" name: local-publish-sts description: 'Build SQL Tools Service (STS) and run the Cake LocalPublish target so the resulting binaries are available under artifacts/publish for local testing. Use when: building STS locally, running LocalPublish, rebuilding STS after code changes, preparing STS for use by another extension/client, "publish STS", "local publish", "build SQL Tools Service", "rebuild STS". This skill only builds; if the goal is to also point vscode-mssql at the output, follow up with the hook-local-sts-into-mssql skill.'
Local-publish STS
Build and publish the SQL Tools Service locally via the Cake LocalPublish target. Produces a runnable MicrosoftSqlToolsServiceLayer host plus all companion service DLLs under artifacts/publish/.
When to use
- Iterating on STS code and wanting a fresh self-contained build.
- Preparing a local STS for vscode-mssql or any other client that consumes it
- The user says "build STS", "publish STS", "local publish", "rebuild STS".
This skill only builds. To wire the output into a vscode-mssql repo's environment, run the hook-local-sts-into-mssql skill afterward.
Procedure
Step 1: Run LocalPublish
From the STS repo root:
Windows:
.\build.ps1 --target=LocalPublish --configuration=Debug
On non-Windows:
./build.sh --target=LocalPublish --configuration=Debug
The build typically takes ~1–2 minutes on a warm cache. Use an initial_wait of at least 300 seconds when running via tools that need a hint.
Step 2: Confirm output
The published binaries live at (relative to repo root):
artifacts/publish/Microsoft.SqlTools.ServiceLayer/default/net10.0/
(.NET version may differ in the rare case that we've bumped to a new version)
Verify with Test-Path against MicrosoftSqlToolsServiceLayer.exe (Windows) or MicrosoftSqlToolsServiceLayer (Linux/macOS).
Step 3: Report back
Tell the user:
- ✅ Build succeeded.
- The absolute path to the publish folder (they'll need it if they want to wire it into a client).
- Reminder: re-run this skill after each STS code change, and stop any running consumer (e.g. EDH instances) first to release file locks (see "Handling lock errors" below).
Build targets
Defined in build.cake (search for Task(...)). For day-to-day dev, LocalPublish is what you want. The others are situational:
| Target | What it does | When to use | |
|---|---|---|---|
LocalPublish | Build + publish for the current RID only | Default dev loop | |
Quick | Cleanup + LocalPublish | After a botched build to start clean | |
Install | Cleanup + LocalPublish + copy to ~/.sqltoolsservice/local/ | Sharing with a globally-configured client | |
Local | Setup + Restore + TestAll + LocalPublish | Pre-PR sanity pass | |
Default | Alias for Local | Same as above | |
AllPublish | Publish for all RIDs in build.json | Reproducing CI artifacts | |
TestAll / TestCore | Run unit tests, must include --runTests argument | Test-only iteration |
Configuration flag accepts Debug (default for local work) or Release.
Handling lock errors
If LocalPublish fails with MSB3027 / MSB3021 "file is locked" errors mentioning MicrosoftSqlToolsServiceLayer.dll, Microsoft.SqlTools.Hosting.dll, or sibling DLLs, a previously launched consumer process is still running an STS host and holds locks on the publish output.
- Locate the locking processes:
``pwsh Get-CimInstance Win32_Process -Filter "Name='dotnet.exe'" | Where-Object { $_.CommandLine -like "*MicrosoftSqlToolsServiceLayer.dll*" -or $_.CommandLine -like "*SqlToolsResourceProviderService.dll*" } | Select-Object ProcessId, CommandLine ``
- Ask the user before killing them — they may be in the middle of an
active EDH / Azure Data Studio session they'd prefer to close manually.
- With approval, kill by PID (name-based termination isn't available in
the agent runtime):
``pwsh Stop-Process -Id <PID1>,<PID2> -Force ``
- Re-run the publish.
Notes
- The
net10.0segment of the publish path tracks theFrameworksarray inbuild.json. If the framework version changes, readbuild.jsonto get the new path segment rather than hardcoding it. LocalPublishwrites to thedefaultRID slot specifically because it depends on theRestrictToLocalRuntimetask. Other RIDs only appear afterAllPublish.