This is an automated email from the ASF dual-hosted git repository.

dgrove pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/openwhisk-runtime-swift.git


The following commit(s) were added to refs/heads/master by this push:
     new c4d08d0  Add Support for Swift 5.7 (#153)
c4d08d0 is described below

commit c4d08d09ce2afbfc8c0aa478128fa185d8868b8a
Author: Andrea Scuderi <[email protected]>
AuthorDate: Thu Jul 6 00:44:56 2023 +0100

    Add Support for Swift 5.7 (#153)
---
 .github/workflows/ci.yaml                          |   4 +
 .gitignore                                         |   3 +
 .travis.yml                                        |   2 +-
 README.md                                          | 132 +++++++-
 ansible/files/runtimes.json                        |  14 +
 core/swift57Action/CHANGELOG.md                    |  25 ++
 core/swift57Action/Dockerfile                      |  66 ++++
 .../swift57Action/Package.swift                    |  51 ++-
 core/swift57Action/_Whisk.swift                    | 277 ++++++++++++++++
 settings.gradle => core/swift57Action/build.gradle |  30 +-
 core/swift57Action/main.swift                      | 129 ++++++++
 core/swift57Action/swiftbuild.py                   | 111 +++++++
 core/swift57Action/swiftbuild.py.launcher.swift    | 359 +++++++++++++++++++++
 core/swift57Action/swiftbuildandlink.sh            |  18 ++
 examples/swift-async-main-single/Makefile          |  52 +++
 examples/swift-async-main-single/main.swift        |  62 ++++
 .../swift-async-main-zip/HelloSwift5/Package.swift |  48 ++-
 .../HelloSwift5/Sources/main.swift                 |  41 +--
 examples/swift-async-main-zip/Makefile             |  56 ++++
 settings.gradle                                    |   2 +
 tests/dat/actions/Makefile                         |   7 +-
 tests/dat/actions/SwiftyRequest5/Package.resolved  |  79 -----
 .../SwiftyRequestAsyncCodable57/Package.resolved   |  86 +++++
 .../SwiftyRequestAsyncCodable57/Package.swift      |  55 ++--
 .../SwiftyRequestAsyncCodable57/Sources/main.swift |  53 +++
 .../actions/SwiftyRequestCodable5/Package.resolved |  79 -----
 tests/dat/build.sh                                 |   6 +
 .../Swift57ActionContainerTests.scala              | 145 +++++++++
 .../Swift57CodableActionContainerTests.scala       |  34 +-
 .../test/scala/runtime/sdk/Swift57SDKTests.scala   |  33 +-
 tools/travis/build.sh                              |   1 +
 tools/travis/publish.sh                            |   2 +
 32 files changed, 1699 insertions(+), 363 deletions(-)

diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index db6661e..7c0161f 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -101,6 +101,8 @@ jobs:
           ./gradlew :core:swift53Action:distDocker -PdockerRegistry=docker.io 
-PdockerImagePrefix=openwhisk -PdockerImageTag=$SHORT_COMMIT
           ./gradlew :core:swift54Action:distDocker -PdockerRegistry=docker.io 
-PdockerImagePrefix=openwhisk -PdockerImageTag=nightly
           ./gradlew :core:swift54Action:distDocker -PdockerRegistry=docker.io 
-PdockerImagePrefix=openwhisk -PdockerImageTag=$SHORT_COMMIT
+          ./gradlew :core:swift57Action:distDocker -PdockerRegistry=docker.io 
-PdockerImagePrefix=openwhisk -PdockerImageTag=nightly
+          ./gradlew :core:swift57Action:distDocker -PdockerRegistry=docker.io 
-PdockerImagePrefix=openwhisk -PdockerImageTag=$SHORT_COMMIT
       - name: Push Release Images
         if: ${{ env.PUSH_RELEASE == 'true' }}
         working-directory: runtime
@@ -113,5 +115,7 @@ jobs:
             RUNTIME="swift53Action"
           elif [ ${RUNTIME_VERSION} == "5.4" ]; then
             RUNTIME="swift54Action"
+          elif [ ${RUNTIME_VERSION} == "5.7" ]; then
+            RUNTIME="swift57Action"
           fi
           ./gradlew :core:$RUNTIME:distDocker -PdockerRegistry=docker.io 
-PdockerImagePrefix=openwhisk -PdockerImageTag=$IMAGE_TAG
diff --git a/.gitignore b/.gitignore
index 9bf0539..d5be8df 100644
--- a/.gitignore
+++ b/.gitignore
@@ -81,3 +81,6 @@ test.json
 *.done
 examples/*/*.zip
 ActionLoop/
+
+#Swift
+**/.swiftpm/
\ No newline at end of file
diff --git a/.travis.yml b/.travis.yml
index 85f1568..be86098 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -16,7 +16,7 @@
 #
 
 sudo: required
-dist: xenial
+dist: jammy
 jdk: openjdk8
 language: java
 services:
diff --git a/README.md b/README.md
index b46e800..155d418 100644
--- a/README.md
+++ b/README.md
@@ -26,6 +26,7 @@
 - [Swift 5.1   CHANGELOG.md](core/swift51Action/CHANGELOG.md)
 - [Swift 5.3   CHANGELOG.md](core/swift53Action/CHANGELOG.md)
 - [Swift 5.4   CHANGELOG.md](core/swift54Action/CHANGELOG.md)
+- [Swift 5.7   CHANGELOG.md](core/swift57Action/CHANGELOG.md)
 
 ## Quick Swift Action
 ### Simple swift action hello.swift
@@ -45,7 +46,7 @@ func main(args: Any) -> Any {
 
 For the return result, not only support `dictionary`, but also support `array`
 
-So a very simple `hello array` function woule be:
+So a very simple `hello array` function would be:
 
 ```swift
 func main(args: Any) -> Any {
@@ -63,7 +64,7 @@ So the function can be:
      return args
  }
 ```
-When invokes above action, we can pass an array object as the input parameter.
+When invoking the above action, we can pass an array object as the input 
parameter.
 
 ## Swift 5.x support
 
@@ -85,13 +86,13 @@ func main(input: Employee, respondWith: (Employee?, Error?) 
-> Void) -> Void {
     respondWith(input, nil)
 }
 ```
-```
+```bash
 wsk action update helloCodableAsync helloCodableAsync.swift swift:5.1
 ```
-```
+```bash
 ok: updated action helloCodableAsync
 ```
-```
+```bash
 wsk action invoke helloCodableAsync -r -p id 73 -p name Andrea
 ```
 ```json
@@ -125,13 +126,13 @@ func main(input: Employee, respondWith: (Employee?, 
Error?) -> Void) -> Void {
     }
 }
 ```
-```
+```bash
 wsk action update helloCodableError helloCodableError.swift swift:5.1
 ```
-```
+```bash
 ok: updated action helloCodableError
 ```
-```
+```bash
 wsk action invoke helloCodableError -b -p id 51 -p name Carlos
 ```
 ```json
@@ -159,14 +160,125 @@ To avoid the cold-start delay, you can compile your 
Swift file into a binary and
 
 Use the docker container and pass the single source file as stdin.
 Pass the name of the method to the flag `-compile`
-```
+```bash
 docker run -i openwhisk/action-swift-v5.1 -compile main <main.swift 
>../action.zip
 ```
 
 ### Compiling Swift 5.1 multiple files with dependencies
 Use the docker container and pass a zip archive containing a `Package.swift` 
and source files a main source file in the location `Sources/main.swift`.
-```
+```bash
 zip - -r * | docker run -i openwhisk/action-swift-v5.1 -compile main 
>../action.zip
 ```
 
 For more build examples see [here](./examples/)
+
+# Swift 5.7
+
+In addition to previous ways of defining an action is now possible to use 
throwing async/await inside the action.
+
+### Async throwing Action with Any Input and Any Output
+
+```swift
+func action(args: Any) async throws -> Any {
+    //async code sleep for 1 sec
+    try await Task.sleep(nanoseconds: 1_000_000_000)
+
+    let newArgs = args as! [String:Any]
+    if let name = newArgs["name"] as? String {
+        return [ "greeting" : "Hello \(name)!" ]
+    } else {
+        return [ "greeting" : "Hello stranger!" ]
+    }
+}
+```
+
+### Async throwing Action with a Codable Input and a Codable Output
+
+```swift
+struct Input: Codable {
+    let name: String?
+}
+
+struct Output: Codable {
+    let count: Int
+}
+
+func action(input: Input) async throws -> Output? {
+    try await Task.sleep(nanoseconds: 1_000_000_000)
+    if let name = input.name {
+        return Output(count: name.count)
+    } else {
+        return Output(count: 0)
+    }
+}
+```
+
+### Async throwing Action with Codable Output
+
+```swift
+struct Input: Codable {
+    let name: String?
+}
+
+struct Output: Codable {
+    let count: Int
+}
+
+func action() async throws -> Output? {
+    try await Task.sleep(nanoseconds: 1_000_000_000)
+    return Output(count: 0)
+}
+```
+
+
+### Example of an async throwing Action with a Codable Input and a Codable 
Output
+
+In the following example, the main action decodes the URL from `AnInput`, 
downloads the content from the URL, decodes the JSON and returns the `response` 
in `AnOutput`.
+In case of failure, the runtime will return an error.
+
+```swift
+import AsyncHTTPClient
+import Foundation
+import _Concurrency
+import NIOCore
+import NIOFoundationCompat
+
+enum RequestError: Error {
+    case requestError
+}
+struct AnInput: Codable {
+    let url: String?
+}
+
+struct AnOutput: Codable {
+    let args: [String: String]
+    let headers: [String: String]
+    let origin: String
+    let url: String
+}
+
+let httpClient = HTTPClient(eventLoopGroupProvider: .createNew)
+let decoder = JSONDecoder()
+
+func main(param: AnInput) async throws -> AnOutput {
+
+    let echoURL = param.url ?? "https://httpbin.org/get";
+    let request = HTTPClientRequest(url: echoURL)
+    let response = try await httpClient.execute(request, timeout: .seconds(3))
+    if response.status == .ok {
+        let bytes = try await response.body.collect(upTo: 1024 * 1024) // 1 MB 
Buffer
+        let data = Data(buffer: bytes)
+        return try decoder.decode(AnOutput.self, from: data)
+    } else {
+        throw RequestError.requestError
+    }
+}
+```
+
+The full swift package is 
[here](/tests/dat/actions/SwiftyRequestAsyncCodable57/).
+
+Note that the package of this action contains a dependency from 
`AsynHTTPClient`, in such case, it's preferred to build the action.
+
+```shell
+zip - -r * | docker run -i openwhisk/action-swift-v5.7 -compile main 
>../action.zip
+```
diff --git a/ansible/files/runtimes.json b/ansible/files/runtimes.json
index bbc4958..ed5cbe1 100644
--- a/ansible/files/runtimes.json
+++ b/ansible/files/runtimes.json
@@ -71,6 +71,20 @@
           "attachmentName": "codefile",
           "attachmentType": "text/plain"
         }
+      },
+      {
+        "kind": "swift:5.7",
+        "default": false,
+        "image": {
+          "prefix": "testing",
+          "name": "action-swift-v5.7",
+          "tag": "latest"
+        },
+        "deprecated": false,
+        "attached": {
+          "attachmentName": "codefile",
+          "attachmentType": "text/plain"
+        }
       }
     ]
   },
