From d8205170be103d02b67e67e99b7aa3efa8850ad6 Mon Sep 17 00:00:00 2001 From: Dianna Date: Mon, 4 Nov 2024 03:44:25 +0000 Subject: [PATCH 01/13] generalize Unidoc.PluginError to Unidoc.ServerError, Unidoc.PluginEvent to Unidoc.ServerEvent --- .../HTTP.LogLevel.swift} | 5 +- .../HTTP.ActivityTimeoutError.swift | 23 ++++++ Sources/HTTPServer/HTTP.Server.swift | 71 +++++++++--------- Sources/HTTPServer/HTTP.ServerEvent.swift | 13 ++++ .../HTTP.ServerRequest.Origin.swift | 6 +- Sources/HTTPServer/HTTP.ServerRequest.swift | 8 +- Sources/HTTPServer/Logging/Log.swift | 4 +- .../Unidoc.GraphLinker.Event.swift | 2 +- .../Unidoc.BuildArtifact (ext).swift | 2 +- .../UnidocServer/Plugins/Never (ext).swift | 2 +- .../UnidocServer/Plugins/Unidoc.Plugin.swift | 2 +- .../Plugins/Unidoc.PluginContext.swift | 4 +- .../Plugins/Unidoc.PluginError.swift | 57 -------------- .../Plugins/Unidoc.PluginMessage.swift | 4 +- .../Requests/Unidoc.ClientOrigin.swift | 6 +- .../UnidocServer/Requests/Unidoc.Router.swift | 2 +- .../Requests/Unidoc.ServerRequest.swift | 18 ++--- .../UnidocServer/Server/Unidoc.Server.swift | 66 +++++++++++++--- .../Server/Unidoc.ServerError.swift | 75 +++++++++++++++++++ .../Unidoc.ServerEvent.swift} | 2 +- .../Server/Unidoc.ServerEventType.swift | 11 +++ .../Server/Unidoc.ServerLogger.swift | 16 +++- .../unidoc-tools/Unidoc.Server (ext).swift | 4 +- 23 files changed, 264 insertions(+), 139 deletions(-) rename Sources/{HTTPServer/Logging/Log.Level.swift => HTTP/HTTP.LogLevel.swift} (57%) create mode 100644 Sources/HTTPServer/HTTP.ActivityTimeoutError.swift create mode 100644 Sources/HTTPServer/HTTP.ServerEvent.swift delete mode 100644 Sources/UnidocServer/Plugins/Unidoc.PluginError.swift create mode 100644 Sources/UnidocServer/Server/Unidoc.ServerError.swift rename Sources/UnidocServer/{Plugins/Unidoc.PluginEvent.swift => Server/Unidoc.ServerEvent.swift} (81%) create mode 100644 Sources/UnidocServer/Server/Unidoc.ServerEventType.swift diff --git a/Sources/HTTPServer/Logging/Log.Level.swift b/Sources/HTTP/HTTP.LogLevel.swift similarity index 57% rename from Sources/HTTPServer/Logging/Log.Level.swift rename to Sources/HTTP/HTTP.LogLevel.swift index 4a7a3bdbc..2dda9a0bd 100644 --- a/Sources/HTTPServer/Logging/Log.Level.swift +++ b/Sources/HTTP/HTTP.LogLevel.swift @@ -1,10 +1,9 @@ -extension Log +extension HTTP { @frozen public - enum Level + enum LogLevel:Comparable, Equatable { case debug case error - case warning } } diff --git a/Sources/HTTPServer/HTTP.ActivityTimeoutError.swift b/Sources/HTTPServer/HTTP.ActivityTimeoutError.swift new file mode 100644 index 000000000..eae3a4b22 --- /dev/null +++ b/Sources/HTTPServer/HTTP.ActivityTimeoutError.swift @@ -0,0 +1,23 @@ +import HTTP + +extension HTTP +{ + @frozen public + enum ActivityTimeoutError:Error + { + case connection + case stream + } +} +extension HTTP.ActivityTimeoutError:CustomStringConvertible +{ + public + var description:String + { + switch self + { + case .connection: "Connection timed out before peer initiated any streams" + case .stream: "Stream timed out before peer sent any headers" + } + } +} diff --git a/Sources/HTTPServer/HTTP.Server.swift b/Sources/HTTPServer/HTTP.Server.swift index 4558b547f..c247f5995 100644 --- a/Sources/HTTPServer/HTTP.Server.swift +++ b/Sources/HTTPServer/HTTP.Server.swift @@ -42,6 +42,8 @@ extension HTTP request:ServerRequest, headers:HTTPHeaders, body:[UInt8]) async throws -> HTTP.ServerResponse + + func log(event:ServerEvent, ip origin:ServerRequest.Origin?) } } extension HTTP.Server @@ -206,28 +208,28 @@ extension HTTP.Server return } - let ip:HTTP.ServerRequest.Origin = .init(owner: policylist[address], - v6: address) + let origin:HTTP.ServerRequest.Origin = .init(owner: policylist[address], + ip: address) + handler: do { try await self.handle(connection: connection, - ip: ip, + origin: origin, as: Authority.self) } catch NIOSSLError.uncleanShutdown { } - catch let error as IOError + catch let error { - if error.errnoCode != 104 + if case let error as IOError = error, error.errnoCode == 104 { - Log[.error] = "(HTTP/1.1) \(error)" + // Ignore connection reset by peer. + break handler } - } - catch let error - { - Log[.error] = "(HTTP/1.1) \(error)" + + self.log(event: .http1(error), ip: origin) } try await connection.channel.close() @@ -243,20 +245,19 @@ extension HTTP.Server return } - let ip:HTTP.ServerRequest.Origin = .init(owner: policylist[address], - v6: address) - + let origin:HTTP.ServerRequest.Origin = .init(owner: policylist[address], + ip: address) do { try await self.handle(connection: channel, streams: streams.inbound, - ip: ip, + origin: origin, as: Authority.self) } catch let error { - Log[.error] = "(HTTP/2: \(address)) \(error)" + self.log(event: .http2(error), ip: origin) } try await channel.close() @@ -271,7 +272,7 @@ extension HTTP.Server } catch let error { - Log[.error] = "\(error)" + self.log(event: .tcp(error), ip: nil) } } } @@ -285,7 +286,7 @@ extension HTTP.Server connection:NIOAsyncChannel< HTTPPart, HTTPPart>, - ip:HTTP.ServerRequest.Origin, + origin:HTTP.ServerRequest.Origin, as _:Authority.Type) async throws where Authority:HTTP.ServerAuthority { try await connection.executeThenClose @@ -324,13 +325,13 @@ extension HTTP.Server message = .init( response: try await self.respond(to: part, inbound: &parts, - ip: ip, + origin: origin, as: Authority.self), using: connection.channel.allocator) } catch let error { - Log[.error] = "(application) \(error)" + self.log(event: .application(error), ip: origin) message = .init(redacting: error, using: connection.channel.allocator) @@ -358,7 +359,7 @@ extension HTTP.Server func respond(to h1:HTTPRequestHead, inbound:inout AsyncThrowingChannel< HTTPPart, any Error>.Iterator, - ip:HTTP.ServerRequest.Origin, + origin:HTTP.ServerRequest.Origin, as _:Authority.Type) async throws -> HTTP.ServerResponse where Authority:HTTP.ServerAuthority { @@ -374,7 +375,9 @@ extension HTTP.Server fallthrough case .GET: - return try await self.get(request: .init(uri: uri, ip: ip), headers: h1.headers) + return try await self.get( + request: .init(origin: origin, uri: uri), + headers: h1.headers) case .PUT: guard @@ -428,7 +431,7 @@ extension HTTP.Server } return try await self.post( - request: .init(uri: uri, ip: ip), + request: .init(origin: origin, uri: uri), headers: h1.headers, body: body) @@ -444,7 +447,7 @@ extension HTTP.Server func handle( connection:any Channel, streams:NIOHTTP2AsyncSequence, - ip:HTTP.ServerRequest.Origin, + origin:HTTP.ServerRequest.Origin, as _:Authority.Type) async throws where Authority:HTTP.ServerAuthority { // I am not sure why the sequence of streams has no backpressure. Out of an abundance @@ -494,7 +497,7 @@ extension HTTP.Server let request:Task = .init { - try await self.respond(to: inbound, ip: ip, as: Authority.self) + try await self.respond(to: inbound, origin: origin, as: Authority.self) } stream.frames.channel.closeFuture.whenComplete { @@ -513,7 +516,7 @@ extension HTTP.Server } catch let error { - Log[.error] = "(application: \(ip.v6)) \(error)" + self.log(event: .application(error), ip: origin) message = .init( redacting: error, @@ -545,10 +548,7 @@ extension HTTP.Server } else { - Log[.warning] = """ - (HTTP/2: \(ip.v6)) \ - Connection timed out before peer initiated any streams. - """ + self.log(event: .http2(HTTP.ActivityTimeoutError.connection), ip: origin) } // There doesn’t seem to be any benefit from sticking around after sending @@ -562,7 +562,7 @@ extension HTTP.Server private func respond(to h2:NIOAsyncChannelInboundStream, - ip:HTTP.ServerRequest.Origin, + origin:HTTP.ServerRequest.Origin, as _:Authority.Type) async throws -> HTTP.ServerResponse where Authority:HTTP.ServerAuthority { @@ -604,10 +604,7 @@ extension HTTP.Server continue waiting case nil, nil?: - Log[.error] = """ - (HTTP/2: \(ip.v6)) Stream timed out before peer sent any headers. - """ - + self.log(event: .http2(HTTP.ActivityTimeoutError.stream), ip: origin) return .resource("Time limit exceeded", status: 408) } } @@ -635,7 +632,9 @@ extension HTTP.Server fallthrough case "GET": - return try await self.get(request: .init(uri: path, ip: ip), headers: headers) + return try await self.get( + request: .init(origin: origin, uri: path), + headers: headers) case "PUT": guard @@ -739,7 +738,7 @@ extension HTTP.Server } return try await self.post( - request: .init(uri: path, ip: ip), + request: .init(origin: origin, uri: path), headers: headers, body: body) diff --git a/Sources/HTTPServer/HTTP.ServerEvent.swift b/Sources/HTTPServer/HTTP.ServerEvent.swift new file mode 100644 index 000000000..c2f533e1d --- /dev/null +++ b/Sources/HTTPServer/HTTP.ServerEvent.swift @@ -0,0 +1,13 @@ +import HTTP + +extension HTTP +{ + @frozen public + enum ServerEvent:Sendable + { + case application(any Error) + case http1(any Error) + case http2(any Error) + case tcp(any Error) + } +} diff --git a/Sources/HTTPServer/HTTP.ServerRequest.Origin.swift b/Sources/HTTPServer/HTTP.ServerRequest.Origin.swift index b6dca86df..6d362372b 100644 --- a/Sources/HTTPServer/HTTP.ServerRequest.Origin.swift +++ b/Sources/HTTPServer/HTTP.ServerRequest.Origin.swift @@ -8,12 +8,12 @@ extension HTTP.ServerRequest public let owner:IP.Owner public - let v6:IP.V6 + let ip:IP.V6 - init(owner:IP.Owner, v6:IP.V6) + init(owner:IP.Owner, ip:IP.V6) { self.owner = owner - self.v6 = v6 + self.ip = ip } } } diff --git a/Sources/HTTPServer/HTTP.ServerRequest.swift b/Sources/HTTPServer/HTTP.ServerRequest.swift index 94f23204f..1b1eabac4 100644 --- a/Sources/HTTPServer/HTTP.ServerRequest.swift +++ b/Sources/HTTPServer/HTTP.ServerRequest.swift @@ -10,14 +10,14 @@ extension HTTP struct ServerRequest:Sendable { public - let uri:URI + let origin:Origin public - let ip:Origin + let uri:URI - init(uri:URI, ip:Origin) + init(origin:Origin, uri:URI) { + self.origin = origin self.uri = uri - self.ip = ip } } } diff --git a/Sources/HTTPServer/Logging/Log.swift b/Sources/HTTPServer/Logging/Log.swift index 1bf479f71..c0b916afe 100644 --- a/Sources/HTTPServer/Logging/Log.swift +++ b/Sources/HTTPServer/Logging/Log.swift @@ -4,11 +4,13 @@ @preconcurrency import Darwin #endif +import HTTP + @frozen public enum Log { @inlinable public static - subscript(level:Level) -> String? + subscript(level:HTTP.LogLevel) -> String? { get { diff --git a/Sources/UnidocLinkerPlugin/Unidoc.GraphLinker.Event.swift b/Sources/UnidocLinkerPlugin/Unidoc.GraphLinker.Event.swift index df25d63c4..4c55dfd21 100644 --- a/Sources/UnidocLinkerPlugin/Unidoc.GraphLinker.Event.swift +++ b/Sources/UnidocLinkerPlugin/Unidoc.GraphLinker.Event.swift @@ -14,7 +14,7 @@ extension Unidoc.GraphLinker case failed(Unidoc.Edition, action:Unidoc.LinkerAction) } } -extension Unidoc.GraphLinker.Event:Unidoc.PluginEvent +extension Unidoc.GraphLinker.Event:Unidoc.ServerEvent { public func h3(_ h3:inout HTML.ContentEncoder) diff --git a/Sources/UnidocServer/Operations/Procedures/Unidoc.BuildArtifact (ext).swift b/Sources/UnidocServer/Operations/Procedures/Unidoc.BuildArtifact (ext).swift index c225f04af..788234f7b 100644 --- a/Sources/UnidocServer/Operations/Procedures/Unidoc.BuildArtifact (ext).swift +++ b/Sources/UnidocServer/Operations/Procedures/Unidoc.BuildArtifact (ext).swift @@ -40,7 +40,7 @@ extension Unidoc.BuildArtifact } else { - Log[.warning] = "No destination bucket configured for exporting build logs!" + Log[.debug] = "No destination bucket configured for exporting build logs!" for log:Unidoc.BuildLog in self.logs { print(String.init(decoding: try Gzip.extract(from: log.text.bytes), diff --git a/Sources/UnidocServer/Plugins/Never (ext).swift b/Sources/UnidocServer/Plugins/Never (ext).swift index 9c3c8cfe3..ff50cff2e 100644 --- a/Sources/UnidocServer/Plugins/Never (ext).swift +++ b/Sources/UnidocServer/Plugins/Never (ext).swift @@ -1,6 +1,6 @@ import HTML -extension Never:Unidoc.PluginEvent +extension Never:Unidoc.ServerEvent { public func h3(_ h3:inout HTML.ContentEncoder) {} diff --git a/Sources/UnidocServer/Plugins/Unidoc.Plugin.swift b/Sources/UnidocServer/Plugins/Unidoc.Plugin.swift index ce8c99f47..740dac71f 100644 --- a/Sources/UnidocServer/Plugins/Unidoc.Plugin.swift +++ b/Sources/UnidocServer/Plugins/Unidoc.Plugin.swift @@ -8,7 +8,7 @@ extension Unidoc public protocol Plugin:Sendable { - associatedtype Event:PluginEvent + associatedtype Event:ServerEvent /// Restart cooldown. static var cooldown:Duration { get } diff --git a/Sources/UnidocServer/Plugins/Unidoc.PluginContext.swift b/Sources/UnidocServer/Plugins/Unidoc.PluginContext.swift index 763883c16..f79af0cff 100644 --- a/Sources/UnidocServer/Plugins/Unidoc.PluginContext.swift +++ b/Sources/UnidocServer/Plugins/Unidoc.PluginContext.swift @@ -7,7 +7,7 @@ import UnixTime extension Unidoc { @frozen public - struct PluginContext where Event:PluginEvent + struct PluginContext where Event:ServerEvent { @usableFromInline let shared:(any ServerLogger)? @@ -38,6 +38,6 @@ extension Unidoc.PluginContext @inlinable public func log(event:Event, date:UnixAttosecond = .now()) { - self.shared?.log(event: event, date: date, from: self.plugin) + self.shared?.log(event: event, from: self.plugin, date: date) } } diff --git a/Sources/UnidocServer/Plugins/Unidoc.PluginError.swift b/Sources/UnidocServer/Plugins/Unidoc.PluginError.swift deleted file mode 100644 index c9c244cea..000000000 --- a/Sources/UnidocServer/Plugins/Unidoc.PluginError.swift +++ /dev/null @@ -1,57 +0,0 @@ -import HTML - -extension Unidoc -{ - @frozen public - struct PluginError:Error, Sendable - { - @usableFromInline - let type:String - @usableFromInline - let path:String? - @usableFromInline - let details:String - - @inlinable public - init(type:String, path:String?, details:String) - { - self.type = type - self.path = path - self.details = details - } - } -} -extension Unidoc.PluginError -{ - init(error:__shared any Error, path:String?) - { - self.init( - type: String.init(reflecting: Swift.type(of: error)), - path: path, - details: String.init(reflecting: error)) - } -} -extension Unidoc.PluginError:Unidoc.PluginEvent -{ - @inlinable public - func h3(_ h3:inout HTML.ContentEncoder) - { - h3 += "Server error" - } - - @inlinable public - func dl(_ dl:inout HTML.ContentEncoder) - { - dl[.dt] = "Type" - dl[.dd] = self.type - - if let path:String = self.path - { - dl[.dt] = "Path" - dl[.dd] {$0[.a] { $0.target = "_blank" ; $0.href = path } = path } - } - - dl[.dt] = "Description" - dl[.dd, .pre] = self.details - } -} diff --git a/Sources/UnidocServer/Plugins/Unidoc.PluginMessage.swift b/Sources/UnidocServer/Plugins/Unidoc.PluginMessage.swift index 5bfb2a50b..e04fcc1d1 100644 --- a/Sources/UnidocServer/Plugins/Unidoc.PluginMessage.swift +++ b/Sources/UnidocServer/Plugins/Unidoc.PluginMessage.swift @@ -7,12 +7,12 @@ extension Unidoc struct PluginMessage:Sendable { @usableFromInline - let event:any PluginEvent + let event:any ServerEvent @usableFromInline let date:UnixAttosecond @inlinable public - init(event:any PluginEvent, date:UnixAttosecond) + init(event:any ServerEvent, date:UnixAttosecond) { self.event = event self.date = date diff --git a/Sources/UnidocServer/Requests/Unidoc.ClientOrigin.swift b/Sources/UnidocServer/Requests/Unidoc.ClientOrigin.swift index 0aa399fbd..871cf2dc9 100644 --- a/Sources/UnidocServer/Requests/Unidoc.ClientOrigin.swift +++ b/Sources/UnidocServer/Requests/Unidoc.ClientOrigin.swift @@ -7,14 +7,14 @@ extension Unidoc struct ClientOrigin:Sendable { public - let ip:HTTP.ServerRequest.Origin + let origin:HTTP.ServerRequest.Origin public let guess:Unidoc.ClientGuess? @inlinable public - init(ip:HTTP.ServerRequest.Origin, guess:Unidoc.ClientGuess? = nil) + init(origin:HTTP.ServerRequest.Origin, guess:Unidoc.ClientGuess? = nil) { - self.ip = ip + self.origin = origin self.guess = guess } } diff --git a/Sources/UnidocServer/Requests/Unidoc.Router.swift b/Sources/UnidocServer/Requests/Unidoc.Router.swift index 43e06139d..1374a4103 100644 --- a/Sources/UnidocServer/Requests/Unidoc.Router.swift +++ b/Sources/UnidocServer/Requests/Unidoc.Router.swift @@ -767,7 +767,7 @@ extension Unidoc.Router do { return .unordered(try Unidoc.WebhookOperation.init(json: json, - from: self.origin.ip.owner, + from: self.client.origin.owner, with: self.headers)) } catch let error diff --git a/Sources/UnidocServer/Requests/Unidoc.ServerRequest.swift b/Sources/UnidocServer/Requests/Unidoc.ServerRequest.swift index d133b46be..28b2bae3a 100644 --- a/Sources/UnidocServer/Requests/Unidoc.ServerRequest.swift +++ b/Sources/UnidocServer/Requests/Unidoc.ServerRequest.swift @@ -23,7 +23,7 @@ extension Unidoc public let accepted:UnixAttosecond public - let origin:ClientOrigin + let client:ClientOrigin public let host:String? public @@ -34,14 +34,14 @@ extension Unidoc headers:HTTP.Headers, authorization:Authorization, accepted:UnixAttosecond, - origin:ClientOrigin, + client:ClientOrigin, host:String?, uri:URI) { self.headers = headers self.authorization = authorization self.accepted = accepted - self.origin = origin + self.client = client self.host = host self.uri = uri } @@ -68,7 +68,7 @@ extension Unidoc.ServerRequest var privilege:Unidoc.ClientPrivilege? { - switch self.origin.ip.owner + switch self.client.origin.owner { case .googlebot: return .majorSearchEngine(.googlebot, verified: true) @@ -80,7 +80,7 @@ extension Unidoc.ServerRequest break } - switch self.origin.guess + switch self.client.guess { case .barbie(let locale)?: if case .web(_?, login: _) = self.authorization @@ -103,7 +103,7 @@ extension Unidoc.ServerRequest extension Unidoc.ServerRequest { public - init(headers:HPACKHeaders, origin:Unidoc.ClientOrigin, uri:URI) + init(headers:HPACKHeaders, client:Unidoc.ClientOrigin, uri:URI) { let host:String? = headers[":authority"].last.map { @@ -120,18 +120,18 @@ extension Unidoc.ServerRequest self.init(headers: .http2(headers), authorization: .from(headers), accepted: .now(), - origin: origin, + client: client, host: host, uri: uri) } public - init(headers:HTTPHeaders, origin:Unidoc.ClientOrigin, uri:URI) + init(headers:HTTPHeaders, client:Unidoc.ClientOrigin, uri:URI) { self.init(headers: .http1_1(headers), authorization: .from(headers), accepted: .now(), - origin: origin, + client: client, host: headers["host"].last, uri: uri) } diff --git a/Sources/UnidocServer/Server/Unidoc.Server.swift b/Sources/UnidocServer/Server/Unidoc.Server.swift index 946143f75..9215597f5 100644 --- a/Sources/UnidocServer/Server/Unidoc.Server.swift +++ b/Sources/UnidocServer/Server/Unidoc.Server.swift @@ -105,7 +105,7 @@ extension Unidoc.Server } return self.format(username: username, - locale: request.origin.guess?.locale, + locale: request.client.guess?.locale, time: request.accepted) } @@ -202,10 +202,11 @@ extension Unidoc.Server } catch let error { - self.logger?.log(event: Unidoc.PluginError.init(error: error, path: nil), + self.logger?.log( + event: Unidoc.ServerError.init(error: error), + from: Plugin.id, // This could be a while since `started` was set. - date: .now(), - from: Plugin.id) + date: .now()) } try await cooldown @@ -236,13 +237,45 @@ extension Unidoc.Server } catch let error { - self.logger?.log(event: Unidoc.PluginError.init(error: error, path: nil), - date: .now(), - from: nil) + self.logger?.log( + event: Unidoc.ServerError.init(error: error), + level: .error) } } } } + +extension Unidoc.Server +{ + public + func log(event:HTTP.ServerEvent, ip origin:HTTP.ServerRequest.Origin?) + { + let error:any Error + let type:String + + switch event + { + case .application(let value): + error = value + type = "Application error" + + case .http1(let value): + error = value + type = "HTTP/1 error" + + case .http2(let value): + error = value + type = "HTTP/2 error" + + case .tcp(let value): + error = value + type = "TCP error" + } + + let event:Unidoc.ServerError = .init(error: error, type: type, from: origin) + self.logger?.log(event: event, level: .debug, date: .now()) + } +} extension Unidoc.Server { private @@ -449,10 +482,23 @@ extension Unidoc.Server catch let error { let errorPage:Unidoc.ServerErrorPage = .init(error: error) - let error:Unidoc.PluginError = .init(error: error, path: "\(request.uri)") - self.logger?.log(event: error, date: format.time, from: nil) + let error:Unidoc.ServerError = .init(error: error, + from: request.client.origin, + path: "\(request.uri)") + self.logger?.log(event: error, level: .error, date: format.time) + + let html:HTTP.Resource = errorPage.resource(format: format) - return .error(errorPage.resource(format: format)) + if case .production = self.options.mode + { + /// This will still look the same to humans, but it will not appear as if + /// the server is down to Googlebot. + return .unauthorized(html) + } + else + { + return .error(html) + } } switch operation diff --git a/Sources/UnidocServer/Server/Unidoc.ServerError.swift b/Sources/UnidocServer/Server/Unidoc.ServerError.swift new file mode 100644 index 000000000..f2b6e5c36 --- /dev/null +++ b/Sources/UnidocServer/Server/Unidoc.ServerError.swift @@ -0,0 +1,75 @@ +import HTML +import HTTP +import HTTPServer +import IP + +extension Unidoc +{ + @frozen public + struct ServerError:Error, Sendable + { + @usableFromInline + let details:String + @usableFromInline + let origin:HTTP.ServerRequest.Origin? + @usableFromInline + let type:String + @usableFromInline + let path:String? + + @inlinable public + init(details:String, + type:String, + from origin:HTTP.ServerRequest.Origin?, + path:String?) + { + self.details = details + self.origin = origin + self.type = type + self.path = path + } + } +} +extension Unidoc.ServerError +{ + init(error:__shared any Error, + type:String? = nil, + from origin:HTTP.ServerRequest.Origin? = nil, + path:String? = nil) + { + self.init(details: String.init(reflecting: error), + type: type ?? String.init(reflecting: Swift.type(of: error)), + from: origin, + path: path) + } +} +extension Unidoc.ServerError:Unidoc.ServerEvent +{ + @inlinable public + func h3(_ h3:inout HTML.ContentEncoder) + { + h3 += "Server error" + } + + @inlinable public + func dl(_ dl:inout HTML.ContentEncoder) + { + dl[.dt] = "Type" + dl[.dd] = self.type + + if let origin:HTTP.ServerRequest.Origin = self.origin + { + dl[.dt] = "Origin" + dl[.dd] = "\(origin.ip)" + } + + if let path:String = self.path + { + dl[.dt] = "Path" + dl[.dd] {$0[.a] { $0.target = "_blank" ; $0.href = path } = path } + } + + dl[.dt] = "Description" + dl[.dd, .pre] = self.details + } +} diff --git a/Sources/UnidocServer/Plugins/Unidoc.PluginEvent.swift b/Sources/UnidocServer/Server/Unidoc.ServerEvent.swift similarity index 81% rename from Sources/UnidocServer/Plugins/Unidoc.PluginEvent.swift rename to Sources/UnidocServer/Server/Unidoc.ServerEvent.swift index 79ef9f75d..6da7621c1 100644 --- a/Sources/UnidocServer/Plugins/Unidoc.PluginEvent.swift +++ b/Sources/UnidocServer/Server/Unidoc.ServerEvent.swift @@ -3,7 +3,7 @@ import HTML extension Unidoc { public - protocol PluginEvent:Sendable + protocol ServerEvent:Sendable { func h3(_ h3:inout HTML.ContentEncoder) func dl(_ dl:inout HTML.ContentEncoder) diff --git a/Sources/UnidocServer/Server/Unidoc.ServerEventType.swift b/Sources/UnidocServer/Server/Unidoc.ServerEventType.swift new file mode 100644 index 000000000..34ccba4b6 --- /dev/null +++ b/Sources/UnidocServer/Server/Unidoc.ServerEventType.swift @@ -0,0 +1,11 @@ +import HTTP + +extension Unidoc +{ + @frozen public + enum ServerEventType:Sendable + { + case global(HTTP.LogLevel) + case plugin(String) + } +} diff --git a/Sources/UnidocServer/Server/Unidoc.ServerLogger.swift b/Sources/UnidocServer/Server/Unidoc.ServerLogger.swift index 2ce690ca1..333d56cb9 100644 --- a/Sources/UnidocServer/Server/Unidoc.ServerLogger.swift +++ b/Sources/UnidocServer/Server/Unidoc.ServerLogger.swift @@ -1,6 +1,7 @@ import HTML import HTTP import UnidocRender +import UnixCalendar import UnixTime extension Unidoc @@ -16,6 +17,19 @@ extension Unidoc func log(response:HTTP.ServerResponse, time:Duration, for request:ServerRequest) nonisolated - func log(event:any PluginEvent, date:UnixAttosecond, from plugin:String?) + func log(event:any ServerEvent, type:ServerEventType, date:UnixAttosecond) + } +} +extension Unidoc.ServerLogger +{ + @inlinable public nonisolated + func log(event:any Unidoc.ServerEvent, from plugin:String, date:UnixAttosecond = .now()) + { + self.log(event: event, type: .plugin(plugin), date: date) + } + @inlinable public nonisolated + func log(event:any Unidoc.ServerEvent, level:HTTP.LogLevel, date:UnixAttosecond = .now()) + { + self.log(event: event, type: .global(level), date: date) } } diff --git a/Sources/unidoc-tools/Unidoc.Server (ext).swift b/Sources/unidoc-tools/Unidoc.Server (ext).swift index 7a672b613..597e27629 100644 --- a/Sources/unidoc-tools/Unidoc.Server (ext).swift +++ b/Sources/unidoc-tools/Unidoc.Server (ext).swift @@ -11,7 +11,7 @@ extension Unidoc.Server:HTTP.Server { let request:Unidoc.ServerRequest = .init( headers: headers, - origin: .init(ip: request.ip), + client: .init(origin: request.origin), uri: request.uri) return try await self.get(request: request) } @@ -24,7 +24,7 @@ extension Unidoc.Server:HTTP.Server { let request:Unidoc.ServerRequest = .init( headers: headers, - origin: .init(ip: request.ip), + client: .init(origin: request.origin), uri: request.uri) return try await self.post(request: request, body: body) } From 7b2db9c7c432c2b79be424f8fe1c14691989bd94 Mon Sep 17 00:00:00 2001 From: Dianna Date: Mon, 4 Nov 2024 19:19:31 +0000 Subject: [PATCH 02/13] first attempt at splitting SymbolGraphBuilderTests into two workflow jobs --- .github/workflows/test.yml | 51 +++++- Package.swift | 6 + Scripts/GeneratePackageSymbolGraphs | 49 +++++- Scripts/GenerateTestSymbolGraphs | 13 ++ Scripts/TestAll | 2 +- Sources/SymbolGraphBuilderTests/Main.swift | 163 ----------------- .../SymbolGraphObject (ext).swift | 10 ++ Sources/SymbolGraphValidationTests/Main.swift | 164 ++++++++++++++++++ 8 files changed, 276 insertions(+), 182 deletions(-) create mode 100644 Sources/SymbolGraphValidationTests/Main.swift diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index da6d33c9b..8c17e3401 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,9 +8,9 @@ on: branches: [ master ] jobs: - server: + linux-server: runs-on: ubuntu-24.04 - name: Linux + name: Linux (server) steps: - name: Checkout repository uses: actions/checkout@v3 @@ -37,9 +37,9 @@ jobs: swift:6.0.1-noble \ /bin/bash Scripts/TestAll - macos: + linux: runs-on: macos-15 - name: macOS + name: Linux env: UNIDOC_ENABLE_INDEXSTORE: "1" @@ -47,15 +47,48 @@ jobs: - name: Checkout repository uses: actions/checkout@v3 - - name: Build debug + - name: Build release run: | swift --version - swift build + swift build -c release \ + --product ssgc \ + --explicit-target-dependency-import-check=error \ + -Xcxx -I/usr/lib/swift \ + -Xcxx -I/usr/lib/swift/Block + mv .build/release/ssgc /usr/bin/ssgc + + - name: Build packages + run: Scripts/GeneratePackageSymbolGraphs + + - name: Validate packages + run: | + swift test -c release \ + --filter SymbolGraphValidationTests \ + -Xcxx -I/usr/lib/swift \ + -Xcxx -I/usr/lib/swift/Block + + macos: + runs-on: macos-15 + name: macOS + env: + UNIDOC_ENABLE_INDEXSTORE: "1" + + steps: + - name: Checkout repository + uses: actions/checkout@v3 - name: Build release run: | - swift build -c release + swift --version + swift build -c release \ + --product ssgc \ + --explicit-target-dependency-import-check=error + mv .build/release/ssgc /usr/bin/ssgc + + - name: Build packages + run: Scripts/GeneratePackageSymbolGraphs - - name: Test SymbolGraphBuilder + - name: Validate packages run: | - swift run -c release SymbolGraphBuilderTests + swift test -c release \ + --filter SymbolGraphValidationTests diff --git a/Package.swift b/Package.swift index ee7295830..28e5dce67 100644 --- a/Package.swift +++ b/Package.swift @@ -654,6 +654,12 @@ let package:Package = .init( .product(name: "Testing_", package: "swift-grammar"), ]), + .testTarget(name: "SymbolGraphValidationTests", + dependencies: [ + .target(name: "SymbolGraphTesting"), + .target(name: "System_"), + ]), + .executableTarget(name: "SymbolGraphBuilderTests", dependencies: [ .target(name: "SymbolGraphBuilder"), diff --git a/Scripts/GeneratePackageSymbolGraphs b/Scripts/GeneratePackageSymbolGraphs index a36172ff6..15aede057 100755 --- a/Scripts/GeneratePackageSymbolGraphs +++ b/Scripts/GeneratePackageSymbolGraphs @@ -3,14 +3,45 @@ set -e swift --version -.build/release/ssgc -u $SWIFT_INSTALLATION \ - -n swift \ - -o TestPackages/swift.bson +ssgc -u $SWIFT_INSTALLATION \ + -r https://github.com/apple/swift-atomics.git \ + -t 1.2.0 \ + -o TestPackages/swift-atomics.bson -.build/release/ssgc -u $SWIFT_INSTALLATION \ - -p TestPackages/swift-test \ - -o TestPackages/swift-test.bson +ssgc -u $SWIFT_INSTALLATION \ + -r https://github.com/apple/swift-nio.git \ + -t 2.75.0 \ + -o TestPackages/swift-nio.bson -.build/release/ssgc -u $SWIFT_INSTALLATION \ - -p TestPackages/swift-malibu \ - -o TestPackages/swift-malibu.bson +ssgc -u $SWIFT_INSTALLATION \ + -r https://github.com/apple/swift-nio-ssl.git \ + -t 2.29.0 \ + -o TestPackages/swift-nio-ssl.bson + +ssgc -u $SWIFT_INSTALLATION \ + -r https://github.com/apple/swift-async-dns-resolver.git \ + -t 0.1.2 \ + -o TestPackages/swift-async-dns-resolver.bson + +ssgc -u $SWIFT_INSTALLATION \ + -r https://github.com/apple/swift-syntax.git \ + -t 600.0.1 \ + -o TestPackages/swift-syntax.bson + +ssgc -u $SWIFT_INSTALLATION \ + -r https://github.com/apple/swift-snapshot-testing.git \ + -t 1.17.5 \ + -o TestPackages/swift-snapshot-testing.bson + +# ssgc -u $SWIFT_INSTALLATION \ +# -r https://github.com/apple/indexstore-db.git \ +# -t swift-6.0-RELEASE \ +# -o TestPackages/indexstore-db.bson \ +# -Xcxx -I/usr/lib/swift \ +# -Xcxx -I/usr/lib/swift/Block + +ssgc -u $SWIFT_INSTALLATION \ + -r https://github.com/apple/swift-book.git \ + -t swift-5.10-fcs \ + -b book \ + -o TestPackages/swift-snapshot-testing.bson diff --git a/Scripts/GenerateTestSymbolGraphs b/Scripts/GenerateTestSymbolGraphs index 55e894a32..4029f3c15 100755 --- a/Scripts/GenerateTestSymbolGraphs +++ b/Scripts/GenerateTestSymbolGraphs @@ -2,6 +2,7 @@ set -e +swift --version swift build \ --package-path TestModules \ -Xswiftc -emit-symbol-graph \ @@ -36,3 +37,15 @@ swift symbolgraph-extract \ -include-spi-symbols \ -pretty-print \ -module-name Swift + + +.build/release/ssgc -u $SWIFT_INSTALLATION \ + -n swift \ + -o TestPackages/swift.bson + +for PACKAGE in swift-test swift-malibu swift-snippets swift-exportation +do + .build/release/ssgc -u $SWIFT_INSTALLATION \ + -p TestPackages/$PACKAGE \ + -o TestPackages/$PACKAGE.bson +done diff --git a/Scripts/TestAll b/Scripts/TestAll index c1c63056f..cf946e615 100755 --- a/Scripts/TestAll +++ b/Scripts/TestAll @@ -11,7 +11,6 @@ swift build -c release \ --build-tests Scripts/GenerateTestSymbolGraphs -Scripts/GeneratePackageSymbolGraphs swift test -c release \ --explicit-target-dependency-import-check=error \ @@ -19,6 +18,7 @@ swift test -c release \ -Xcxx -I/usr/lib/swift/Block \ --no-parallel \ --skip-build \ + --skip SymbolGraphValidationTests \ --disable-testable-imports for f in .build/release/*Tests; do diff --git a/Sources/SymbolGraphBuilderTests/Main.swift b/Sources/SymbolGraphBuilderTests/Main.swift index 5d3fbf1cd..c24236a73 100644 --- a/Sources/SymbolGraphBuilderTests/Main.swift +++ b/Sources/SymbolGraphBuilderTests/Main.swift @@ -225,150 +225,6 @@ enum Main:TestMain, TestBattery tests.expect(b.article.footer ==? .omit) } - if let tests:TestGroup = tests / "swift-atomics", - let docs:SymbolGraphObject = (tests.do - { - try workspace.build(package: try .remote( - project: "swift-atomics", - from: "https://github.com/apple/swift-atomics.git", - at: "1.1.0", - in: workspace), - with: toolchain) - }) - { - tests.expect(docs.graph.cultures.count >? 0) - tests.expect(docs.graph.decls.nodes.count >? 0) - - docs.roundtrip(for: tests) - } - - // https://github.com/tayloraswift/swift-unidoc/issues/211 - #if !os(macOS) - if let tests:TestGroup = tests / "swift-nio", - let docs:SymbolGraphObject = (tests.do - { - try workspace.build(package: try .remote( - project: "swift-nio", - from: "https://github.com/apple/swift-nio.git", - at: "2.65.0", - in: workspace), - with: toolchain) - }) - { - // the swift-docc-plugin dependency should have been linted. - tests.expect(docs.metadata.dependencies.map(\.package.name) **? [ - "swift-atomics", - "swift-collections", - // swift-nio grew a dependency on swift-system in 2.63.0 - "swift-system", - ]) - - tests.expect(docs.graph.cultures.count >? 0) - tests.expect(docs.graph.decls.nodes.count >? 0) - - docs.roundtrip(for: tests) - } - #endif - - // SwiftNIO has lots of dependencies. If we can handle SwiftNIO, - // we can handle anything! - if let tests:TestGroup = tests / "swift-nio-ssl", - let docs:SymbolGraphObject = (tests.do - { - try workspace.build(package: try .remote( - project: "swift-nio-ssl", - from: "https://github.com/apple/swift-nio-ssl.git", - at: "2.27.2", - in: workspace), - with: toolchain) - }) - { - tests.expect(docs.metadata.dependencies.map(\.package.name) **? [ - "swift-collections", - "swift-atomics", - "swift-nio", - ]) - - tests.expect(docs.graph.cultures.count >? 0) - tests.expect(docs.graph.decls.nodes.count >? 0) - - docs.roundtrip(for: tests) - } - - // The swift-async-dns-resolver repo includes a git submodule, so we should be able - // to handle that. - if let tests:TestGroup = tests / "swift-async-dns-resolver", - let docs:SymbolGraphObject = (tests.do - { - try workspace.build(package: try .remote( - project: "swift-async-dns-resolver", - from: "https://github.com/apple/swift-async-dns-resolver.git", - at: "0.1.2", - in: workspace), - with: toolchain) - }) - { - tests.expect(docs.metadata.dependencies.map(\.package.name) **? [ - "swift-collections", - "swift-atomics", - "swift-nio", - ]) - - tests.expect(docs.graph.cultures.count >? 0) - tests.expect(docs.graph.decls.nodes.count >? 0) - - docs.roundtrip(for: tests) - } - - // SwiftSyntax is a morbidly obese package. If we can handle SwiftSyntax, - // we can handle anything! - if let tests:TestGroup = tests / "swift-syntax", - let docs:SymbolGraphObject = (tests.do - { - try workspace.build(package: try .remote( - project: "swift-syntax", - from: "https://github.com/apple/swift-syntax.git", - at: "508.0.0", - in: workspace), - with: toolchain) - }) - { - // the swift-argument-parser dependency should have been linted. - tests.expect(docs.metadata.dependencies.map(\.package.name) **? []) - - tests.expect(docs.graph.cultures.count >? 0) - tests.expect(docs.graph.decls.nodes.count >? 0) - - docs.roundtrip(for: tests) - } - - // The swift-snapshot-testing package at 1.17.0 has a dependency on SwiftSyntax with - // prerelease bounds on both sides, so we should be able to handle that. - - // This test is disabled on macOS because `swift symbolgraph-extract` crashes there. - #if os(Linux) - if let tests:TestGroup = tests / "swift-snapshot-testing", - let docs:SymbolGraphObject = (tests.do - { - try workspace.build(package: try .remote( - project: "swift-snapshot-testing", - from: "https://github.com/pointfreeco/swift-snapshot-testing.git", - at: "1.17.5", - in: workspace), - with: toolchain) - }) - { - tests.expect(docs.metadata.dependencies.map(\.package.name) **? [ - "swift-syntax", - ]) - - tests.expect(docs.graph.cultures.count >? 0) - tests.expect(docs.graph.decls.nodes.count >? 0) - - docs.roundtrip(for: tests) - } - #endif - // IndexstoreDB links the LLVM Blocks runtime, so this tests that we handle that. // Since it involves specifying the location of the Swift runtime, we can only expect // this to work within a particular Docker container. @@ -390,24 +246,5 @@ enum Main:TestMain, TestBattery docs.roundtrip(for: tests, in: workspace.artifacts) } #endif - - if let tests:TestGroup = tests / "TSPL", - let docs:SymbolGraphObject = (tests.do - { - try workspace.build(package: try .remote( - project: "swift-book", - from: "https://github.com/apple/swift-book.git", - at: "swift-5.10-fcs", - as: .book, - in: workspace), - with: toolchain) - }) - { - tests.expect(docs.graph.cultures.count >? 0) - tests.expect(docs.graph.articles.nodes.count >? 0) - tests.expect(docs.graph.decls.nodes.count ==? 0) - - docs.roundtrip(for: tests) - } } } diff --git a/Sources/SymbolGraphTesting/SymbolGraphObject (ext).swift b/Sources/SymbolGraphTesting/SymbolGraphObject (ext).swift index 52ddd6ee5..677137ac6 100644 --- a/Sources/SymbolGraphTesting/SymbolGraphObject (ext).swift +++ b/Sources/SymbolGraphTesting/SymbolGraphObject (ext).swift @@ -38,6 +38,16 @@ extension SymbolGraphObject } extension SymbolGraphObject { + public + func roundtrip() throws + { + let encoded:BSON.Document = .init(encoding: self) + let decoded:Self = try .init(buffer: encoded.bytes) + + #expect(decoded.metadata == self.metadata) + #expect(decoded.graph == self.graph) + } + public func roundtrip(in directory:FilePath.Directory) throws { diff --git a/Sources/SymbolGraphValidationTests/Main.swift b/Sources/SymbolGraphValidationTests/Main.swift new file mode 100644 index 000000000..b34d2febc --- /dev/null +++ b/Sources/SymbolGraphValidationTests/Main.swift @@ -0,0 +1,164 @@ +import BSON +import SymbolGraphs +import SymbolGraphTesting +import Symbols +import System_ +import Testing + +@Suite +struct Precompiled +{ + private + var directory:FilePath.Directory { "TestPackages" } + + @Test + func swift_atomics() throws + { + let object:SymbolGraphObject = try .load(package: "swift-atomics", + in: self.directory) + + #expect(object.graph.cultures.count > 0) + #expect(object.graph.decls.nodes.count > 0) + + try object.roundtrip() + } + + @Test + func swift_nio() throws + { + // https://github.com/tayloraswift/swift-unidoc/issues/211 + #if !os(macOS) + + let object:SymbolGraphObject = try .load(package: "swift-nio", + in: self.directory) + + let dependencies:Set = object.metadata.dependencies.reduce(into: []) + { + $0.insert($1.package.name) + } + + // the swift-docc-plugin dependency should have been linted. + // swift-nio grew a dependency on swift-system in 2.63.0 + #expect(dependencies == ["swift-atomics", "swift-collections", "swift-system"]) + + #expect(object.graph.cultures.count > 0) + #expect(object.graph.decls.nodes.count > 0) + + try object.roundtrip() + + #endif + } + + @Test + func swift_nio_ssl() throws + { + let object:SymbolGraphObject = try .load(package: "swift-nio-ssl", + in: self.directory) + + let dependencies:Set = object.metadata.dependencies.reduce(into: []) + { + $0.insert($1.package.name) + } + + #expect(dependencies == ["swift-atomics", "swift-collections", "swift-nio"]) + + #expect(object.graph.cultures.count > 0) + #expect(object.graph.decls.nodes.count > 0) + + try object.roundtrip() + } + + // The swift-async-dns-resolver repo includes a git submodule, so we should be able + // to handle that. + @Test + func swift_async_dns_resolver() throws + { + let object:SymbolGraphObject = try .load(package: "swift-async-dns-resolver", + in: self.directory) + + let dependencies:Set = object.metadata.dependencies.reduce(into: []) + { + $0.insert($1.package.name) + } + + #expect(dependencies == ["swift-atomics", "swift-collections", "swift-nio"]) + + #expect(object.graph.cultures.count > 0) + #expect(object.graph.decls.nodes.count > 0) + + try object.roundtrip() + } + + // SwiftSyntax is a morbidly obese package. If we can handle SwiftSyntax, + // we can handle anything! + @Test + func swift_syntax() throws + { + let object:SymbolGraphObject = try .load(package: "swift-syntax", + in: self.directory) + + // the swift-argument-parser dependency should have been linted. + #expect(object.metadata.dependencies == []) + + #expect(object.graph.cultures.count > 0) + #expect(object.graph.decls.nodes.count > 0) + + try object.roundtrip() + } + + /// The swift-snapshot-testing package at 1.17.0 has a dependency on SwiftSyntax with + /// prerelease bounds on both sides, so we should be able to handle that. + /// + /// This test is disabled on macOS because `swift symbolgraph-extract` crashes there. + @Test + func swift_snapshot_testing() throws + { + #if !os(macOS) + + let object:SymbolGraphObject = try .load(package: "swift-snapshot-testing", + in: self.directory) + + let dependencies:Set = object.metadata.dependencies.reduce(into: []) + { + $0.insert($1.package.name) + } + + #expect(dependencies == ["swift-syntax"]) + + #expect(object.graph.cultures.count > 0) + #expect(object.graph.decls.nodes.count > 0) + + try object.roundtrip() + + #endif + } + + // @Test + // func indexstore_db() throws + // { + // let object:SymbolGraphObject = try .load(package: "indexstore-db", + // in: self.directory) + + // #expect(object.metadata.dependencies == []) + + // #expect(object.graph.cultures.count > 0) + // #expect(object.graph.decls.nodes.count > 0) + + // try object.roundtrip() + // } + + @Test + func swift_book() throws + { + let object:SymbolGraphObject = try .load(package: "swift-book", + in: self.directory) + + #expect(object.metadata.dependencies == []) + + #expect(object.graph.cultures.count > 0) + #expect(object.graph.articles.nodes.count > 0) + #expect(object.graph.decls.nodes.count == 0) + + try object.roundtrip() + } +} From 8a278c1905030bd052fc33091407bec3f9cf4250 Mon Sep 17 00:00:00 2001 From: Dianna Date: Mon, 4 Nov 2024 19:29:55 +0000 Subject: [PATCH 03/13] install in home directory in CI --- .github/workflows/test.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8c17e3401..572169c1e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -55,7 +55,9 @@ jobs: --explicit-target-dependency-import-check=error \ -Xcxx -I/usr/lib/swift \ -Xcxx -I/usr/lib/swift/Block - mv .build/release/ssgc /usr/bin/ssgc + mkdir $HOME/bin + mv .build/release/ssgc $HOME/bin + echo "$HOME/bin" >> $GITHUB_PATH - name: Build packages run: Scripts/GeneratePackageSymbolGraphs @@ -83,7 +85,9 @@ jobs: swift build -c release \ --product ssgc \ --explicit-target-dependency-import-check=error - mv .build/release/ssgc /usr/bin/ssgc + mkdir $HOME/bin + mv .build/release/ssgc $HOME/bin + echo "$HOME/bin" >> $GITHUB_PATH - name: Build packages run: Scripts/GeneratePackageSymbolGraphs From 09e1c6a93e88e086325d643cd4ea8771e8c24229 Mon Sep 17 00:00:00 2001 From: Dianna Date: Mon, 4 Nov 2024 19:30:13 +0000 Subject: [PATCH 04/13] enable passing flags through ssgc compile --- Scripts/GeneratePackageSymbolGraphs | 12 ++++---- Sources/SymbolGraphBuilder/SSGC.Compile.swift | 30 +++++++++++++++---- Sources/SymbolGraphValidationTests/Main.swift | 20 ++++++------- 3 files changed, 41 insertions(+), 21 deletions(-) diff --git a/Scripts/GeneratePackageSymbolGraphs b/Scripts/GeneratePackageSymbolGraphs index 15aede057..448da159d 100755 --- a/Scripts/GeneratePackageSymbolGraphs +++ b/Scripts/GeneratePackageSymbolGraphs @@ -33,12 +33,12 @@ ssgc -u $SWIFT_INSTALLATION \ -t 1.17.5 \ -o TestPackages/swift-snapshot-testing.bson -# ssgc -u $SWIFT_INSTALLATION \ -# -r https://github.com/apple/indexstore-db.git \ -# -t swift-6.0-RELEASE \ -# -o TestPackages/indexstore-db.bson \ -# -Xcxx -I/usr/lib/swift \ -# -Xcxx -I/usr/lib/swift/Block +ssgc -u $SWIFT_INSTALLATION \ + -r https://github.com/apple/indexstore-db.git \ + -t swift-6.0-RELEASE \ + -o TestPackages/indexstore-db.bson \ + -Xcxx -I/usr/lib/swift \ + -Xcxx -I/usr/lib/swift/Block ssgc -u $SWIFT_INSTALLATION \ -r https://github.com/apple/swift-book.git \ diff --git a/Sources/SymbolGraphBuilder/SSGC.Compile.swift b/Sources/SymbolGraphBuilder/SSGC.Compile.swift index 64c26f6d0..b02a0b184 100644 --- a/Sources/SymbolGraphBuilder/SSGC.Compile.swift +++ b/Sources/SymbolGraphBuilder/SSGC.Compile.swift @@ -64,6 +64,23 @@ extension SSGC help: "The Apple SDK to use") var appleSDK:AppleSDK? = nil + + @Option( + name: [.customLong("Xswiftc")], + help: "Extra flags to pass to the Swift compiler") + var swiftc:[String] = [] + + @Option( + name: [.customLong("Xcxx")], + help: "Extra flags to pass to the C++ compiler") + var cxx:[String] = [] + + @Option( + name: [.customLong("Xcc")], + help: "Extra flags to pass to the C compiler") + var cc:[String] = [] + + @Option( name: [.customLong("ci")], help: "Run in CI mode under the specified validation level") @@ -246,6 +263,7 @@ extension SSGC.Compile recoverFromAppleBugs: true, // self.recoverFromAppleBugs, pretty: self.pretty) + let flags:SSGC.PackageBuild.Flags = .init(swift: self.swiftc, cxx: self.cxx, c: self.cc) let object:SymbolGraphObject if let project:String = self.project, @@ -268,7 +286,8 @@ extension SSGC.Compile from: repo, at: ref, as: self.type, - in: workspace) + in: workspace, + flags: flags) defer { @@ -302,12 +321,12 @@ extension SSGC.Compile { computedPath = projectPath } - else if - let search:FilePath.Directory = self.search, + else if + let search:FilePath.Directory = self.search, let name:String = self.project { print(""" - Warning: '--search-path' is deprecated, use '--project-path' with the + Warning: '--search-path' is deprecated, use '--project-path' with the full path to the project root instead """) @@ -320,7 +339,8 @@ extension SSGC.Compile let build:SSGC.PackageBuild = .local(project: computedPath, using: ".build.ssgc", - as: self.type) + as: self.type, + flags: flags) defer { diff --git a/Sources/SymbolGraphValidationTests/Main.swift b/Sources/SymbolGraphValidationTests/Main.swift index b34d2febc..74d39ba45 100644 --- a/Sources/SymbolGraphValidationTests/Main.swift +++ b/Sources/SymbolGraphValidationTests/Main.swift @@ -133,19 +133,19 @@ struct Precompiled #endif } - // @Test - // func indexstore_db() throws - // { - // let object:SymbolGraphObject = try .load(package: "indexstore-db", - // in: self.directory) + @Test + func indexstore_db() throws + { + let object:SymbolGraphObject = try .load(package: "indexstore-db", + in: self.directory) - // #expect(object.metadata.dependencies == []) + #expect(object.metadata.dependencies == []) - // #expect(object.graph.cultures.count > 0) - // #expect(object.graph.decls.nodes.count > 0) + #expect(object.graph.cultures.count > 0) + #expect(object.graph.decls.nodes.count > 0) - // try object.roundtrip() - // } + try object.roundtrip() + } @Test func swift_book() throws From 356b98327ef3f481c76db12d62959158a3d26604 Mon Sep 17 00:00:00 2001 From: Dianna Date: Mon, 4 Nov 2024 19:52:23 +0000 Subject: [PATCH 05/13] provide package name --- .github/workflows/test.yml | 11 +++++++++-- Scripts/GeneratePackageSymbolGraphs | 8 ++++++++ Sources/SymbolGraphBuilder/SSGC.Compile.swift | 3 +++ 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 572169c1e..1d4815643 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -34,16 +34,22 @@ jobs: -v $PWD:/swift/swift-unidoc \ -w /swift/swift-unidoc \ -e SWIFT_INSTALLATION=/usr \ - swift:6.0.1-noble \ + swift:6.0.2-noble \ /bin/bash Scripts/TestAll linux: - runs-on: macos-15 + runs-on: ubuntu-24.04 name: Linux env: UNIDOC_ENABLE_INDEXSTORE: "1" steps: + - name: Install Swift + uses: tayloraswift/swift-install-action@master + with: + swift-prefix: "swift-6.0.2-release/ubuntu2404/swift-6.0.2-RELEASE" + swift-id: "swift-6.0.2-RELEASE-ubuntu24.04" + - name: Checkout repository uses: actions/checkout@v3 @@ -74,6 +80,7 @@ jobs: name: macOS env: UNIDOC_ENABLE_INDEXSTORE: "1" + SWIFT_INSTALLATION: "/usr" steps: - name: Checkout repository diff --git a/Scripts/GeneratePackageSymbolGraphs b/Scripts/GeneratePackageSymbolGraphs index 448da159d..8f3f60df4 100755 --- a/Scripts/GeneratePackageSymbolGraphs +++ b/Scripts/GeneratePackageSymbolGraphs @@ -6,36 +6,43 @@ swift --version ssgc -u $SWIFT_INSTALLATION \ -r https://github.com/apple/swift-atomics.git \ -t 1.2.0 \ + -n swift-atomics \ -o TestPackages/swift-atomics.bson ssgc -u $SWIFT_INSTALLATION \ -r https://github.com/apple/swift-nio.git \ -t 2.75.0 \ + -n swift-nio \ -o TestPackages/swift-nio.bson ssgc -u $SWIFT_INSTALLATION \ -r https://github.com/apple/swift-nio-ssl.git \ -t 2.29.0 \ + -n swift-nio-ssl \ -o TestPackages/swift-nio-ssl.bson ssgc -u $SWIFT_INSTALLATION \ -r https://github.com/apple/swift-async-dns-resolver.git \ -t 0.1.2 \ + -n swift-async-dns-resolver \ -o TestPackages/swift-async-dns-resolver.bson ssgc -u $SWIFT_INSTALLATION \ -r https://github.com/apple/swift-syntax.git \ -t 600.0.1 \ + -n swift-syntax \ -o TestPackages/swift-syntax.bson ssgc -u $SWIFT_INSTALLATION \ -r https://github.com/apple/swift-snapshot-testing.git \ -t 1.17.5 \ + -n swift-snapshot-testing \ -o TestPackages/swift-snapshot-testing.bson ssgc -u $SWIFT_INSTALLATION \ -r https://github.com/apple/indexstore-db.git \ -t swift-6.0-RELEASE \ + -n indexstore-db \ -o TestPackages/indexstore-db.bson \ -Xcxx -I/usr/lib/swift \ -Xcxx -I/usr/lib/swift/Block @@ -44,4 +51,5 @@ ssgc -u $SWIFT_INSTALLATION \ -r https://github.com/apple/swift-book.git \ -t swift-5.10-fcs \ -b book \ + -n swift-book \ -o TestPackages/swift-snapshot-testing.bson diff --git a/Sources/SymbolGraphBuilder/SSGC.Compile.swift b/Sources/SymbolGraphBuilder/SSGC.Compile.swift index b02a0b184..a3d94966e 100644 --- a/Sources/SymbolGraphBuilder/SSGC.Compile.swift +++ b/Sources/SymbolGraphBuilder/SSGC.Compile.swift @@ -67,16 +67,19 @@ extension SSGC @Option( name: [.customLong("Xswiftc")], + parsing: .unconditional, help: "Extra flags to pass to the Swift compiler") var swiftc:[String] = [] @Option( name: [.customLong("Xcxx")], + parsing: .unconditional, help: "Extra flags to pass to the C++ compiler") var cxx:[String] = [] @Option( name: [.customLong("Xcc")], + parsing: .unconditional, help: "Extra flags to pass to the C compiler") var cc:[String] = [] From 6f37d716f9048d3f502a299845b79cf414604d60 Mon Sep 17 00:00:00 2001 From: Dianna Date: Mon, 4 Nov 2024 20:00:19 +0000 Subject: [PATCH 06/13] i think we need double dashes --- Scripts/GeneratePackageSymbolGraphs | 4 ++-- Sources/SymbolGraphBuilder/SSGC.Compile.swift | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Scripts/GeneratePackageSymbolGraphs b/Scripts/GeneratePackageSymbolGraphs index 8f3f60df4..87c07a5d7 100755 --- a/Scripts/GeneratePackageSymbolGraphs +++ b/Scripts/GeneratePackageSymbolGraphs @@ -44,8 +44,8 @@ ssgc -u $SWIFT_INSTALLATION \ -t swift-6.0-RELEASE \ -n indexstore-db \ -o TestPackages/indexstore-db.bson \ - -Xcxx -I/usr/lib/swift \ - -Xcxx -I/usr/lib/swift/Block + --Xcxx -I/usr/lib/swift \ + --Xcxx -I/usr/lib/swift/Block ssgc -u $SWIFT_INSTALLATION \ -r https://github.com/apple/swift-book.git \ diff --git a/Sources/SymbolGraphBuilder/SSGC.Compile.swift b/Sources/SymbolGraphBuilder/SSGC.Compile.swift index a3d94966e..89efed67f 100644 --- a/Sources/SymbolGraphBuilder/SSGC.Compile.swift +++ b/Sources/SymbolGraphBuilder/SSGC.Compile.swift @@ -67,19 +67,19 @@ extension SSGC @Option( name: [.customLong("Xswiftc")], - parsing: .unconditional, + parsing: .unconditionalSingleValue, help: "Extra flags to pass to the Swift compiler") var swiftc:[String] = [] @Option( name: [.customLong("Xcxx")], - parsing: .unconditional, + parsing: .unconditionalSingleValue, help: "Extra flags to pass to the C++ compiler") var cxx:[String] = [] @Option( name: [.customLong("Xcc")], - parsing: .unconditional, + parsing: .unconditionalSingleValue, help: "Extra flags to pass to the C compiler") var cc:[String] = [] From 65ce4fdf61b46ec57f16cae0ddea443f62603973 Mon Sep 17 00:00:00 2001 From: Dianna Date: Mon, 4 Nov 2024 20:01:37 +0000 Subject: [PATCH 07/13] fix wrong SWIFT_INSTALLATION --- .github/workflows/test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1d4815643..805868251 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -59,8 +59,8 @@ jobs: swift build -c release \ --product ssgc \ --explicit-target-dependency-import-check=error \ - -Xcxx -I/usr/lib/swift \ - -Xcxx -I/usr/lib/swift/Block + -Xcxx -I$SWIFT_INSTALLATION/lib/swift \ + -Xcxx -I$SWIFT_INSTALLATION/lib/swift/Block mkdir $HOME/bin mv .build/release/ssgc $HOME/bin echo "$HOME/bin" >> $GITHUB_PATH From ff94c96a33232c81fbf9137b94ac8a0b7b71d580 Mon Sep 17 00:00:00 2001 From: Dianna Date: Mon, 4 Nov 2024 20:01:53 +0000 Subject: [PATCH 08/13] ditto --- .github/workflows/test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 805868251..70d7e6e7e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -72,8 +72,8 @@ jobs: run: | swift test -c release \ --filter SymbolGraphValidationTests \ - -Xcxx -I/usr/lib/swift \ - -Xcxx -I/usr/lib/swift/Block + -Xcxx -I$SWIFT_INSTALLATION/lib/swift \ + -Xcxx -I$SWIFT_INSTALLATION/lib/swift/Block macos: runs-on: macos-15 From ed26d739d02cc8b3e700f9fd5a347c51616269d4 Mon Sep 17 00:00:00 2001 From: Dianna Date: Mon, 4 Nov 2024 20:15:45 +0000 Subject: [PATCH 09/13] use correct organization names --- Scripts/GeneratePackageSymbolGraphs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Scripts/GeneratePackageSymbolGraphs b/Scripts/GeneratePackageSymbolGraphs index 87c07a5d7..d0ff63b8a 100755 --- a/Scripts/GeneratePackageSymbolGraphs +++ b/Scripts/GeneratePackageSymbolGraphs @@ -28,19 +28,19 @@ ssgc -u $SWIFT_INSTALLATION \ -o TestPackages/swift-async-dns-resolver.bson ssgc -u $SWIFT_INSTALLATION \ - -r https://github.com/apple/swift-syntax.git \ + -r https://github.com/swiftlang/swift-syntax.git \ -t 600.0.1 \ -n swift-syntax \ -o TestPackages/swift-syntax.bson ssgc -u $SWIFT_INSTALLATION \ - -r https://github.com/apple/swift-snapshot-testing.git \ + -r https://github.com/pointfreeco/swift-snapshot-testing.git \ -t 1.17.5 \ -n swift-snapshot-testing \ -o TestPackages/swift-snapshot-testing.bson ssgc -u $SWIFT_INSTALLATION \ - -r https://github.com/apple/indexstore-db.git \ + -r https://github.com/swiftlang/indexstore-db.git \ -t swift-6.0-RELEASE \ -n indexstore-db \ -o TestPackages/indexstore-db.bson \ @@ -48,7 +48,7 @@ ssgc -u $SWIFT_INSTALLATION \ --Xcxx -I/usr/lib/swift/Block ssgc -u $SWIFT_INSTALLATION \ - -r https://github.com/apple/swift-book.git \ + -r https://github.com/swiftlang/swift-book.git \ -t swift-5.10-fcs \ -b book \ -n swift-book \ From 066b33ccc1f11adb9f2739f18fa7486350147d93 Mon Sep 17 00:00:00 2001 From: Dianna Date: Mon, 4 Nov 2024 20:15:53 +0000 Subject: [PATCH 10/13] lint --- Sources/SymbolGraphBuilderTests/Main.swift | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/Sources/SymbolGraphBuilderTests/Main.swift b/Sources/SymbolGraphBuilderTests/Main.swift index c24236a73..5c44c1c60 100644 --- a/Sources/SymbolGraphBuilderTests/Main.swift +++ b/Sources/SymbolGraphBuilderTests/Main.swift @@ -224,27 +224,5 @@ enum Main:TestMain, TestBattery /// `AutomaticSeeAlso` should be disabled, because it was disabled globally in A. tests.expect(b.article.footer ==? .omit) } - - // IndexstoreDB links the LLVM Blocks runtime, so this tests that we handle that. - // Since it involves specifying the location of the Swift runtime, we can only expect - // this to work within a particular Docker container. - #if false - if let tests:TestGroup = tests / "indexstore-db", - let docs:SymbolGraphObject = (tests.do - { - try workspace.build(package: try .remote( - package: "indexstore-db", - from: "https://github.com/apple/indexstore-db.git", - at: "swift-6.0-RELEASE", - in: workspace, - flags: .init(cxx: ["-I/usr/lib/swift", "-I/usr/lib/swift/Block"])), - with: toolchain) - }) - { - tests.expect(docs.metadata.dependencies.map(\.package.name) **? []) - - docs.roundtrip(for: tests, in: workspace.artifacts) - } - #endif } } From 1284f5ae3a3794ba153b5c547123bd4e9a37fd86 Mon Sep 17 00:00:00 2001 From: Dianna Date: Mon, 4 Nov 2024 20:46:16 +0000 Subject: [PATCH 11/13] fork macOS scripts from Linux scripts --- .github/workflows/test.yml | 7 ++- .../{ => Linux}/GeneratePackageSymbolGraphs | 6 +-- Scripts/{ => Linux}/GenerateTestSymbolGraphs | 0 Scripts/{ => Linux}/TestAll | 8 +-- Scripts/macOS/GeneratePackageSymbolGraphs | 53 +++++++++++++++++++ 5 files changed, 63 insertions(+), 11 deletions(-) rename Scripts/{ => Linux}/GeneratePackageSymbolGraphs (91%) rename Scripts/{ => Linux}/GenerateTestSymbolGraphs (100%) rename Scripts/{ => Linux}/TestAll (69%) create mode 100755 Scripts/macOS/GeneratePackageSymbolGraphs diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 70d7e6e7e..6b1b24a49 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -35,7 +35,7 @@ jobs: -w /swift/swift-unidoc \ -e SWIFT_INSTALLATION=/usr \ swift:6.0.2-noble \ - /bin/bash Scripts/TestAll + /bin/bash Scripts/Linux/TestAll linux: runs-on: ubuntu-24.04 @@ -66,7 +66,7 @@ jobs: echo "$HOME/bin" >> $GITHUB_PATH - name: Build packages - run: Scripts/GeneratePackageSymbolGraphs + run: Scripts/Linux/GeneratePackageSymbolGraphs - name: Validate packages run: | @@ -80,7 +80,6 @@ jobs: name: macOS env: UNIDOC_ENABLE_INDEXSTORE: "1" - SWIFT_INSTALLATION: "/usr" steps: - name: Checkout repository @@ -97,7 +96,7 @@ jobs: echo "$HOME/bin" >> $GITHUB_PATH - name: Build packages - run: Scripts/GeneratePackageSymbolGraphs + run: Scripts/macOS/GeneratePackageSymbolGraphs - name: Validate packages run: | diff --git a/Scripts/GeneratePackageSymbolGraphs b/Scripts/Linux/GeneratePackageSymbolGraphs similarity index 91% rename from Scripts/GeneratePackageSymbolGraphs rename to Scripts/Linux/GeneratePackageSymbolGraphs index d0ff63b8a..97c1923b4 100755 --- a/Scripts/GeneratePackageSymbolGraphs +++ b/Scripts/Linux/GeneratePackageSymbolGraphs @@ -44,12 +44,12 @@ ssgc -u $SWIFT_INSTALLATION \ -t swift-6.0-RELEASE \ -n indexstore-db \ -o TestPackages/indexstore-db.bson \ - --Xcxx -I/usr/lib/swift \ - --Xcxx -I/usr/lib/swift/Block + --Xcxx -I$SWIFT_INSTALLATION/lib/swift \ + --Xcxx -I$SWIFT_INSTALLATION/lib/swift/Block ssgc -u $SWIFT_INSTALLATION \ -r https://github.com/swiftlang/swift-book.git \ -t swift-5.10-fcs \ -b book \ -n swift-book \ - -o TestPackages/swift-snapshot-testing.bson + -o TestPackages/swift-book.bson diff --git a/Scripts/GenerateTestSymbolGraphs b/Scripts/Linux/GenerateTestSymbolGraphs similarity index 100% rename from Scripts/GenerateTestSymbolGraphs rename to Scripts/Linux/GenerateTestSymbolGraphs diff --git a/Scripts/TestAll b/Scripts/Linux/TestAll similarity index 69% rename from Scripts/TestAll rename to Scripts/Linux/TestAll index cf946e615..91974c7e5 100755 --- a/Scripts/TestAll +++ b/Scripts/Linux/TestAll @@ -6,16 +6,16 @@ export UNIDOC_ENABLE_INDEXSTORE=1 swift --version swift build -c release \ --explicit-target-dependency-import-check=error \ - -Xcxx -I/usr/lib/swift \ - -Xcxx -I/usr/lib/swift/Block \ + -Xcxx -I$SWIFT_INSTALLATION/lib/swift \ + -Xcxx -I$SWIFT_INSTALLATION/lib/swift/Block \ --build-tests Scripts/GenerateTestSymbolGraphs swift test -c release \ --explicit-target-dependency-import-check=error \ - -Xcxx -I/usr/lib/swift \ - -Xcxx -I/usr/lib/swift/Block \ + -Xcxx -I$SWIFT_INSTALLATION/lib/swift \ + -Xcxx -I$SWIFT_INSTALLATION/lib/swift/Block \ --no-parallel \ --skip-build \ --skip SymbolGraphValidationTests \ diff --git a/Scripts/macOS/GeneratePackageSymbolGraphs b/Scripts/macOS/GeneratePackageSymbolGraphs new file mode 100755 index 000000000..44b87cb8c --- /dev/null +++ b/Scripts/macOS/GeneratePackageSymbolGraphs @@ -0,0 +1,53 @@ +#!/bin/bash +set -e + +swift --version + +ssgc \ + -r https://github.com/apple/swift-atomics.git \ + -t 1.2.0 \ + -n swift-atomics \ + -o TestPackages/swift-atomics.bson + +ssgc \ + -r https://github.com/apple/swift-nio.git \ + -t 2.75.0 \ + -n swift-nio \ + -o TestPackages/swift-nio.bson + +ssgc \ + -r https://github.com/apple/swift-nio-ssl.git \ + -t 2.29.0 \ + -n swift-nio-ssl \ + -o TestPackages/swift-nio-ssl.bson + +ssgc \ + -r https://github.com/apple/swift-async-dns-resolver.git \ + -t 0.1.2 \ + -n swift-async-dns-resolver \ + -o TestPackages/swift-async-dns-resolver.bson + +ssgc \ + -r https://github.com/swiftlang/swift-syntax.git \ + -t 600.0.1 \ + -n swift-syntax \ + -o TestPackages/swift-syntax.bson + +ssgc \ + -r https://github.com/pointfreeco/swift-snapshot-testing.git \ + -t 1.17.5 \ + -n swift-snapshot-testing \ + -o TestPackages/swift-snapshot-testing.bson + +ssgc \ + -r https://github.com/swiftlang/indexstore-db.git \ + -t swift-6.0-RELEASE \ + -n indexstore-db \ + -o TestPackages/indexstore-db.bson + +ssgc \ + -r https://github.com/swiftlang/swift-book.git \ + -t swift-5.10-fcs \ + -b book \ + -n swift-book \ + -o TestPackages/swift-book.bson From 32fbc4c86aef54de58b16ac6147a39cf067eaab9 Mon Sep 17 00:00:00 2001 From: Dianna Date: Mon, 4 Nov 2024 21:04:33 +0000 Subject: [PATCH 12/13] forgot to update this path --- Scripts/Linux/TestAll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Scripts/Linux/TestAll b/Scripts/Linux/TestAll index 91974c7e5..c15c748e4 100755 --- a/Scripts/Linux/TestAll +++ b/Scripts/Linux/TestAll @@ -10,7 +10,7 @@ swift build -c release \ -Xcxx -I$SWIFT_INSTALLATION/lib/swift/Block \ --build-tests -Scripts/GenerateTestSymbolGraphs +Scripts/Linux/GenerateTestSymbolGraphs swift test -c release \ --explicit-target-dependency-import-check=error \ From 513e7ce794056076f16d898bef15ff0d01c50e99 Mon Sep 17 00:00:00 2001 From: Dianna Date: Mon, 4 Nov 2024 21:07:40 +0000 Subject: [PATCH 13/13] =?UTF-8?q?don=E2=80=99t=20build=20tests=20twice?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/test.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6b1b24a49..a20668109 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -57,7 +57,7 @@ jobs: run: | swift --version swift build -c release \ - --product ssgc \ + --build-tests \ --explicit-target-dependency-import-check=error \ -Xcxx -I$SWIFT_INSTALLATION/lib/swift \ -Xcxx -I$SWIFT_INSTALLATION/lib/swift/Block @@ -71,6 +71,7 @@ jobs: - name: Validate packages run: | swift test -c release \ + --skip-build \ --filter SymbolGraphValidationTests \ -Xcxx -I$SWIFT_INSTALLATION/lib/swift \ -Xcxx -I$SWIFT_INSTALLATION/lib/swift/Block