Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Swiftly proxies #155

Open
wants to merge 21 commits into
base: main
Choose a base branch
from
Open

Swiftly proxies #155

wants to merge 21 commits into from

Conversation

cmcgee1024
Copy link
Member

@cmcgee1024 cmcgee1024 commented Aug 10, 2024

Add a design for the new swiftly proxy system for more flexible routing of command invocations to a toolchain.

Re-target the symbolic links that swiftly creates to point to swiftly itself, which can decide the selected toolchain more flexibly on a per-invocation basis.

Add support for reading the toolchain version from a .swift-version file if a selector isn't given. The swiftly use command will attempt to update a swift version file, or in certain circumstances it will create the version file for you. The special swiftly install with no selector argument that will attempt to install a toolchain version specified in a version file.

Create a swiftly run subcommand that can run arbitrary commands, such as build scripts or makefile generators. This subcommand will set the PATH environment variable to the currently selected toolchain, and other special environment variables like CC and CXX to specifically point to the clang and clang++ executables. Add an ability for this subcommand to accept arbitrary toolchain selectors that take the higher precedence over the presence of the swift version file or the global default.

swiftly run swift build +latest
swiftly run cmake -G ninja +main-snapshot +install

Update swiftly use and swiftly list to take into account that there is a global default, which is the fallback if there is no .swift-version file, but also a potentially different toolchain that is in use in the current context. The swiftly use subcommand with not arguments will show in brackets the reason why the current in-use toolchain is selected, whether it is a special .swift-version file in which case it will show the file path, or it is the global default.

Add a design proposal for the new swiftly proxy system
@BrianHenryIE
Copy link

Hijackingswift altogether isn't ideal. I've used which swift to determine the toolchain directory and proxying adds a level of indirection that isn't obvious.

https://github.com/anders0nmat/swift-embedded-pm/pull/3/files

Consider:

swiftly run 5.10.1 build

Or proxy CLI arguments that don't exist in swiftly to swift:

swiftly build

(I just write Swift for fun, so take my suggestions with a grain of salt)

@cmcgee1024
Copy link
Member Author

@BrianHenryIE your feedback is appreciated, thank you.

I've used which swift to determine the toolchain directory and proxying adds a level of indirection that isn't obvious.

https://github.com/anders0nmat/swift-embedded-pm/pull/3/files

It seems from the above patch that the end goal is to be able to invoke the llvm-ar executable from the current toolchain. I'm curious, why dig through the symlink to the real path using the realpath command? The llvm-ar command should be a sibling of the swift command, whether if it is a symlink created by swiftly, or a toolchain binary installed by other means (e.g. manual installation, system package). Inspecting the symlink would seem to couple this CMake script to swiftly being the toolchain manager.

Consider:

swiftly run 5.10.1 build

Providing a swiftly run subcommand is something that we can consider as an enhancement to the current swiftly design. We could allow someone to run any command that they want, not just the toolchain ones. The command runs where the PATH is set to the toolchain binaries with the highest precedence. Also, we can set certain environment variables like CC and CXX to the selected clang version.

# Let's use the swift toolchain to compile this C project:
swiftly run 5.10 ./configure
swiftly run 5.10 make

We can put these ideas and more into #22

Copy link
Contributor

@adam-fowler adam-fowler left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not 100% convinced by this yet. I wonder how the core team would feel about the swift exe being hijacked by swiftly.

@@ -208,6 +216,10 @@ To use the latest installed main snapshot, leave off the date:

`swiftly use main-snapshot`

The use subcommand also supports `.swift-version` files. If version file is present in the current working directory, or an ancestory directory, then swiftly will update that file with the new version to use. This can be a useful feature for a team to share and align on toolchain versions with git. As a special case, if swiftly could not find a version file, but it could find a Package.swift file it will create a new version file for you in the package and set that to the requested toolchain version.

Note: The `.swift-version` file mechanisms can be overridden using the `--global-default` flag so that your swiftly installation's default toolchain can be set explicitly.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would rather the default is the other way. ie use edits global settings and you can change local settings with a --local flag.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that there are advantage of having this local as the default. It encourages the sharing of the toolchain revision that the team is working with through discovery of this feature of swiftly. Also, this helps to tie into one of the values of using swiftly itself, which is how easily and flexibly you can switch toolchains.

In terms of precedence, git defaults to local over global for its configuration.

I'm curious what you think are the pitfalls of this approach.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I realised as I was writing this, there is previous art that defaults to local. It is more a preference on my behalf and how I'd use swiftly