diff --git a/core/swift57Action/CHANGELOG.md b/core/swift57Action/CHANGELOG.md
new file mode 100644
index 0000000..45636dc
--- /dev/null
+++ b/core/swift57Action/CHANGELOG.md
@@ -0,0 +1,25 @@
+<!--
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+-->
+
+# Apache OpenWhisk Swift 5.7 Runtime Container
+
+- Support for swift async/await
+
+## 1.17.0
+ - Next Apache Release
diff --git a/core/swift57Action/Dockerfile b/core/swift57Action/Dockerfile
new file mode 100644
index 0000000..cefe98d
--- /dev/null
+++ b/core/swift57Action/Dockerfile
@@ -0,0 +1,66 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# build go proxy from source
+FROM golang:1.18 AS builder_source
+ARG GO_PROXY_GITHUB_USER=apache
+ARG GO_PROXY_GITHUB_BRANCH=master
+RUN git clone --branch ${GO_PROXY_GITHUB_BRANCH} \
+   https://github.com/${GO_PROXY_GITHUB_USER}/openwhisk-runtime-go /src ; \
+   cd /src ; env GO111MODULE=on CGO_ENABLED=0 go build main/proxy.go && \
+   mv proxy /bin/proxy
+
+# or build it from a release
+FROM golang:1.18 AS builder_release
+ARG [email protected]
+RUN curl -sL 
https://github.com/apache/openwhisk-runtime-go/archive/{$GO_PROXY_RELEASE_VERSION}.tar.gz
 | tar xzf - \
+  && cd openwhisk-runtime-go-*/main \
+  && GO111MODULE=on CGO_ENABLED=0 go build -o /bin/proxy
+
+FROM swift:5.7.2
+
+# select the builder to use
+ARG GO_PROXY_BUILD_FROM=release
+
+RUN rm -rf /var/lib/apt/lists/* \
+  && apt-get clean && apt-get -qq update \
+       && apt-get install -y --no-install-recommends locales python3 vim 
libssl-dev libicu-dev \
+       && rm -rf /var/lib/apt/lists/* \
+       && locale-gen en_US.UTF-8
+
+ENV LANG="en_US.UTF-8" \
+       LANGUAGE="en_US:en" \
+       LC_ALL="en_US.UTF-8"
+
+RUN mkdir -p /swiftAction
+WORKDIR /swiftAction
+
+COPY --from=builder_source /bin/proxy /bin/proxy_source
+COPY --from=builder_release /bin/proxy /bin/proxy_release
+RUN mv /bin/proxy_${GO_PROXY_BUILD_FROM} /bin/proxy
+ADD swiftbuild.py /bin/compile
+ADD swiftbuild.py.launcher.swift /bin/compile.launcher.swift
+COPY _Whisk.swift /swiftAction/Sources/
+COPY Package.swift /swiftAction/
+COPY swiftbuildandlink.sh /swiftAction/
+COPY main.swift /swiftAction/Sources/
+RUN swift build -c release; \
+       touch /swiftAction/Sources/main.swift; \
+       rm /swiftAction/.build/release/Action
+
+ENV OW_COMPILER=/bin/compile
+ENTRYPOINT [ "/bin/proxy" ]
diff --git a/settings.gradle b/core/swift57Action/Package.swift
similarity index 58%
copy from settings.gradle
copy to core/swift57Action/Package.swift
index 8079687..1d48af9 100644
--- a/settings.gradle
+++ b/core/swift57Action/Package.swift
@@ -1,3 +1,6 @@
+// swift-tools-version:5.7
+// The swift-tools-version declares the minimum version of Swift required to 
build this package.
+
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
@@ -15,31 +18,23 @@
  * limitations under the License.
  */
 
