diff --git a/.build/Build.cs b/.build/Build.cs index e35ee98f1..fe12092ef 100644 --- a/.build/Build.cs +++ b/.build/Build.cs @@ -3,9 +3,11 @@ using Nuke.Common.Execution; using Nuke.Common.Git; using Nuke.Common.IO; +using Nuke.Common.Tooling; using Nuke.Common.Tools.DotNet; using Nuke.Common.Tools.GitVersion; using Nuke.Common.Tools.MSBuild; +using Nuke.Common.Tools.Npm; using Rocket.Surgery.Nuke.DotNetCore; namespace Build; @@ -61,6 +63,18 @@ public sealed partial class Solution : NukeBuild, public Target Test => _ => _.Inherit(x => x.CoreTest); + public Target NpmInstall => _ => _ + .Executes(() => + NpmTasks.NpmCi(s => s + .SetProcessWorkingDirectory(VscodeTestExtensionProjectDirectory))); + + public Target TestVscodeExtension => _ => _ + .DependsOn(NpmInstall) + .Executes(() => + NpmTasks.NpmRun(s => s + .SetProcessWorkingDirectory(VscodeTestExtensionProjectDirectory) + .SetCommand("test"))); + public Target BuildVersion => _ => _.Inherit(x => x.BuildVersion) .Before(Default) .Before(Clean); @@ -68,4 +82,6 @@ public sealed partial class Solution : NukeBuild, [Parameter("Configuration to build")] public Configuration Configuration { get; } = IsLocalBuild ? Configuration.Debug : Configuration.Release; AbsolutePath ICanUpdateReadme.ReadmeFilePath => RootDirectory / "README.md"; + + private const string VscodeTestExtensionProjectDirectory = "vscode-testextension"; } diff --git a/.build/Solution.cs b/.build/Solution.cs index 00877d256..a1132e6cf 100644 --- a/.build/Solution.cs +++ b/.build/Solution.cs @@ -102,6 +102,7 @@ RocketSurgeonGitHubActionsConfiguration configuration .ConfigureStep(step => step.FetchDepth = 0) .UseDotNetSdks("3.1", "7.0") .AddNuGetCache() + .AddVscodeExtensionTests() .PublishLogs() .PublishArtifacts() .FailFast = false; @@ -109,3 +110,24 @@ RocketSurgeonGitHubActionsConfiguration configuration return configuration; } } + +public static class Extensions +{ + public static RocketSurgeonsGithubActionsJob AddVscodeExtensionTests(this RocketSurgeonsGithubActionsJob job) + { + return job + .AddStep(new RunStep("Npm install") { + Run = string.Join(Environment.NewLine, [ + "cd vscode-testextension", + "npm ci", + "cd .." + ]) + }) + .AddStep(new UsingStep("Vscode extension tests") { + Uses = "coactions/setup-xvfb@v1", + With = { + ["run"] = "npm run test", + ["working-directory"] = "vscode-testextension" + }}); + } +} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1041e266b..3b281d9ce 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -117,6 +117,16 @@ jobs: id: pack run: | dotnet nuke Pack --skip + - name: Npm install + run: | + cd vscode-testextension + npm ci + cd .. + - name: 🚦 Vscode extension tests + uses: coactions/setup-xvfb@v1 + with: + run: 'npm run test' + working-directory: 'vscode-testextension' - name: 🏺 Publish coverage data if: always() uses: actions/upload-artifact@v3 diff --git a/.nuke/build.schema.json b/.nuke/build.schema.json index 57832ac84..e18c1f5f0 100644 --- a/.nuke/build.schema.json +++ b/.nuke/build.schema.json @@ -103,9 +103,11 @@ "GenerateCodeCoverageReportCobertura", "GenerateCodeCoverageSummary", "GenerateReadme", + "NpmInstall", "Pack", "Restore", "Test", + "TestVscodeTestExtension", "Trigger_Code_Coverage_Reports", "TriggerCodeCoverageReports" ] @@ -140,9 +142,11 @@ "GenerateCodeCoverageReportCobertura", "GenerateCodeCoverageSummary", "GenerateReadme", + "NpmInstall", "Pack", "Restore", "Test", + "TestVscodeTestExtension", "Trigger_Code_Coverage_Reports", "TriggerCodeCoverageReports" ] diff --git a/vscode-testextension/package-lock.json b/vscode-testextension/package-lock.json index 32b58bf83..4f5fe8deb 100644 --- a/vscode-testextension/package-lock.json +++ b/vscode-testextension/package-lock.json @@ -21,6 +21,7 @@ "glob": "^10.3.10", "mocha": "^10.2.0", "source-map-support": "^0.5.21", + "tmp-promise": "^3.0.3", "typescript": "^5.2.2" }, "engines": { @@ -1194,6 +1195,53 @@ "node": ">=0.10.0" } }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -1371,6 +1419,27 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/tmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "dev": true, + "dependencies": { + "rimraf": "^3.0.0" + }, + "engines": { + "node": ">=8.17.0" + } + }, + "node_modules/tmp-promise": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-3.0.3.tgz", + "integrity": "sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==", + "dev": true, + "dependencies": { + "tmp": "^0.2.0" + } + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", diff --git a/vscode-testextension/package.json b/vscode-testextension/package.json index 4fc42ed8d..4f17df07a 100644 --- a/vscode-testextension/package.json +++ b/vscode-testextension/package.json @@ -55,6 +55,7 @@ "glob": "^10.3.10", "mocha": "^10.2.0", "source-map-support": "^0.5.21", + "tmp-promise": "^3.0.3", "typescript": "^5.2.2" }, "dependencies": { diff --git a/vscode-testextension/test/runTest.ts b/vscode-testextension/test/runTest.ts index c70caa8f0..be768ad87 100644 --- a/vscode-testextension/test/runTest.ts +++ b/vscode-testextension/test/runTest.ts @@ -1,4 +1,5 @@ import * as path from 'path'; +import * as tmp from 'tmp-promise'; import { runTests } from '@vscode/test-electron'; @@ -12,10 +13,25 @@ async function main() { // Passed to --extensionTestsPath const extensionTestsPath = path.resolve(__dirname, './suite/index'); - // Download VS Code, unzip it and run the integration test - await runTests({ extensionDevelopmentPath, extensionTestsPath }); + // The path to the user data directory used by vscode + // As the default one is too long (> 103 characters) on some CI setups, forcing it to a temporary and hopefully shorter one. + const userDataDir = await tmp.dir({ unsafeCleanup: true }); + + try { + // Download VS Code, unzip it and run the integration test + await runTests({ + extensionDevelopmentPath, + extensionTestsPath, + launchArgs: ["--user-data-dir", userDataDir.path] + }); + } + finally + { + await userDataDir.cleanup(); + } } catch (err) { console.error('Failed to run tests'); + console.error(err); process.exit(1); } }