From 15074d2c60b6794367ab26fc83fdc5a84334505f Mon Sep 17 00:00:00 2001 From: Matthew Bastien Date: Thu, 22 May 2025 13:59:12 -0400 Subject: [PATCH 1/3] create new utilities for IS_PRODUCTION_BUILD and IS_RUNNING_IN_CI --- src/debugger/buildConfig.ts | 7 ++--- src/debugger/debugAdapterFactory.ts | 7 ++--- src/debugger/lldb.ts | 29 ++++++++++++++------ src/ui/SwiftOutputChannel.ts | 3 +- src/utilities/utilities.ts | 16 +++++++++++ test/integration-tests/debugger/lldb.test.ts | 3 +- 6 files changed, 45 insertions(+), 20 deletions(-) diff --git a/src/debugger/buildConfig.ts b/src/debugger/buildConfig.ts index f73890452..94650c6d9 100644 --- a/src/debugger/buildConfig.ts +++ b/src/debugger/buildConfig.ts @@ -26,7 +26,7 @@ import { Version } from "../utilities/version"; import { TestLibrary } from "../TestExplorer/TestRunner"; import { TestKind, isDebugging, isRelease } from "../TestExplorer/TestKind"; import { buildOptions } from "../tasks/SwiftTaskProvider"; -import { CI_DISABLE_ASLR } from "./lldb"; +import { updateLaunchConfigForCI } from "./lldb"; export class BuildConfigurationFactory { public static buildAll( @@ -697,7 +697,7 @@ export class TestingConfigurationFactory { async function getBaseConfig(ctx: FolderContext, expandEnvVariables: boolean) { const { folder, nameSuffix } = getFolderAndNameSuffix(ctx, expandEnvVariables); const packageName = await ctx.swiftPackage.name; - return { + return updateLaunchConfigForCI({ type: SWIFT_LAUNCH_CONFIG_TYPE, request: "launch", sourceLanguages: ["swift"], @@ -706,8 +706,7 @@ async function getBaseConfig(ctx: FolderContext, expandEnvVariables: boolean) { args: [], preLaunchTask: `swift: Build All${nameSuffix}`, terminal: "console", - ...CI_DISABLE_ASLR, - }; + }); } export function getFolderAndNameSuffix( diff --git a/src/debugger/debugAdapterFactory.ts b/src/debugger/debugAdapterFactory.ts index 84a68daa3..0e6cc7676 100644 --- a/src/debugger/debugAdapterFactory.ts +++ b/src/debugger/debugAdapterFactory.ts @@ -20,7 +20,7 @@ import { registerLoggingDebugAdapterTracker } from "./logTracker"; import { SwiftToolchain } from "../toolchain/toolchain"; import { SwiftOutputChannel } from "../ui/SwiftOutputChannel"; import { fileExists } from "../utilities/filesystem"; -import { CI_DISABLE_ASLR, getLLDBLibPath } from "./lldb"; +import { updateLaunchConfigForCI, getLLDBLibPath } from "./lldb"; import { getErrorDescription, swiftRuntimeEnv } from "../utilities/utilities"; import configuration from "../configuration"; @@ -171,10 +171,7 @@ export class LLDBDebugConfigurationProvider implements vscode.DebugConfiguration launchConfig.debugAdapterExecutable = lldbDapPath; } - return { - ...launchConfig, - ...CI_DISABLE_ASLR, - }; + return updateLaunchConfigForCI(launchConfig); } private async promptToInstallCodeLLDB(): Promise { diff --git a/src/debugger/lldb.ts b/src/debugger/lldb.ts index 91d3b5179..808aa6c3a 100644 --- a/src/debugger/lldb.ts +++ b/src/debugger/lldb.ts @@ -15,20 +15,31 @@ // Based on code taken from CodeLLDB https://github.com/vadimcn/vscode-lldb/ // LICENSED with MIT License +import * as vscode from "vscode"; import * as path from "path"; import * as fs from "fs/promises"; -import { execFile } from "../utilities/utilities"; +import { execFile, IS_RUNNING_IN_CI } from "../utilities/utilities"; import { Result } from "../utilities/result"; import { SwiftToolchain } from "../toolchain/toolchain"; -export const CI_DISABLE_ASLR = - // DisableASLR when running in Docker CI https://stackoverflow.com/a/78471987 - process.env["CI"] - ? { - disableASLR: false, - initCommands: ["settings set target.disable-aslr false"], - } - : {}; +/** + * Updates the provided debug configuration to be compatible with running in CI. + * + * Will be optimized out of production builds. + */ +export function updateLaunchConfigForCI( + config: vscode.DebugConfiguration +): vscode.DebugConfiguration { + if (!IS_RUNNING_IN_CI) { + return config; + } + + const result = structuredClone(config); + // Tell LLDB not to disable ASLR when running in Docker CI https://stackoverflow.com/a/78471987 + result.disableASLR = false; + result.initCommands = ["settings set target.disable-aslr false"]; + return result; +} /** * Get the path to the LLDB library. diff --git a/src/ui/SwiftOutputChannel.ts b/src/ui/SwiftOutputChannel.ts index ecad10f33..82ae15d46 100644 --- a/src/ui/SwiftOutputChannel.ts +++ b/src/ui/SwiftOutputChannel.ts @@ -14,6 +14,7 @@ import * as vscode from "vscode"; import configuration from "../configuration"; +import { IS_RUNNING_IN_CI } from "../utilities/utilities"; export class SwiftOutputChannel implements vscode.OutputChannel { private channel: vscode.OutputChannel; @@ -76,7 +77,7 @@ export class SwiftOutputChannel implements vscode.OutputChannel { } logDiagnostic(message: string, label?: string) { - if (!configuration.diagnostics && process.env["CI"] !== "1") { + if (!configuration.diagnostics && !IS_RUNNING_IN_CI) { return; } const fullMessage = label !== undefined ? `${label}: ${message}` : message; diff --git a/src/utilities/utilities.ts b/src/utilities/utilities.ts index e3787cfb8..a3b6c8933 100644 --- a/src/utilities/utilities.ts +++ b/src/utilities/utilities.ts @@ -20,6 +20,22 @@ import configuration from "../configuration"; import { FolderContext } from "../FolderContext"; import { SwiftToolchain } from "../toolchain/toolchain"; +/** + * Whether or not this is a production build. + * + * Code that checks for this will be removed completely when the extension is packaged into + * a VSIX. + */ +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. + */ +export const IS_RUNNING_IN_CI = process.env.CI === "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 4f505e0d8..74fcddfc2 100644 --- a/test/integration-tests/debugger/lldb.test.ts +++ b/test/integration-tests/debugger/lldb.test.ts @@ -17,6 +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"; suite("lldb contract test suite", () => { let workspaceContext: WorkspaceContext; @@ -25,7 +26,7 @@ suite("lldb contract test suite", () => { async setup(ctx) { // lldb.exe on Windows is not launching correctly, but only in Docker. if ( - process.env["CI"] && + IS_RUNNING_IN_CI && process.platform === "win32" && ctx.globalToolchainSwiftVersion.isGreaterThanOrEqual(new Version(6, 0, 0)) && ctx.globalToolchainSwiftVersion.isLessThan(new Version(6, 0, 2)) From 33b65e3a0c0110a5f5281f3b9123459f832fc4ac Mon Sep 17 00:00:00 2001 From: Matthew Bastien Date: Thu, 22 May 2025 13:59:57 -0400 Subject: [PATCH 2/3] remove non-production code during production builds --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index f5a4ca823..3e75ffff8 100644 --- a/package.json +++ b/package.json @@ -1656,11 +1656,11 @@ "scripts": { "vscode:prepublish": "npm run bundle", "bundle": "del-cli ./dist && npm run bundle-extension && npm run bundle-documentation-webview", - "bundle-extension": "del-cli ./dist && esbuild ./src/extension.ts --bundle --outfile=dist/src/extension.js --external:vscode --format=cjs --platform=node --target=node18 --minify --sourcemap", + "bundle-extension": "del-cli ./dist && esbuild ./src/extension.ts --bundle --outfile=dist/src/extension.js --external:vscode --define:process.env.NODE_ENV=\\\"production\\\" --define:process.env.CI=\\\"\\\" --format=cjs --platform=node --target=node18 --minify --sourcemap", "bundle-documentation-webview": "npm run compile-documentation-webview -- --minify", "compile": "del-cli ./dist/ && tsc --build", "watch": "npm run compile -- --watch", - "compile-documentation-webview": "del-cli ./assets/documentation-webview && esbuild ./src/documentation/webview/webview.ts --bundle --outfile=assets/documentation-webview/index.js --format=cjs --sourcemap", + "compile-documentation-webview": "del-cli ./assets/documentation-webview && esbuild ./src/documentation/webview/webview.ts --bundle --outfile=assets/documentation-webview/index.js --define:process.env.NODE_ENV=\\\"production\\\" --define:process.env.CI=\\\"\\\" --format=cjs --sourcemap", "watch-documentation-webview": "npm run compile-documentation-webview -- --watch", "lint": "eslint ./ --ext ts && tsc --noEmit", "update-swift-docc-render": "tsx ./scripts/update_swift_docc_render.ts", From 1bae7f58ad8362e0bb13ad518ea6b358031f54ce Mon Sep 17 00:00:00 2001 From: Matthew Bastien Date: Thu, 22 May 2025 14:55:37 -0400 Subject: [PATCH 3/3] fix unit test failure --- test/unit-tests/debugger/debugAdapterFactory.test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/test/unit-tests/debugger/debugAdapterFactory.test.ts b/test/unit-tests/debugger/debugAdapterFactory.test.ts index 7aecbb0a1..ade452fe4 100644 --- a/test/unit-tests/debugger/debugAdapterFactory.test.ts +++ b/test/unit-tests/debugger/debugAdapterFactory.test.ts @@ -152,6 +152,7 @@ suite("LLDBDebugConfigurationProvider Tests", () => { update: mockFn(), }); mockWorkspace.getConfiguration.returns(instance(mockLldbConfiguration)); + mockLLDB.updateLaunchConfigForCI.returnsArg(0); mockLLDB.getLLDBLibPath.resolves(Result.makeSuccess("/path/to/liblldb.dyLib")); mockDebuggerConfig.setupCodeLLDB = "prompt"; mockDebugAdapter.getLaunchConfigType.returns(LaunchConfigType.CODE_LLDB);