Skip to content

Commit 9748352

Browse files
authored
Add new Linux platforms: Ubuntu 24.04, Debian 12, Fedora 39 (#173)
Add support for these new platforms to swiftly, the autodetection, the tests, and docker support. Remove the swiftly installer portion of the code. Add the new entries to the --platform option Remove all of the platform def environment variables to force auto-detection coverage. Remove mention of CentOS from the README.md since it is not particularly relevant anymore Add new Linux distributions to the GitHub workflow. Add required system packages that are missing for debian 12 and fedora 39. Bump the tsc dependency to fix compile errors on Linux with newer glibc. Skip tests that rely on snapshots for platforms where snapshots are not available.
1 parent c35819a commit 9748352

27 files changed

+192
-1648
lines changed

.github/workflows/pull_request.yml

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,11 @@ jobs:
2121
name: Test
2222
uses: swiftlang/github-workflows/.github/workflows/swift_package_test.yml@main
2323
with:
24-
# linux_os_versions: "[\"jammy\", \"noble\", \"focal\", \"amazonlinux2\", \"rhel-ubi9\", \"bookworm\", \"fedora39\"]"
25-
# Not working: noble (compile error in TSC FileSystem), bookworm (missing memory.h), fedora39 (missing memory.h)
26-
linux_os_versions: "[\"jammy\", \"focal\", \"rhel-ubi9\"]"
24+
# Amazon Linux 2 won't work with GH infrastructure
25+
linux_os_versions: "[\"jammy\", \"focal\", \"rhel-ubi9\", \"noble\", \"bookworm\", \"fedora39\"]"
2726
# We only care about the current stable release, because that's where we make our swiftly releases
2827
linux_exclude_swift_versions: "[{\"swift_version\": \"nightly-main\"},{\"swift_version\": \"nightly-6.0\"},{\"swift_version\": \"5.8\"},{\"swift_version\": \"5.9\"},{\"swift_version\": \"5.10\"}]"
29-
linux_pre_build_command: ((apt-get update && apt-get -y install curl make) || ((curl --help || yum -y install curl) && yum -y install make)) && ./scripts/install-libarchive.sh
28+
linux_pre_build_command: ./scripts/prep-gh-action.sh && ./scripts/install-libarchive.sh
3029
enable_windows_checks: false
3130

3231
releasebuild:
@@ -36,7 +35,7 @@ jobs:
3635
linux_os_versions: "[\"rhel-ubi9\"]"
3736
# We only care about the current stable release, because that's where we make our swiftly releases
3837
linux_exclude_swift_versions: "[{\"swift_version\": \"nightly-main\"},{\"swift_version\": \"nightly-6.0\"},{\"swift_version\": \"5.8\"},{\"swift_version\": \"5.9\"},{\"swift_version\": \"5.10\"}]"
39-
linux_pre_build_command: echo ""
38+
linux_pre_build_command: ./scripts/prep-gh-action.sh
4039
linux_build_command: swift run build-swiftly-release --skip 0.4.0
4140
enable_windows_checks: false
4241

@@ -47,6 +46,6 @@ jobs:
4746
# We only need to run this with one swift release and on one of the linux distributions
4847
linux_os_versions: "[\"jammy\"]"
4948
linux_exclude_swift_versions: "[{\"swift_version\": \"nightly-main\"},{\"swift_version\": \"nightly-6.0\"},{\"swift_version\": \"5.8\"},{\"swift_version\": \"5.9\"},{\"swift_version\": \"5.10\"}]"
50-
linux_pre_build_command: echo ""
49+
linux_pre_build_command: ./scripts/prep-gh-action.sh
5150
linux_build_command: swift run swiftformat --lint --dryrun .
5251
enable_windows_checks: false

Package.resolved

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Package.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ let package = Package(
1717
.package(url: "https://github.com/apple/swift-argument-parser", from: "1.3.0"),
1818
.package(url: "https://github.com/swift-server/async-http-client", from: "1.21.2"),
1919
.package(url: "https://github.com/apple/swift-nio.git", from: "2.64.0"),
20-
.package(url: "https://github.com/apple/swift-tools-support-core.git", from: "0.6.1"),
20+
.package(url: "https://github.com/apple/swift-tools-support-core.git", from: "0.7.1"),
2121
.package(url: "https://github.com/apple/swift-docc-plugin", from: "1.3.0"),
2222
// This dependency provides the correct version of the formatter so that you can run `swift run swiftformat Package.swift Plugins/ Sources/ Tests/`
2323
.package(url: "https://github.com/nicklockwood/SwiftFormat", exact: "0.49.18"),

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ Target: x86_64-unknown-linux-gnu
4444
## Platform support
4545

4646
- Linux-based platforms listed on https://swift.org/download
47-
- CentOS 7 will not be supported due to some dependencies of swiftly not supporting it, however.
4847

4948
Right now, swiftly is in early stages of development and is supported on Linux and macOS. For more detailed information about swiftly's intended features and implementation, check out the [design document](DESIGN.md).
5049

Sources/LinuxPlatform/Linux.swift

Lines changed: 105 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,17 @@ var swiftGPGKeysRefreshed = false
77
/// This implementation can be reused for any supported Linux platform.
88
/// TODO: replace dummy implementations
99
public struct Linux: Platform {
10+
let linuxPlatforms = [
11+
PlatformDefinition.ubuntu2404,
12+
PlatformDefinition.ubuntu2204,
13+
PlatformDefinition.ubuntu2004,
14+
PlatformDefinition.ubuntu1804,
15+
PlatformDefinition.fedora39,
16+
PlatformDefinition.rhel9,
17+
PlatformDefinition.amazonlinux2,
18+
PlatformDefinition.debian12,
19+
]
20+
1021
public init() {}
1122

1223
public var appDataDirectory: URL {
@@ -125,6 +136,26 @@ public struct Linux: Platform {
125136
"tzdata",
126137
"zlib1g-dev",
127138
]
139+
case "ubuntu2404":
140+
[
141+
"binutils",
142+
"git",
143+
"unzip",
144+
"gnupg2",
145+
"libc6-dev",
146+
"libcurl4-openssl-dev",
147+
"libedit2",
148+
"libgcc-13-dev",
149+
"libpython3-dev",
150+
"libsqlite3-0",
151+
"libstdc++-13-dev",
152+
"libxml2-dev",
153+
"libncurses-dev",
154+
"libz3-dev",
155+
"pkg-config",
156+
"tzdata",
157+
"zlib1g-dev",
158+
]
128159
case "amazonlinux2":
129160
[
130161
"binutils",
@@ -158,6 +189,39 @@ public struct Linux: Platform {
158189
"unzip",
159190
"zip",
160191
]
192+
case "fedora39":
193+
[
194+
"binutils",
195+
"gcc",
196+
"git",
197+
"unzip",
198+
"libcurl-devel",
199+
"libedit-devel",
200+
"libicu-devel",
201+
"sqlite-devel",
202+
"libuuid-devel",
203+
"libxml2-devel",
204+
"python3-devel",
205+
"libstdc++-devel",
206+
"libstdc++-static",
207+
]
208+
case "debian12":
209+
[
210+
"binutils-gold",
211+
"libicu-dev",
212+
"libcurl4-openssl-dev",
213+
"libedit-dev",
214+
"libsqlite3-dev",
215+
"libncurses-dev",
216+
"libpython3-dev",
217+
"libxml2-dev",
218+
"pkg-config",
219+
"uuid-dev",
220+
"tzdata",
221+
"git",
222+
"gcc",
223+
"libstdc++-12-dev",
224+
]
161225
default:
162226
[]
163227
}
@@ -169,10 +233,16 @@ public struct Linux: Platform {
169233
"apt-get"
170234
case "ubuntu2204":
171235
"apt-get"
236+
case "ubuntu2404":
237+
"apt-get"
172238
case "amazonlinux2":
173239
"yum"
174240
case "ubi9":
175241
"yum"
242+
case "fedora39":
243+
"yum"
244+
case "debian12":
245+
"apt-get"
176246
default:
177247
nil
178248
}
@@ -196,7 +266,7 @@ public struct Linux: Platform {
196266
// Import the latest swift keys, but only once per session, which will help with the performance in tests
197267
if !swiftGPGKeysRefreshed {
198268
let tmpFile = self.getTempFilePath()
199-
FileManager.default.createFile(atPath: tmpFile.path, contents: nil, attributes: [.posixPermissions: 0o600])
269+
let _ = FileManager.default.createFile(atPath: tmpFile.path, contents: nil, attributes: [.posixPermissions: 0o600])
200270
defer {
201271
try? FileManager.default.removeItem(at: tmpFile)
202272
}
@@ -407,7 +477,7 @@ public struct Linux: Platform {
407477
public func verifySignature(httpClient: SwiftlyHTTPClient, archiveDownloadURL: URL, archive: URL) async throws {
408478
SwiftlyCore.print("Downloading toolchain signature...")
409479
let sigFile = self.getTempFilePath()
410-
FileManager.default.createFile(atPath: sigFile.path, contents: nil)
480+
let _ = FileManager.default.createFile(atPath: sigFile.path, contents: nil)
411481
defer {
412482
try? FileManager.default.removeItem(at: sigFile)
413483
}
@@ -425,59 +495,43 @@ public struct Linux: Platform {
425495
}
426496
}
427497

428-
private func manualSelectPlatform(_ platformPretty: String?) -> PlatformDefinition {
498+
private func manualSelectPlatform(_ platformPretty: String?) async -> PlatformDefinition {
429499
if let platformPretty = platformPretty {
430500
print("\(platformPretty) is not an officially supported platform, but the toolchains for another platform may still work on it.")
431501
} else {
432502
print("This platform could not be detected, but a toolchain for one of the supported platforms may work on it.")
433503
}
434504

505+
let selections = self.linuxPlatforms.enumerated().map { "\($0 + 1)) \($1.namePretty)" }.joined(separator: "\n")
506+
435507
print("""
436508
Please select the platform to use for toolchain downloads:
437509
438510
0) Cancel
439-
1) Ubuntu 22.04
440-
2) Ubuntu 20.04
441-
3) Ubuntu 18.04
442-
4) RHEL 9
443-
5) Amazon Linux 2
511+
\(selections)
444512
""")
445513

446-
let choice = SwiftlyCore.readLine(prompt: "> ") ?? "0"
514+
let choice = SwiftlyCore.readLine(prompt: "Pick one of the available selections [0-\(self.linuxPlatforms.count)] ") ?? "0"
447515

448-
switch choice {
449-
case "1":
450-
return PlatformDefinition.ubuntu2204
451-
case "2":
452-
return PlatformDefinition.ubuntu2004
453-
case "3":
454-
return PlatformDefinition.ubuntu1804
455-
case "4":
456-
return PlatformDefinition.rhel9
457-
case "5":
458-
return PlatformDefinition.amazonlinux2
459-
default:
516+
guard let choiceNum = Int(choice) else {
517+
fatalError("Installation canceled")
518+
}
519+
520+
guard choiceNum > 0 && choiceNum <= self.linuxPlatforms.count else {
460521
fatalError("Installation canceled")
461522
}
523+
524+
return self.linuxPlatforms[choiceNum - 1]
462525
}
463526

464527
public func detectPlatform(disableConfirmation: Bool, platform: String?) async throws -> PlatformDefinition {
465528
// We've been given a hint to use
466-
if let platform = platform {
467-
switch platform {
468-
case "ubuntu22.04":
469-
return PlatformDefinition.ubuntu2204
470-
case "ubuntu20.04":
471-
return PlatformDefinition.ubuntu2004
472-
case "ubuntu18.04":
473-
return PlatformDefinition.ubuntu1804
474-
case "amazonlinux2":
475-
return PlatformDefinition.amazonlinux2
476-
case "rhel9":
477-
return PlatformDefinition.rhel9
478-
default:
479-
fatalError("Unrecognized platform \(platform)")
529+
if let platform {
530+
guard let pd = linuxPlatforms.first(where: { $0.nameFull == platform }) else {
531+
fatalError("Unrecognized platform \(platform). Recognized values: \(self.linuxPlatforms.map(\.nameFull).joined(separator: ", ")).")
480532
}
533+
534+
return pd
481535
}
482536

483537
let osReleaseFiles = ["/etc/os-release", "/usr/lib/os-release"]
@@ -498,98 +552,62 @@ public struct Linux: Platform {
498552
} else {
499553
print(message)
500554
}
501-
return self.manualSelectPlatform(platformPretty)
502-
}
503-
504-
let data = FileManager.default.contents(atPath: releaseFile)
505-
guard let data = data else {
506-
let message = "Unable to read OS release information from file \(releaseFile)"
507-
if disableConfirmation {
508-
throw Error(message: message)
509-
} else {
510-
print(message)
511-
}
512-
return self.manualSelectPlatform(platformPretty)
555+
return await self.manualSelectPlatform(platformPretty)
513556
}
514557

515-
guard let releaseInfo = String(data: data, encoding: .utf8) else {
516-
let message = "Unable to read OS release information from file \(releaseFile)"
517-
if disableConfirmation {
518-
throw Error(message: message)
519-
} else {
520-
print(message)
521-
}
522-
return self.manualSelectPlatform(platformPretty)
523-
}
558+
let releaseInfo = try String(contentsOfFile: releaseFile, encoding: .utf8)
524559

525560
var id: String?
526561
var idlike: String?
527562
var versionID: String?
528-
var ubuntuCodeName: String?
529563
for info in releaseInfo.split(separator: "\n").map(String.init) {
530564
if info.hasPrefix("ID=") {
531565
id = String(info.dropFirst("ID=".count)).replacingOccurrences(of: "\"", with: "")
532566
} else if info.hasPrefix("ID_LIKE=") {
533567
idlike = String(info.dropFirst("ID_LIKE=".count)).replacingOccurrences(of: "\"", with: "")
534568
} else if info.hasPrefix("VERSION_ID=") {
535-
versionID = String(info.dropFirst("VERSION_ID=".count)).replacingOccurrences(of: "\"", with: "")
536-
} else if info.hasPrefix("UBUNTU_CODENAME=") {
537-
ubuntuCodeName = String(info.dropFirst("UBUNTU_CODENAME=".count)).replacingOccurrences(of: "\"", with: "")
569+
versionID = String(info.dropFirst("VERSION_ID=".count)).replacingOccurrences(of: "\"", with: "").replacingOccurrences(of: ".", with: "")
538570
} else if info.hasPrefix("PRETTY_NAME=") {
539571
platformPretty = String(info.dropFirst("PRETTY_NAME=".count)).replacingOccurrences(of: "\"", with: "")
540572
}
541573
}
542574

543-
guard let id = id, let idlike = idlike else {
575+
guard let id, let versionID else {
544576
let message = "Unable to find release information from file \(releaseFile)"
545577
if disableConfirmation {
546578
throw Error(message: message)
547579
} else {
548580
print(message)
549581
}
550-
return self.manualSelectPlatform(platformPretty)
582+
return await self.manualSelectPlatform(platformPretty)
551583
}
552584

553-
if (id + idlike).contains("amzn") {
554-
guard let versionID = versionID, versionID == "2" else {
585+
if (id + (idlike ?? "")).contains("amzn") {
586+
guard versionID == "2" else {
555587
let message = "Unsupported version of Amazon Linux"
556588
if disableConfirmation {
557589
throw Error(message: message)
558590
} else {
559591
print(message)
560592
}
561-
return self.manualSelectPlatform(platformPretty)
593+
return await self.manualSelectPlatform(platformPretty)
562594
}
563595

564-
return PlatformDefinition(name: "amazonlinux2", nameFull: "amazonlinux2", namePretty: "Amazon Linux 2")
565-
} else if (id + idlike).contains("ubuntu") {
566-
if ubuntuCodeName == "jammy" {
567-
return PlatformDefinition(name: "ubuntu2204", nameFull: "ubuntu22.04", namePretty: "Ubuntu 22.04")
568-
} else if ubuntuCodeName == "focal" {
569-
return PlatformDefinition(name: "ubuntu2004", nameFull: "ubuntu20.04", namePretty: "Ubuntu 20.04")
570-
} else if ubuntuCodeName == "bionic" {
571-
return PlatformDefinition(name: "ubuntu1804", nameFull: "ubuntu18.04", namePretty: "Ubuntu 18.04")
572-
} else {
573-
let message = "Unsupported version of Ubuntu Linux"
574-
if disableConfirmation {
575-
throw Error(message: message)
576-
} else {
577-
print(message)
578-
}
579-
return self.manualSelectPlatform(platformPretty)
580-
}
581-
} else if (id + idlike).contains("rhel") {
582-
guard let versionID = versionID, versionID.hasPrefix("9") else {
596+
return PlatformDefinition.amazonlinux2
597+
} else if (id + (idlike ?? "")).contains("rhel") {
598+
guard versionID.hasPrefix("9") else {
583599
let message = "Unsupported version of RHEL"
584600
if disableConfirmation {
585601
throw Error(message: message)
586602
} else {
587603
print(message)
588604
}
589-
return self.manualSelectPlatform(platformPretty)
605+
return await self.manualSelectPlatform(platformPretty)
590606
}
591607

592-
return PlatformDefinition(name: "ubi9", nameFull: "ubi9", namePretty: "RHEL 9")
608+
return PlatformDefinition.rhel9
609+
} else if let pd = [PlatformDefinition.ubuntu1804, .ubuntu2004, .ubuntu2204, .ubuntu2404, .debian12, .fedora39].first(where: { $0.name == id + versionID }) {
610+
return pd
593611
}
594612

595613
let message = "Unsupported Linux platform"
@@ -598,7 +616,7 @@ public struct Linux: Platform {
598616
} else {
599617
print(message)
600618
}
601-
return self.manualSelectPlatform(platformPretty)
619+
return await self.manualSelectPlatform(platformPretty)
602620
}
603621

604622
public func getShell() async throws -> String {

Sources/SwiftlyCore/HTTPClient.swift

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,6 @@ struct SwiftOrgPlatform: Codable {
7272
PlatformDefinition.ubuntu2204
7373
case "Red Hat Universal Base Image 9":
7474
PlatformDefinition.rhel9
75-
case "Ubuntu 23.10":
76-
PlatformDefinition(name: "ubuntu2310", nameFull: "ubuntu23.10", namePretty: "Ubuntu 23.10")
7775
case "Ubuntu 24.04":
7876
PlatformDefinition(name: "ubuntu2404", nameFull: "ubuntu24.04", namePretty: "Ubuntu 24.04")
7977
case "Debian 12":

0 commit comments

Comments
 (0)