From 968a522fed6d85d72bb46b7d92cfa6840c4cd165 Mon Sep 17 00:00:00 2001 From: Adam Ward Date: Tue, 29 Jul 2025 13:01:19 -0400 Subject: [PATCH] Bump extension version --- .github/workflows/nightly.yml | 8 +- .github/workflows/pull_request.yml | 6 +- .github/workflows/scripts/setup-linux.sh | 2 - .github/workflows/scripts/windows/setup.ps1 | 5 ++ .vscode-test.js | 81 ++++++++++--------- .vscodeignore | 2 +- package-lock.json | 4 +- package.json | 2 +- scripts/dev_package.ts | 21 +---- scripts/download_vsix.ts | 51 +++++++----- scripts/lib/utilities.ts | 44 +++++++++- scripts/package.ts | 22 +---- scripts/preview_package.ts | 40 +++++---- scripts/test_windows.ps1 | 1 - scripts/versions.js | 37 --------- src/debugger/lldb.ts | 4 +- src/sourcekit-lsp/LanguageClientManager.ts | 20 +++++ .../extensions/PollIndexRequest.ts | 32 ++++++++ src/utilities/utilities.ts | 21 +++-- test/integration-tests/debugger/lldb.test.ts | 4 +- .../LanguageClientIntegration.test.ts | 6 +- .../utilities/lsputilities.ts | 33 -------- 22 files changed, 231 insertions(+), 215 deletions(-) delete mode 100644 scripts/versions.js create mode 100644 src/sourcekit-lsp/extensions/PollIndexRequest.ts diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 831524515..07e21444e 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -66,9 +66,8 @@ jobs: windows_env_vars: | CI=1 VSCODE_SWIFT_VSIX_ID=${{needs.package.outputs.artifact-id}} - VSCODE_SWIFT_VSIX=vscode-swift.vsix GITHUB_REPOSITORY=${{github.repository}} - windows_pre_build_command: .github\workflows\scripts\windows\setup.ps1 + windows_pre_build_command: . .github\workflows\scripts\windows\setup.ps1 windows_build_command: scripts\test_windows.ps1 enable_windows_docker: false @@ -87,6 +86,7 @@ jobs: CI=1 VSCODE_VERSION=insiders VSCODE_SWIFT_VSIX_ID=${{needs.package.outputs.artifact-id}} + VSCODE_SWIFT_VSIX_PRERELEASE=1 GITHUB_REPOSITORY=${{github.repository}} linux_pre_build_command: . .github/workflows/scripts/setup-linux.sh linux_build_command: ./scripts/test.sh @@ -96,8 +96,8 @@ jobs: CI=1 VSCODE_VERSION=insiders VSCODE_SWIFT_VSIX_ID=${{needs.package.outputs.artifact-id}} - VSCODE_SWIFT_PRERELEASE_VSIX=vscode-swift-prerelease.vsix + VSCODE_SWIFT_VSIX_PRERELEASE=1 GITHUB_REPOSITORY=${{github.repository}} - windows_pre_build_command: .github\workflows\scripts\windows\setup.ps1 + windows_pre_build_command: . .github\workflows\scripts\windows\setup.ps1 windows_build_command: scripts\test_windows.ps1 enable_windows_docker: false diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 4ffd2739e..e69f3360d 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -23,8 +23,7 @@ jobs: . .github/workflows/scripts/setup-linux.sh [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" npm ci - npm run package - npm run preview-package + npm run dev-package for file in *.vsix; do name="$(basename "$file" .vsix)-${{github.run_number}}.vsix" echo "Created bundle $name" @@ -67,9 +66,8 @@ jobs: CI=1 FAST_TEST_RUN=${{ contains(github.event.pull_request.labels.*.name, 'full-test-run') && '0' || '1'}} VSCODE_SWIFT_VSIX_ID=${{needs.package.outputs.artifact-id}} - VSCODE_SWIFT_VSIX=vscode-swift.vsix GITHUB_REPOSITORY=${{github.repository}} - windows_pre_build_command: .github\workflows\scripts\windows\setup.ps1 + windows_pre_build_command: . .github\workflows\scripts\windows\setup.ps1 windows_build_command: scripts\test_windows.ps1 enable_windows_docker: false diff --git a/.github/workflows/scripts/setup-linux.sh b/.github/workflows/scripts/setup-linux.sh index e68846393..01cc9530d 100755 --- a/.github/workflows/scripts/setup-linux.sh +++ b/.github/workflows/scripts/setup-linux.sh @@ -29,6 +29,4 @@ env | sort if [ -n "$VSCODE_SWIFT_VSIX_ID" ]; then npm ci --ignore-scripts npx tsx scripts/download_vsix.ts - export VSCODE_SWIFT_VSIX="vscode-swift.vsix" - export VSCODE_SWIFT_PRERELEASE_VSIX="vscode-swift-prerelease.vsix" fi diff --git a/.github/workflows/scripts/windows/setup.ps1 b/.github/workflows/scripts/windows/setup.ps1 index fddfcc87b..2b20d25f1 100644 --- a/.github/workflows/scripts/windows/setup.ps1 +++ b/.github/workflows/scripts/windows/setup.ps1 @@ -10,3 +10,8 @@ if ($Process.ExitCode -eq 0) { Write-Host ('FAILED ({0})' -f $Process.ExitCode) exit 1 } + +Get-Content $env:GITHUB_ENV | foreach { + $name, $value = $_.split('=') + Set-Content env:\$name $value +} diff --git a/.vscode-test.js b/.vscode-test.js index 010a3e45b..7f60e5848 100644 --- a/.vscode-test.js +++ b/.vscode-test.js @@ -15,7 +15,6 @@ const { defineConfig } = require("@vscode/test-cli"); const path = require("path"); const { version, publisher, name } = require("./package.json"); -const { preview } = require("./scripts/versions"); const isCIBuild = process.env["CI"] === "1"; const isFastTestRun = process.env["FAST_TEST_RUN"] === "1"; @@ -41,51 +40,67 @@ if (dataDir) { if (process.platform === "darwin" && process.arch === "x64") { launchArgs.push("--disable-gpu"); } -const isStableRun = process.env["VSCODE_VERSION"] !== "insiders"; + +const installExtensions = []; +let vsixPath = process.env["VSCODE_SWIFT_VSIX"]; let versionStr = version; -if (!isStableRun) { - const segments = version.split(".").map(v => parseInt(v, 10)); - versionStr = preview({ major: segments[0], minor: segments[1], patch: segments[2] }); -} -let vsixPath = isStableRun - ? process.env["VSCODE_SWIFT_VSIX"] - : process.env["VSCODE_SWIFT_PRERELEASE_VSIX"]; -const install = []; -const installExtensions = ["vadimcn.vscode-lldb", "llvm-vs-code-extensions.lldb-dap"]; +let extensionDevelopmentPath; if (vsixPath) { + // https://github.com/swiftlang/vscode-swift/issues/1751 + // Will install extensions before CI tests run + installExtensions.push("vadimcn.vscode-lldb", "llvm-vs-code-extensions.lldb-dap"); + + // Absolute path to vsix needed if (!path.isAbsolute(vsixPath)) { vsixPath = path.join(__dirname, vsixPath); } - console.log("Installing " + vsixPath); + console.log("Installing VSIX " + vsixPath); installExtensions.push(vsixPath); + + // Determine version to use + const match = /swift-vscode-(\d+.\d+.\d+(-dev)?)(-\d+)?.vsix/g.exec(path.basename(vsixPath)); + if (match) { + versionStr = match[1]; + } + console.log("Running tests against extension version " + versionStr); + + extensionDevelopmentPath = `${__dirname}/.vscode-test/extensions/${publisher}.${name}-${versionStr}`; + console.log("Running tests against extension development path " + extensionDevelopmentPath); } +const vscodeVersion = process.env["VSCODE_VERSION"] ?? "stable"; +console.log("Running tests against VS Code version " + vscodeVersion); + +const installConfigs = []; for (const ext of installExtensions) { - install.push({ + installConfigs.push({ label: `installExtension-${ext}`, installExtensions: [ext], - launchArgs, + launchArgs: launchArgs.concat("--disable-extensions"), files: ["dist/test/sleep.test.js"], - version: process.env["VSCODE_VERSION"] ?? "stable", + version: vscodeVersion, + skipExtensionDependencies: true, reuseMachineInstall: !isCIBuild, }); } +const env = { + ...process.env, + RUNNING_UNDER_VSCODE_TEST_CLI: "1", +}; +console.log("Running tests against environment:\n" + JSON.stringify(env, undefined, 2)); + module.exports = defineConfig({ tests: [ - ...install, + ...installConfigs, { label: "integrationTests", files: ["dist/test/common.js", "dist/test/integration-tests/**/*.test.js"], - version: process.env["VSCODE_VERSION"] ?? "stable", + version: vscodeVersion, workspaceFolder: "./assets/test", launchArgs, - extensionDevelopmentPath: vsixPath - ? [`${__dirname}/.vscode-test/extensions/${publisher}.${name}-${versionStr}`] - : undefined, - env: { - VSCODE_TEST: "1", - }, + extensionDevelopmentPath, + env, mocha: { ui: "tdd", color: true, @@ -102,7 +117,7 @@ module.exports = defineConfig({ }, }, }, - skipExtensionDependencies: install.length > 0, + skipExtensionDependencies: installConfigs.length > 0, reuseMachineInstall: !isCIBuild, }, { @@ -116,15 +131,11 @@ module.exports = defineConfig({ "dist/test/integration-tests/testexplorer/TestExplorerIntegration.test.js", "dist/test/integration-tests/commands/dependency.test.js", ], - version: process.env["VSCODE_VERSION"] ?? "stable", + version: vscodeVersion, workspaceFolder: "./assets/test.code-workspace", launchArgs, - extensionDevelopmentPath: vsixPath - ? [`${__dirname}/.vscode-test/extensions/${publisher}.${name}-${versionStr}`] - : undefined, - env: { - VSCODE_TEST: "1", - }, + extensionDevelopmentPath, + env, mocha: { ui: "tdd", color: true, @@ -141,17 +152,15 @@ module.exports = defineConfig({ }, }, }, - skipExtensionDependencies: install.length > 0, + skipExtensionDependencies: installConfigs.length > 0, reuseMachineInstall: !isCIBuild, }, { label: "unitTests", files: ["dist/test/common.js", "dist/test/unit-tests/**/*.test.js"], - version: process.env["VSCODE_VERSION"] ?? "stable", + version: vscodeVersion, launchArgs: launchArgs.concat("--disable-extensions"), - env: { - VSCODE_TEST: "1", - }, + env, mocha: { ui: "tdd", color: true, diff --git a/.vscodeignore b/.vscodeignore index 10751b3fd..15e06a506 100644 --- a/.vscodeignore +++ b/.vscodeignore @@ -1,7 +1,7 @@ **/* !LICENSE !NOTICE.txt -!CHANGELOG.md +!CHANGELOG-*.md !README.md !icon.png !package.json diff --git a/package-lock.json b/package-lock.json index 805aa1bc5..52d565142 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "swift-vscode", - "version": "2.8.0", + "version": "2.12.0-dev", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "swift-vscode", - "version": "2.8.0", + "version": "2.12.0-dev", "hasInstallScript": true, "dependencies": { "@vscode/codicons": "^0.0.38", diff --git a/package.json b/package.json index 4884de8e2..91d44386c 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "swift-vscode", "displayName": "Swift", "description": "Swift Language Support for Visual Studio Code.", - "version": "2.10.0", + "version": "2.12.0-dev", "publisher": "swiftlang", "icon": "icon.png", "repository": { diff --git a/scripts/dev_package.ts b/scripts/dev_package.ts index 4595c0517..e1c6b5641 100644 --- a/scripts/dev_package.ts +++ b/scripts/dev_package.ts @@ -13,26 +13,11 @@ //===----------------------------------------------------------------------===// /* eslint-disable no-console */ -import { - exec, - getExtensionVersion, - getRootDirectory, - main, - updateChangelog, -} from "./lib/utilities"; -// eslint-disable-next-line @typescript-eslint/no-require-imports -const { dev } = require("./versions"); +import { getExtensionVersion, main, packageExtension } from "./lib/utilities"; // eslint-disable-next-line @typescript-eslint/no-floating-promises main(async () => { - const rootDirectory = getRootDirectory(); const version = await getExtensionVersion(); - // Increment the patch version from the package.json - const devVersion = dev(version); - // Update version in CHANGELOG - await updateChangelog(devVersion); - // Use VSCE to package the extension - await exec("npx", ["vsce", "package", "--no-update-package-json", devVersion], { - cwd: rootDirectory, - }); + const devVersion = `${version.major}.${version.minor}.${version.patch}-dev`; + await packageExtension(devVersion); }); diff --git a/scripts/download_vsix.ts b/scripts/download_vsix.ts index 27e89d3bd..88986acd0 100644 --- a/scripts/download_vsix.ts +++ b/scripts/download_vsix.ts @@ -13,12 +13,15 @@ //===----------------------------------------------------------------------===// /* eslint-disable no-console */ -import decompress from "decompress"; +import * as DecompressType from "decompress"; import { createWriteStream } from "node:fs"; -import { rename, unlink } from "node:fs/promises"; +import { appendFile, unlink } from "node:fs/promises"; import { pipeline } from "node:stream/promises"; import { Octokit } from "octokit"; +// eslint-disable-next-line @typescript-eslint/no-require-imports +const decompress: typeof DecompressType = require("decompress"); + const artifact_id = process.env["VSCODE_SWIFT_VSIX_ID"]; if (!artifact_id) { console.error("No VSCODE_SWIFT_VSIX_ID provided"); @@ -29,6 +32,11 @@ if (!token) { console.error("No GITHUB_TOKEN provided"); process.exit(1); } +const envFile = process.env["GITHUB_ENV"]; +if (!envFile) { + console.error("No GITHUB_ENV provided"); + process.exit(1); +} const repository = process.env["GITHUB_REPOSITORY"] || "swiftlang/vscode-swift"; const owner = repository.split("/")[0]; const repo = repository.split("/")[1]; @@ -57,22 +65,29 @@ const repo = repository.split("/")[1]; await pipeline(data, createWriteStream("artifacts.zip", data)); const files = await decompress("artifacts.zip", process.cwd()); console.log(`Downloaded artifact(s): ${files.map(f => f.path).join(", ")}`); - const newName = process.env["VSCODE_SWIFT_VSIX"] || "vscode-swift.vsix"; - const releaseVSIX = files.find(f => /swift-vscode-\d+.\d+.\d+-\d+.vsix/m.test(f.path)); - if (!releaseVSIX) { - console.error("Cound not find vscode-swift release VSIX in artifact bundle"); - process.exit(1); - } - await rename(releaseVSIX.path, newName); - const prereleaseVSIX = files.find(f => /swift-vscode-\d+.\d+.\d{8}-\d+.vsix/m.test(f.path)); - if (!prereleaseVSIX) { - console.error("Cound not find vscode-swift pre-release VSIX in artifact bundle"); - process.exit(1); + const testPrerelease = process.env["VSCODE_SWIFT_VSIX_PRERELEASE"] === "1"; + if (testPrerelease) { + const prereleaseVSIX = files.find(f => + /swift-vscode-\d+.\d+.\d{8}(-dev)?-\d+.vsix/m.test(f.path) + ); + if (prereleaseVSIX) { + await appendFile(envFile, `VSCODE_SWIFT_VSIX=${prereleaseVSIX.path}\n`); + console.log(`Running tests against: ${prereleaseVSIX.path}`); + } else { + console.error("Cound not find vscode-swift pre-release VSIX in artifact bundle"); + process.exit(1); + } + } else { + const releaseVSIX = files.find(f => + /swift-vscode-\d+.\d+.\d+(-dev)?-\d+.vsix/m.test(f.path) + ); + if (releaseVSIX) { + await appendFile(envFile, `VSCODE_SWIFT_VSIX=${releaseVSIX.path}\n`); + console.log(`Running tests against: ${releaseVSIX.path}`); + } else { + console.error("Cound not find vscode-swift release VSIX in artifact bundle"); + process.exit(1); + } } - console.log(`Renamed artifact: ${releaseVSIX.path} => ${newName}`); - const preNewName = - process.env["VSCODE_SWIFT_PRERELEASE_VSIX"] || "vscode-swift-prerelease.vsix"; - await rename(prereleaseVSIX.path, preNewName); - console.log(`Renamed artifact: ${prereleaseVSIX.path} => ${preNewName}`); await unlink("artifacts.zip"); })(); diff --git a/scripts/lib/utilities.ts b/scripts/lib/utilities.ts index 86043bf2d..0dc5bbc0d 100644 --- a/scripts/lib/utilities.ts +++ b/scripts/lib/utilities.ts @@ -14,7 +14,7 @@ /* eslint-disable no-console */ import * as child_process from "child_process"; -import { mkdtemp, readFile, rm } from "fs/promises"; +import { copyFile, mkdtemp, readFile, rm } from "fs/promises"; import * as path from "path"; import * as os from "os"; import * as semver from "semver"; @@ -126,9 +126,11 @@ export async function withTemporaryDirectory( } } -export async function updateChangelog(version: string): Promise { +export async function updateChangelog(version: string): Promise { + const tempChangelog = path.join(getRootDirectory(), `CHANGELOG-${version}.md`); + await copyFile(getChangelog(), tempChangelog); await replaceInFile({ - files: getChangelog(), + files: tempChangelog, from: /{{releaseVersion}}/g, to: version, }); @@ -137,8 +139,42 @@ export async function updateChangelog(version: string): Promise { const month = (date.getUTCMonth() + 1).toString().padStart(2, "0"); const day = date.getUTCDate().toString().padStart(2, "0"); await replaceInFile({ - files: getChangelog(), + files: tempChangelog, from: /{{releaseDate}}/g, to: `${year}-${month}-${day}`, }); + return tempChangelog; +} + +export async function packageExtension(version: string) { + // Update version in a temporary CHANGELOG + const changelogPath = await updateChangelog(version); + + // Use VSCE to package the extension + // Note: There are no sendgrid secrets in the extension. `--allow-package-secrets` works around a false positive + // where the symbol `SG.MessageTransports.is` can appear in the dist.js if we're unlucky enough + // to have `SG` as the minified name of a namespace. Here is the rule we sometimes mistakenly match: + // https://github.com/secretlint/secretlint/blob/5706ac4942f098b845570541903472641d4ae914/packages/%40secretlint/secretlint-rule-sendgrid/src/index.ts#L35 + await exec( + "npx", + [ + "vsce", + "package", + "--allow-package-secrets", + "sendgrid", + "--no-update-package-json", + "--changelog-path", + path.basename(changelogPath), + version, + ], + { + cwd: getRootDirectory(), + } + ); + + // Clean up temporary changelog + await rm(changelogPath, { force: true }).catch(error => { + console.error(`Failed to remove temporary changelog '${changelogPath}'`); + console.error(error); + }); } diff --git a/scripts/package.ts b/scripts/package.ts index 397cbdccf..bb486c5f2 100644 --- a/scripts/package.ts +++ b/scripts/package.ts @@ -13,18 +13,12 @@ //===----------------------------------------------------------------------===// /* eslint-disable no-console */ -import { - exec, - getExtensionVersion, - getRootDirectory, - main, - updateChangelog, -} from "./lib/utilities"; +import { getExtensionVersion, main, packageExtension } from "./lib/utilities"; // eslint-disable-next-line @typescript-eslint/no-floating-promises main(async () => { - const rootDirectory = getRootDirectory(); const version = await getExtensionVersion(); + // Leave the "prerelease" tag out const versionString = `${version.major}.${version.minor}.${version.patch}`; if (process.platform === "win32") { @@ -32,15 +26,5 @@ main(async () => { return process.exit(0); } - // Update version in CHANGELOG - await updateChangelog(versionString); - - // Use VSCE to package the extension - // Note: There are no sendgrid secrets in the extension. `--allow-package-secrets` works around a false positive - // where the symbol `SG.MessageTransports.is` can appear in the dist.js if we're unlucky enough - // to have `SG` as the minified name of a namespace. Here is the rule we sometimes mistakenly match: - // https://github.com/secretlint/secretlint/blob/5706ac4942f098b845570541903472641d4ae914/packages/%40secretlint/secretlint-rule-sendgrid/src/index.ts#L35 - await exec("npx", ["vsce", "package", "--allow-package-secrets", "sendgrid"], { - cwd: rootDirectory, - }); + await packageExtension(versionString); }); diff --git a/scripts/preview_package.ts b/scripts/preview_package.ts index d14b39179..43705e940 100644 --- a/scripts/preview_package.ts +++ b/scripts/preview_package.ts @@ -12,23 +12,28 @@ // //===----------------------------------------------------------------------===// /* eslint-disable no-console */ -import { - exec, - getExtensionVersion, - getRootDirectory, - main, - updateChangelog, -} from "./lib/utilities"; -// eslint-disable-next-line @typescript-eslint/no-require-imports -const { preview } = require("./versions"); +import { getExtensionVersion, main, packageExtension } from "./lib/utilities"; + +/** + * Formats the given date as a string in the form "YYYYMMdd". + * + * @param date The date to format as a string. + * @returns The formatted date. + */ +function formatDate(date: Date): string { + const year = date.getUTCFullYear().toString().padStart(4, "0"); + const month = (date.getUTCMonth() + 1).toString().padStart(2, "0"); + const day = date.getUTCDate().toString().padStart(2, "0"); + return year + month + day; +} // eslint-disable-next-line @typescript-eslint/no-floating-promises main(async () => { - const rootDirectory = getRootDirectory(); const version = await getExtensionVersion(); - // Increment the minor version and set the patch version to today's date - const minor = version.minor + 1; - const previewVersion = preview(version); + // Decrement the minor version and set the patch version to today's date + const minor = version.minor - 1; + const patch = formatDate(new Date()); + const previewVersion = `${version.major}.${minor}.${patch}`; // Make sure that the new minor version is odd if (minor % 2 !== 1) { throw new Error( @@ -36,12 +41,5 @@ main(async () => { " The version in the package.json has probably been incorrectly set to an odd minor version." ); } - // Update version in CHANGELOG - await updateChangelog(previewVersion); - // Use VSCE to package the extension - await exec( - "npx", - ["vsce", "package", "--pre-release", "--no-update-package-json", previewVersion], - { cwd: rootDirectory } - ); + await packageExtension(previewVersion); }); diff --git a/scripts/test_windows.ps1 b/scripts/test_windows.ps1 index 2f88225da..fe156ea92 100644 --- a/scripts/test_windows.ps1 +++ b/scripts/test_windows.ps1 @@ -128,7 +128,6 @@ if ($versionLine -match "Swift version (\d+)\.(\d+)") { npm ci -ignore-script node-pty npm run lint npm run format -npm run package npm run test if ($LASTEXITCODE -eq 0) { Write-Host 'SUCCESS' diff --git a/scripts/versions.js b/scripts/versions.js deleted file mode 100644 index fd2fe66a8..000000000 --- a/scripts/versions.js +++ /dev/null @@ -1,37 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the VS Code Swift open source project -// -// Copyright (c) 2025 the VS Code Swift project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of VS Code Swift project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// -/** - * Formats the given date as a string in the form "YYYYMMdd". - * - * @param date The date to format as a string. - * @returns The formatted date. - */ -function formatDate(date) { - const year = date.getUTCFullYear().toString().padStart(4, "0"); - const month = (date.getUTCMonth() + 1).toString().padStart(2, "0"); - const day = date.getUTCDate().toString().padStart(2, "0"); - return year + month + day; -} - -module.exports = { - preview: function (version) { - const minor = version.minor + 1; - const patch = formatDate(new Date()); - return `${version.major}.${minor}.${patch}`; - }, - dev: function (version) { - const patch = version.patch + 1; - return `${version.major}.${version.minor}.${patch}-dev`; - }, -}; diff --git a/src/debugger/lldb.ts b/src/debugger/lldb.ts index 808aa6c3a..7d56b79ba 100644 --- a/src/debugger/lldb.ts +++ b/src/debugger/lldb.ts @@ -18,7 +18,7 @@ import * as vscode from "vscode"; import * as path from "path"; import * as fs from "fs/promises"; -import { execFile, IS_RUNNING_IN_CI } from "../utilities/utilities"; +import { execFile, IS_RUNNING_UNDER_TEST } from "../utilities/utilities"; import { Result } from "../utilities/result"; import { SwiftToolchain } from "../toolchain/toolchain"; @@ -30,7 +30,7 @@ import { SwiftToolchain } from "../toolchain/toolchain"; export function updateLaunchConfigForCI( config: vscode.DebugConfiguration ): vscode.DebugConfiguration { - if (!IS_RUNNING_IN_CI) { + if (!IS_RUNNING_UNDER_TEST) { return config; } diff --git a/src/sourcekit-lsp/LanguageClientManager.ts b/src/sourcekit-lsp/LanguageClientManager.ts index dd44aee3b..aa4152299 100644 --- a/src/sourcekit-lsp/LanguageClientManager.ts +++ b/src/sourcekit-lsp/LanguageClientManager.ts @@ -41,6 +41,7 @@ import { LSPActiveDocumentManager } from "./didChangeActiveDocument"; import { DidChangeActiveDocumentNotification } from "./extensions/DidChangeActiveDocumentRequest"; import { lspClientOptions } from "./LanguageClientConfiguration"; import { SwiftOutputChannel } from "../logging/SwiftOutputChannel"; +import { PollIndexRequest, WorkspaceSynchronizeRequest } from "./extensions/PollIndexRequest"; interface LanguageClientManageOptions { /** @@ -313,6 +314,25 @@ export class LanguageClientManager implements vscode.Disposable { } } + /** + * Wait for the LSP to indicate it is done indexing + */ + async waitForIndex(): Promise { + const requestType = this.swiftVersion.isGreaterThanOrEqual(new Version(6, 2, 0)) + ? WorkspaceSynchronizeRequest.type + : PollIndexRequest.type; + + await this.useLanguageClient(async (client, token) => + client.sendRequest( + requestType, + requestType.method === WorkspaceSynchronizeRequest.type.method + ? { index: true } + : {}, + token + ) + ); + } + /** * Restart language client using supplied workspace folder * @param workspaceFolder workspace folder to send to server diff --git a/src/sourcekit-lsp/extensions/PollIndexRequest.ts b/src/sourcekit-lsp/extensions/PollIndexRequest.ts new file mode 100644 index 000000000..754167985 --- /dev/null +++ b/src/sourcekit-lsp/extensions/PollIndexRequest.ts @@ -0,0 +1,32 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the VS Code Swift open source project +// +// Copyright (c) 2025 the VS Code Swift project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of VS Code Swift project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +// We use namespaces to store request information just like vscode-languageclient +/* eslint-disable @typescript-eslint/no-namespace */ + +import { MessageDirection, RequestType } from "vscode-languageclient"; + +// eslint-disable-next-line @typescript-eslint/no-namespace +export namespace PollIndexRequest { + export const method = "workspace/_pollIndex" as const; + export const messageDirection: MessageDirection = MessageDirection.clientToServer; + export const type = new RequestType(method); +} + +// eslint-disable-next-line @typescript-eslint/no-namespace +export namespace WorkspaceSynchronizeRequest { + export const method = "workspace/synchronize" as const; + export const messageDirection: MessageDirection = MessageDirection.clientToServer; + export const type = new RequestType(method); +} diff --git a/src/utilities/utilities.ts b/src/utilities/utilities.ts index 0f768b40a..be7ba7834 100644 --- a/src/utilities/utilities.ts +++ b/src/utilities/utilities.ts @@ -29,19 +29,26 @@ import { SwiftToolchain } from "../toolchain/toolchain"; export const IS_PRODUCTION_BUILD = process.env.NODE_ENV === "production"; /** - * Whether or not the code is being run in CI. - * - * Code that checks for this will be removed completely when the extension is packaged into - * a VSIX. + * Whether or not the code is being run in a Github Actions workflow. + */ +export const IS_RUNNING_UNDER_GITHUB_ACTIONS = process.env.GITHUB_ACTIONS === "true"; + +/** + * Whether or not the code is being run by `act` CLT. + */ +export const IS_RUNNING_UNDER_ACT = process.env.ACT === "true"; + +/** + * Whether or not the code is being run in a docker container. */ -export const IS_RUNNING_IN_CI = process.env.CI === "1"; +export const IS_RUNNING_UNDER_DOCKER = IS_RUNNING_UNDER_ACT || IS_RUNNING_UNDER_GITHUB_ACTIONS; /** * Whether or not the code is being run as part of a test suite. * - * This will NOT be removed when the extension is packaged into a VSIX. + * This will NOT be removed when the extension is packaged into a VSIX, unlike "CI" variable. */ -export const IS_RUNNING_UNDER_TEST = process.env.VSCODE_TEST === "1"; +export const IS_RUNNING_UNDER_TEST = process.env.RUNNING_UNDER_VSCODE_TEST_CLI === "1"; /** * Get required environment variable for Swift product diff --git a/test/integration-tests/debugger/lldb.test.ts b/test/integration-tests/debugger/lldb.test.ts index 74fcddfc2..0e07007d1 100644 --- a/test/integration-tests/debugger/lldb.test.ts +++ b/test/integration-tests/debugger/lldb.test.ts @@ -17,7 +17,7 @@ import { getLLDBLibPath } from "../../../src/debugger/lldb"; import { WorkspaceContext } from "../../../src/WorkspaceContext"; import { activateExtensionForTest } from "../utilities/testutilities"; import { Version } from "../../../src/utilities/version"; -import { IS_RUNNING_IN_CI } from "../../../src/utilities/utilities"; +import { IS_RUNNING_UNDER_DOCKER } from "../../../src/utilities/utilities"; suite("lldb contract test suite", () => { let workspaceContext: WorkspaceContext; @@ -26,7 +26,7 @@ suite("lldb contract test suite", () => { async setup(ctx) { // lldb.exe on Windows is not launching correctly, but only in Docker. if ( - IS_RUNNING_IN_CI && + IS_RUNNING_UNDER_DOCKER && process.platform === "win32" && ctx.globalToolchainSwiftVersion.isGreaterThanOrEqual(new Version(6, 0, 0)) && ctx.globalToolchainSwiftVersion.isLessThan(new Version(6, 0, 2)) diff --git a/test/integration-tests/language/LanguageClientIntegration.test.ts b/test/integration-tests/language/LanguageClientIntegration.test.ts index 060f92b77..655834cd6 100644 --- a/test/integration-tests/language/LanguageClientIntegration.test.ts +++ b/test/integration-tests/language/LanguageClientIntegration.test.ts @@ -21,7 +21,7 @@ import { testAssetUri } from "../../fixtures"; import { executeTaskAndWaitForResult, waitForNoRunningTasks } from "../../utilities/tasks"; import { createBuildAllTask } from "../../../src/tasks/SwiftTaskProvider"; import { activateExtensionForSuite, folderInRootWorkspace } from "../utilities/testutilities"; -import { waitForClientState, waitForIndex } from "../utilities/lsputilities"; +import { waitForClientState } from "../utilities/lsputilities"; import { FolderContext } from "../../../src/FolderContext"; async function buildProject(ctx: WorkspaceContext, name: string) { @@ -51,12 +51,12 @@ suite("Language Client Integration Suite @slow", function () { clientManager = ctx.languageClientManager.get(folderContext); await clientManager.restart(); await waitForClientState(clientManager, langclient.State.Running); - await waitForIndex(clientManager, folderContext.swiftVersion); + await clientManager.waitForIndex(); }, }); setup(async () => { - await waitForIndex(clientManager, folderContext.swiftVersion); + await clientManager.waitForIndex(); }); suite("Symbols", () => { diff --git a/test/integration-tests/utilities/lsputilities.ts b/test/integration-tests/utilities/lsputilities.ts index 7422d6731..b0673a955 100644 --- a/test/integration-tests/utilities/lsputilities.ts +++ b/test/integration-tests/utilities/lsputilities.ts @@ -15,7 +15,6 @@ import * as vscode from "vscode"; import * as langclient from "vscode-languageclient/node"; import { LanguageClientManager } from "../../../src/sourcekit-lsp/LanguageClientManager"; -import { Version } from "../../../src/utilities/version"; export async function waitForClient( languageClientManager: LanguageClientManager, @@ -34,38 +33,6 @@ export async function waitForClient( return result; } -// eslint-disable-next-line @typescript-eslint/no-namespace -export namespace PollIndexRequest { - export const method = "workspace/_pollIndex" as const; - export const messageDirection: langclient.MessageDirection = - langclient.MessageDirection.clientToServer; - export const type = new langclient.RequestType(method); -} - -// eslint-disable-next-line @typescript-eslint/no-namespace -export namespace WorkspaceSynchronizeRequest { - export const method = "workspace/synchronize" as const; - export const messageDirection: langclient.MessageDirection = - langclient.MessageDirection.clientToServer; - export const type = new langclient.RequestType(method); -} -export async function waitForIndex( - languageClientManager: LanguageClientManager, - swiftVersion: Version -): Promise { - const requestType = swiftVersion.isGreaterThanOrEqual(new Version(6, 2, 0)) - ? WorkspaceSynchronizeRequest.type - : PollIndexRequest.type; - - await languageClientManager.useLanguageClient(async (client, token) => - client.sendRequest( - requestType, - requestType === WorkspaceSynchronizeRequest.type ? { index: true } : {}, - token - ) - ); -} - export async function waitForClientState( languageClientManager: LanguageClientManager, expectedState: langclient.State