From 47598654bb5a14ce9dbf372eb2fb01e1834d270a Mon Sep 17 00:00:00 2001 From: "Chris (SPG) McGee" Date: Sat, 23 Nov 2024 07:27:51 -0500 Subject: [PATCH 01/27] Test swiftly release artifacts in a plain Linux environment Currently, there is no test coverage of a swiftly installation where there is no swift support at all, and nothing involving swiftly. Add a github workflow that performs a swiftly install using the release artifact. In order to facilitate this create an E2E test that performs these steps, but only in an environment where it can mutate the system. Also, make this test deployable to a plain Linux system with no swift support installed on it. --- .github/workflows/pull_request.yml | 28 +++++++++++- Tests/SwiftlyTests/E2ETests.swift | 31 +++++++++++++ .../BuildSwiftlyRelease.swift | 43 ++++++++++++++++++- 3 files changed, 99 insertions(+), 3 deletions(-) diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index b1554a2c..7bfa26c8 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -39,13 +39,39 @@ jobs: - name: Checkout repository uses: actions/checkout@v4 - name: Build Artifact - run: swift run build-swiftly-release --skip "999.0.0" + run: swift run build-swiftly-release --skip --tests "999.0.0" - name: Upload Artifact uses: actions/upload-artifact@v4 with: + name: swiftly-release-x86_64 path: .build/release/swiftly-*.tar.gz if-no-files-found: error retention-days: 1 + - name: Upload Tests + uses: actions/upload-artifact@v4 + with: + name: swiftly-tests-x86_64 + path: .build/debug/test-swiftly.tar.gz + if-no-files-found: error + retention-days: 1 + + releasetest: + name: Test Release + needs: releasebuildcheck + runs-on: ubuntu-latest + container: + image: "ubuntu:22.04" + steps: + - name: Download Release + uses: actions/download-artifact@v4 + with: + name: swiftly-release-x86_64 + - name: Download Tests + uses: actions/download-artifact@v4 + with: + name: swiftly-tests-x86_64 + - name: Extract and Run Workflow Tests + run: mv swiftly-*.tar.gz swiftly.tar.gz && tar zxf test-swiftly.tar.gz && SWIFTLY_SYSTEM_MUTATING=1 ./swiftlyPackageTests.xctest SwiftlyTests.E2ETests/testAutomatedWorkflow formatcheck: name: Format Check diff --git a/Tests/SwiftlyTests/E2ETests.swift b/Tests/SwiftlyTests/E2ETests.swift index 29ac97a0..bd83acba 100644 --- a/Tests/SwiftlyTests/E2ETests.swift +++ b/Tests/SwiftlyTests/E2ETests.swift @@ -63,4 +63,35 @@ final class E2ETests: SwiftlyTests { try await validateInstalledToolchains([installedToolchain], description: "install latest") } } + + func testAutomatedWorkflow() async throws { + try XCTSkipIf(ProcessInfo.processInfo.environment["SWIFTLY_SYSTEM_MUTATING"] == nil, "Not running test since it mutates the system and SWIFTLY_SYSTEM_MUTATING environment variable is not set. This test should be run in a throw away environment, such as a container.") + + print("Extracting swiftly release") +#if os(Linux) + try Swiftly.currentPlatform.runProgram("tar", "-zxvf", "swiftly.tar.gz", quiet: false) +#elseif os(macOS) + try Swiftly.currentPlatform.runProgram("installer", "-pkg", "swiftly.pkg", "-target", "CurrentUserHomeDirectory", quiet: false) +#endif + + print("Running 'swiftly init --assume-yes --verbose' to install swiftly and the latest toolchain") + +#if os(Linux) + let extractedSwiftly = "./swiftly" +#elseif os(macOS) + let extractedSwiftly = FileManager.default.homeDirectoryForCurrentUser.appendingPathComponent("usr/local/bin/swiftly").path +#endif + + try Swiftly.currentPlatform.runProgram(extractedSwiftly, "init", "--assume-yes", "--verbose", quiet: false) + + let shell = try await Swiftly.currentPlatform.getShell() + + try Swiftly.currentPlatform.runProgram(shell, "-l", "-c", "swiftly install --assume-yes latest --post-install-file=./post-install.sh") + + if FileManager.default.fileExists(atPath: "./post-install.sh") { + try Swiftly.currentPlatform.runProgram("./post-install.sh") + } + + try Swiftly.currentPlatform.runProgram(shell, "-l", "-c", "swift --version", quiet: false) + } } diff --git a/Tools/build-swiftly-release/BuildSwiftlyRelease.swift b/Tools/build-swiftly-release/BuildSwiftlyRelease.swift index 1ca10696..f391b607 100644 --- a/Tools/build-swiftly-release/BuildSwiftlyRelease.swift +++ b/Tools/build-swiftly-release/BuildSwiftlyRelease.swift @@ -40,6 +40,10 @@ public func runProgramEnv(_ args: String..., quiet: Bool = false, env: [String: } public func runProgram(_ args: String..., quiet: Bool = false) throws { + try runProgram(args, quiet: quiet) +} + +public func runProgram(_ args: [String], quiet: Bool = false) throws { let process = Process() process.executableURL = URL(fileURLWithPath: "/usr/bin/env") process.arguments = args @@ -190,6 +194,9 @@ struct BuildSwiftlyRelease: AsyncParsableCommand { var identifier: String = "org.swift.swiftly" #endif + @Flag(help: "Produce a swiftly-test.tar.gz that has a standalone test suite to test the released bundle.") + var tests: Bool = false + @Argument(help: "Version of swiftly to build the release.") var version: String @@ -243,14 +250,14 @@ struct BuildSwiftlyRelease: AsyncParsableCommand { func checkSwiftRequirement() async throws -> String { guard !self.skip else { - return try await self.assertTool("swift", message: "Please install swift and make sure that it is added to your path.") + return try await self.assertTool("/usr/bin/swift", message: "Please install swift and make sure that it is added to your path.") } guard let requiredSwiftVersion = try? self.findSwiftVersion() else { throw Error(message: "Unable to determine the required swift version for this version of swiftly. Please make sure that you `cd ` and there is a .swift-version file there.") } - let swift = try await self.assertTool("swift", message: "Please install swift \(requiredSwiftVersion) and make sure that it is added to your path.") + let swift = try await self.assertTool("/usr/bin/swift", message: "Please install swift \(requiredSwiftVersion) and make sure that it is added to your path.") // We also need a swift toolchain with the correct version guard let swiftVersion = try await runProgramOutput(swift, "--version"), swiftVersion.contains("Swift version \(requiredSwiftVersion)") else { @@ -380,11 +387,33 @@ struct BuildSwiftlyRelease: AsyncParsableCommand { try runProgram(tar, "--directory=\(releaseDir)", "-czf", releaseArchive, "swiftly", "LICENSE.txt") print(releaseArchive) + + if self.tests { + try runProgram(swift, "build", "--build-tests", "--pkg-config-path=\(pkgConfigPath)/lib/pkgconfig") + + // Copy swift standard libraries to the build directory to bundle them with the test executable + let swiftLibEnum = FileManager.default.enumerator(atPath: "/usr/lib/swift") + var soFiles: [String] = [] + + while let file = swiftLibEnum?.nextObject() as? String { + if file.hasSuffix(".so") { + let baseName = file.split(separator: "/").last! + try? FileManager.default.removeItem(atPath: cwd + "/.build/debug/" + baseName) + try FileManager.default.copyItem(atPath: "/usr/lib/swift/" + file, toPath: cwd + "/.build/debug/" + baseName) + soFiles.append(String(baseName)) + } + } + + try runProgram([tar, "--directory=\(cwd + "/.build/debug")", "-czf", "\(cwd + "/.build/debug/test-swiftly.tar.gz")", "swiftlyPackageTests.xctest"] + soFiles) + + print(".build/debug/test-swiftly.tar.gz") + } } func buildMacOSRelease(cert: String?, identifier: String) async throws { // Check system requirements let git = try await self.assertTool("git", message: "Please install git with either `xcode-select --install` or `brew install git`") + let tar = try await self.assertTool("tar", message: "Tar not found") let swift = try await checkSwiftRequirement() @@ -439,5 +468,15 @@ struct BuildSwiftlyRelease: AsyncParsableCommand { ".build/release/swiftly-\(self.version).pkg" ) } + + print(".build/release/swiftly-\(self.version).pkg") + + if self.tests { + try runProgram(swift, "build", "--build-tests") + + try runProgram([tar, "--directory=.build/debug", "-czf", ".build/debug/test-swiftly.tar.gz", "swiftlyPackageTests.xctest"]) + + print(".build/debug/test-swiftly.tar.gz") + } } } From 94da425c7b85310428cfb00abbbd4418def6b9c6 Mon Sep 17 00:00:00 2001 From: "Chris (SPG) McGee" Date: Sat, 23 Nov 2024 07:40:15 -0500 Subject: [PATCH 02/27] Remove verbose flag --- .swift-version | 2 +- Tests/SwiftlyTests/E2ETests.swift | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.swift-version b/.swift-version index e0ea36fe..7a9f89d8 100644 --- a/.swift-version +++ b/.swift-version @@ -1 +1 @@ -6.0 +6.0.2 \ No newline at end of file diff --git a/Tests/SwiftlyTests/E2ETests.swift b/Tests/SwiftlyTests/E2ETests.swift index bd83acba..49f57c35 100644 --- a/Tests/SwiftlyTests/E2ETests.swift +++ b/Tests/SwiftlyTests/E2ETests.swift @@ -82,7 +82,7 @@ final class E2ETests: SwiftlyTests { let extractedSwiftly = FileManager.default.homeDirectoryForCurrentUser.appendingPathComponent("usr/local/bin/swiftly").path #endif - try Swiftly.currentPlatform.runProgram(extractedSwiftly, "init", "--assume-yes", "--verbose", quiet: false) + try Swiftly.currentPlatform.runProgram(extractedSwiftly, "init", "--assume-yes", quiet: false) let shell = try await Swiftly.currentPlatform.getShell() From 83e27d34e01738593807c65df036681c4fcb1084 Mon Sep 17 00:00:00 2001 From: "Chris (SPG) McGee" Date: Sat, 23 Nov 2024 07:48:46 -0500 Subject: [PATCH 03/27] Add ca-certificates package to the test release container --- .github/workflows/pull_request.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 7bfa26c8..d74a6bb9 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -62,6 +62,8 @@ jobs: container: image: "ubuntu:22.04" steps: + - name: Prepare System + run: apt update && apt -y install ca-certificates gpg - name: Download Release uses: actions/download-artifact@v4 with: From 47b6b63d6818f91b3dfd9053f986e29706c46869 Mon Sep 17 00:00:00 2001 From: "Chris (SPG) McGee" Date: Sat, 23 Nov 2024 11:52:44 -0500 Subject: [PATCH 04/27] Move all of the archives to /root and extract from there --- .github/workflows/pull_request.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index d74a6bb9..07df5641 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -73,7 +73,7 @@ jobs: with: name: swiftly-tests-x86_64 - name: Extract and Run Workflow Tests - run: mv swiftly-*.tar.gz swiftly.tar.gz && tar zxf test-swiftly.tar.gz && SWIFTLY_SYSTEM_MUTATING=1 ./swiftlyPackageTests.xctest SwiftlyTests.E2ETests/testAutomatedWorkflow + run: mv swiftly-*.tar.gz /root/swiftly.tar.gz && mv test-swiftly-tar.gz /root && cd /root && tar zxf test-swiftly.tar.gz && SWIFTLY_SYSTEM_MUTATING=1 ./swiftlyPackageTests.xctest SwiftlyTests.E2ETests/testAutomatedWorkflow formatcheck: name: Format Check From b10b4929a741da9317d34c27a48f9888846f657f Mon Sep 17 00:00:00 2001 From: "Chris (SPG) McGee" Date: Sat, 23 Nov 2024 12:01:55 -0500 Subject: [PATCH 05/27] Fix typo in workflow script --- .github/workflows/pull_request.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 07df5641..9de4dee2 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -73,7 +73,7 @@ jobs: with: name: swiftly-tests-x86_64 - name: Extract and Run Workflow Tests - run: mv swiftly-*.tar.gz /root/swiftly.tar.gz && mv test-swiftly-tar.gz /root && cd /root && tar zxf test-swiftly.tar.gz && SWIFTLY_SYSTEM_MUTATING=1 ./swiftlyPackageTests.xctest SwiftlyTests.E2ETests/testAutomatedWorkflow + run: mv swiftly-*.tar.gz /root/swiftly.tar.gz && mv test-swiftly.tar.gz /root && cd /root && tar zxf test-swiftly.tar.gz && SWIFTLY_SYSTEM_MUTATING=1 ./swiftlyPackageTests.xctest SwiftlyTests.E2ETests/testAutomatedWorkflow formatcheck: name: Format Check From a54826c61b30e52722e6983529b56a49af52869e Mon Sep 17 00:00:00 2001 From: "Chris (SPG) McGee" Date: Sun, 24 Nov 2024 08:26:26 -0500 Subject: [PATCH 06/27] Fixups and more introspection --- .github/workflows/pull_request.yml | 2 +- Tests/SwiftlyTests/E2ETests.swift | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 9de4dee2..d74e2460 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -73,7 +73,7 @@ jobs: with: name: swiftly-tests-x86_64 - name: Extract and Run Workflow Tests - run: mv swiftly-*.tar.gz /root/swiftly.tar.gz && mv test-swiftly.tar.gz /root && cd /root && tar zxf test-swiftly.tar.gz && SWIFTLY_SYSTEM_MUTATING=1 ./swiftlyPackageTests.xctest SwiftlyTests.E2ETests/testAutomatedWorkflow + run: cp swiftly-*.tar.gz /root/swiftly.tar.gz && cp test-swiftly.tar.gz /root && cd /root && tar zxf test-swiftly.tar.gz && SWIFTLY_SYSTEM_MUTATING=1 ./swiftlyPackageTests.xctest SwiftlyTests.E2ETests/testAutomatedWorkflow formatcheck: name: Format Check diff --git a/Tests/SwiftlyTests/E2ETests.swift b/Tests/SwiftlyTests/E2ETests.swift index 49f57c35..d409c81f 100644 --- a/Tests/SwiftlyTests/E2ETests.swift +++ b/Tests/SwiftlyTests/E2ETests.swift @@ -89,9 +89,13 @@ final class E2ETests: SwiftlyTests { try Swiftly.currentPlatform.runProgram(shell, "-l", "-c", "swiftly install --assume-yes latest --post-install-file=./post-install.sh") if FileManager.default.fileExists(atPath: "./post-install.sh") { - try Swiftly.currentPlatform.runProgram("./post-install.sh") + try Swiftly.currentPlatform.runProgram(shell, "./post-install.sh") } + // TODO remove this + print("CHECKING /root/.profile") + try Swiftly.currentPlatform.runProgram("cat", "/root/.profile") + try Swiftly.currentPlatform.runProgram(shell, "-l", "-c", "swift --version", quiet: false) } } From 0e1320c6856804368a31857016426fe7bf2d947f Mon Sep 17 00:00:00 2001 From: "Chris (SPG) McGee" Date: Sun, 24 Nov 2024 08:36:21 -0500 Subject: [PATCH 07/27] Place the profile check in a different location --- Tests/SwiftlyTests/E2ETests.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Tests/SwiftlyTests/E2ETests.swift b/Tests/SwiftlyTests/E2ETests.swift index d409c81f..65a2aaa6 100644 --- a/Tests/SwiftlyTests/E2ETests.swift +++ b/Tests/SwiftlyTests/E2ETests.swift @@ -86,16 +86,16 @@ final class E2ETests: SwiftlyTests { let shell = try await Swiftly.currentPlatform.getShell() + // TODO remove this + print("CHECKING /root/.profile") + try Swiftly.currentPlatform.runProgram("cat", "/root/.profile") + try Swiftly.currentPlatform.runProgram(shell, "-l", "-c", "swiftly install --assume-yes latest --post-install-file=./post-install.sh") if FileManager.default.fileExists(atPath: "./post-install.sh") { try Swiftly.currentPlatform.runProgram(shell, "./post-install.sh") } - // TODO remove this - print("CHECKING /root/.profile") - try Swiftly.currentPlatform.runProgram("cat", "/root/.profile") - try Swiftly.currentPlatform.runProgram(shell, "-l", "-c", "swift --version", quiet: false) } } From fcdfe5bcfcf679378f38fa6a83e28f3cca9ca8ad Mon Sep 17 00:00:00 2001 From: "Chris (SPG) McGee" Date: Sun, 24 Nov 2024 08:50:43 -0500 Subject: [PATCH 08/27] Force shell into interactive mode so that it sources the profile changes --- .github/workflows/pull_request.yml | 2 +- Tests/SwiftlyTests/E2ETests.swift | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index d74e2460..107b6de4 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -63,7 +63,7 @@ jobs: image: "ubuntu:22.04" steps: - name: Prepare System - run: apt update && apt -y install ca-certificates gpg + run: apt-get update && apt-get -y install ca-certificates gpg - name: Download Release uses: actions/download-artifact@v4 with: diff --git a/Tests/SwiftlyTests/E2ETests.swift b/Tests/SwiftlyTests/E2ETests.swift index 65a2aaa6..e4ef292c 100644 --- a/Tests/SwiftlyTests/E2ETests.swift +++ b/Tests/SwiftlyTests/E2ETests.swift @@ -86,16 +86,16 @@ final class E2ETests: SwiftlyTests { let shell = try await Swiftly.currentPlatform.getShell() - // TODO remove this + // TODO: remove this print("CHECKING /root/.profile") try Swiftly.currentPlatform.runProgram("cat", "/root/.profile") - try Swiftly.currentPlatform.runProgram(shell, "-l", "-c", "swiftly install --assume-yes latest --post-install-file=./post-install.sh") + try Swiftly.currentPlatform.runProgram(shell, "-i", "-l", "-c", "swiftly install --assume-yes latest --post-install-file=./post-install.sh") if FileManager.default.fileExists(atPath: "./post-install.sh") { try Swiftly.currentPlatform.runProgram(shell, "./post-install.sh") } - try Swiftly.currentPlatform.runProgram(shell, "-l", "-c", "swift --version", quiet: false) + try Swiftly.currentPlatform.runProgram(shell, "-i", "-l", "-c", "swift --version", quiet: false) } } From 03964ede2d397af080b8cf034c817b99804659a0 Mon Sep 17 00:00:00 2001 From: "Chris (SPG) McGee" Date: Sun, 24 Nov 2024 12:24:22 -0500 Subject: [PATCH 09/27] Add verbose shell logging --- Tests/SwiftlyTests/E2ETests.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Tests/SwiftlyTests/E2ETests.swift b/Tests/SwiftlyTests/E2ETests.swift index e4ef292c..24cb1416 100644 --- a/Tests/SwiftlyTests/E2ETests.swift +++ b/Tests/SwiftlyTests/E2ETests.swift @@ -90,12 +90,12 @@ final class E2ETests: SwiftlyTests { print("CHECKING /root/.profile") try Swiftly.currentPlatform.runProgram("cat", "/root/.profile") - try Swiftly.currentPlatform.runProgram(shell, "-i", "-l", "-c", "swiftly install --assume-yes latest --post-install-file=./post-install.sh") + try Swiftly.currentPlatform.runProgram(shell, "-v", "-l", "-c", "swiftly install --assume-yes latest --post-install-file=./post-install.sh") if FileManager.default.fileExists(atPath: "./post-install.sh") { try Swiftly.currentPlatform.runProgram(shell, "./post-install.sh") } - try Swiftly.currentPlatform.runProgram(shell, "-i", "-l", "-c", "swift --version", quiet: false) + try Swiftly.currentPlatform.runProgram(shell, "-v", "-l", "-c", "swift --version", quiet: false) } } From 98d34a2f241008a1899691ef839b0b60e9a6e481 Mon Sep 17 00:00:00 2001 From: "Chris (SPG) McGee" Date: Sun, 24 Nov 2024 12:39:37 -0500 Subject: [PATCH 10/27] Add more tracing information --- Tests/SwiftlyTests/E2ETests.swift | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Tests/SwiftlyTests/E2ETests.swift b/Tests/SwiftlyTests/E2ETests.swift index 24cb1416..c751006c 100644 --- a/Tests/SwiftlyTests/E2ETests.swift +++ b/Tests/SwiftlyTests/E2ETests.swift @@ -89,6 +89,12 @@ final class E2ETests: SwiftlyTests { // TODO: remove this print("CHECKING /root/.profile") try Swiftly.currentPlatform.runProgram("cat", "/root/.profile") + if FileManager.default.fileExists(atPath: "/root/.bash_profile") { + print("FILE EXISTS! /root/.bash_profile") + } + if FileManager.default.fileExists(atPath: "/root/.bash_login") { + print("FILE EXISTS! /root/.bash_login") + } try Swiftly.currentPlatform.runProgram(shell, "-v", "-l", "-c", "swiftly install --assume-yes latest --post-install-file=./post-install.sh") From 065524227eb0f2f6f1784a2ab89d049cc051ca9d Mon Sep 17 00:00:00 2001 From: "Chris (SPG) McGee" Date: Sun, 24 Nov 2024 13:01:22 -0500 Subject: [PATCH 11/27] Dump the shopt values in the test --- Tests/SwiftlyTests/E2ETests.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/Tests/SwiftlyTests/E2ETests.swift b/Tests/SwiftlyTests/E2ETests.swift index c751006c..b3c0827a 100644 --- a/Tests/SwiftlyTests/E2ETests.swift +++ b/Tests/SwiftlyTests/E2ETests.swift @@ -95,6 +95,7 @@ final class E2ETests: SwiftlyTests { if FileManager.default.fileExists(atPath: "/root/.bash_login") { print("FILE EXISTS! /root/.bash_login") } + try Swiftly.currentPlatform.runProgram(shell, "-v", "-l", "-c", "shopt") try Swiftly.currentPlatform.runProgram(shell, "-v", "-l", "-c", "swiftly install --assume-yes latest --post-install-file=./post-install.sh") From f4c25e7a5b4d3937eb386988ed4b98561a92a75f Mon Sep 17 00:00:00 2001 From: "Chris (SPG) McGee" Date: Sun, 24 Nov 2024 13:14:17 -0500 Subject: [PATCH 12/27] Set BASH_ENV to force the user ~/.profile to get loaded by the bash shell --- Tests/SwiftlyTests/E2ETests.swift | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Tests/SwiftlyTests/E2ETests.swift b/Tests/SwiftlyTests/E2ETests.swift index b3c0827a..d13289b0 100644 --- a/Tests/SwiftlyTests/E2ETests.swift +++ b/Tests/SwiftlyTests/E2ETests.swift @@ -97,7 +97,9 @@ final class E2ETests: SwiftlyTests { } try Swiftly.currentPlatform.runProgram(shell, "-v", "-l", "-c", "shopt") - try Swiftly.currentPlatform.runProgram(shell, "-v", "-l", "-c", "swiftly install --assume-yes latest --post-install-file=./post-install.sh") + var env = ProcessInfo.processInfo.environment + env["BASH_ENV"] = FileManager.default.homeDirectoryForCurrentUser.appendingPathComponent(".profile").path + try Swiftly.currentPlatform.runProgram(shell, "-v", "-l", "-c", "swiftly install --assume-yes latest --post-install-file=./post-install.sh", env: env) if FileManager.default.fileExists(atPath: "./post-install.sh") { try Swiftly.currentPlatform.runProgram(shell, "./post-install.sh") From db282307e57a95f00db53ecb4d91056fa7f9ada0 Mon Sep 17 00:00:00 2001 From: "Chris (SPG) McGee" Date: Sun, 24 Nov 2024 13:29:04 -0500 Subject: [PATCH 13/27] Insert a default UTC timezone for Linux if none is already set --- Tests/SwiftlyTests/E2ETests.swift | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Tests/SwiftlyTests/E2ETests.swift b/Tests/SwiftlyTests/E2ETests.swift index d13289b0..e1cb5b83 100644 --- a/Tests/SwiftlyTests/E2ETests.swift +++ b/Tests/SwiftlyTests/E2ETests.swift @@ -101,7 +101,14 @@ final class E2ETests: SwiftlyTests { env["BASH_ENV"] = FileManager.default.homeDirectoryForCurrentUser.appendingPathComponent(".profile").path try Swiftly.currentPlatform.runProgram(shell, "-v", "-l", "-c", "swiftly install --assume-yes latest --post-install-file=./post-install.sh", env: env) + // TODO: check if the user is root already before runing post install if FileManager.default.fileExists(atPath: "./post-install.sh") { +#if os(Linux) + if !FileManager.default.fileExists(atPath: "/etc/timezone") { + // Prevent tzdata package installation from trying to prompt for the time zone + try? Swiftly.currentPlatform.runProgram(shell, "echo 'Etc/UTC' > /etc/timezone") + } +#endif try Swiftly.currentPlatform.runProgram(shell, "./post-install.sh") } From c45a29ad28e62fd88f30e65224f0b69188884415 Mon Sep 17 00:00:00 2001 From: "Chris (SPG) McGee" Date: Sun, 24 Nov 2024 13:53:39 -0500 Subject: [PATCH 14/27] Pre-install tzdata and configure timezone --- .github/workflows/pull_request.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 107b6de4..d680bc34 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -63,7 +63,7 @@ jobs: image: "ubuntu:22.04" steps: - name: Prepare System - run: apt-get update && apt-get -y install ca-certificates gpg + run: apt-get update && DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC apt-get -y install ca-certificates gpg tzdata - name: Download Release uses: actions/download-artifact@v4 with: From 4960048936110e98ae686a2f906a454bb0f0f3c1 Mon Sep 17 00:00:00 2001 From: "Chris (SPG) McGee" Date: Sun, 24 Nov 2024 14:08:05 -0500 Subject: [PATCH 15/27] Clean up and pass the environment to the swift version invocation --- Tests/SwiftlyTests/E2ETests.swift | 27 +++++++-------------------- 1 file changed, 7 insertions(+), 20 deletions(-) diff --git a/Tests/SwiftlyTests/E2ETests.swift b/Tests/SwiftlyTests/E2ETests.swift index e1cb5b83..f2f9bdd7 100644 --- a/Tests/SwiftlyTests/E2ETests.swift +++ b/Tests/SwiftlyTests/E2ETests.swift @@ -86,32 +86,19 @@ final class E2ETests: SwiftlyTests { let shell = try await Swiftly.currentPlatform.getShell() - // TODO: remove this - print("CHECKING /root/.profile") - try Swiftly.currentPlatform.runProgram("cat", "/root/.profile") - if FileManager.default.fileExists(atPath: "/root/.bash_profile") { - print("FILE EXISTS! /root/.bash_profile") - } - if FileManager.default.fileExists(atPath: "/root/.bash_login") { - print("FILE EXISTS! /root/.bash_login") + var env = ProcessInfo.processInfo.environment + + // Setting this environment helps to ensure that the profile gets sourced with bash, even if it is not in an interactive shell + if shell == "/bin/bash" { + env["BASH_ENV"] = FileManager.default.homeDirectoryForCurrentUser.appendingPathComponent(".profile").path } - try Swiftly.currentPlatform.runProgram(shell, "-v", "-l", "-c", "shopt") - var env = ProcessInfo.processInfo.environment - env["BASH_ENV"] = FileManager.default.homeDirectoryForCurrentUser.appendingPathComponent(".profile").path - try Swiftly.currentPlatform.runProgram(shell, "-v", "-l", "-c", "swiftly install --assume-yes latest --post-install-file=./post-install.sh", env: env) + try Swiftly.currentPlatform.runProgram(shell, "-l", "-c", "swiftly install --assume-yes latest --post-install-file=./post-install.sh", env: env) - // TODO: check if the user is root already before runing post install if FileManager.default.fileExists(atPath: "./post-install.sh") { -#if os(Linux) - if !FileManager.default.fileExists(atPath: "/etc/timezone") { - // Prevent tzdata package installation from trying to prompt for the time zone - try? Swiftly.currentPlatform.runProgram(shell, "echo 'Etc/UTC' > /etc/timezone") - } -#endif try Swiftly.currentPlatform.runProgram(shell, "./post-install.sh") } - try Swiftly.currentPlatform.runProgram(shell, "-v", "-l", "-c", "swift --version", quiet: false) + try Swiftly.currentPlatform.runProgram(shell, "-l", "-c", "swift --version", quiet: false, env: env) } } From c1cdd20fb6044cfdcb0cf3fafc4028fba50eeb41 Mon Sep 17 00:00:00 2001 From: "Chris (SPG) McGee" Date: Sun, 24 Nov 2024 14:25:05 -0500 Subject: [PATCH 16/27] Add release tests with zsh --- .github/workflows/pull_request.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index d680bc34..985abcfd 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -75,6 +75,26 @@ jobs: - name: Extract and Run Workflow Tests run: cp swiftly-*.tar.gz /root/swiftly.tar.gz && cp test-swiftly.tar.gz /root && cd /root && tar zxf test-swiftly.tar.gz && SWIFTLY_SYSTEM_MUTATING=1 ./swiftlyPackageTests.xctest SwiftlyTests.E2ETests/testAutomatedWorkflow + releasetestzsh: + name: Test Release ZSH + needs: releasebuildcheck + runs-on: ubuntu-latest + container: + image: "ubuntu:24.04" + steps: + - name: Prepare System + run: apt-get update && DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC apt-get -y install ca-certificates gpg tzdata zsh && chsh -s /bin/zsh + - name: Download Release + uses: actions/download-artifact@v4 + with: + name: swiftly-release-x86_64 + - name: Download Tests + uses: actions/download-artifact@v4 + with: + name: swiftly-tests-x86_64 + - name: Extract and Run Workflow Tests + run: cp swiftly-*.tar.gz /root/swiftly.tar.gz && cp test-swiftly.tar.gz /root && cd /root && tar zxf test-swiftly.tar.gz && SWIFTLY_SYSTEM_MUTATING=1 ./swiftlyPackageTests.xctest SwiftlyTests.E2ETests/testAutomatedWorkflow + formatcheck: name: Format Check uses: swiftlang/github-workflows/.github/workflows/swift_package_test.yml@main From 523e2422567bc99b9d3e9b56061dba990290a3d0 Mon Sep 17 00:00:00 2001 From: "Chris (SPG) McGee" Date: Sun, 24 Nov 2024 15:30:14 -0500 Subject: [PATCH 17/27] Add fish shell testing, make a zshenv file that redirect to zprofile to mimic zsh login shell --- .github/workflows/pull_request.yml | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 985abcfd..35ceca31 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -83,7 +83,27 @@ jobs: image: "ubuntu:24.04" steps: - name: Prepare System - run: apt-get update && DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC apt-get -y install ca-certificates gpg tzdata zsh && chsh -s /bin/zsh + run: apt-get update && DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC apt-get -y install ca-certificates gpg tzdata zsh && chsh -s /bin/zsh && echo '. /root/.zprofile' > /root/.zshenv + - name: Download Release + uses: actions/download-artifact@v4 + with: + name: swiftly-release-x86_64 + - name: Download Tests + uses: actions/download-artifact@v4 + with: + name: swiftly-tests-x86_64 + - name: Extract and Run Workflow Tests + run: cp swiftly-*.tar.gz /root/swiftly.tar.gz && cp test-swiftly.tar.gz /root && cd /root && tar zxf test-swiftly.tar.gz && SWIFTLY_SYSTEM_MUTATING=1 ./swiftlyPackageTests.xctest SwiftlyTests.E2ETests/testAutomatedWorkflow + + releasetestzsh: + name: Test Release FISH + needs: releasebuildcheck + runs-on: ubuntu-latest + container: + image: "ubuntu:24.04" + steps: + - name: Prepare System + run: apt-get update && DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC apt-get -y install ca-certificates gpg tzdata fish && chsh -s /bin/fish - name: Download Release uses: actions/download-artifact@v4 with: From d8105bad11de50951248502f9a166edcf341e3d1 Mon Sep 17 00:00:00 2001 From: "Chris (SPG) McGee" Date: Sun, 24 Nov 2024 15:41:08 -0500 Subject: [PATCH 18/27] Fix job name --- .github/workflows/pull_request.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 35ceca31..b36ee73e 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -95,7 +95,7 @@ jobs: - name: Extract and Run Workflow Tests run: cp swiftly-*.tar.gz /root/swiftly.tar.gz && cp test-swiftly.tar.gz /root && cd /root && tar zxf test-swiftly.tar.gz && SWIFTLY_SYSTEM_MUTATING=1 ./swiftlyPackageTests.xctest SwiftlyTests.E2ETests/testAutomatedWorkflow - releasetestzsh: + releasetestfish: name: Test Release FISH needs: releasebuildcheck runs-on: ubuntu-latest From b7c6bdd11634df06887718e33409650bab287a72 Mon Sep 17 00:00:00 2001 From: "Chris (SPG) McGee" Date: Sun, 24 Nov 2024 16:05:53 -0500 Subject: [PATCH 19/27] Add verbose zsh and fish logging --- Tests/SwiftlyTests/E2ETests.swift | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Tests/SwiftlyTests/E2ETests.swift b/Tests/SwiftlyTests/E2ETests.swift index f2f9bdd7..92579183 100644 --- a/Tests/SwiftlyTests/E2ETests.swift +++ b/Tests/SwiftlyTests/E2ETests.swift @@ -91,14 +91,16 @@ final class E2ETests: SwiftlyTests { // Setting this environment helps to ensure that the profile gets sourced with bash, even if it is not in an interactive shell if shell == "/bin/bash" { env["BASH_ENV"] = FileManager.default.homeDirectoryForCurrentUser.appendingPathComponent(".profile").path + } else if shell == "/bin/fish" { + env["fish_trace"] = "on" } - try Swiftly.currentPlatform.runProgram(shell, "-l", "-c", "swiftly install --assume-yes latest --post-install-file=./post-install.sh", env: env) + try Swiftly.currentPlatform.runProgram(shell, "-v", "-l", "-c", "swiftly install --assume-yes latest --post-install-file=./post-install.sh", env: env) if FileManager.default.fileExists(atPath: "./post-install.sh") { try Swiftly.currentPlatform.runProgram(shell, "./post-install.sh") } - try Swiftly.currentPlatform.runProgram(shell, "-l", "-c", "swift --version", quiet: false, env: env) + try Swiftly.currentPlatform.runProgram(shell, "-v", "-l", "-c", "swift --version", quiet: false, env: env) } } From 9dc18fab10a9d58bf1338da839db524ba6a94977 Mon Sep 17 00:00:00 2001 From: "Chris (SPG) McGee" Date: Sun, 24 Nov 2024 16:15:51 -0500 Subject: [PATCH 20/27] Explicitly set the zsh dot dir, and disable verbose logging --- Tests/SwiftlyTests/E2ETests.swift | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Tests/SwiftlyTests/E2ETests.swift b/Tests/SwiftlyTests/E2ETests.swift index 92579183..d8a51e3a 100644 --- a/Tests/SwiftlyTests/E2ETests.swift +++ b/Tests/SwiftlyTests/E2ETests.swift @@ -91,16 +91,18 @@ final class E2ETests: SwiftlyTests { // Setting this environment helps to ensure that the profile gets sourced with bash, even if it is not in an interactive shell if shell == "/bin/bash" { env["BASH_ENV"] = FileManager.default.homeDirectoryForCurrentUser.appendingPathComponent(".profile").path + } else if shell == "/bin/zsh" { + env["ZDOTDIR"] = FileManager.default.homeDirectoryForCurrentUser.path } else if shell == "/bin/fish" { env["fish_trace"] = "on" } - try Swiftly.currentPlatform.runProgram(shell, "-v", "-l", "-c", "swiftly install --assume-yes latest --post-install-file=./post-install.sh", env: env) + try Swiftly.currentPlatform.runProgram(shell, "-l", "-c", "swiftly install --assume-yes latest --post-install-file=./post-install.sh", env: env) if FileManager.default.fileExists(atPath: "./post-install.sh") { try Swiftly.currentPlatform.runProgram(shell, "./post-install.sh") } - try Swiftly.currentPlatform.runProgram(shell, "-v", "-l", "-c", "swift --version", quiet: false, env: env) + try Swiftly.currentPlatform.runProgram(shell, "-l", "-c", "swift --version", quiet: false, env: env) } } From b8923d395da5dcb4bf8f7b624374a3017ef4ee17 Mon Sep 17 00:00:00 2001 From: "Chris (SPG) McGee" Date: Sun, 24 Nov 2024 16:48:53 -0500 Subject: [PATCH 21/27] Check the fish conf.d file --- Tests/SwiftlyTests/E2ETests.swift | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Tests/SwiftlyTests/E2ETests.swift b/Tests/SwiftlyTests/E2ETests.swift index d8a51e3a..02ab484a 100644 --- a/Tests/SwiftlyTests/E2ETests.swift +++ b/Tests/SwiftlyTests/E2ETests.swift @@ -89,12 +89,14 @@ final class E2ETests: SwiftlyTests { var env = ProcessInfo.processInfo.environment // Setting this environment helps to ensure that the profile gets sourced with bash, even if it is not in an interactive shell - if shell == "/bin/bash" { + if shell.hasSuffix("bash") { env["BASH_ENV"] = FileManager.default.homeDirectoryForCurrentUser.appendingPathComponent(".profile").path - } else if shell == "/bin/zsh" { + } else if shell.hasSuffix("zsh") { env["ZDOTDIR"] = FileManager.default.homeDirectoryForCurrentUser.path - } else if shell == "/bin/fish" { + } else if shell.hasSuffix("fish") { env["fish_trace"] = "on" + // TODO remove this check + try Swiftly.currentPlatform.runProgram(shell, "cat", FileManager.default.homeDirectoryForCurrentUser.appendingPathComponent(".config/fish/conf.d/swiftly.fish").path) } try Swiftly.currentPlatform.runProgram(shell, "-l", "-c", "swiftly install --assume-yes latest --post-install-file=./post-install.sh", env: env) From 0c7879f644f3ca38ee1c32a38aa0525bcf691f72 Mon Sep 17 00:00:00 2001 From: "Chris (SPG) McGee" Date: Sun, 24 Nov 2024 16:56:56 -0500 Subject: [PATCH 22/27] Fix the check --- Tests/SwiftlyTests/E2ETests.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Tests/SwiftlyTests/E2ETests.swift b/Tests/SwiftlyTests/E2ETests.swift index 02ab484a..fec666ab 100644 --- a/Tests/SwiftlyTests/E2ETests.swift +++ b/Tests/SwiftlyTests/E2ETests.swift @@ -95,8 +95,8 @@ final class E2ETests: SwiftlyTests { env["ZDOTDIR"] = FileManager.default.homeDirectoryForCurrentUser.path } else if shell.hasSuffix("fish") { env["fish_trace"] = "on" - // TODO remove this check - try Swiftly.currentPlatform.runProgram(shell, "cat", FileManager.default.homeDirectoryForCurrentUser.appendingPathComponent(".config/fish/conf.d/swiftly.fish").path) + // TODO: remove this check + try Swiftly.currentPlatform.runProgram(shell, "-c", "cat", FileManager.default.homeDirectoryForCurrentUser.appendingPathComponent(".config/fish/conf.d/swiftly.fish").path) } try Swiftly.currentPlatform.runProgram(shell, "-l", "-c", "swiftly install --assume-yes latest --post-install-file=./post-install.sh", env: env) From eb7c5d7a0008863d33ec4e18229babfabb5638b7 Mon Sep 17 00:00:00 2001 From: "Chris (SPG) McGee" Date: Sun, 24 Nov 2024 18:44:45 -0500 Subject: [PATCH 23/27] Fix the fish shell check --- Tests/SwiftlyTests/E2ETests.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/SwiftlyTests/E2ETests.swift b/Tests/SwiftlyTests/E2ETests.swift index fec666ab..92576002 100644 --- a/Tests/SwiftlyTests/E2ETests.swift +++ b/Tests/SwiftlyTests/E2ETests.swift @@ -96,7 +96,7 @@ final class E2ETests: SwiftlyTests { } else if shell.hasSuffix("fish") { env["fish_trace"] = "on" // TODO: remove this check - try Swiftly.currentPlatform.runProgram(shell, "-c", "cat", FileManager.default.homeDirectoryForCurrentUser.appendingPathComponent(".config/fish/conf.d/swiftly.fish").path) + try Swiftly.currentPlatform.runProgram(shell, "-c", "cat \(FileManager.default.homeDirectoryForCurrentUser.appendingPathComponent(".config/fish/conf.d/swiftly.fish").path)") } try Swiftly.currentPlatform.runProgram(shell, "-l", "-c", "swiftly install --assume-yes latest --post-install-file=./post-install.sh", env: env) From de9f95a88201fb8ab544e4466305c6c6254a8cfb Mon Sep 17 00:00:00 2001 From: "Chris (SPG) McGee" Date: Sun, 24 Nov 2024 20:16:01 -0500 Subject: [PATCH 24/27] Set XDG_CONFIG_HOME to point fish to the correct location --- Tests/SwiftlyTests/E2ETests.swift | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Tests/SwiftlyTests/E2ETests.swift b/Tests/SwiftlyTests/E2ETests.swift index 92576002..e8fe8cfe 100644 --- a/Tests/SwiftlyTests/E2ETests.swift +++ b/Tests/SwiftlyTests/E2ETests.swift @@ -95,8 +95,7 @@ final class E2ETests: SwiftlyTests { env["ZDOTDIR"] = FileManager.default.homeDirectoryForCurrentUser.path } else if shell.hasSuffix("fish") { env["fish_trace"] = "on" - // TODO: remove this check - try Swiftly.currentPlatform.runProgram(shell, "-c", "cat \(FileManager.default.homeDirectoryForCurrentUser.appendingPathComponent(".config/fish/conf.d/swiftly.fish").path)") + env["XDG_CONFIG_HOME"] = "/root/.config" } try Swiftly.currentPlatform.runProgram(shell, "-l", "-c", "swiftly install --assume-yes latest --post-install-file=./post-install.sh", env: env) From 329dc51af3d2025bc75b59f171b0465c4345b5f3 Mon Sep 17 00:00:00 2001 From: "Chris (SPG) McGee" Date: Sun, 24 Nov 2024 20:25:15 -0500 Subject: [PATCH 25/27] Remove fish tracing --- Tests/SwiftlyTests/E2ETests.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/Tests/SwiftlyTests/E2ETests.swift b/Tests/SwiftlyTests/E2ETests.swift index e8fe8cfe..c7e3b2fc 100644 --- a/Tests/SwiftlyTests/E2ETests.swift +++ b/Tests/SwiftlyTests/E2ETests.swift @@ -94,7 +94,6 @@ final class E2ETests: SwiftlyTests { } else if shell.hasSuffix("zsh") { env["ZDOTDIR"] = FileManager.default.homeDirectoryForCurrentUser.path } else if shell.hasSuffix("fish") { - env["fish_trace"] = "on" env["XDG_CONFIG_HOME"] = "/root/.config" } From 676e47ca5efff36b3ae0dadb915e0cab6be9d18c Mon Sep 17 00:00:00 2001 From: "Chris (SPG) McGee" Date: Sun, 24 Nov 2024 20:28:40 -0500 Subject: [PATCH 26/27] Fix XDG_CONFIG_HOME to point to the user home directory, not just root --- Tests/SwiftlyTests/E2ETests.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/SwiftlyTests/E2ETests.swift b/Tests/SwiftlyTests/E2ETests.swift index c7e3b2fc..af9dde2e 100644 --- a/Tests/SwiftlyTests/E2ETests.swift +++ b/Tests/SwiftlyTests/E2ETests.swift @@ -94,7 +94,7 @@ final class E2ETests: SwiftlyTests { } else if shell.hasSuffix("zsh") { env["ZDOTDIR"] = FileManager.default.homeDirectoryForCurrentUser.path } else if shell.hasSuffix("fish") { - env["XDG_CONFIG_HOME"] = "/root/.config" + env["XDG_CONFIG_HOME"] = FileManager.default.homeDirectoryForCurrentUser.appendingPathComponent(".config").path } try Swiftly.currentPlatform.runProgram(shell, "-l", "-c", "swiftly install --assume-yes latest --post-install-file=./post-install.sh", env: env) From 0496e16bfb8cc969d0a696479b1d4efdc518d264 Mon Sep 17 00:00:00 2001 From: "Chris (SPG) McGee" Date: Sun, 24 Nov 2024 20:29:42 -0500 Subject: [PATCH 27/27] Remove hard-coded swift paths --- Tools/build-swiftly-release/BuildSwiftlyRelease.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Tools/build-swiftly-release/BuildSwiftlyRelease.swift b/Tools/build-swiftly-release/BuildSwiftlyRelease.swift index f391b607..a58dbeaf 100644 --- a/Tools/build-swiftly-release/BuildSwiftlyRelease.swift +++ b/Tools/build-swiftly-release/BuildSwiftlyRelease.swift @@ -250,14 +250,14 @@ struct BuildSwiftlyRelease: AsyncParsableCommand { func checkSwiftRequirement() async throws -> String { guard !self.skip else { - return try await self.assertTool("/usr/bin/swift", message: "Please install swift and make sure that it is added to your path.") + return try await self.assertTool("swift", message: "Please install swift and make sure that it is added to your path.") } guard let requiredSwiftVersion = try? self.findSwiftVersion() else { throw Error(message: "Unable to determine the required swift version for this version of swiftly. Please make sure that you `cd ` and there is a .swift-version file there.") } - let swift = try await self.assertTool("/usr/bin/swift", message: "Please install swift \(requiredSwiftVersion) and make sure that it is added to your path.") + let swift = try await self.assertTool("swift", message: "Please install swift \(requiredSwiftVersion) and make sure that it is added to your path.") // We also need a swift toolchain with the correct version guard let swiftVersion = try await runProgramOutput(swift, "--version"), swiftVersion.contains("Swift version \(requiredSwiftVersion)") else {