DESIGN.md Outdated Show resolved Hide resolved
@cmcgee1024
Copy link
Member Author

I'm not 100% convinced by this yet. I wonder how the core team would feel about the swift exe being hijacked by swiftly.

I'm definitely interested to hear if there are opinions from the core team about this enhancement. I prefer to think of this as extending the semantics, not "hijacking" the toolchain itself. There are precedents for a proxy mechanism of a toolchain manager on top of the toolchain itself, such as rustup.

DESIGN.md Outdated
* The presence of a .swift-version file in the current working directory, or ancestor directory, with the required toolchain version
* The swiftly default (in-use) toolchain set in the config.json by `swiftly install` or `swiftly use` commands

In the first two cases, if there is no matching toolchain installed, swiftly will attempt to automatically install the requested toolchain and use it if the installation succeeeds.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'll need a way to disable this. People with a bad network connection will not be wanting to download 900MB of swift toolchain just to build a project.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I'll update this since this has come up a few times. It could be a case of over automation. Instead, if there's no matching toolchain then the command fails. The swiftly install with no arguments can be used to install the currently selected toolchain with the full capabilities of that subcommand, including post install script, etc. Also, it's clear that an error is related to the install operation itself since that is the request.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we also have a command line option to ignore the .swift-version file. This would make it easier for things like CI to test a library (which includes a .swift-version file) against multiple swift toolchains

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I think that this in this case the command-line selectors will take precedence over both the .swift-version file and the global default in-use toolchain from the config.json. The CI can do this to force specific toolchain(s):

swiftly install 5.10.1 # Install this specific toolchain
swift build +5.10.1   # Build with this toolchain

…ocation

clarify the boundaries of the swiftly toolchain abstraction and elaborate on how to work around them
Copy link
Member

@0xTim 0xTim left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd be interested to hear the core team's view on intercepting any calls to swift. Node does a similar thing with nvm IIRC so there's precedent, not that that's the best example of an ecosystem if there are any security concerns 😅

I would say that the + syntax is not overly discoverable or intuitive, I'm not aware of any other tool that has this. I'd be more inclined to have an actual flag that can either be intercepted or called via swiftly run etc.

Overall however I agree that having a mechanism for being able to run commands in Swift with different versions without having to constantly switch your local version is valuable and should be implemented

DESIGN.md Outdated