-include 'tests'
-
-include 'core:swift51Action'
-
-include 'core:swift53Action'
-
-include 'core:swift54Action'
-
-rootProject.name = 'runtime-swift'
-
-gradle.ext.openwhisk = [
-        version: '1.0.1-SNAPSHOT'
-]
-
-gradle.ext.scala = [
-    version: '2.12.7',
-    depVersion  : '2.12',
-    compileFlags: ['-feature', '-unchecked', '-deprecation', 
'-Xfatal-warnings', '-Ywarn-unused-import']
-]
-
-gradle.ext.scalafmt = [
-    version: '1.5.0',
-    config: new File(rootProject.projectDir, '.scalafmt.conf')
-]
-
-gradle.ext.akka = [version : '2.6.12']
-gradle.ext.akka_http = [version : '10.2.4']
-
+import PackageDescription
+
+let package = Package(
+    name: "Action",
+    platforms: [
+        .macOS(.v12),
+    ],
+    products: [
+      .executable(
+        name: "Action",
+        targets:  ["Action"]
+      )
+    ],
+    targets: [
+      .executableTarget(
+        name: "Action",
+        path: "."
+      )
+    ]
+)
diff --git a/core/swift57Action/_Whisk.swift b/core/swift57Action/_Whisk.swift
new file mode 100644
index 0000000..3cade25
--- /dev/null
+++ b/core/swift57Action/_Whisk.swift
@@ -0,0 +1,277 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Foundation
+import Dispatch
+#if canImport(FoundationNetworking)
+import FoundationNetworking
+#endif
+
+class Whisk {
+
+    static var baseUrl = ProcessInfo.processInfo.environment["__OW_API_HOST"]
+    static var apiKey = ProcessInfo.processInfo.environment["__OW_API_KEY"]
+    // This will allow user to modify the default JSONDecoder and JSONEncoder 
used by epilogue
+    static var jsonDecoder = JSONDecoder()
+    static var jsonEncoder = JSONEncoder()
+
+    class func invoke(actionNamed action: String, withParameters params: 
[String: Any], blocking: Bool = true) -> [String: Any] {
+        let parsedAction = parseQualifiedName(name: action)
+        let strBlocking = blocking ? "true" : "false"
+        let path = 
"/api/v1/namespaces/\(parsedAction.namespace)/actions/\(parsedAction.name)?blocking=\(strBlocking)"
+        return sendWhiskRequestSyncronish(uriPath: path, params: params, 
method: "POST")
+    }
+
+    class func trigger(eventNamed event : String, withParameters params: 
[String: Any]) -> [String: Any] {
+        let parsedEvent = parseQualifiedName(name: event)
+        let path = 
"/api/v1/namespaces/\(parsedEvent.namespace)/triggers/\(parsedEvent.name)?blocking=true"
+        return sendWhiskRequestSyncronish(uriPath: path, params: params, 
method: "POST")
+    }
+
+    class func createTrigger(triggerNamed trigger: String, withParameters 
params: [String:Any]) -> [String: Any] {
+        let parsedTrigger = parseQualifiedName(name: trigger)
+        let path = 
"/api/v1/namespaces/\(parsedTrigger.namespace)/triggers/\(parsedTrigger.name)"
+        return sendWhiskRequestSyncronish(uriPath: path, params: params, 
method: "PUT")
+    }
+
+    class func createRule(ruleNamed ruleName: String, withTrigger triggerName: 
String, andAction actionName: String) -> [String: Any] {
+        let parsedRule = parseQualifiedName(name: ruleName)
+        let path = 
"/api/v1/namespaces/\(parsedRule.namespace)/rules/\(parsedRule.name)"
+        let params = ["trigger":triggerName, "action":actionName]
+        return sendWhiskRequestSyncronish(uriPath: path, params: params, 
method: "PUT")
+    }
+
+    // handle the GCD dance to make the post async, but then obtain/return
+    // the result from this function sync
+    private class func sendWhiskRequestSyncronish(uriPath path: String, 
params: [String: Any], method: String) -> [String: Any] {
+        var response : [String: Any]!
+
+        let queue = DispatchQueue.global()
+        let invokeGroup = DispatchGroup()
+
+        invokeGroup.enter()
+        queue.async {
+            postUrlSession(uriPath: path, params: params, method: method, 
group: invokeGroup) { result in
+                response = result
+            }
+        }
+
+        // On one hand, FOREVER seems like an awfully long time...
+        // But on the other hand, I think we can rely on the system to kill 
this
+        // if it exceeds a reasonable execution time.
+        switch invokeGroup.wait(timeout: DispatchTime.distantFuture) {
+        case DispatchTimeoutResult.success:
+            break
+        case DispatchTimeoutResult.timedOut:
+            break
+        }
+
+        return response
+    }
+
+
+    /**
+     * Using new UrlSession
+     */
+    private class func postUrlSession(uriPath: String, params : [String:Any], 
method: String,group: DispatchGroup, callback : @escaping([String:Any]) -> 
Void) {
+
+        guard let encodedPath = 
uriPath.addingPercentEncoding(withAllowedCharacters: 
CharacterSet.urlQueryAllowed) else {
+            callback(WhiskError.invalidURIPath.body)
+            return
+        }
+
+        let urlStr = "\(baseUrl!)\(encodedPath)"
+        if let url = URL(string: urlStr) {
+            var request = URLRequest(url: url)
+            request.httpMethod = method
+
+            do {
+                request.addValue("application/json", forHTTPHeaderField: 
"Content-Type")
+                request.httpBody = try JSONSerialization.data(withJSONObject: 
params)
+
+                let loginData: Data = apiKey!.data(using: 
String.Encoding.utf8, allowLossyConversion: false)!
+                let base64EncodedAuthKey  = 
loginData.base64EncodedString(options: NSData.Base64EncodingOptions(rawValue: 
0))
+                request.addValue("Basic \(base64EncodedAuthKey)", 
forHTTPHeaderField: "Authorization")
+                let session = URLSession(configuration: 
URLSessionConfiguration.default)
+
+                let task = session.dataTask(with: request, completionHandler: 
{data, response, error -> Void in
+
+                    // exit group after we are done
+                    defer {
+                        group.leave()
+                    }
+
+                    if let error = error {
+                        callback(WhiskError.generic(error).body)
+                    } else {
+                        if let data = data {
+                            let decodeReponse = decodeWhiskResponse(data: data)
+                            callback(decodeReponse)
+                        }
+                    }
+                })
+
+                task.resume()
+            } catch {
+                callback(WhiskError.invalidParams(error).body)
+            }
+        }
+    }
+
+    static func invoke(actionNamed action: String, withParameters params: 
[String: Any], blocking: Bool = true) async throws -> Data {
+        let parsedAction = parseQualifiedName(name: action)
+        let strBlocking = blocking ? "true" : "false"
+        let path = 
"/api/v1/namespaces/\(parsedAction.namespace)/actions/\(parsedAction.name)?blocking=\(strBlocking)"
+        return try await postUrlSession(uriPath: path, params: params, method: 
"POST")
+    }
+
+    static func trigger(eventNamed event: String, withParameters params: 
[String: Any]) async throws -> Data {
+        let parsedEvent = parseQualifiedName(name: event)
+        let path = 
"/api/v1/namespaces/\(parsedEvent.namespace)/triggers/\(parsedEvent.name)?blocking=true"
+        return try await postUrlSession(uriPath: path, params: params, method: 
"POST")
+    }
+
+    static func createTrigger(triggerNamed trigger: String, withParameters 
params : [String:Any]) async throws -> Data {
+        let parsedTrigger = parseQualifiedName(name: trigger)
+        let path = 
"/api/v1/namespaces/\(parsedTrigger.namespace)/triggers/\(parsedTrigger.name)"
+        return try await postUrlSession(uriPath: path, params: params, method: 
"PUT")
+    }
+
+    static func createRule(ruleNamed ruleName: String, withTrigger 
triggerName: String, andAction actionName: String) async throws -> Data {
+        let parsedRule = parseQualifiedName(name: ruleName)
+        let path = 
"/api/v1/namespaces/\(parsedRule.namespace)/rules/\(parsedRule.name)"
+        let params = ["trigger":triggerName, "action":actionName]
+        return try await postUrlSession(uriPath: path, params: params, method: 
"PUT")
+    }
+
+    private static func postUrlSession(uriPath: String, params : [String:Any], 
method: String) async throws -> Data {
+
+        guard let encodedPath = 
uriPath.addingPercentEncoding(withAllowedCharacters: 
CharacterSet.urlQueryAllowed) else {
+            throw WhiskError.invalidURIPath
+        }
+        guard let baseUrl = baseUrl,
+              let url = URL(string: "\(baseUrl)\(encodedPath)") else {
+            throw WhiskError.invalidURL
+        }
+        var request = URLRequest(url: url)
+        request.httpMethod = method
+        request.addValue("application/json", forHTTPHeaderField: 
"Content-Type")
+
+        do {
+            request.httpBody = try JSONSerialization.data(withJSONObject: 
params)
+        } catch {
+            throw WhiskError.invalidParams(error)
+        }
+
+        guard let loginData: Data = apiKey?.data(using: String.Encoding.utf8, 
allowLossyConversion: false) else {
+            throw WhiskError.invalidLogin
+        }
+        let base64EncodedAuthKey  = loginData.base64EncodedString(options: 
NSData.Base64EncodingOptions(rawValue: 0))
+        request.addValue("Basic \(base64EncodedAuthKey)", forHTTPHeaderField: 
"Authorization")
+        let session = URLSession(configuration: 
URLSessionConfiguration.default)
+        return try await session.asyncWhiskData(with: request)
+    }
+
+    static func decodeWhiskResponse(data: Data) -> [String: Any] {
+        do {
+            let respJson = try JSONSerialization.jsonObject(with: data)
+            if let respJson = respJson as? [String:Any] {
+                return respJson
+            } else {
+                return WhiskError.jsonIsNotDictionary.body
+            }
+        } catch {
+            return WhiskError.invalidJSON(error).body
+        }
+    }
+
+    // separate an OpenWhisk qualified name (e.g. "/whisk.system/samples/date")
+    // into namespace and name components
+    private class func parseQualifiedName(name qualifiedName : String) -> 
(namespace : String, name : String) {
+        let defaultNamespace = "_"
+        let delimiter = "/"
+
+        let segments :[String] = qualifiedName.components(separatedBy: 
delimiter)
+
+        if segments.count > 2 {
+            return (segments[1], 
Array(segments[2..<segments.count]).joined(separator: delimiter))
+        } else if segments.count == 2 {
+            // case "/action" or "package/action"
+            let name = qualifiedName.hasPrefix(delimiter) ? segments[1] : 
segments.joined(separator: delimiter)
+            return (defaultNamespace, name)
+        } else {
+            return (defaultNamespace, segments[0])
+        }
+    }
+}
+
+enum WhiskError: LocalizedError {
+    case invalidURIPath
+    case generic(Error)
+    case invalidURL
+    case invalidLogin
+    case invalidJSON(Error)
+    case invalidParams(Error)
+    case jsonIsNotDictionary
+    case noData
+
+    var errorDescription: String {
+        switch self {
+        case .noData:
+            return ""
+        case .generic(let error):
+            return error.localizedDescription
+        case .invalidURL:
+            return "Invalid URL"
+        case .invalidJSON(let error):
+            return "Error creating json from response: \(error)"
+        case .jsonIsNotDictionary:
+            return " response from server is not a dictionary"
+        case .invalidURIPath:
+            return "Error encoding uri path to make openwhisk REST call."
+        case .invalidParams(let error):
+            return "Got error creating params body: \(error)"
+        case .invalidLogin:
+            return "Invalid __OW_API_KEY"
+        }
+    }
+
+    var body: [String: String] {
+        return ["error": errorDescription]
+    }
+}
+
+extension URLSession {
+
+    // The async version of it, it's not supported
+    // See: 
https://github.com/apple/swift-corelibs-foundation/blob/main/Docs/Status.md#entities
+
+    func asyncWhiskData(with request: URLRequest) async throws -> Data {
+        let taskResult = await withCheckedContinuation { continuation in
+            self.dataTask(with: request) { data, response, error in
+                continuation.resume(returning: (data, response, error))
+            }.resume()
+        }
+        if let error = taskResult.2 {
+            throw WhiskError.generic(error)
+        }
+        guard let data = taskResult.0 else {
+            throw WhiskError.noData
+        }
+        return data
+    }
+}
diff --git a/settings.gradle b/core/swift57Action/build.gradle
similarity index 58%
copy from settings.gradle
copy to core/swift57Action/build.gradle
index 8079687..054558d 100644
--- a/settings.gradle
+++ b/core/swift57Action/build.gradle
@@ -15,31 +15,5 @@
  * limitations under the License.
  */
 
-include 'tests'
-
-include 'core:swift51Action'
-
-include 'core:swift53Action'
-
-include 'core:swift54Action'
-
-rootProject.name = 'runtime-swift'
-
-gradle.ext.openwhisk = [
-        version: '1.0.1-SNAPSHOT'
-]
-
-gradle.ext.scala = [
-    version: '2.12.7',
-    depVersion  : '2.12',
-    compileFlags: ['-feature', '-unchecked', '-deprecation', 
'-Xfatal-warnings', '-Ywarn-unused-import']
-]
-
-gradle.ext.scalafmt = [
-    version: '1.5.0',
-    config: new File(rootProject.projectDir, '.scalafmt.conf')
-]
-
-gradle.ext.akka = [version : '2.6.12']
-gradle.ext.akka_http = [version : '10.2.4']
-
+ext.dockerImageName = 'action-swift-v5.7'
+apply from: '../../gradle/docker.gradle'
diff --git a/core/swift57Action/main.swift b/core/swift57Action/main.swift
new file mode 100644
index 0000000..603c696
--- /dev/null
+++ b/core/swift57Action/main.swift
@@ -0,0 +1,129 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Foundation
+
+enum MainActionError: LocalizedError {
+    case invalidArgs
+    var errorDescription: String? {
+        switch self {
+        case .invalidArgs:
+            return "Invalid arguments"
+        }
+    }
+}
+
+func main(args: Any) async throws -> Any {
+
+    //async code sleep for 1 microsecond
+    try await Task.sleep(nanoseconds: 1_000)
+
+    guard let newArgs = args as? [String:Any] else {
+        throw MainActionError.invalidArgs
+    }
+    if let name = newArgs["name"] as? String {
+        return [ "greeting" : "Hello \(name)!" ]
+    } else {
+        return [ "greeting" : "Hello stranger!" ]
+    }
+}
+
+
+/* Examples of Actions supported by Swift 5.7
+
+// Action with Any Input and Any Output
+func main(args: Any) -> Any {
+    let newArgs = args as! [String:Any]
+    if let name = newArgs["name"] as? String {
+        return [ "greeting" : "Hello \(name)!" ]
+    } else {
+        return [ "greeting" : "Hello stranger!" ]
+    }
+}
+
+// Async Action with Any Input and Any Output
+func mainAsync(args: Any) async -> Any {
+    do {
+        //async code sleep for 1 sec
+        try await Task.sleep(nanoseconds: 1_000_000_000)
+
+        let newArgs = args as! [String:Any]
+        if let name = newArgs["name"] as? String {
+            return [ "greeting" : "Hello \(name)!" ]
+        } else {
+            return [ "greeting" : "Hello stranger!" ]
+        }
+    } catch {
+        return ["error" : error.localizedDescription]
+    }
+}
+
+// Async throwing Action with Any Input and Any Output
+func mainAsyncThrows(args: Any) async throws -> Any {
+    //async code sleep for 1 sec
+    try await Task.sleep(nanoseconds: 1_000_000_000)
+
+    let newArgs = args as! [String:Any]
+    if let name = newArgs["name"] as? String {
+        return [ "greeting" : "Hello \(name)!" ]
+    } else {
+        return [ "greeting" : "Hello stranger!" ]
+    }
+}
+
+struct Input: Codable {
+    let name: String?
+}
+
+struct Output: Codable {
+    let count: Int
+}
+
+// Action with Codable Input and completion with Codable Output and Error
+func mainCompletionCodable(input: Input, completion: @escaping (Output?, 
Error?) -> Void) -> Void {
+    if let name = input.name {
+        let output = Output(count: name.count)
+        completion(output, nil)
+    } else {
+        let output = Output(count: 0)
+        completion(output, nil)
+    }
+}
+
+// Action with Codable Input and completion with Codable Output and Error
+func mainCompletionCodableNoInput(completion: @escaping (Output?, Error?) -> 
Void) -> Void {
+    let output = Output(count: 0)
+    completion(output, nil)
+}
+
+// Async throwing Action with Codable Output
+func mainCodableAsyncThrowsNoInput() async throws -> Output? {
+    try await Task.sleep(nanoseconds: 1_000_000_000)
+    return Output(count: 0)
+}
+
+// Async throwing Action with a Codable Input and a Codable Output
+func mainCodableAsyncThrows(input: Input) async throws -> Output? {
+    try await Task.sleep(nanoseconds: 1_000_000_000)
+    if let name = input.name {
+        return Output(count: name.count)
+    } else {
+        return Output(count: 0)
+    }
+}
+
+*/
diff --git a/core/swift57Action/swiftbuild.py b/core/swift57Action/swiftbuild.py
new file mode 100755
index 0000000..775381c
--- /dev/null
+++ b/core/swift57Action/swiftbuild.py
@@ -0,0 +1,111 @@
+#!/usr/bin/env python3
+"""Swift Action Compiler
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+"""
+
+from __future__ import print_function
+import os
+import re
+import sys
+import codecs
+import subprocess
+from io import StringIO
+
+def eprint(*args, **kwargs):
+    print(*args, file=sys.stderr, **kwargs)
+
+def sources(launcher, source_dir, main):
+    actiondir = "%s/Sources" % source_dir
+    # copy the launcher fixing the main
+    dst = "%s/main.swift" % actiondir
+    with codecs.open(dst, 'a', 'utf-8') as d:
+        with codecs.open(launcher, 'r', 'utf-8') as e:
+            code = e.read()
+            code += "try await _WhiskRuntime.wiskRunLoop { jsonData in\n"
+            code += "   await _WhiskRuntime.runAsyncMain(mainFunction: %s, 
json: jsonData)\n" % main
+            code += "}\n"
+            d.write(code)
+
+def swift_build(dir, buildcmd):
+    # compile...
+    env = {
+      "PATH": os.environ["PATH"]
+    }
+    p = subprocess.Popen(buildcmd,
+        stdout=subprocess.PIPE,
+        stderr=subprocess.PIPE,
+        cwd=dir,
+        env=env)
+    (o, e) = p.communicate()
+    # stdout/stderr may be either text or bytes, depending on Python
+    # version, so if bytes, decode to text. Note that in Python 2
+    # a string will match both types; so also skip decoding in that case
+    if isinstance(o, bytes) and not isinstance(o, str):
+        o = o.decode('utf-8')
+    if isinstance(e, bytes) and not isinstance(e, str):
+        e = e.decode('utf-8')
+    return p.returncode, o, e
+
+def build(source_dir, target_file, buildcmd):
+    r, o, e = swift_build(source_dir, buildcmd)
+    #if e: print(e)
+    #if o: print(o)
+    if r != 0:
+        print(e)
+        print(o)
+        print(r)
+        return
+
+    bin_file = "%s/.build/release/Action" % source_dir
+    os.rename(bin_file, target_file)
+    if not os.path.isfile(target_file):
+        print("failed %s -> %s" % (bin_file, target_file))
+        return
+
+
+def main(argv):
+    if len(argv) < 4:
+        print("usage: <main-function> <source-dir> <target-dir>")
+        sys.exit(1)
+
+    main = argv[1]
+    source_dir = os.path.abspath(argv[2])
+    target = os.path.abspath("%s/exec" % argv[3])
+    launch = os.path.abspath(argv[0]+".launcher.swift")
+
+    src = "%s/exec" % source_dir
+
+    #check if single source
+    if os.path.isfile(src):
+        actiondir = os.path.abspath("Sources")
+        if not os.path.isdir(actiondir):
+            os.makedirs(actiondir, mode=0o755)
+        dst = "%s/main.swift" % actiondir
+        os.rename(src, dst)
+        sources(launch, os.path.abspath("."), main)
+        build(os.path.abspath("."), target, ["./swiftbuildandlink.sh"])
+    else:
+        actiondir = "%s/Sources" % source_dir
+        if not os.path.isdir(actiondir):
+            os.makedirs(actiondir, mode=0o755)
+        
os.rename(os.path.abspath("Sources/_Whisk.swift"),"%s/Sources/_Whisk.swift" % 
source_dir)
+        sources(launch, source_dir, main)
+        build(source_dir, target, ["swift", "build", "-c", "release"])
+
+if __name__ == '__main__':
+    main(sys.argv)
diff --git a/core/swift57Action/swiftbuild.py.launcher.swift 
b/core/swift57Action/swiftbuild.py.launcher.swift
new file mode 100644
index 0000000..79f395e
--- /dev/null
+++ b/core/swift57Action/swiftbuild.py.launcher.swift
@@ -0,0 +1,359 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Imports
+import Foundation
+import _Concurrency
+#if os(Linux)
+import Glibc
+#else
+import Darwin
+#endif
+
+public struct _WhiskRuntime {
+
+    private enum WhiskRuntimeErrorMessage: String {
+        case actionHandlerCallbackError = "Action handler callback returned an 
error:"
+        case actionHandlerCallbackNullOrError = "Action handler callback did 
not return response or error."
+        case failToEncodeDictionary = "Failed to encode Dictionary type to 
JSON string:"
+        case failToEncodeCodableToJson = "JSONEncoder failed to encode Codable 
type to JSON string:"
+        case errorSerializingJSON = "Error serializing JSON, data does not 
appear to be valid JSON"
+        case failedToExecuteActionHandler = "Failed to execute action handler 
with error:"
+    }
+
+    public static func wiskRunLoop(actionMain: ((Data) async -> Void)) async 
throws {
+        while let inputStr: String = readLine() {
+            let json = inputStr.data(using: .utf8, allowLossyConversion: true)!
+            let parsed = try JSONSerialization.jsonObject(with: json, options: 
[]) as! [String: Any]
+            for (key, value) in parsed {
+                if key != "value" {
+                    setenv("__OW_\(key.uppercased())",value as! String,1)
+                }
+            }
+            let jsonData = try JSONSerialization.data(withJSONObject: 
parsed["value"] as Any, options: [])
+            await actionMain(jsonData)
+        }
+    }
+
+    private static func whiskPrintJSONDecoderError(json: Data, error: Error?) {
+        let jsonString = String(
+            data: json,
+            encoding: .utf8
+        ) ?? ""
+        let fixedJSONString = jsonString.replacingOccurrences(of: "\"", with: 
"\\\"")
+
+        let message = "JSONDecoder failed to decode JSON string 
\(fixedJSONString) to Codable type:"
+        var errStr =  "{\"error\":\"\(message)\"}\n"
+        if let error = error {
+            errStr = "{\"error\":\"\(message) 
\(error.localizedDescription)\"\n}"
+        }
+        whiskPrintBuffer(jsonString: errStr)
+    }
+
+    private static func whiskPrintError(message: WhiskRuntimeErrorMessage, 
error: Error?){
+        var errStr =  "{\"error\":\"\(message.rawValue)\"}\n"
+        if let error = error {
+            errStr = "{\"error\":\"\(message.rawValue) 
\(error.localizedDescription)\"\n}"
+        }
+        whiskPrintBuffer(jsonString: errStr)
+    }
+
+    private static func whiskPrintResult(jsonData: Data){
+        let jsonString = String(data: jsonData, encoding: .utf8)!
+        whiskPrintBuffer(jsonString: jsonString)
+    }
+
+    private static func whiskPrintBuffer(jsonString: String){
+        var buf : [UInt8] = Array(jsonString.utf8)
+        buf.append(10)
+        fflush(stdout)
+        fflush(stderr)
+        write(3, buf, buf.count)
+    }
+
+    /**
+     Execute an async throwing Action with Any Input and Any Output
+
+     Example:
+
+     ```
+     func action(args: Any) async throws -> Any {
+         //async code sleep for 1 sec
+         try await Task.sleep(nanoseconds: 1_000_000_000)
+
+         let newArgs = args as! [String:Any]
+         if let name = newArgs["name"] as? String {
+             return [ "greeting" : "Hello \(name)!" ]
+         } else {
+             return [ "greeting" : "Hello stranger!" ]
+         }
+     }
+     ```
+
+     - Parameters:
+        - mainFunction: action
+        - json: action parameters
+        - Returns: Void
+    */
+    public static func runAsyncMain(mainFunction: (Any) async throws -> Any, 
json: Data) async -> Void {
+        do {
+            let parsed = try JSONSerialization.jsonObject(with: json, options: 
[])
+            let result = try await mainFunction(parsed)
+            if JSONSerialization.isValidJSONObject(result) {
+                do {
+                    let jsonData = try JSONSerialization.data(withJSONObject: 
result, options: [])
+                    whiskPrintResult(jsonData: jsonData)
+                } catch {
+                    whiskPrintError(message: .failToEncodeDictionary, error: 
error)
+                }
+            } else {
+                whiskPrintError(message: .errorSerializingJSON, error: nil)
+            }
+        } catch let error as DecodingError {
+            whiskPrintJSONDecoderError(json: json, error: error)
+            return
+        } catch {
+            whiskPrintError(message: .failedToExecuteActionHandler, error: 
error)
+            return
+        }
+    }
+
+    /**
+     Execute an Action with Codable Input and completion with Codable Output 
and Error
+
+     Example:
+
+     ```
+     struct Input: Codable {
+         let name: String?
+     }
+
+     struct Output: Codable {
+         let count: Int
+     }
+
+     func action(input: Input, completion: @escaping (Output?, Error?) -> 
Void) -> Void {
+         if let name = input.name {
+             let output = Output(count: name.count)
+             completion(output, nil)
+         } else {
+             let output = Output(count: 0)
+             completion(output, nil)
+         }
+     }
+     ```
+
+     - Parameters:
+        - mainFunction: action
+        - json: action parameters
+        - Returns: Void
+    */
+    public static func runAsyncMain<In: Decodable, Out: 
Encodable>(mainFunction: (In, @escaping (Out?, Error?) -> Void) -> Void, json: 
Data) {
+        do {
+            let input = try Whisk.jsonDecoder.decode(In.self, from: json)
+            let resultHandler = { (out: Out?, error: Error?) in
+                if let error = error {
+                    whiskPrintError(message: .actionHandlerCallbackError, 
error: error)
+                    return
+                }
+                guard let out = out else {
+                    whiskPrintError(message: 
.actionHandlerCallbackNullOrError, error: nil)
+                    return
+                }
+                do {
+                    let jsonData = try Whisk.jsonEncoder.encode(out)
+                    whiskPrintResult(jsonData: jsonData)
+                } catch let error as EncodingError {
+                    whiskPrintError(message: .failToEncodeCodableToJson, 
error: error)
+                    return
+                } catch {
+                    whiskPrintError(message: .failedToExecuteActionHandler, 
error: error)
+                    return
+                }
+            }
+            let _ = mainFunction(input, resultHandler)
+        } catch let error as DecodingError {
+            whiskPrintJSONDecoderError(json: json, error: error)
+            return
+        } catch {
+            whiskPrintError(message: .failedToExecuteActionHandler, error: 
error)
+            return
+        }
+    }
+
+    /**
+     Execute an async throwing Action with a Codable Input and a Codable Output
+
+     Example:
+
+     ```
+     struct Input: Codable {
+         let name: String?
+     }
+
+     struct Output: Codable {
+         let count: Int
+     }
+
+     func action(input: Input) async throws -> Output? {
+         try await Task.sleep(nanoseconds: 1_000_000_000)
+         if let name = input.name {
+             return Output(count: name.count)
+         } else {
+             return Output(count: 0)
+         }
+     }
+     ```
+
+     - Parameters:
+        - mainFunction: action
+        - json: action parameters
+        - Returns: Void
+    */
+    public static func runAsyncMain<In: Decodable, Out: 
Encodable>(mainFunction: (In) async throws -> Out?, json: Data) async {
+        do {
+            let input = try Whisk.jsonDecoder.decode(In.self, from: json)
+            do {
+                let out = try await mainFunction(input)
+                guard let out = out else {
+                    whiskPrintError(message: 
.actionHandlerCallbackNullOrError, error: nil)
+                    return
+                }
+                do {
+                    let jsonData = try Whisk.jsonEncoder.encode(out)
+                    whiskPrintResult(jsonData: jsonData)
+                } catch let error as EncodingError {
+                    whiskPrintError(message: .failToEncodeCodableToJson, 
error: error)
+                    return
+                } catch {
+                    whiskPrintError(message: .failedToExecuteActionHandler, 
error: error)
+                    return
+                }
+            } catch {
+                whiskPrintError(message: .actionHandlerCallbackError, error: 
error)
+                return
+            }
+        } catch let error as DecodingError {
+            whiskPrintJSONDecoderError(json: json, error: error)
+            return
+        } catch {
+            whiskPrintError(message: .failedToExecuteActionHandler, error: 
error)
+            return
+        }
+    }
+
+    /**
+     Execute an Action with Codable Input and completion with Codable Output 
and Error
+
+     Example:
+
+     ```
+     struct Input: Codable {
+         let name: String?
+     }
+
+     struct Output: Codable {
+         let count: Int
+     }
+
+     func action(completion: @escaping (Output?, Error?) -> Void) -> Void {
+         let output = Output(count: 0)
+         completion(output, nil)
+     }
+     ```
+
+     - Parameters:
+        - mainFunction: action
+        - json: action parameters
+        - Returns: Void
+    */
+    public static func runAsyncMain<Out: Encodable>(mainFunction: ( @escaping 
(Out?, Error?) -> Void) -> Void, json: Data) {
+        let resultHandler = { (out: Out?, error: Error?) in
+            if let error = error {
+                whiskPrintError(message: .actionHandlerCallbackError, error: 
error)
+                return
+            }
+            guard let out = out else {
+                whiskPrintError(message: .actionHandlerCallbackNullOrError, 
error: nil)
+                return
+            }
+            do {
+                let jsonData = try Whisk.jsonEncoder.encode(out)
+                whiskPrintResult(jsonData: jsonData)
+            } catch let error as EncodingError {
+                whiskPrintError(message: .failToEncodeCodableToJson, error: 
error)
+                return
+            } catch {
+                whiskPrintError(message: .failedToExecuteActionHandler, error: 
error)
+                return
+            }
+        }
+        let _ = mainFunction(resultHandler)
+    }
+
+    /**
+     Execute an async throwing Action with Codable Output
+
+     Example:
+
+     ```
+     struct Input: Codable {
+         let name: String?
+     }
+
+     struct Output: Codable {
+         let count: Int
+     }
+
+     func action() async throws -> Output? {
+         try await Task.sleep(nanoseconds: 1_000_000_000)
+         return Output(count: 0)
+     }
+     ```
+
+     - Parameters:
+        - mainFunction: action
+        - json: action parameters
+        - Returns: Void
+    */
+    public static func runAsyncMain<Out: Encodable>(mainFunction: () async 
throws -> Out?, json: Data) async {
+        do {
+            let out = try await mainFunction()
+            guard let out = out else {
+                whiskPrintError(message: .actionHandlerCallbackNullOrError, 
error: nil)
+                return
+            }
+            do {
+                let jsonData = try Whisk.jsonEncoder.encode(out)
+                whiskPrintResult(jsonData: jsonData)
+            } catch let error as EncodingError {
+                whiskPrintError(message: .failToEncodeCodableToJson, error: 
error)
+                return
+            } catch {
+                whiskPrintError(message: .failedToExecuteActionHandler, error: 
error)
+                return
+            }
+        } catch {
+            whiskPrintError(message: .actionHandlerCallbackError, error: error)
+            return
+        }
+    }
+}
+
+
+
+
diff --git a/core/swift57Action/swiftbuildandlink.sh 
b/core/swift57Action/swiftbuildandlink.sh
new file mode 100755
index 0000000..c35a1ba
--- /dev/null
+++ b/core/swift57Action/swiftbuildandlink.sh
@@ -0,0 +1,18 @@
+#!/bin/sh
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+swift build -c release
diff --git a/examples/swift-async-main-single/Makefile 
b/examples/swift-async-main-single/Makefile
new file mode 100644
index 0000000..0a9ac82
--- /dev/null
+++ b/examples/swift-async-main-single/Makefile
@@ -0,0 +1,52 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+OW_USER?=whisk
+OW_RUNTIME?=$(OW_USER)/action-swift-v5.7
+OW_COMPILER?=$(OW_USER)/action-swift-v5.7
+WSK?=wsk -i
+MAIN=async_main
+PACKAGE=test
+SRC=$(MAIN).swift
+NAME=swift-$(MAIN)-single
+ZIP=$(MAIN).zip
+
+deploy: package.done $(ZIP)
+       $(WSK) action update $(PACKAGE)/$(NAME) $(ZIP) --main $(MAIN) --docker 
$(OW_RUNTIME)
+
+devel: package.done $(SRC)
+       $(WSK) action update $(PACKAGE)/$(NAME) $(SRC) --main $(MAIN) --docker 
$(OW_COMPILER)
+
+$(ZIP): $(SRC)
+       docker run -i $(OW_COMPILER) -compile $(MAIN) <$(SRC) >$(ZIP)
+
+clean:
+       $(WSK) action delete $(PACKAGE)/$(NAME)
+       rm $(ZIP) package.done
+
+test: test.json
+       $(WSK) action invoke test/$(NAME) -r --blocking -d
+       $(WSK) action invoke test/$(NAME) -P test.json -r --blocking -d
+
+test.json:
+       echo '{ "name": "Mike" }' >test.json
+
+package.done:
+       $(WSK) package update $(PACKAGE)
+       touch package.done
+
+.PHONY: deploy devel test clean
diff --git a/examples/swift-async-main-single/main.swift 
b/examples/swift-async-main-single/main.swift
new file mode 100644
index 0000000..164cdf6
--- /dev/null
+++ b/examples/swift-async-main-single/main.swift
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import Foundation
+import _Concurrency
+
+func main(args: Any) async -> Any {
+    do {
+        try await Task.sleep(nanoseconds: 1_000_000_000)
+        let newArgs = args as! [String:Any]
+        if let name = newArgs["name"] as? String {
+            return [ "greeting" : "Hello \(name)!" ]
+        } else {
+            return [ "greeting" : "Hello stranger!" ]
+        }
+    } catch {
+        return ["error:" : String(describing: error)]
+    }
+}
+
+func mainenv(args: Any) -> Any {
+    let env = ProcessInfo.processInfo.environment
+    var a = "???"
+    var b = "???"
+    var c = "???"
+    var d = "???"
+    var e = "???"
+    var f = "???"
+    if let v : String = env["__OW_API_HOST"] {
+        a = "\(v)"
+    }
+    if let v : String = env["__OW_API_KEY"] {
+        b = "\(v)"
+    }
+    if let v : String = env["__OW_NAMESPACE"] {
+        c = "\(v)"
+    }
+    if let v : String = env["__OW_ACTION_NAME"] {
+        d = "\(v)"
+    }
+    if let v : String = env["__OW_ACTIVATION_ID"] {
+        e = "\(v)"
+    }
+    if let v : String = env["__OW_DEADLINE"] {
+        f = "\(v)"
+    }
+    return ["api_host": a, "api_key": b, "namespace": c, "action_name": d, 
"activation_id": e, "deadline": f]
+}
diff --git a/settings.gradle 
b/examples/swift-async-main-zip/HelloSwift5/Package.swift
similarity index 58%
copy from settings.gradle
copy to examples/swift-async-main-zip/HelloSwift5/Package.swift
index 8079687..3b3e045 100644
--- a/settings.gradle
+++ b/examples/swift-async-main-zip/HelloSwift5/Package.swift
@@ -1,3 +1,6 @@
+// swift-tools-version:5.7
+// The swift-tools-version declares the minimum version of Swift required to 
build this package.
+
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
@@ -15,31 +18,20 @@
  * limitations under the License.
  */
 
