Skip to content

Commit dcff571

Browse files
authored
Merge pull request #467 from swift-actions/win-support-sanitize
Enable windows support
2 parents 0ce29fe + 74dee77 commit dcff571

File tree

9 files changed

+398
-16
lines changed

9 files changed

+398
-16
lines changed

.github/workflows/ci.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,11 @@ jobs:
2222
runs-on: ${{ matrix.os }}
2323
strategy:
2424
matrix:
25-
os: [ubuntu-latest, macos-latest]
25+
os: [ubuntu-latest, macos-latest, windows-latest]
2626
swift: ["5.6.1"]
27+
include:
28+
- os: windows-latest
29+
swift: "5.3"
2730
steps:
2831
- uses: actions/checkout@v3
2932
- run: npm install

__tests__/os.test.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,13 @@ describe("os resolver", () => {
1919
expect(mac.os).toBe(os.OS.MacOS);
2020
expect(mac.version).toBe("latest");
2121
expect(mac.name).toBe("macOS");
22+
23+
setSystem({ os: "win32", dist: "Windows", release: "latest" });
24+
25+
let windows = await os.getSystem();
26+
expect(windows.os).toBe(os.OS.Windows);
27+
expect(windows.version).toBe("latest");
28+
expect(windows.name).toBe("Windows");
2229
});
2330

