Skip to content

Commit 3c116a4

Browse files
award999plemarquandmichael-weng
authored
Setup Windows GH actions job (#1195)
* Setup Windows GH actions jobs We cannot use the existing windows job setup because it launches a docker container which we cannot open a VS Code window in to run the tests as no tool like Xvfb exists for Windows This patch goes through and fixes up tests and behaviours that were incorrect on Windows. Co-authored-by: Paul LeMarquand <[email protected]> Co-authored-by: Michael (SPG) Weng <[email protected]>
1 parent e7f81c9 commit 3c116a4

30 files changed

+571
-319
lines changed

.github/workflows/pull_request.yml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ jobs:
99
name: Test
1010
uses: swiftlang/github-workflows/.github/workflows/swift_package_test.yml@main
1111
with:
12+
# Linux
1213
linux_exclude_swift_versions: '[{"swift_version": "nightly-main"}]'
1314
linux_env_vars: |
1415
NODE_VERSION=v18.19.0
@@ -23,7 +24,15 @@ jobs:
2324
/bin/bash -c "source $NVM_DIR/nvm.sh && nvm install $NODE_VERSION"
2425
echo "$NODE_PATH" >> $GITHUB_PATH
2526
linux_build_command: ./docker/test.sh
26-
enable_windows_checks: false
27+
# Windows
28+
windows_exclude_swift_versions: '[{"swift_version": "nightly"}]'
29+
windows_env_vars: |
30+
CI=1
31+
VSCODE_TEST=1
32+
FAST_TEST_RUN=1
33+
windows_pre_build_command: .github\workflows\scripts\windows\install-nodejs.ps1
34+
windows_build_command: docker\test-windows.ps1
35+
enable_windows_docker: false
2736

2837
soundness:
2938
name: Soundness
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
$NODEJS='https://nodejs.org/dist/v18.20.4/node-v18.20.4-x64.msi'
2+
$NODEJS_SHA256='c2654d3557abd59de08474c6dd009b1d358f420b8e4010e4debbf130b1dfb90a'
3+
Set-Variable ErrorActionPreference Stop
4+
Set-Variable ProgressPreference SilentlyContinue
5+
Write-Host -NoNewLine ('Downloading {0} ... ' -f ${NODEJS})
6+
Invoke-WebRequest -Uri ${NODEJS} -OutFile $env:TEMP\node.msi
7+
Write-Host 'SUCCESS'
8+
Write-Host -NoNewLine ('Verifying SHA256 ({0}) ... ' -f ${NODEJS_SHA256})
9+
$Hash = Get-FileHash $env:TEMP\node.msi -Algorithm sha256
10+
if ($Hash.Hash -eq ${NODEJS_SHA256}) {
11+
Write-Host 'SUCCESS'
12+
} else {
13+
Write-Host ('FAILED ({0})' -f $Hash.Hash)
14+
exit 1
15+
}
16+
Write-Host -NoNewLine 'Installing node.js for Windows ... '
17+
$Process = Start-Process msiexec "/i $env:TEMP\node.msi /norestart /qn" -Wait -PassThru
18+
if ($Process.ExitCode -eq 0) {
19+
Write-Host 'SUCCESS'
20+
} else {
21+
Write-Host ('FAILED ({0})' -f $Process.ExitCode)
22+
exit 1
23+
}
24+
Remove-Item -Force $env:TEMP\node.msi

.vscode-test.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ module.exports = defineConfig({
5353
},
5454
},
5555
reuseMachineInstall: !isCIBuild,
56+
installExtensions: ["vadimcn.vscode-lldb"],
5657
},
5758
{
5859
label: "unitTests",

docker/test-windows.ps1

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
$env:CI = "1"
2+
$env:FAST_TEST_RUN = "1"
3+
npm ci -ignore-script node-pty
4+
npm run lint
5+
npm run format
6+
npm run package
7+
$Process = Start-Process npm "run integration-test" -Wait -PassThru -NoNewWindow
8+
if ($Process.ExitCode -eq 0) {
9+
Write-Host 'SUCCESS'
10+
} else {
11+
Write-Host ('FAILED ({0})' -f $Process.ExitCode)
12+
exit 1
13+
}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1280,7 +1280,7 @@
12801280
"pretest": "npm run compile-tests",
12811281
"soundness": "docker compose -f docker/docker-compose.yaml -p swift-vscode-soundness-prb run --rm soundness",
12821282
"test-soundness": "scripts/soundness.sh",
1283-
"test": "VSCODE_TEST=1 vscode-test",
1283+
"test": "vscode-test",
12841284
"test-ci": "docker/test-ci.sh ci",
12851285
"test-nightly": "docker/test-ci.sh nightly",
12861286
"integration-test": "npm test -- --label integrationTests",

src/DiagnosticsManager.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,13 +89,13 @@ export class DiagnosticsManager implements vscode.Disposable {
8989
.then(map => {
9090
// Clean up old "swiftc" diagnostics
9191
this.removeSwiftcDiagnostics();
92-
map.forEach((diagnostics, uri) =>
92+
map.forEach((diagnostics, uri) => {
9393
this.handleDiagnostics(
9494
vscode.Uri.file(uri),
9595
DiagnosticsManager.isSwiftc,
9696
diagnostics
97-
)
98-
);
97+
);
98+
});
9999
})
100100
.catch(e =>
101101
context.outputChannel.log(`${e}`, 'Failed to provide "swiftc" diagnostics')

src/FolderContext.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,10 @@ export class FolderContext implements vscode.Disposable {
152152

153153
/** Create Test explorer for this folder */
154154
addTestExplorer() {
155-
this.testExplorer = new TestExplorer(this);
155+
if (this.testExplorer === undefined) {
156+
this.testExplorer = new TestExplorer(this);
157+
}
158+
return this.testExplorer;
156159
}
157160

158161
/** Create Test explorer for this folder */

src/TestExplorer/TestParsers/XCTestOutputParser.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
import { ITestRunState, TestIssueDiff } from "./TestRunState";
1616
import { sourceLocationToVSCodeLocation } from "../../utilities/utilities";
1717
import { MarkdownString, Location } from "vscode";
18+
// eslint-disable-next-line @typescript-eslint/no-require-imports
19+
import stripAnsi = require("strip-ansi");
1820

1921
/** Regex for parsing XCTest output */
2022
interface TestRegex {
@@ -148,7 +150,10 @@ export class XCTestOutputParser implements IXCTestOutputParser {
148150
* Parse results from `swift test` and update tests accordingly
149151
* @param output Output from `swift test`
150152
*/
151-
public parseResult(output: string, runState: ITestRunState) {
153+
public parseResult(rawOutput: string, runState: ITestRunState) {
154+
// Windows is inserting ANSI codes into the output to do things like clear the cursor,
155+
// which we don't care about.
156+
const output = process.platform === "win32" ? stripAnsi(rawOutput) : rawOutput;
152157
const output2 = output.replace(/\r\n/g, "\n");
153158
const lines = output2.split("\n");
154159
if (runState.excess) {

src/TestExplorer/TestRunner.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ import { BuildConfigurationFactory, TestingConfigurationFactory } from "../debug
4040
import { TestKind, isDebugging, isRelease } from "./TestKind";
4141
import { reduceTestItemChildren } from "./TestUtils";
4242
import { CompositeCancellationToken } from "../utilities/cancellation";
43+
// eslint-disable-next-line @typescript-eslint/no-require-imports
44+
import stripAnsi = require("strip-ansi");
4345

4446
export enum TestLibrary {
4547
xctest = "XCTest",
@@ -264,7 +266,7 @@ export class TestRunProxy {
264266
test?: vscode.TestItem
265267
) {
266268
testRun.appendOutput(output, location, test);
267-
this.runState.output.push(output);
269+
this.runState.output.push(stripAnsi(output));
268270
}
269271

270272
private prependIterationToOutput(output: string): string {

src/commands/build.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,16 +74,28 @@ export async function debugBuildWithOptions(
7474
) {
7575
const current = ctx.currentFolder;
7676
if (!current) {
77+
ctx.outputChannel.appendLine(
78+
"debugBuildWithOptions: No current folder on WorkspaceContext"
79+
);
7780
return;
7881
}
7982

8083
const file = vscode.window.activeTextEditor?.document.fileName;
8184
if (!file) {
85+
ctx.outputChannel.appendLine("debugBuildWithOptions: No active text editor");
8286
return;
8387
}
8488

8589
const target = current.swiftPackage.getTarget(file);
86-
if (!target || target.type !== "executable") {
90+
if (!target) {
91+
ctx.outputChannel.appendLine("debugBuildWithOptions: No active target");
92+
return;
93+
}
94+
95+
if (target.type !== "executable") {
96+
ctx.outputChannel.appendLine(
97+
`debugBuildWithOptions: Target is not an executable, instead is ${target.type}`
98+
);
8799
return;
88100
}
89101

0 commit comments

Comments
 (0)