-include 'tests'
-
-include 'core:swift51Action'
-
-include 'core:swift53Action'
-
-include 'core:swift54Action'
-
-rootProject.name = 'runtime-swift'
-
-gradle.ext.openwhisk = [
-        version: '1.0.1-SNAPSHOT'
-]
-
-gradle.ext.scala = [
-    version: '2.12.7',
-    depVersion  : '2.12',
-    compileFlags: ['-feature', '-unchecked', '-deprecation', 
'-Xfatal-warnings', '-Ywarn-unused-import']
-]
-
-gradle.ext.scalafmt = [
-    version: '1.5.0',
-    config: new File(rootProject.projectDir, '.scalafmt.conf')
-]
-
-gradle.ext.akka = [version : '2.6.12']
-gradle.ext.akka_http = [version : '10.2.4']
-
+import PackageDescription
+
+let package = Package(
+    name: "Action",
+    products: [
+      .executable(
+        name: "Action",
+        targets:  ["Action"]
+      )
+    ],
+    targets: [
+      .target(
+        name: "Action",
+        path: "."
+      )
+    ]
+)
diff --git a/settings.gradle 
b/examples/swift-async-main-zip/HelloSwift5/Sources/main.swift
similarity index 58%
copy from settings.gradle
copy to examples/swift-async-main-zip/HelloSwift5/Sources/main.swift
index 8079687..5cbbd7e 100644
--- a/settings.gradle
+++ b/examples/swift-async-main-zip/HelloSwift5/Sources/main.swift
@@ -15,31 +15,16 @@
  * limitations under the License.
  */
 