2431
it("throws an error if the os is not supported", async () => {

__tests__/swift-versions.test.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import * as versions from "../src/swift-versions";
33

44
const macOS: System = { os: OS.MacOS, version: "latest", name: "macOS" };
55
const ubuntu: System = { os: OS.Ubuntu, version: "latest", name: "Ubuntu" };
6+
const windows: System = { os: OS.Windows, version: "latest", name: "Windows" };
67

78
describe("swift version resolver", () => {
89
it("identifies X.X.X versions", async () => {
@@ -39,12 +40,19 @@ describe("swift version resolver", () => {
3940
});
4041

4142
it("throws an error if the version isn't available for the system", async () => {
42-
expect.assertions(1);
43+
expect.assertions(2);
44+
4345
try {
4446
await versions.verify("5.0.3", macOS);
4547
} catch (e) {
4648
expect(e).toEqual(new Error('Version "5.0.3" is not available'));
4749
}
50+
51+
try {
52+
await versions.verify("5.2", windows);
53+
} catch (e) {
54+
expect(e).toEqual(new Error('Version "5.2" is not available'));
55+
}
4856
});
4957

5058
it("throws an error if version is invalid", async () => {

__tests__/visual-studio.test.ts

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
import os from "os";
2+
import * as path from "path";
3+
import * as vs from "../src/visual-studio";
4+
import { swiftPackage } from "../src/swift-versions";
5+
import { OS, System } from "../src/os";
6+
7+
jest.mock("fs", () => {
8+
const original = jest.requireActual("fs");
9+
return {
10+
...original,
11+
existsSync: jest.fn((path) => true),
12+
};
13+
});
14+
15+
const windows: System = { os: OS.Windows, version: "latest", name: "Windows" };
16+
17+
describe("visual studio resolver", () => {
18+
const env = process.env;
19+
20+
beforeEach(() => {
21+
jest.resetModules();
22+
process.env = { ...env };
23+
});
24+
25+
afterEach(() => {
26+
process.env = env;
27+
});
28+
29+
it("fetches visual studio requirement for swift version", async () => {
30+
jest.spyOn(os, "release").mockReturnValue("10.0.17763");
31+
32+
const req5_3 = vs.vsRequirement(swiftPackage("5.3", windows));
33+
expect(req5_3.version).toBe("16");
34+
expect(req5_3.components).toContain(
35+
"Microsoft.VisualStudio.Component.VC.Tools.x86.x64"
36+
);
37+
expect(req5_3.components).toContain(
38+
"Microsoft.VisualStudio.Component.Windows10SDK.17763"
39+
);
40+
41+
const req5_6 = vs.vsRequirement(swiftPackage("5.6", windows));
42+
expect(req5_6.version).toBe("16");
43+
expect(req5_6.components).toContain(
44+
"Microsoft.VisualStudio.Component.VC.Tools.x86.x64"
45+
);
46+
expect(req5_6.components).toContain(
47+
"Microsoft.VisualStudio.Component.Windows10SDK.17763"
48+
);
49+
});
50+
51+
it("adds latest sdk for release newer than or equal to build 17763", async () => {
52+
jest.spyOn(os, "release").mockReturnValue("10.0.17763");
53+
const req17763 = vs.vsRequirement(swiftPackage("5.3", windows));
54+
expect(req17763.components).toContain(
55+
"Microsoft.VisualStudio.Component.Windows10SDK.17763"
56+
);
57+
58+
jest.spyOn(os, "release").mockReturnValue("10.0.18363");
59+
const req18363 = vs.vsRequirement(swiftPackage("5.3", windows));
60+
expect(req18363.components).toContain(
61+
"Microsoft.VisualStudio.Component.Windows10SDK.18363"
62+
);
63+
});
64+
65+
it("adds recommended sdk for release older than build 17763", async () => {
66+
jest.spyOn(os, "release").mockReturnValue("10.0.16299");
67+
const req16299 = vs.vsRequirement(swiftPackage("5.3", windows));
68+
expect(req16299.components).toContain(
69+
"Microsoft.VisualStudio.Component.Windows10SDK.17763"
70+
);
71+
});
72+
73+
it("finds vswhere path from environment value", async () => {
74+
const vswherePath = path.join("C:", "bin");
75+
const vswhereExe = path.join(vswherePath, "vswhere.exe");
76+
process.env.VSWHERE_PATH = vswherePath;
77+
expect(await vs.getVsWherePath()).toBe(vswhereExe);
78+
});
79+
80+
it("finds vswhere path from ProgramFiles environment value", async () => {
81+
const vswhereExe = path.join(
82+
"C:",
83+
"Program Files (x86)",
84+
"Microsoft Visual Studio",
85+
"Installer",
86+
"vswhere.exe"
87+
);
88+
process.env["ProgramFiles(x86)"] = path.join("C:", "Program Files (x86)");
89+
expect(await vs.getVsWherePath()).toBe(vswhereExe);
90+
});
91+
});

src/main.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import * as system from "./os";
44
import * as versions from "./swift-versions";
55
import * as macos from "./macos-install";
66
import * as linux from "./linux-install";
7+
import * as windows from "./windows-install";
78
import { getVersion } from "./get-version";
89

910
async function run() {
@@ -20,6 +21,8 @@ async function run() {
2021
case system.OS.Ubuntu:
2122
await linux.install(version, platform);
2223
break;
24+
case system.OS.Windows:
25+
await windows.install(version, platform);
2326
}
2427

2528
const current = await getVersion();

src/os.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,19 @@ import getos from "getos";
33
export enum OS {
44
MacOS,
55
Ubuntu,
6+
Windows,
7+
}
8+
9+
export namespace OS {
10+
export function all(): OS[] {
11+
return [OS.MacOS, OS.Ubuntu, OS.Windows];
12+
}
613
}
714

815
const AVAILABLE_OS: { [platform: string]: string[] } = {
916
macOS: ["latest", "11.0", "10.15"],
1017
Ubuntu: ["latest", "20.04", "18.04", "16.04"],
18+
Windows: ["latest", "10"],
1119
};
1220

1321
export interface System {
@@ -41,6 +49,9 @@ export async function getSystem(): Promise<System> {
4149
name: "Ubuntu",
4250
};
4351
break;
52+
case "win32":
53+
system = { os: OS.Windows, version: "latest", name: "Windows" };
54+
break;
4455
default:
4556
throw new Error(`"${detectedSystem.os}" is not a supported platform`);
4657
}

src/swift-versions.ts

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,20 @@ import * as core from "@actions/core";
33
import { System, OS } from "./os";
44

55
const VERSIONS_LIST: [string, OS[]][] = [
6-
["5.6.1", [OS.MacOS, OS.Ubuntu]],
7-
["5.6", [OS.MacOS, OS.Ubuntu]],
8-
["5.5.3", [OS.MacOS, OS.Ubuntu]],
9-
["5.5.2", [OS.MacOS, OS.Ubuntu]],
10-
["5.5.1", [OS.MacOS, OS.Ubuntu]],
11-
["5.5", [OS.MacOS, OS.Ubuntu]],
12-
["5.4.3", [OS.MacOS, OS.Ubuntu]],
13-
["5.4.2", [OS.MacOS, OS.Ubuntu]],
14-
["5.4.1", [OS.MacOS, OS.Ubuntu]],
15-
["5.4", [OS.MacOS, OS.Ubuntu]],
16-
["5.3.3", [OS.MacOS, OS.Ubuntu]],
17-
["5.3.2", [OS.MacOS, OS.Ubuntu]],
18-
["5.3.1", [OS.MacOS, OS.Ubuntu]],
19-
["5.3", [OS.MacOS, OS.Ubuntu]],
6+
["5.6.1", OS.all()],
7+
["5.6", OS.all()],
8+
["5.5.3", OS.all()],
9+
["5.5.2", OS.all()],
10+
["5.5.1", OS.all()],
11+
["5.5", OS.all()],
12+
["5.4.3", OS.all()],
13+
["5.4.2", OS.all()],
14+
["5.4.1", OS.all()],
15+
["5.4", OS.all()],
16+
["5.3.3", OS.all()],
17+
["5.3.2", OS.all()],
18+
["5.3.1", OS.all()],
19+
["5.3", OS.all()],
2020
["5.2.5", [OS.Ubuntu]],
2121
["5.2.4", [OS.MacOS, OS.Ubuntu]],
2222
["5.2.3", [OS.Ubuntu]],
@@ -68,6 +68,7 @@ function notEmpty<T>(value: T | null | undefined): value is T {
6868
export interface Package {
6969
url: string;
7070
name: string;
71+
version: string;
7172
}
7273

7374
export function swiftPackage(version: string, system: System): Package {
@@ -86,13 +87,19 @@ export function swiftPackage(version: string, system: System): Package {
8687
archiveName = `swift-${version}-RELEASE-ubuntu${system.version}`;
8788
archiveFile = `${archiveName}.tar.gz`;
8889
break;
90+
case OS.Windows:
91+
platform = "windows10";
92+
archiveName = `swift-${version}-RELEASE-windows10.exe`;
93+
archiveFile = archiveName;
94+
break;
8995
default:
9096
throw new Error("Cannot create download URL for an unsupported platform");
9197
}
9298

9399
return {
94100
url: `https://swift.org/builds/swift-${version}-release/${platform}/swift-${version}-RELEASE/${archiveFile}`,
95101
name: archiveName,
102+
version: version,
96103
};
97104
}
98105

0 commit comments

Comments
 (0)