Swiftly helps you to easily install different Swift toolchains locally on your account. It also provides a single path where you can run the tools in the currently selected toolchain. Toolchain selection is [configurable](#toolchain-selection) using different mechanisms.

Note that swiftly is *not* a virtual toolchain in itself since there are cases where it cannot behave as a self-contained Swift toolchain. For example, there can be external dependencies on specific files, such as headers or libraries, far too many and variable between toolchain versions to be managed by swiftly. Also, for long-lived processes, there is no way to gracefully restart them without help from the client.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sentence needs some tweaking I think

Suggested change
Note that swiftly is *not* a virtual toolchain in itself since there are cases where it cannot behave as a self-contained Swift toolchain. For example, there can be external dependencies on specific files, such as headers or libraries, far too many and variable between toolchain versions to be managed by swiftly. Also, for long-lived processes, there is no way to gracefully restart them without help from the client.
Note that swiftly is *not* a virtual toolchain in itself since there are cases where it cannot behave as a self-contained Swift toolchain. For example, there can be external dependencies on specific files, such as headers or libraries, far too many variables between toolchain versions to be managed by swiftly. Also, for long-lived processes, there is no way to gracefully restart them without help from the client.

@cmcgee1024
Copy link
Member Author

I'd be interested to hear the core team's view on intercepting any calls to swift. Node does a similar thing with nvm IIRC so there's precedent, not that that's the best example of an ecosystem if there are any security concerns 😅

Do you know a way to engage the core team on this? I'm also curious if there are any concerns or suggestions from there. The proxy idea has been mentioned in the forums a couple of times now, the last one points to this PR. I have received some feedback, but I don't know if any have been representative of the core.

I would say that the + syntax is not overly discoverable or intuitive, I'm not aware of any other tool that has this. I'd be more inclined to have an actual flag that can either be intercepted or called via swiftly run etc.

Thank you, this is a fair observation.

The proxy concept along with the + syntax is inspired in part by rustup:
=> https://rust-lang.github.io/rustup/concepts/proxies.html

In their documentation there is only a small mention of the special selector syntax:
=> https://rust-lang.github.io/rustup/overrides.html#toolchain-override-shorthand

I think that this syntax can be discoverable in swiftly by providing (some) examples in the getting started guide, demonstrating how to use swiftly. In the swiftly steady state I imagine that the syntax won't be used very often as the toolchain will likely be selected with either the in-use global default for the user, or hopefully, the project's .swift-version file that aligns the project participants. In these cases swiftly works just like using the toolchain directly, with the exception of times when the selected toolchain isn't installed where it prompts the user to install it. This is what's interesting about the proxy concept.

I can see the + syntax being particularly useful when someone wants to run a check against the latest snapshot, or a previous stable build.

Overall however I agree that having a mechanism for being able to run commands in Swift with different versions without having to constantly switch your local version is valuable and should be implemented

I'm wondering, since this has come up a few times, if it might be worth providing both proxy capability and #22 at the same time in this PR to suit different preferences and use cases.

Copy link
Contributor

@patrickfreed patrickfreed left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I personally tend to prefer a subcommand over the + syntax since swiftly isn't ubiquitous (yet 🙂) like rustup is, and so introducing swiftly-specific syntax to a non-swiftly binary invocation may cause confusion for non-swiftly users when they encounter someone else using it (or more frustratingly, compatibility issues in scripts and what not). That said, it is a generally useful syntax, so if the core team is supportive, then I don't have a problem with it.

To avoid blocking the work for this, I'd suggest we start with the more conservative swiftly run <toolchain> or swiftly exec <toolchain> command and then add the + syntax later.

DESIGN.md Outdated
For cases where the physical toolchain must be located, such as references specific header files, or shared libraries that are not proxied by swiftly there is a method to resolve the currently selected toolchain to its physical location using `swiftly use`.

```
swiftly use --location
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

perhaps --print-location? As it is, it looks like --location affects use in some way.

DESIGN.md Outdated
@@ -60,7 +67,7 @@ A simple setup for managing the toolchains could look like this:

The toolchains (i.e. the contents of a given Swift download tarball) would be contained in the toolchains directory, each named according to the major/minor/patch version. `config.json` would contain any required metadata (e.g. the latest Swift version, which toolchain is selected, etc.). If pulling in Foundation to use `JSONEncoder`/`JSONDecoder` (or some other JSON tool) would be a problem, we could also use something simpler.

The `~/.local/bin` directory would include symlinks pointing to the `bin` directory of the "active" toolchain, if any.
The `~/.local/bin` directory would include symlinks pointing to swiftly itself. When these binaries are run swiftly proxies them to the requested toolchain, or a default.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be good to more clearly explain what "these binaries" refer to in this sentence.

@0xTim
Copy link
Member

0xTim commented Aug 27, 2024

Do you know a way to engage the core team on this?

Maybe @shahmishal can bring it up but this should probably be raised at the Platform Steering Group until whatever group will end up with ownership of this takes over them

@airspeedswift
Copy link
Member

this should probably be raised at the Platform Steering Group

I think this is right. There are plans to add a third steering group in future (dubbed "Ecosystem") and this might fall under that rather than Platform, but I could see it going either way in this case so starting with the platform steering group is the right way to go for now.

The first step is to write up a pitch and post it to the forums. That pitch should cover the pros/cons of the approach, and recommend one (with the others being alternatives considered). Then engagement on the merits can happen in that thread. That said, it's fine to hash out early ideas on a doc in this repo beforehand.

Once the pitch has had some time to converge on a way forward, the platform steering group would take it up as a proposal. You don't need the steering group to pre-clear that pitch, though you might want to give them a heads up about it, so they can engage in it too since they'll ultimately be the ones deciding which way to go with this.

Note that since Swiftly was ingested into swiftlang and so is part of the Swift project now, I don't see anything contentious about close integration between the swift launch tool and swiftly per se. But of course, the other tradeoffs cited in this thread about exactly how that integration actually works should be discussed.

@cmcgee1024
Copy link
Member Author

Thanks everyone for the discussion here. This has been really positive. I will change the shape of this PR in a couple of ways and see if this can be accomplished in the near term:

  • Retain proxy concept for further refinement in the future.
  • Implement Implement exec command #22 in here to support a swiftly specific syntax for on-the-fly toolchain selection and also the extra capabilities that feature can provide.
  • Defer the special toolchain selector syntax (ie. the injection of the '+' into tool invocations) for later after a pitch has been made on the forums and the platform steering group.

Please let me know if there are any concerns over this latest pivot.

Change the nature of the swiftly symlinks so that they point
to the swiftly executable at install time. These do not change
when new toolchains are used. Toolchain selection happens each
time when the proxies are run. The proxies are created for a
well-known set of toolchain binaries that are constant for
a wide variety of toolchain versions and platforms.

Add support for .swift-version files for toolchain selection.
Update the use command so that it can point out which toolchain
is in use based on context, such as swift version files that are
located in the current working directory or above. The fallback
selection comes from the global default configuration's 'inUse'
setting. When querying for what's in use the global default
is shown with the "(default)" tag. If the in-use toolchain is
selected by a swift-version file the path to that file is displayed.

Provide a print location flag to the use subcommand that can print
the file path of the toolchain that is in use in the current
context.

When using a new toolchain, depending on whether a swift version
is selecting the current one, update the swift version file with
the selected toolchain version. If no swift version file can be
located, attempt to create a new one at the top of the git worktree.
If there is no git worktree, then fallback to updating the global
default in the configuration.

Provide a global default flag for the use subcommand so that only
the global default in-use toolchain is considered and not any of
the swift version files.
@cmcgee1024
Copy link
Member Author

@swift-ci test macOS

@rauhul
Copy link
Member

rauhul commented Sep 5, 2024

Out of curiosity, do you have an idea of how this would interact with xcrun?

@cmcgee1024
Copy link
Member Author

Out of curiosity, do you have an idea of how this would interact with xcrun?

Swiftly's mechanisms for toolchain selection are entirely separate from xcrun. But, it will install toolchain packages in the user's volume, and those should be reachable with xcrun.

Provide a run command that allows arbitrary commands to be run in the context of the selected toolchain.

Provide a one-off selection mechanism with a special syntax on the run command.
@cmcgee1024
Copy link
Member Author

@swift-ci test macOS

@cmcgee1024
Copy link
Member Author

@swift-ci test macOS

@cmcgee1024
Copy link
Member Author

@swift-ci test macOS

@cmcgee1024 cmcgee1024 marked this pull request as ready for review September 9, 2024 15:57
@cmcgee1024
Copy link
Member Author

@swift-ci test macOS

1 similar comment
@cmcgee1024
Copy link
Member Author

@swift-ci test macOS

@cmcgee1024
Copy link
Member Author

The macOS check is passing despite the failure:

Test Suite 'All tests' passed at 2024-09-09 17:12:09.524.
	 Executed 68 tests, with 0 failures (0 unexpected) in 61.581 (61.592) seconds

@cmcgee1024
Copy link
Member Author

@swift-ci test macOS

@cmcgee1024
Copy link
Member Author

@swift-ci test macOS

@cmcgee1024
Copy link
Member Author

macOS is still passing all of the tests:

Test Suite 'All tests' passed at 2024-09-10 11:04:46.361.
	 Executed 68 tests, with 0 failures (0 unexpected) in 61.283 (61.293) seconds

@cmcgee1024 cmcgee1024 changed the title DRAFT: Swiftly proxies Swiftly proxies Sep 10, 2024
With no arguments the install subcommand will install the currently
selected toolchain from the `.swift-version` files.
Copy link
Contributor

@patrickfreed patrickfreed left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the delay!

DESIGN.md Outdated

```
# Download and install the latest main snapshot toolchain and run 'swift build' to build the package with it.
swiftly run swift build +main-snapshot +install
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it might be a bit overkill to support the install command this way, since users can just run swiftly install main-snapshot before running this command. At least for now, I'd support simplifying this so there's only one way to install a toolchain.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you, I'll remove this. It might have made more sense in the context of the original proxy proposal.

Comment on lines +487 to +489
**--version:**

*Show the version.*
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need this implemented separately. The user can just run swiftly run swift --version if they want the Swift version, or swift use to print the in use toolchain.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a global flag coming from the argument parser, not an explicit option for the run subcommand. See the --help below. The CLI reference generator that I wrote for swiftly could probably use a bit of refinement to skip over these special flags. It's very naive at the moment, but I think better than having to maintain our own reference manually.

Run a command while proxying to the selected toolchain commands.

```
swiftly run <command>... [--version] [--help]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This docstring should mention the + syntax as an option

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This documentation is generated using a plugin that inspects the argument parser. The + syntax is specific to this subcommand and so the usage here doesn't pick this up as a typical flag, option, or argument. Hopefully the examples usages below capture how to use this syntax. Note that the + isn't strictly required, so not knowing about it doesn't block naive uses of swiftly run.

let contents = try? String(contentsOf: svFile, encoding: .utf8)

guard let contents = contents else {
return (nil, .swiftVersionFile(svFile, nil, Error(message: "The swift version file could not be read: \(svFile)")))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than returning a tuple, could we just throw this error?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error is part of the tuple here because in some contexts the error is ignored, while others it is thrown.

For example, when swiftly use is displaying the currently selected toolchain, or it is trying to find the swift version file to update with the used version it doesn't care if the file is well-formed, or not matching a toolchain that is currently installed. Whereas in other cases like the proxies or the swiftly run that will interfere with the ability to run the command against a toolchain.

// The toolchain goes to the beginning of the PATH
var newPath = newEnv["PATH"] ?? ""
if !newPath.hasPrefix(tcPath.path + ":") {
newPath = ([tcPath.path] + newPath.split(separator: ":").map { String($0) }).joined(separator: ":")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rather than splitting and joining again, can we just concatenate tcPath, ":", and newPath?

internal static func execute(_ toolchain: ToolchainVersion, _ config: inout Config) async throws {
let previousToolchain = config.inUse
/// Use a toolchain. This method can modify and save the input config.
internal static func execute(_ toolchain: ToolchainVersion, _ globalDefault: Bool, _ config: inout Config) async throws {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we pass globalDefault by keyword arg? It can be hard to remember what the lone boolean indicates at the callsites.

Comment on lines 118 to 119
} else if let newVersionFile = findNewVersionFile(), !globalDefault {
try toolchain.name.write(to: newVersionFile, atomically: true, encoding: .utf8)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I personally don't think swiftly should be creating local .swift-version files if they don't already exist, at least not without user-opt in. I think it's fine to update an existing one, but I imagine most users will have a single Swift version that they use for all of their projects, and swiftly automatically creating these files may be a bit annoying.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I can change this over to a prompt to either go ahead and create a file that can be shared, or update the global default.

var message = "Set the active toolchain to \(toolchain)"
if let previousToolchain {
message += " (was \(previousToolchain))"
var message = "Set the used toolchain to \(toolchain)"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"used" -> "in-use"

Comment on lines +5 to +21
let proxyList = [
"clang",
"lldb",
"lldb-dap",
"lldb-server",
"clang++",
"sourcekit-lsp",
"clangd",
"swift",
"docc",
"swiftc",
"lld",
"llvm-ar",
"plutil",
"repl_swift",
"wasm-ld",
]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a bit concerned about this--what if a new toolchain has a new executable not on this list? Or what if a toolchain doesn't have a executable on this list? Perhaps being concerned about that is too pessimistic, but it seems somewhat brittle to me. I can't think of any solutions off the top of my head given that we want to support selecting a toolchain via .swift-version files, though. The only thing I can think of is requiring users to run swiftly use to select the toolchain from the file, but that does seem quite un-ergonomic.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea of the stable proxy allowed list came out of some necessity, which was to install the proxies at swiftly init time instead of toolchain installation time, but also as a measure of security, which strongly favours allow lists over deny lists.

I can imagine that the commands in this list can be useful to someone in the context of swiftly. We can change this list over time, and manage the proxy symlinks as we do upgrades from version to version. If anyone has suggestions on adding/removing commands from the list I'm interested in hearing your opinions.

This is also one of the reasons that I updated the swiftly design document to clarify that the purpose of swiftly is not to be a fully virtual toolchain. Not all clients of the toolchain will be able to work within the abstraction that swiftly provides. In one case there is a need to reach inside and grab a dylib (.so). There are potentially many others where someone would like to reach in for a particular header file, or other resources. Swiftly isn't equipped to symlink, or proxy, everything in there. It's just not practical.

So, for cases where someone needs access to something more obscure, there is the escape hatch of the swiftly use --print-location to get at the real toolchain path where they can reach into the internals as needed at the cost of being optionally dependent on swiftly for that capability.

…swiftly install`.

Guard automatic creation of .swift-version file from `swiftly use` around a prompt overridable using an `--assume-yes`.

Minor cleanup
Fix all of the swift.org urls so that they use www.swift.org to avoid redirection
@cmcgee1024
Copy link
Member Author

@swift-ci test macOS

@cmcgee1024
Copy link
Member Author

The macOS tests are all passing with this latest commit:

Test Suite 'All tests' passed at 2024-09-20 15:11:26.338.
	 Executed 68 tests, with 0 failures (0 unexpected) in 74.036 (74.046) seconds

@cmcgee1024
Copy link
Member Author

cmcgee1024 commented Sep 20, 2024

The RHEL 9 tests failed on a network failure, otherwise everything passed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants