Skip to content

MIgrate to GH actions #22

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

Merged
merged 8 commits into from
Nov 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
root = true

[*]
indent_style = space
indent_size = 4
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
18 changes: 18 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: Main

on:
push:
branches: [main]
schedule:
- cron: "0 8,20 * * *"

jobs:
unit-tests:
name: Unit tests
uses: apple/swift-nio/.github/workflows/unit_tests.yml@main
with:
linux_5_9_arguments_override: "-Xswiftc -warnings-as-errors --explicit-target-dependency-import-check error"
linux_5_10_arguments_override: "-Xswiftc -warnings-as-errors --explicit-target-dependency-import-check error"
linux_6_0_arguments_override: "-Xswiftc -warnings-as-errors --explicit-target-dependency-import-check error -Xswiftc -require-explicit-sendable"
linux_nightly_6_0_arguments_override: "--explicit-target-dependency-import-check error -Xswiftc -require-explicit-sendable"
linux_nightly_main_arguments_override: "--explicit-target-dependency-import-check error -Xswiftc -require-explicit-sendable"
28 changes: 28 additions & 0 deletions .github/workflows/pull_request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: PR

on:
pull_request:
types: [opened, reopened, synchronize]

jobs:
soundness:
name: Soundness
uses: swiftlang/github-workflows/.github/workflows/soundness.yml@main
with:
license_header_check_project_name: "Hummingbird server framework"


unit-tests:
name: Unit tests
uses: apple/swift-nio/.github/workflows/unit_tests.yml@main
with:
linux_5_9_arguments_override: "-Xswiftc -warnings-as-errors --explicit-target-dependency-import-check error -Xswiftc -strict-concurrency=complete"
# TODO: `enable -Xswiftc -strict-concurrency=complete`
linux_5_10_arguments_override: "-Xswiftc -warnings-as-errors --explicit-target-dependency-import-check error"
linux_6_0_arguments_override: "-Xswiftc -warnings-as-errors --explicit-target-dependency-import-check error -Xswiftc -require-explicit-sendable -Xswiftc -strict-concurrency=complete"
linux_nightly_6_0_arguments_override: "--explicit-target-dependency-import-check error -Xswiftc -require-explicit-sendable"
linux_nightly_main_arguments_override: "--explicit-target-dependency-import-check error -Xswiftc -require-explicit-sendable"

cxx-interop:
name: Cxx interop
uses: apple/swift-nio/.github/workflows/cxx_interop.yml@main
Comment on lines +26 to +28
Copy link
Member

Choose a reason for hiding this comment

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

What's this used for?

18 changes: 18 additions & 0 deletions .github/workflows/pull_request_label.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: PR label

on:
pull_request:
types: [labeled, unlabeled, opened, reopened, synchronize]