-include 'tests'
-
-include 'core:swift51Action'
-
-include 'core:swift53Action'
-
-include 'core:swift54Action'
-
-rootProject.name = 'runtime-swift'
-
-gradle.ext.openwhisk = [
-        version: '1.0.1-SNAPSHOT'
-]
-
-gradle.ext.scala = [
-    version: '2.12.7',
-    depVersion  : '2.12',
-    compileFlags: ['-feature', '-unchecked', '-deprecation', 
'-Xfatal-warnings', '-Ywarn-unused-import']
-]
-
-gradle.ext.scalafmt = [
-    version: '1.5.0',
-    config: new File(rootProject.projectDir, '.scalafmt.conf')
-]
-
-gradle.ext.akka = [version : '2.6.12']
-gradle.ext.akka_http = [version : '10.2.4']
-
+func main(args: Any) async -> Any {
+    do {
+        try await Task.sleep(nanoseconds: 1_000_000_000)
+        let newArgs = args as! [String:Any]
+        if let name = newArgs["name"] as? String {
+            return [ "greeting" : "Hello \(name)!" ]
+        } else {
+            return [ "greeting" : "Hello stranger!" ]
+        }
+    } catch {
+        return ["error:" : String(describing: error)]
+    }
+}
diff --git a/examples/swift-async-main-zip/Makefile 
b/examples/swift-async-main-zip/Makefile
new file mode 100644
index 0000000..6868e8b
--- /dev/null
+++ b/examples/swift-async-main-zip/Makefile
@@ -0,0 +1,56 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+OW_USER?=whisk
+OW_RUNTIME?=$(OW_USER)/action-swift-v5.7
+OW_COMPILER?=$(OW_USER)/action-swift-v5.7
+WSK?=wsk -i
+MAIN=main
+PACKAGE=test
+SRCS=HelloSwift5/Sources/$(MAIN).swift HelloSwift5/Package.swift
+NAME=swift-$(MAIN)-zip
+BINZIP=$(MAIN)-bin.zip
+SRCZIP=$(MAIN)-src.zip
+
+deploy: package.done $(BINZIP)
+       $(WSK) action update $(PACKAGE)/$(NAME) $(BINZIP) --main $(MAIN) 
--docker $(OW_RUNTIME)
+
+devel: package.done $(SRCZIP)
+       $(WSK) action update $(PACKAGE)/$(NAME) $(SRCZIP) --main $(MAIN) 
--docker $(OW_COMPILER)
+
+$(BINZIP): $(SRCS)
+       cd HelloSwift5 ; zip - -r * | docker run -i $(OW_COMPILER) -compile 
$(MAIN) >../$(BINZIP)
+
+$(SRCZIP): $(SRCS)
+       cd HelloSwift5 ; zip ../$(SRCZIP) -r *
+
+clean:
+       -$(WSK) action delete $(PACKAGE)/$(NAME)
+       -rm  $(BINZIP) $(SRCZIP) package.done test.json
+
+test: test.json
+       $(WSK) action invoke test/$(NAME) -r
+       $(WSK) action invoke test/$(NAME) -P test.json -r
+
+test.json:
+       echo '{ "name": "Mike" }' >test.json
+
+package.done:
+       $(WSK) package update $(PACKAGE)
+       touch package.done
+
+.PHONY: deploy devel test clean
diff --git a/settings.gradle b/settings.gradle
index 8079687..19a4a3e 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -23,6 +23,8 @@ include 'core:swift53Action'
 
 include 'core:swift54Action'
 
