@@ -126,7 +126,7 @@ public func getShell() async throws -> String {
126126}
127127#endif
128128
129- public func isAmazonLinux2 ( ) - > Bool {
129+ public func isRHEL9 ( ) - > Bool {
130130 let osReleaseFiles = [ " /etc/os-release " , " /usr/lib/os-release " ]
131131 var releaseFile : String ?
132132 for file in osReleaseFiles {
@@ -165,7 +165,7 @@ public func isAmazonLinux2() -> Bool {
165165 return false
166166 }
167167
168- guard let versionID = versionID , versionID == " 2 " , ( id + idlike) . contains ( " amzn " ) else {
168+ guard let versionID, versionID. hasPrefix ( " 9 " ) , ( id + idlike) . contains ( " rhel " ) else {
169169 return false
170170 }
171171
@@ -182,6 +182,14 @@ struct BuildSwiftlyRelease: AsyncParsableCommand {
182182 @Flag ( name: . long, help: " Skip the git repo checks and proceed. " )
183183 var skip : Bool = false
184184
185+ #if os(macOS)
186+ @Option ( help: " Installation certificate to use when building the macOS package " )
187+ var cert : String ?
188+
189+ @Option ( help: " Package identifier of macOS package " )
190+ var identifier : String = " org.swift.swiftly "
191+ #endif
192+
185193 @Argument ( help: " Version of swiftly to build the release. " )
186194 var version : String
187195
@@ -191,7 +199,7 @@ struct BuildSwiftlyRelease: AsyncParsableCommand {
191199#if os(Linux)
192200 try await self . buildLinuxRelease ( )
193201#elseif os(macOS)
194- try await self . buildMacOSRelease ( )
202+ try await self . buildMacOSRelease ( cert : self . cert , identifier : self . identifier )
195203#else
196204 #error("Unsupported OS")
197205#endif
@@ -234,6 +242,10 @@ struct BuildSwiftlyRelease: AsyncParsableCommand {
234242 }
235243
236244 func checkSwiftRequirement( ) async throws -> String {
245+ guard !self . skip else {
246+ return try await self . assertTool ( " swift " , message: " Please install swift and make sure that it is added to your path. " )
247+ }
248+
237249 guard let requiredSwiftVersion = try ? self . findSwiftVersion ( ) else {
238250 throw Error ( message: " Unable to determine the required swift version for this version of swiftly. Please make sure that you `cd <swiftly_git_dir>` and there is a .swift-version file there. " )
239251 }
@@ -275,7 +287,7 @@ struct BuildSwiftlyRelease: AsyncParsableCommand {
275287
276288 func buildLinuxRelease( ) async throws {
277289 // Check system requirements
278- guard isAmazonLinux2 ( ) else {
290+ guard isRHEL9 ( ) else {
279291 // TODO: see if docker can be used to spawn an Amazon Linux 2 container to continue the release building process
280292 throw Error ( message: " Linux releases must be made from Amazon Linux 2 because it has the oldest version of glibc for maximum compatibility with other versions of Linux " )
281293 }
@@ -286,13 +298,19 @@ struct BuildSwiftlyRelease: AsyncParsableCommand {
286298 let make = try await self . assertTool ( " make " , message: " Please install make with `yum install make` " )
287299 let git = try await self . assertTool ( " git " , message: " Please install git with `yum install git` " )
288300 let strip = try await self . assertTool ( " strip " , message: " Please install strip with `yum install binutils` " )
301+ let sha256sum = try await self . assertTool ( " sha256sum " , message: " Please install sha256sum with `yum install coreutils` " )
289302
290303 let swift = try await self . checkSwiftRequirement ( )
291304
292305 try await self . checkGitRepoStatus ( git)
293306
294- // Build a specific version of libarchive
307+ // Start with a fresh SwiftPM package
308+ try runProgram ( swift, " package " , " reset " )
309+
310+ // Build a specific version of libarchive with a check on the tarball's SHA256
295311 let libArchiveVersion = " 3.7.4 "
312+ let libArchiveTarSha = " 7875d49596286055b52439ed42f044bd8ad426aa4cc5aabd96bfe7abb971d5e8 "
313+
296314 let buildCheckoutsDir = FileManager . default. currentDirectoryPath + " /.build/checkouts "
297315 let libArchivePath = buildCheckoutsDir + " /libarchive- \( libArchiveVersion) "
298316 let pkgConfigPath = libArchivePath + " /pkgconfig "
@@ -302,6 +320,11 @@ struct BuildSwiftlyRelease: AsyncParsableCommand {
302320
303321 try ? FileManager . default. removeItem ( atPath: libArchivePath)
304322 try runProgram ( curl, " -o " , " \( buildCheckoutsDir + " /libarchive- \( libArchiveVersion) .tar.gz " ) " , " --remote-name " , " --location " , " https://github.com/libarchive/libarchive/releases/download/v \( libArchiveVersion) /libarchive- \( libArchiveVersion) .tar.gz " )
323+ let libArchiveTarShaActual = try await runProgramOutput ( sha256sum, " \( buildCheckoutsDir) /libarchive- \( libArchiveVersion) .tar.gz " )
324+ guard let libArchiveTarShaActual, libArchiveTarShaActual. starts ( with: libArchiveTarSha) else {
325+ let shaActual = libArchiveTarShaActual ?? " none "
326+ throw Error ( message: " The libarchive tar.gz file sha256sum is \( shaActual) , but expected \( libArchiveTarSha) " )
327+ }
305328 try runProgram ( tar, " --directory= \( buildCheckoutsDir) " , " -xzf " , " \( buildCheckoutsDir) /libarchive- \( libArchiveVersion) .tar.gz " )
306329
307330 let cwd = FileManager . default. currentDirectoryPath
@@ -338,8 +361,6 @@ struct BuildSwiftlyRelease: AsyncParsableCommand {
338361
339362 FileManager . default. changeCurrentDirectoryPath ( cwd)
340363
341- try runProgram ( swift, " package " , " clean " )
342-
343364 // Statically link standard libraries for maximum portability of the swiftly binary
344365 try runProgram ( swift, " build " , " --product=swiftly " , " --pkg-config-path= \( pkgConfigPath) /lib/pkgconfig " , " --static-swift-stdlib " , " --configuration=release " )
345366
@@ -361,7 +382,7 @@ struct BuildSwiftlyRelease: AsyncParsableCommand {
361382 print ( releaseArchive)
362383 }
363384
364- func buildMacOSRelease( ) async throws {
385+ func buildMacOSRelease( cert : String ? , identifier : String ) async throws {
365386 // Check system requirements
366387 let git = try await self . assertTool ( " git " , message: " Please install git with either `xcode-select --install` or `brew install git` " )
367388
@@ -389,17 +410,34 @@ struct BuildSwiftlyRelease: AsyncParsableCommand {
389410 try ? FileManager . default. createDirectory ( atPath: swiftlyLicenseDir, withIntermediateDirectories: true )
390411 try await self . collectLicenses ( swiftlyLicenseDir)
391412
392- try runProgram (
393- pkgbuild,
394- " --root " ,
395- swiftlyBinDir + " /.. " ,
396- " --install-location " ,
397- " usr/local " ,
398- " --version " ,
399- self . version,
400- " --identifier " ,
401- " org.swift.swiftly " ,
402- " .build/release/swiftly- \( self . version) .pkg "
403- )
413+ if let cert {
414+ try runProgram (
415+ pkgbuild,
416+ " --root " ,
417+ swiftlyBinDir + " /.. " ,
418+ " --install-location " ,
419+ " usr/local " ,
420+ " --version " ,
421+ self . version,
422+ " --identifier " ,
423+ identifier,
424+ " --sign " ,
425+ cert,
426+ " .build/release/swiftly- \( self . version) .pkg "
427+ )
428+ } else {
429+ try runProgram (
430+ pkgbuild,
431+ " --root " ,
432+ swiftlyBinDir + " /.. " ,
433+ " --install-location " ,
434+ " usr/local " ,
435+ " --version " ,
436+ self . version,
437+ " --identifier " ,
438+ identifier,
439+ " .build/release/swiftly- \( self . version) .pkg "
440+ )
441+ }
404442 }
405443}
0 commit comments