jobs:
semver-label-check:
name: Semantic version label check
runs-on: ubuntu-latest
timeout-minutes: 1
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
persist-credentials: false
- name: Check for Semantic Version label
uses: apple/swift-nio/.github/actions/pull_request_semver_label_checker@main
13 changes: 13 additions & 0 deletions .license_header_template
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
@@===----------------------------------------------------------------------===@@
@@
@@ This source file is part of the Hummingbird server framework project
@@
@@ Copyright (c) YEARS the Hummingbird authors
@@ Licensed under Apache License v2.0
@@
@@ See LICENSE.txt for license information
@@ See CONTRIBUTORS.txt for the list of Hummingbird authors
@@
@@ SPDX-License-Identifier: Apache-2.0
@@
@@===----------------------------------------------------------------------===@@
36 changes: 36 additions & 0 deletions .licenseignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
.gitignore
**/.gitignore
.licenseignore
.gitattributes
.git-blame-ignore-revs
.mailfilter
.mailmap
.spi.yml
.swift-format
.swiftformatignore
.editorconfig
.github/*
*.md
*.txt
*.yml
*.yaml
*.json
Package.swift
**/Package.swift
Package@-*.swift
**/Package@-*.swift
Package.resolved
**/Package.resolved
Makefile
*.modulemap
**/*.modulemap
**/*.docc/*
*.xcprivacy
**/*.xcprivacy
*.symlink
**/*.symlink
Dockerfile
**/Dockerfile
Snippets/*
dev/git.commit.template
.unacceptablelanguageignore
5 changes: 5 additions & 0 deletions .spi.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
version: 1
builder:
configs:
- documentation_targets:
- OpenAPIHummingbird
8 changes: 4 additions & 4 deletions .swift-format
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@
"lineLength" : 120,
"maximumBlankLines" : 1,
"prioritizeKeepingFunctionOutputTogether" : false,
"respectsExistingLineBreaks" : true,
"respectsExistingLineBreaks" : false,
"rules" : {
"AllPublicDeclarationsHaveDocumentation" : false,
"AllPublicDeclarationsHaveDocumentation" : true,
"AlwaysUseLowerCamelCase" : false,
"AmbiguousTrailingClosureOverload" : true,
"BeginDocumentationCommentWithOneLineSummary" : false,
Expand Down Expand Up @@ -50,9 +50,9 @@
"UseSynthesizedInitializer" : true,
"UseTripleSlashForDocumentationComments" : true,
"UseWhereClausesInForLoops" : false,
"ValidateDocumentationComments" : false
"ValidateDocumentationComments" : true
},
"spacesAroundRangeFormationOperators" : false,
"tabWidth" : 8,
"version" : 1
}
}
13 changes: 3 additions & 10 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,8 @@ import PackageDescription

let package = Package(
name: "swift-openapi-hummingbird",
platforms: [
.macOS(.v14), .iOS(.v17), .tvOS(.v17), .watchOS(.v10),
],
products: [
.library(name: "OpenAPIHummingbird", targets: ["OpenAPIHummingbird"]),
],
platforms: [.macOS(.v14), .iOS(.v17), .tvOS(.v17), .watchOS(.v10)],
products: [.library(name: "OpenAPIHummingbird", targets: ["OpenAPIHummingbird"])],
dependencies: [
.package(url: "https://github.com/apple/swift-openapi-runtime.git", from: "1.0.0"),
.package(url: "https://github.com/hummingbird-project/hummingbird.git", from: "2.0.0"),
Expand All @@ -25,10 +21,7 @@ let package = Package(
),
.testTarget(
name: "OpenAPIHummingbirdTests",
dependencies: [
"OpenAPIHummingbird",
.product(name: "HummingbirdTesting", package: "hummingbird"),
]
dependencies: ["OpenAPIHummingbird", .product(name: "HummingbirdTesting", package: "hummingbird")]
),
]
)
48 changes: 17 additions & 31 deletions Sources/OpenAPIHummingbird/OpenAPITransport.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,22 +24,21 @@ extension RouterMethods {
/// - handler: A handler to be invoked when an HTTP request is received.
/// - method: An HTTP request method.
/// - path: The URL path components, for example `["pets", ":petId"]`.
/// - queryItemNames: The names of query items to be extracted
/// from the request URL that matches the provided HTTP operation.
public func register(
_ handler: @escaping @Sendable (HTTPRequest, HTTPBody?, ServerRequestMetadata) async throws -> (
HTTPResponse, HTTPBody?
),
method: HTTPRequest.Method,
path: String
) throws {
self.on(
.init(path),
method: method
) { request, context in
) {
self.on(.init(path), method: method) { request, context in
let (openAPIRequest, openAPIRequestBody) = try request.makeOpenAPIRequest(context: context)
let openAPIRequestMetadata = context.makeOpenAPIRequestMetadata()
let (openAPIResponse, openAPIResponseBody) = try await handler(openAPIRequest, openAPIRequestBody, openAPIRequestMetadata)
let (openAPIResponse, openAPIResponseBody) = try await handler(
openAPIRequest,
openAPIRequestBody,
openAPIRequestMetadata
)
return Response(openAPIResponse, body: openAPIResponseBody)
}
}
Expand All @@ -50,16 +49,11 @@ extension Request {
func makeOpenAPIRequest<Context: RequestContext>(context: Context) throws -> (HTTPRequest, HTTPBody?) {
let request = self.head
// extract length from content-length header
let length = if let contentLengthHeader = self.headers[.contentLength], let contentLength = Int(contentLengthHeader) {
HTTPBody.Length.known(numericCast(contentLength))
} else {
HTTPBody.Length.unknown
}
let body = HTTPBody(
self.body.map { [UInt8](buffer: $0) },
length: length,
iterationBehavior: .single
)
let length =
if let contentLengthHeader = self.headers[.contentLength], let contentLength = Int(contentLengthHeader) {
HTTPBody.Length.known(numericCast(contentLength))
} else { HTTPBody.Length.unknown }
let body = HTTPBody(self.body.map { [UInt8](buffer: $0) }, length: length, iterationBehavior: .single)
return (request, body)
}
}
Expand All @@ -69,22 +63,18 @@ extension RequestContext {
func makeOpenAPIRequestMetadata() -> ServerRequestMetadata {
let keyAndValues = self.parameters.map { (key: String($0.0), value: $0.1) }
let openAPIParameters = [String: Substring](keyAndValues) { first, _ in first }
return .init(
pathParameters: openAPIParameters
)
return .init(pathParameters: openAPIParameters)
}
}

extension Response {
init(_ response: HTTPResponse, body: HTTPBody?) {
let responseBody: ResponseBody
if let body = body {
let bufferSequence = body.map { ByteBuffer(bytes: $0)}
let bufferSequence = body.map { ByteBuffer(bytes: $0) }
if case .known(let length) = body.length {
responseBody = .init(contentLength: numericCast(length)) { writer in
for try await buffer in bufferSequence {
try await writer.write(buffer)
}
for try await buffer in bufferSequence { try await writer.write(buffer) }
try await writer.finish(nil)
}
} else {
Expand All @@ -94,11 +84,7 @@ extension Response {
responseBody = .init(byteBuffer: ByteBuffer())
}

self.init(
status: response.status,
headers: response.headerFields,
body: responseBody
)
self.init(status: response.status, headers: response.headerFields, body: responseBody)
}
}

Expand All @@ -110,4 +96,4 @@ extension RouteCollection: @retroactive ServerTransport {}
extension Router: ServerTransport {}
extension RouterGroup: ServerTransport {}
extension RouteCollection: ServerTransport {}
#endif
#endif
41 changes: 10 additions & 31 deletions Tests/OpenAPIHummingbirdTests/OpenAPITransportTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,9 @@ final class HBOpenAPITransportTests: XCTestCase {
scheme: "http",
authority: "localhost",
path: "/hello/Maria?greeting=Howdy",
headerFields: [
.xMumble: "mumble",
.connection: "keep-alive",
.contentLength: "4",
]
)
let expectedRequestMetadata = ServerRequestMetadata(
pathParameters: ["name": "Maria"]
headerFields: [.xMumble: "mumble", .connection: "keep-alive", .contentLength: "4"]
)
let expectedRequestMetadata = ServerRequestMetadata(pathParameters: ["name": "Maria"])
let (request, body) = try hbRequest.makeOpenAPIRequest(context: context)
let collectedBody: [UInt8]
if let body = body {
Expand All @@ -71,9 +65,7 @@ final class HBOpenAPITransportTests: XCTestCase {
try await client.execute(
uri: "/hello/Maria?greeting=Howdy",
method: .post,
headers: [
.xMumble: "mumble",
],
headers: [.xMumble: "mumble"],
body: ByteBuffer(string: "👋")
) { hbResponse in
// Check the HBResponse (created from the Response) is what meets expectations.
Expand All @@ -87,7 +79,7 @@ final class HBOpenAPITransportTests: XCTestCase {

func test_largeBody() async throws {
let router = Router()
let bytes = (0..<1_000_000).map { _ in UInt8.random(in: 0...255)}
let bytes = (0..<1_000_000).map { _ in UInt8.random(in: 0...255) }
let byteBuffer = ByteBuffer(bytes: bytes)

router.post("/hello/:name") { hbRequest, context -> Response in
Expand All @@ -97,14 +89,9 @@ final class HBOpenAPITransportTests: XCTestCase {
scheme: "http",
authority: "localhost",
path: "/hello/Maria?greeting=Howdy",
headerFields: [
.connection: "keep-alive",
.contentLength: "1000000",
]
)
let expectedRequestMetadata = ServerRequestMetadata(
pathParameters: ["name": "Maria"]
headerFields: [.connection: "keep-alive", .contentLength: "1000000"]
)
let expectedRequestMetadata = ServerRequestMetadata(pathParameters: ["name": "Maria"])
let (request, body) = try hbRequest.makeOpenAPIRequest(context: context)
XCTAssertEqual(request, expectedRequest)
XCTAssertEqual(context.makeOpenAPIRequestMetadata(), expectedRequestMetadata)
Expand All @@ -116,19 +103,12 @@ final class HBOpenAPITransportTests: XCTestCase {

let app = Application(
router: router,
server: .http1(
additionalChannelHandlers: [
BreakupHTTPBodyChannelHandler()
]
)
server: .http1(additionalChannelHandlers: [BreakupHTTPBodyChannelHandler()])
)

try await app.test(.live) { client in
try await client.execute(
uri: "/hello/Maria?greeting=Howdy",
method: .post,
body: byteBuffer
) { hbResponse in
try await client.execute(uri: "/hello/Maria?greeting=Howdy", method: .post, body: byteBuffer) {
hbResponse in
// Check the Response (created from the Response) is what meets expectations.
XCTAssertEqual(hbResponse.status, .ok)
XCTAssertEqual(byteBuffer, hbResponse.body)
Expand All @@ -147,8 +127,7 @@ class BreakupHTTPBodyChannelHandler: ChannelInboundHandler, RemovableChannelHand
let part = unwrapInboundIn(data)

switch part {
case .head, .end:
context.fireChannelRead(data)
case .head, .end: context.fireChannelRead(data)
case .body(var buffer):
while buffer.readableBytes > 0 {
let size = min(32768, buffer.readableBytes)
Expand Down
23 changes: 0 additions & 23 deletions docker/Dockerfile

This file was deleted.

Loading