+include 'core:swift57Action'
+
 rootProject.name = 'runtime-swift'
 
 gradle.ext.openwhisk = [
diff --git a/tests/dat/actions/Makefile b/tests/dat/actions/Makefile
index a5d9055..8dba11b 100644
--- a/tests/dat/actions/Makefile
+++ b/tests/dat/actions/Makefile
@@ -16,8 +16,8 @@
 #
 
 OW_USER?=whisk
-OW_COMPILER?=$(OW_USER)/action-swift-v5.3
-OUT?=../../build/swift5.3
+OW_COMPILER?=$(OW_USER)/action-swift-v5.7
+OUT?=../../build/swift5.7
 define Build
        cd $(1); \
        docker run -i $(OW_COMPILER) -compile main <./Sources/main.swift 
>$(OUT)/$(1).zip
@@ -48,6 +48,9 @@ Swifty5:
 SwiftyCodable5:
        $(call BuildWithLib,SwiftyRequestCodable5)
 
+SwiftyCodable57:
+       $(call BuildWithLib,SwiftyRequestCodable57)
+
 all: Hello HelloCodable Swifty SwiftyCodable Hello5 HelloCodable5 Swifty5 
SwiftyCodable5
 
 .PHONY: Hello HelloCodable Swifty SwiftyCodable Hello5 HelloCodable5 Swifty5 
SwiftyCodable5
diff --git a/tests/dat/actions/SwiftyRequest5/Package.resolved 
b/tests/dat/actions/SwiftyRequest5/Package.resolved
deleted file mode 100644
index ff2bbd2..0000000
--- a/tests/dat/actions/SwiftyRequest5/Package.resolved
+++ /dev/null
@@ -1,79 +0,0 @@
-{
-  "object": {
-    "pins": [
-      {
-        "package": "async-http-client",
-        "repositoryURL": 
"https://github.com/swift-server/async-http-client.git";,
-        "state": {
-          "branch": null,
-          "revision": "51dc885a30ca704b02fa803099b0a9b5b38067b6",
-          "version": "1.0.0"
-        }
-      },
-      {
-        "package": "CircuitBreaker",
-        "repositoryURL": "https://github.com/IBM-Swift/CircuitBreaker.git";,
-        "state": {
-          "branch": null,
-          "revision": "e9345aa721ca4da428777f2e953b9ad534017675",
-          "version": "5.0.3"
-        }
-      },
-      {
-        "package": "LoggerAPI",
-        "repositoryURL": "https://github.com/IBM-Swift/LoggerAPI.git";,
-        "state": {
-          "branch": null,
-          "revision": "3357dd9526cdf9436fa63bb792b669e6efdc43da",
-          "version": "1.9.0"
-        }
-      },
-      {
-        "package": "swift-log",
-        "repositoryURL": "https://github.com/apple/swift-log.git";,
-        "state": {
-          "branch": null,
-          "revision": "74d7b91ceebc85daf387ebb206003f78813f71aa",
-          "version": "1.2.0"
-        }
-      },
-      {
-        "package": "swift-nio",
-        "repositoryURL": "https://github.com/apple/swift-nio.git";,
-        "state": {
-          "branch": null,
-          "revision": "bc661cbb771328e09faa65432628e9ff6fd333d5",
-          "version": "2.10.0"
-        }
-      },
-      {
-        "package": "swift-nio-extras",
-        "repositoryURL": "https://github.com/apple/swift-nio-extras.git";,
-        "state": {
-          "branch": null,
-          "revision": "ed97628fa310c314c4a5cd8038445054b2991f07",
-          "version": "1.3.1"
-        }
-      },
-      {
-        "package": "swift-nio-ssl",
-        "repositoryURL": "https://github.com/apple/swift-nio-ssl.git";,
-        "state": {
-          "branch": null,
-          "revision": "e5c1af45ac934ac0a6117b2927a51d845cf4f705",
-          "version": "2.4.3"
-        }
-      },
-      {
-        "package": "SwiftyRequest",
-        "repositoryURL": "https://github.com/IBM-Swift/SwiftyRequest.git";,
-        "state": {
-          "branch": null,
-          "revision": "34cf8de7c3920220392d557c8c84b9f06c8c3978",
-          "version": "3.1.0"
-        }
-      }
-    ]
-  },
-  "version": 1
-}
diff --git a/tests/dat/actions/SwiftyRequestAsyncCodable57/Package.resolved 
b/tests/dat/actions/SwiftyRequestAsyncCodable57/Package.resolved
new file mode 100644
index 0000000..888cd6c
--- /dev/null
+++ b/tests/dat/actions/SwiftyRequestAsyncCodable57/Package.resolved
@@ -0,0 +1,86 @@
+{
+  "pins" : [
+    {
+      "identity" : "async-http-client",
+      "kind" : "remoteSourceControl",
+      "location" : "https://github.com/swift-server/async-http-client.git";,
+      "state" : {
+        "revision" : "5bee16a79922e3efcb5cea06ecd27e6f8048b56b",
+        "version" : "1.13.1"
+      }
+    },
+    {
+      "identity" : "swift-atomics",
+      "kind" : "remoteSourceControl",
+      "location" : "https://github.com/apple/swift-atomics.git";,
+      "state" : {
+        "revision" : "ff3d2212b6b093db7f177d0855adbc4ef9c5f036",
+        "version" : "1.0.3"
+      }
+    },
+    {
+      "identity" : "swift-collections",
+      "kind" : "remoteSourceControl",
+      "location" : "https://github.com/apple/swift-collections.git";,
+      "state" : {
+        "revision" : "937e904258d22af6e447a0b72c0bc67583ef64a2",
+        "version" : "1.0.4"
+      }
+    },
+    {
+      "identity" : "swift-log",
+      "kind" : "remoteSourceControl",
+      "location" : "https://github.com/apple/swift-log.git";,
+      "state" : {
+        "revision" : "6fe203dc33195667ce1759bf0182975e4653ba1c",
+        "version" : "1.4.4"
+      }
+    },
+    {
+      "identity" : "swift-nio",
+      "kind" : "remoteSourceControl",
+      "location" : "https://github.com/apple/swift-nio.git";,
+      "state" : {
+        "revision" : "7e3b50b38e4e66f31db6cf4a784c6af148bac846",
+        "version" : "2.46.0"
+      }
+    },
+    {
+      "identity" : "swift-nio-extras",
+      "kind" : "remoteSourceControl",
+      "location" : "https://github.com/apple/swift-nio-extras.git";,
+      "state" : {
+        "revision" : "91dd2d61fb772e1311bb5f13b59266b579d77e42",
+        "version" : "1.15.0"
+      }
+    },
+    {
+      "identity" : "swift-nio-http2",
+      "kind" : "remoteSourceControl",
+      "location" : "https://github.com/apple/swift-nio-http2.git";,
+      "state" : {
+        "revision" : "d6656967f33ed8b368b38e4b198631fc7c484a40",
+        "version" : "1.23.1"
+      }
+    },
+    {
+      "identity" : "swift-nio-ssl",
+      "kind" : "remoteSourceControl",
+      "location" : "https://github.com/apple/swift-nio-ssl.git";,
+      "state" : {
+        "revision" : "4fb7ead803e38949eb1d6fabb849206a72c580f3",
+        "version" : "2.23.0"
+      }
+    },
+    {
+      "identity" : "swift-nio-transport-services",
+      "kind" : "remoteSourceControl",
+      "location" : "https://github.com/apple/swift-nio-transport-services.git";,
+      "state" : {
+        "revision" : "c0d9a144cfaec8d3d596aadde3039286a266c15c",
+        "version" : "1.15.0"
+      }
+    }
+  ],
+  "version" : 2
+}
diff --git a/settings.gradle 
b/tests/dat/actions/SwiftyRequestAsyncCodable57/Package.swift
similarity index 55%
copy from settings.gradle
copy to tests/dat/actions/SwiftyRequestAsyncCodable57/Package.swift
index 8079687..401dadb 100644
--- a/settings.gradle
+++ b/tests/dat/actions/SwiftyRequestAsyncCodable57/Package.swift
@@ -1,3 +1,6 @@
+// swift-tools-version:5.7
+// The swift-tools-version declares the minimum version of Swift required to 
build this package.
+
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
@@ -15,31 +18,27 @@
  * limitations under the License.
  */
 
-include 'tests'
-
-include 'core:swift51Action'
-
-include 'core:swift53Action'
-
-include 'core:swift54Action'
-
-rootProject.name = 'runtime-swift'
-
-gradle.ext.openwhisk = [
-        version: '1.0.1-SNAPSHOT'
-]
-
-gradle.ext.scala = [
-    version: '2.12.7',
-    depVersion  : '2.12',
-    compileFlags: ['-feature', '-unchecked', '-deprecation', 
'-Xfatal-warnings', '-Ywarn-unused-import']
-]
-
-gradle.ext.scalafmt = [
-    version: '1.5.0',
-    config: new File(rootProject.projectDir, '.scalafmt.conf')
-]
-
-gradle.ext.akka = [version : '2.6.12']
-gradle.ext.akka_http = [version : '10.2.4']
-
+import PackageDescription
+
+let package = Package(
+    name: "Action",
+    platforms: [
+        .macOS(.v12),
+    ],
+    products: [
+      .executable(
+        name: "Action",
+        targets:  ["Action"]
+      )
+    ],
+    dependencies: [
+      .package(url: "https://github.com/swift-server/async-http-client.git";, 
from: "1.9.0")
+    ],
+    targets: [
+      .executableTarget(
+        name: "Action",
+        dependencies: [.product(name: "AsyncHTTPClient", package: 
"async-http-client")],
+        path: "."
+      )
+    ]
+)
diff --git a/tests/dat/actions/SwiftyRequestAsyncCodable57/Sources/main.swift 
b/tests/dat/actions/SwiftyRequestAsyncCodable57/Sources/main.swift
new file mode 100644
index 0000000..acfcf1e
--- /dev/null
+++ b/tests/dat/actions/SwiftyRequestAsyncCodable57/Sources/main.swift
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import AsyncHTTPClient
+import Foundation
+import _Concurrency
+import NIOCore
+import NIOFoundationCompat
+
+enum RequestError: Error {
+    case requestError
+}
+struct AnInput: Codable {
+    let url: String?
+}
+
+struct AnOutput: Codable {
+    let args: [String: String]
+    let headers: [String: String]
+    let origin: String
+    let url: String
+}
+
+let httpClient = HTTPClient(eventLoopGroupProvider: .createNew)
+let decoder = JSONDecoder()
+
+func main(param: AnInput) async throws -> AnOutput {
+
+    let echoURL = param.url ?? "https://httpbin.org/get";
+    let request = HTTPClientRequest(url: echoURL)
+    let response = try await httpClient.execute(request, timeout: .seconds(3))
+    if response.status == .ok {
+        let bytes = try await response.body.collect(upTo: 1024 * 1024) // 1 MB 
Buffer
+        let data = Data(buffer: bytes)
+        return try decoder.decode(AnOutput.self, from: data)
+    } else {
+        throw RequestError.requestError
+    }
+}
diff --git a/tests/dat/actions/SwiftyRequestCodable5/Package.resolved 
b/tests/dat/actions/SwiftyRequestCodable5/Package.resolved
deleted file mode 100644
index ff2bbd2..0000000
--- a/tests/dat/actions/SwiftyRequestCodable5/Package.resolved
+++ /dev/null
@@ -1,79 +0,0 @@
-{
-  "object": {
-    "pins": [
-      {
-        "package": "async-http-client",
-        "repositoryURL": 
"https://github.com/swift-server/async-http-client.git";,
-        "state": {
-          "branch": null,
-          "revision": "51dc885a30ca704b02fa803099b0a9b5b38067b6",
-          "version": "1.0.0"
-        }
-      },
-      {
-        "package": "CircuitBreaker",
-        "repositoryURL": "https://github.com/IBM-Swift/CircuitBreaker.git";,
-        "state": {
-          "branch": null,
-          "revision": "e9345aa721ca4da428777f2e953b9ad534017675",
-          "version": "5.0.3"
-        }
-      },
-      {
-        "package": "LoggerAPI",
-        "repositoryURL": "https://github.com/IBM-Swift/LoggerAPI.git";,
-        "state": {
-          "branch": null,
-          "revision": "3357dd9526cdf9436fa63bb792b669e6efdc43da",
-          "version": "1.9.0"
-        }
-      },
-      {
-        "package": "swift-log",
-        "repositoryURL": "https://github.com/apple/swift-log.git";,
-        "state": {
-          "branch": null,
-          "revision": "74d7b91ceebc85daf387ebb206003f78813f71aa",
-          "version": "1.2.0"
-        }
-      },
-      {
-        "package": "swift-nio",
-        "repositoryURL": "https://github.com/apple/swift-nio.git";,
-        "state": {
-          "branch": null,
-          "revision": "bc661cbb771328e09faa65432628e9ff6fd333d5",
-          "version": "2.10.0"
-        }
-      },
-      {
-        "package": "swift-nio-extras",
-        "repositoryURL": "https://github.com/apple/swift-nio-extras.git";,
-        "state": {
-          "branch": null,
-          "revision": "ed97628fa310c314c4a5cd8038445054b2991f07",
-          "version": "1.3.1"
-        }
-      },
-      {
-        "package": "swift-nio-ssl",
-        "repositoryURL": "https://github.com/apple/swift-nio-ssl.git";,
-        "state": {
-          "branch": null,
-          "revision": "e5c1af45ac934ac0a6117b2927a51d845cf4f705",
-          "version": "2.4.3"
-        }
-      },
-      {
-        "package": "SwiftyRequest",
-        "repositoryURL": "https://github.com/IBM-Swift/SwiftyRequest.git";,
-        "state": {
-          "branch": null,
-          "revision": "34cf8de7c3920220392d557c8c84b9f06c8c3978",
-          "version": "3.1.0"
-        }
-      }
-    ]
-  },
-  "version": 1
-}
diff --git a/tests/dat/build.sh b/tests/dat/build.sh
index f9c2751..aace1b2 100755
--- a/tests/dat/build.sh
+++ b/tests/dat/build.sh
@@ -32,3 +32,9 @@ set -e
 ../../tools/build/compile5.sh  action-swift-v5.4 HelloSwift5Codable swift5.4 
"-v"
 ../../tools/build/compile5.sh  action-swift-v5.4 SwiftyRequest5 swift5.4 "-v"
 ../../tools/build/compile5.sh  action-swift-v5.4 SwiftyRequestCodable5 
swift5.4 "-v"
+
+../../tools/build/compile5.sh  action-swift-v5.7 HelloSwift5 swift5.7 "-v"
+../../tools/build/compile5.sh  action-swift-v5.7 HelloSwift5Codable swift5.7 
"-v"
+../../tools/build/compile5.sh  action-swift-v5.7 SwiftyRequest5 swift5.7 "-v"
+../../tools/build/compile5.sh  action-swift-v5.7 SwiftyRequestCodable5 
swift5.7 "-v"
+../../tools/build/compile5.sh  action-swift-v5.7 SwiftyRequestAsyncCodable57 
swift5.7 "-v"
diff --git 
a/tests/src/test/scala/runtime/actionContainers/Swift57ActionContainerTests.scala
 
b/tests/src/test/scala/runtime/actionContainers/Swift57ActionContainerTests.scala
new file mode 100644
index 0000000..e1c15a8
--- /dev/null
+++ 
b/tests/src/test/scala/runtime/actionContainers/Swift57ActionContainerTests.scala
@@ -0,0 +1,145 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package runtime.actionContainers
+
+import java.io.File
+
+import actionContainers.ResourceHelpers
+import org.junit.runner.RunWith
+import org.scalatest.junit.JUnitRunner
+import spray.json.{JsObject, JsString}
+
+@RunWith(classOf[JUnitRunner])
+class Swift57ActionContainerTests extends SwiftActionContainerTests {
+  override lazy val swiftContainerImageName = "action-swift-v5.7"
+  override lazy val swiftBinaryName = 
"tests/dat/build/swift5.7/HelloSwift5.zip"
+  lazy val partyCompile = "tests/dat/build/swift5.7/SwiftyRequest5.zip"
+  lazy val partyCompileCodable = 
"tests/dat/build/swift5.7/SwiftyRequestCodable5.zip"
+  lazy val partyCompileAsyncCodable = 
"tests/dat/build/swift5.7/SwiftyRequestAsyncCodable57.zip"
+
+  val httpCode = """
+                   | import Foundation
+                   | import Dispatch
+                   | #if canImport(FoundationNetworking)
+                   |  import FoundationNetworking
+                   | #endif
+                   | func main(args: Any) -> Any {
+                   |     var resp :[String:Any] = ["error":"getUrl failed"]
+                   |     let newArgs = args as! [String:Any]
+                   |     guard let urlStr = newArgs["getUrl"] as? String else {
+                   |         return ["error":"getUrl not found in action 
input"]
+                   |     }
+                   |     guard let url = URL(string: urlStr) else {
+                   |         return ["error":"invalid url string \(urlStr)"]
+                   |     }
+                   |     let request = URLRequest(url: url)
+                   |     let session = URLSession(configuration: .default)
+                   |     let semaphore = DispatchSemaphore(value: 0)
+                   |     let task = session.dataTask(with: request, 
completionHandler: {data, response, error -> Void in
+                   |         print("done with http request")
+                   |         if let error = error {
+                   |             print("There was an error \(error)")
+                   |         } else if let data = data,
+                   |             let response = response as? HTTPURLResponse,
+                   |             response.statusCode == 200 {
+                   |             do {
+                   |                 let respJson = try 
JSONSerialization.jsonObject(with: data)
+                   |                 if respJson is [String:Any] {
+                   |                     resp = respJson as! [String:Any]
+                   |                 } else {
+                   |                     resp = ["error":"Response from server 
is not a dictionary"]
+                   |                 }
+                   |             } catch {
+                   |                 resp = ["error":"Error creating json from 
response: \(error)"]
+                   |             }
+                   |         }
+                   |         semaphore.signal()
+                   |     })
+                   |     task.resume()
+                   |     _ = semaphore.wait(timeout: .distantFuture)
+                   |     return resp
+                   | }
+                 """.stripMargin
+
+  it should "support ability to use 3rd party packages like SwiftyRequest" in {
+    val zip = new File(partyCompile).toPath
+    val code = ResourceHelpers.readAsBase64(zip)
+
+    val (out, err) = withActionContainer() { c =>
+      val (initCode, initRes) = c.init(initPayload(code))
+      initCode should be(200)
+
+      val args = JsObject("message" -> (JsString("serverless")))
+      val (runCode, runRes) = c.run(runPayload(args))
+
+      runCode should be(200)
+      val json = runRes.get.fields.get("json")
+      json shouldBe Some(args)
+    }
+
+    checkStreams(out, err, {
+      case (o, e) =>
+        if (enforceEmptyOutputStream) o shouldBe empty
+        e shouldBe empty
+    })
+  }
+
+  it should "support ability to use escaping completion in Codable" in {
+    val zip = new File(partyCompileCodable).toPath
+    val code = ResourceHelpers.readAsBase64(zip)
+
+    val (out, err) = withActionContainer() { c =>
+      val (initCode, initRes) = c.init(initPayload(code, main = "mainCodable"))
+      initCode should be(200)
+
+      val (runCode, runRes) = c.run(runPayload(JsObject()))
+
+      runCode should be(200)
+      runRes.get.fields.get("greeting") shouldBe Some(JsString("success"))
+
+    }
+
+    checkStreams(out, err, {
+      case (o, e) =>
+        if (enforceEmptyOutputStream) o shouldBe empty
+        e shouldBe empty
+    })
+  }
+
+  it should "support ability to use async with Codable" in {
+    val zip = new File(partyCompileAsyncCodable).toPath
+    val code = ResourceHelpers.readAsBase64(zip)
+
+    val (out, err) = withActionContainer() { c =>
+      val (initCode, initRes) = c.init(initPayload(code, main = "mainCodable"))
+      initCode should be(200)
+
+      val (runCode, runRes) = c.run(runPayload(JsObject()))
+
+      runCode should be(200)
+      runRes.get.fields.get("url") shouldBe 
Some(JsString("https://httpbin.org/get";))
+
+    }
+
+    checkStreams(out, err, {
+      case (o, e) =>
+        if (enforceEmptyOutputStream) o shouldBe empty
+        e shouldBe empty
+    })
+  }
+}
diff --git a/settings.gradle 
b/tests/src/test/scala/runtime/actionContainers/Swift57CodableActionContainerTests.scala
similarity index 58%
copy from settings.gradle
copy to 
tests/src/test/scala/runtime/actionContainers/Swift57CodableActionContainerTests.scala
index 8079687..431bdc9 100644
--- a/settings.gradle
+++ 
b/tests/src/test/scala/runtime/actionContainers/Swift57CodableActionContainerTests.scala
@@ -15,31 +15,13 @@
  * limitations under the License.
  */
 
-include 'tests'
+package runtime.actionContainers
 
-include 'core:swift51Action'
-
-include 'core:swift53Action'
-
-include 'core:swift54Action'
-
-rootProject.name = 'runtime-swift'
-
-gradle.ext.openwhisk = [
-        version: '1.0.1-SNAPSHOT'
-]
-
-gradle.ext.scala = [
-    version: '2.12.7',
-    depVersion  : '2.12',
-    compileFlags: ['-feature', '-unchecked', '-deprecation', 
'-Xfatal-warnings', '-Ywarn-unused-import']
-]
-
-gradle.ext.scalafmt = [
-    version: '1.5.0',
-    config: new File(rootProject.projectDir, '.scalafmt.conf')
-]
-
-gradle.ext.akka = [version : '2.6.12']
-gradle.ext.akka_http = [version : '10.2.4']
+import org.junit.runner.RunWith
+import org.scalatest.junit.JUnitRunner
 
+@RunWith(classOf[JUnitRunner])
+class Swift57CodableActionContainerTests extends 
SwiftCodableActionContainerTests {
+  override lazy val swiftContainerImageName = "action-swift-v5.7"
+  override lazy val swiftBinaryName = 
"tests/dat/build/swift5.7/HelloSwift5Codable.zip"
+}
diff --git a/settings.gradle 
b/tests/src/test/scala/runtime/sdk/Swift57SDKTests.scala
similarity index 58%
copy from settings.gradle
copy to tests/src/test/scala/runtime/sdk/Swift57SDKTests.scala
index 8079687..d494d33 100644
--- a/settings.gradle
+++ b/tests/src/test/scala/runtime/sdk/Swift57SDKTests.scala
@@ -15,31 +15,12 @@
  * limitations under the License.
  */
 
-include 'tests'
+package runtime.sdk
 
-include 'core:swift51Action'
-
-include 'core:swift53Action'
-
-include 'core:swift54Action'
-
-rootProject.name = 'runtime-swift'
-
-gradle.ext.openwhisk = [
-        version: '1.0.1-SNAPSHOT'
-]
-
-gradle.ext.scala = [
-    version: '2.12.7',
-    depVersion  : '2.12',
-    compileFlags: ['-feature', '-unchecked', '-deprecation', 
'-Xfatal-warnings', '-Ywarn-unused-import']
-]
-
-gradle.ext.scalafmt = [
-    version: '1.5.0',
-    config: new File(rootProject.projectDir, '.scalafmt.conf')
-]
-
-gradle.ext.akka = [version : '2.6.12']
-gradle.ext.akka_http = [version : '10.2.4']
+import org.junit.runner.RunWith
+import org.scalatest.junit.JUnitRunner
 
+@RunWith(classOf[JUnitRunner])
+class Swift57SDKTests extends SwiftSDKTests {
+  override lazy val actionKind = "swift:5.7"
+}
diff --git a/tools/travis/build.sh b/tools/travis/build.sh
index bf6e83b..3239f4a 100755
--- a/tools/travis/build.sh
+++ b/tools/travis/build.sh
@@ -49,6 +49,7 @@ TERM=dumb ./gradlew \
 :core:swift51Action:distDocker \
 :core:swift53Action:distDocker \
 :core:swift54Action:distDocker \
+:core:swift57Action:distDocker \
 -PdockerImagePrefix=${IMAGE_PREFIX}
 
 # Compile test files
diff --git a/tools/travis/publish.sh b/tools/travis/publish.sh
index d2eebdd..cd1694e 100755
--- a/tools/travis/publish.sh
+++ b/tools/travis/publish.sh
@@ -36,6 +36,8 @@ elif [ ${RUNTIME_VERSION} == "5.3" ]; then
   RUNTIME="swift53Action"
 elif [ ${RUNTIME_VERSION} == "5.4" ]; then
   RUNTIME="swift54Action"
+elif [ ${RUNTIME_VERSION} == "5.7" ]; then
+  RUNTIME="swift57Action"
 fi
 
 if [[ ! -z ${DOCKER_USER} ]] && [[ ! -z ${DOCKER_PASSWORD} ]]; then

Reply via email to