From da27e5b1bc2260684b4fccb92e47c000a52a5c3b Mon Sep 17 00:00:00 2001 From: Soumya Ranjan Mahunt Date: Wed, 30 Aug 2023 19:32:08 +0530 Subject: [PATCH] fix: fixed latest toolchain(> 5.6) setup failure on Windows (#3) * fix: fixed latest toolchain(> 5.6) setup failure on Windows * wip: log path * fix: added fix for development snapshots --- .github/workflows/main.yml | 8 +- README.md | 5 +- __tests__/installer/windows.test.ts | 22 ++++- dist/index.js | 93 +++++++++++++++---- src/installer/windows.ts | 139 ++++++++++++++++++++-------- 5 files changed, 203 insertions(+), 64 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 9234573..171505d 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -114,19 +114,19 @@ jobs: cancel-in-progress: true strategy: matrix: - os: [ubuntu-latest, macos-latest, macos-13] + os: [ubuntu-latest, macos-latest, windows-latest] swift: ['latest'] development: [false, true] include: - os: macos-latest swift: '5.0.0' development: false + - os: macos-13 + swift: 'latest' + development: false - os: ubuntu-latest swift: '5.3.0' development: false - - os: windows-latest - swift: '5.6' - development: false - os: windows-latest swift: '5.3' development: false diff --git a/README.md b/README.md index ca0a7bb..edb15ea 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Setup Swift -[![GitHub Action](https://img.shields.io/github/v/tag/SwiftyLab/setup-swift?logo=github&label=GitHub)](https://badge.fury.io/gh/SwiftyLab%2Fsetup-swift) +[![GitHub Action](https://img.shields.io/github/v/tag/SwiftyLab/setup-swift?logo=github&label=GitHub)](https://github.com/marketplace/actions/setup-swift-environment-for-macos-linux-and-windows) [![Supports macOS, Linux & Windows](https://img.shields.io/badge/platform-macOS%20%7C%20Linux%20%7C%20Windows-blue?label=platform)](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/virtual-environments-for-github-hosted-runners#supported-runners-and-hardware-resources) [![Swift 5.9](https://img.shields.io/badge/Swift-5.9-orange?logo=swift&logoColor=white)](https://swift.org) [![CI/CD](https://github.com/SwiftyLab/setup-swift/actions/workflows/main.yml/badge.svg)](https://github.com/SwiftyLab/setup-swift/actions/workflows/main.yml) @@ -24,7 +24,8 @@ Or use the latest development snapshots by enabling the `development` flag: ```yml - uses: SwiftyLab/setup-swift@latest - development: true + with: + development: true ``` After the environment is configured you can run swift and xcode commands using the standard [`run`](https://help.github.com/en/actions/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions#jobsjob_idstepsrun) step: diff --git a/__tests__/installer/windows.test.ts b/__tests__/installer/windows.test.ts index b19d713..c7172ca 100644 --- a/__tests__/installer/windows.test.ts +++ b/__tests__/installer/windows.test.ts @@ -59,17 +59,37 @@ describe('windows toolchain installation verification', () => { expect(installer['visualStudio']).toStrictEqual(visualStudio) }) - it('tests unpack', async () => { + it('tests unpack for default toolchains', async () => { const installer = new WindowsToolchainInstaller(toolchain) const exe = path.resolve('tool', 'downloaded', 'toolchain.exe') const extracted = path.resolve('tool', 'extracted', 'path') process.env.SystemDrive = 'C:' jest.spyOn(toolCache, 'extractTar').mockResolvedValue(extracted) jest.spyOn(exec, 'exec').mockResolvedValue(0) + jest.spyOn(fs, 'access').mockRejectedValueOnce(new Error()) + jest.spyOn(fs, 'access').mockResolvedValue() + jest.spyOn(fs, 'cp').mockResolvedValue() const toolPath = path.join(process.env.SystemDrive, 'Library') await expect(installer['unpack'](exe)).resolves.toBe(toolPath) }) + it('tests unpack for development snapshots', async () => { + const installer = new WindowsToolchainInstaller(toolchain) + const exe = path.resolve('tool', 'downloaded', 'toolchain.exe') + const extracted = path.resolve('tool', 'extracted', 'path') + process.env.SystemDrive = 'C:' + jest.spyOn(toolCache, 'extractTar').mockResolvedValue(extracted) + jest.spyOn(exec, 'exec').mockResolvedValue(0) + jest.spyOn(fs, 'access').mockResolvedValue() + jest.spyOn(fs, 'cp').mockResolvedValue() + const toolPath = path.join( + process.env.SystemDrive, + 'Program Files', + 'Swift' + ) + await expect(installer['unpack'](exe)).resolves.toBe(toolPath) + }) + it('tests add to PATH', async () => { const installer = new WindowsToolchainInstaller(toolchain) installer['visualStudio'] = visualStudio diff --git a/dist/index.js b/dist/index.js index e0487bf..9da3879 100644 --- a/dist/index.js +++ b/dist/index.js @@ -488,31 +488,32 @@ class WindowsToolchainInstaller extends verify_1.VerifyingToolchainInstaller { }); } unpack(exe) { - var _a; return __awaiter(this, void 0, void 0, function* () { core.debug(`Installing toolchain from "${exe}"`); const code = yield (0, exec_1.exec)(`"${exe}"`, ['-q']); - const installation = path.join((_a = process.env.SystemDrive) !== null && _a !== void 0 ? _a : 'C:', 'Library'); - const toolchain = path.join(installation, 'Developer', 'Toolchains', 'unknown-Asserts-development.xctoolchain'); - const sdkroot = path.join(installation, 'Developer', 'Platforms', 'Windows.platform', 'Developer', 'SDKs', 'Windows.sdk'); if (code !== 0) { throw new Error(`Swift installer failed with exit code: "${code}"`); } - core.debug(`Toolchain installed at "${toolchain}"`); - core.debug(`SDK installed at "${sdkroot}"`); - return installation; + const installation = yield Installation.detect(); + return installation.location; }); } - add(installation) { + add(installLocation) { return __awaiter(this, void 0, void 0, function* () { - const toolchain = path.join(installation, 'Developer', 'Toolchains', 'unknown-Asserts-development.xctoolchain'); - const sdkroot = path.join(installation, 'Developer', 'Platforms', 'Windows.platform', 'Developer', 'SDKs', 'Windows.sdk'); - core.debug(`Adding toolchain "${toolchain}" to path`); - const swiftPath = path.join(toolchain, 'usr', 'bin'); - core.exportVariable('SDKROOT', sdkroot); - const swiftDev = path.join(installation, 'Swift-development', 'bin'); - const icu67 = path.join(installation, 'icu-67', 'usr', 'bin'); - for (const envPath of [swiftPath, swiftDev, icu67]) { + const installation = yield Installation.get(installLocation); + core.exportVariable('SDKROOT', installation.sdkroot); + if (installation.devdir) { + core.exportVariable('DEVELOPER_DIR', installation.devdir); + } + const location = installation.location; + const swiftPath = path.join(installation.toolchain, 'usr', 'bin'); + const swiftDev = path.join(location, 'Swift-development', 'bin'); + const icu67 = path.join(location, 'icu-67', 'usr', 'bin'); + const tools = path.join(location, 'Tools'); + const runtimePath = path.join(installation.runtime, 'usr', 'bin'); + const requirePaths = [swiftPath, swiftDev, icu67, tools, runtimePath]; + for (const envPath of requirePaths) { + core.debug(`Adding "${envPath}" to PATH`); core.addPath(envPath); } core.debug(`Swift installed at "${swiftPath}"`); @@ -528,6 +529,66 @@ class WindowsToolchainInstaller extends verify_1.VerifyingToolchainInstaller { } } exports.WindowsToolchainInstaller = WindowsToolchainInstaller; +class Installation { + constructor(location, toolchain, sdkroot, runtime, devdir) { + this.location = location; + this.toolchain = toolchain; + this.sdkroot = sdkroot; + this.runtime = runtime; + this.devdir = devdir; + } + static get(location, fallback) { + return __awaiter(this, void 0, void 0, function* () { + let toolchain; + let sdkroot; + let runtime; + let devdir; + try { + core.debug(`Checking for development snapshot installation`); + toolchain = path.join(location, 'Toolchains', '0.0.0+Asserts'); + sdkroot = path.join(location, 'Toolchains', '0.0.0+Asserts'); + runtime = path.join(location, 'Runtimes', '0.0.0'); + yield fs_1.promises.access(toolchain); + } + catch (error) { + core.debug(`Switching to default installation due to "${error}"`); + if (fallback) { + location = fallback; + } + devdir = path.join(location, 'Developer'); + toolchain = path.join(devdir, 'Toolchains', 'unknown-Asserts-development.xctoolchain'); + sdkroot = path.join(devdir, 'Platforms', 'Windows.platform', 'Developer', 'SDKs', 'Windows.sdk'); + runtime = path.join(location, 'Swift', 'runtime-development'); + } + return new Installation(location, toolchain, sdkroot, runtime, devdir); + }); + } + static detect() { + var _a; + return __awaiter(this, void 0, void 0, function* () { + const systemDrive = (_a = process.env.SystemDrive) !== null && _a !== void 0 ? _a : 'C:'; + const defaultPath = path.join(systemDrive, 'Library'); + const devPath = path.join(systemDrive, 'Program Files', 'Swift'); + const installation = yield Installation.get(devPath, defaultPath); + if (path.relative(devPath, installation.location)) { + const runtimeRoot = path.join(installation.location, 'Swift'); + try { + yield fs_1.promises.access(devPath); + yield fs_1.promises.cp(devPath, runtimeRoot, { recursive: true }); + } + catch (error) { + core.debug(`Runtime check failed with "${error}"`); + } + } + core.debug(`Installation location at "${installation.location}"`); + core.debug(`Toolchain installed at "${installation.toolchain}"`); + core.debug(`SDK installed at "${installation.sdkroot}"`); + core.debug(`Runtime installed at "${installation.runtime}"`); + core.debug(`Development directory at "${installation.devdir}"`); + return installation; + }); + } +} /***/ }), diff --git a/src/installer/windows.ts b/src/installer/windows.ts index 205e67a..eb0b018 100644 --- a/src/installer/windows.ts +++ b/src/installer/windows.ts @@ -45,52 +45,29 @@ export class WindowsToolchainInstaller extends VerifyingToolchainInstaller