remove Swift 3.1.1 runtime (#114)

Remove Swift 3.1.1 action runtime and associated tests and
documentation.  This runtime version has long since been replaced by
Swift 4.x and no longer appears to even build (unavailable
dependencies cause Docker build to hang).

Also add CHANGELOG for Swift 4.2 and 5.1 and update NOTICE date.
diff --git a/.gitignore b/.gitignore
index 557d0a1..9bf0539 100644
--- a/.gitignore
+++ b/.gitignore
@@ -67,7 +67,6 @@
 ansible/roles/nginx/files/*cert.pem
 
 # .zip files must be explicited whitelisted
-!tests/dat/build/swift311/HelloSwift3.zip
 !tests/dat/build/swift4.1/HelloSwift4.zip
 !tests/dat/build/swift4.1/SwiftyRequest.zip
 !tests/dat/build/swift4.1/SwiftyRequestCodable.zip
diff --git a/NOTICE.txt b/NOTICE.txt
index c46a931..de6fcf7 100644
--- a/NOTICE.txt
+++ b/NOTICE.txt
@@ -1,5 +1,5 @@
 Apache OpenWhisk Runtime Swift
-Copyright 2016-2019 The Apache Software Foundation
+Copyright 2016-2020 The Apache Software Foundation
 
 This product includes software developed at
 The Apache Software Foundation (http://www.apache.org/).
diff --git a/README.md b/README.md
index 4056260..4b75fba 100644
--- a/README.md
+++ b/README.md
@@ -23,9 +23,9 @@
 
 
 ## Changelogs
-- [Swift 3.1.1 CHANGELOG.md](core/swift3.1.1Action/CHANGELOG.md)
 - [Swift 4.1   CHANGELOG.md](core/swift41Action/CHANGELOG.md)
 - [Swift 4.2   CHANGELOG.md](core/swift42Action/CHANGELOG.md)
+- [Swift 5.1   CHANGELOG.md](core/swift51Action/CHANGELOG.md)
 
 ## Quick Swift Action
 ### Simple swift action hello.swift
@@ -337,36 +337,6 @@
   wsk action invoke helloSwiftly --blocking
   ```
 
-### Migrating from Swift 3 to Swift 4
-
-### Helper compile.sh helper script
-When compiling and packaging your swift 4 action, there are a couple of differences.
-All your source code needs to be copied to `/swift4Action/spm-build/Sources/Action/` instead of `/swift3Action/spm-build/`
-You Package.swift needs to have the first line with a comment indicating swift4 tooling and format
-```
-// swift-tools-version:4.0
-```
-For swift 4 you need specify additional information in Package.swift such as `products` with executable name `Action` and `targets`
-
-You can take a look at the helper script [tools/build/compile.sh](tools/build/compile.sh) to compile and zip your Actions.
-Having a project directory `Hello` under a directory `actions` like the following:
-```
-actions/Hello/Package.swift
-actions/Hello/Sources/main.swift
-```
-Change to the parent directory then run the compile script specify the project directory, the kind `swift:3.1.1` or `swift:4.2` and any swiftc build flags like the following:
-```
-cd actions/
-runtime-swift/tools/build/compile.sh Hello swift:4.2 -v
-```
-This will produce a zip `build/swift4/Hello.zip`
-
-### SwiftyJSON using single source action file
-If you have a swift:3.1.1 action not compile, just as source using the `SwiftyJSON` package, you need to precompile your action and specify the version of SwiftyJSON you wan to use for swift:4.2 kind action.
-Take into account that starting with Swift 4 there is better support to manage JSON data natively.
-
-Note: This is only applicable to the base image provided for the Swift 4 runtime, other downstream such as IBM Cloud Functions extending this image might provide additional SDK and packages including `SwiftyJSON` and IBM Watson SDK, check the vendor documentation for more specific information about packages and versions.
-
 ### Building the Swift4 Image
 ```
 ./gradlew core:swift40Action:distDocker
diff --git a/ansible/environments/local/group_vars/all b/ansible/environments/local/group_vars/all
index b4826e8..ca6c049 100644
--- a/ansible/environments/local/group_vars/all
+++ b/ansible/environments/local/group_vars/all
@@ -40,15 +40,6 @@
         name: "nodejs6action"
       deprecated: false
     swift:
-    - kind: "swift:3"
-      image:
-        name: "swift3action"
-      deprecated: true
-    - kind: "swift:3.1.1"
-      default: false
-      image:
-        name: "action-swift-v3.1.1"
-      deprecated: false
     - kind: "swift:4.1"
       default: false
       image:
diff --git a/core/swift3.1.1Action/Dockerfile b/core/swift3.1.1Action/Dockerfile
deleted file mode 100644
index d10e086..0000000
--- a/core/swift3.1.1Action/Dockerfile
+++ /dev/null
@@ -1,46 +0,0 @@
-#
-# 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.
-#
-
-# Dockerfile for swift actions, overrides and extends ActionRunner from actionProxy
-# This Dockerfile is partially based on: https://github.com/IBM-Swift/swift-ubuntu-docker/blob/master/swift-development/Dockerfile
-FROM ibmcom/swift-ubuntu:3.1.1
-
-# Set WORKDIR
-WORKDIR /
-
-# Upgrade and install basic Python dependencies
-RUN apt-get -y update \
- && apt-get -y install --fix-missing python2.7 python-gevent python-flask zip
-
-# Add the action proxy
-ADD https://raw.githubusercontent.com/apache/openwhisk-runtime-docker/dockerskeleton%401.3.3/core/actionProxy/actionproxy.py /actionProxy/actionproxy.py
-
-# Add files needed to build and run action
-RUN mkdir -p /swift3Action
-ADD epilogue.swift /swift3Action
-ADD buildandrecord.py /swift3Action
-ADD swift3runner.py /swift3Action
-ADD spm-build /swift3Action/spm-build
-
-
-# Build kitura net
-RUN touch /swift3Action/spm-build/main.swift
-RUN python /swift3Action/buildandrecord.py && rm /swift3Action/spm-build/.build/release/Action
-#RUN cd /swift3Action/spm-build; swift build -v -c release; rm /swift3Action/spm-build/.build/release/Action
-ENV FLASK_PROXY_PORT 8080
-
-CMD ["/bin/bash", "-c", "cd /swift3Action && PYTHONIOENCODING='utf-8' python -u swift3runner.py"]
diff --git a/core/swift3.1.1Action/build.gradle b/core/swift3.1.1Action/build.gradle
deleted file mode 100644
index 678d0ad..0000000
--- a/core/swift3.1.1Action/build.gradle
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * 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.
- */
-
-ext.dockerImageName = 'action-swift-v3.1.1'
-apply from: '../../gradle/docker.gradle'
diff --git a/core/swift3.1.1Action/buildandrecord.py b/core/swift3.1.1Action/buildandrecord.py
deleted file mode 100755
index 6f0ab75..0000000
--- a/core/swift3.1.1Action/buildandrecord.py
+++ /dev/null
@@ -1,77 +0,0 @@
-"""Python to generate build script.
-
-/*
- * 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 sys
-from subprocess import check_output
-
-# Settings
-COMPILE_PREFIX = "/usr/bin/swiftc -module-name Action "
-LINKER_PREFIX =  "/usr/bin/swiftc -Xlinker '-rpath=$ORIGIN' '-L/swift3Action/spm-build/.build/release' -o '/swift3Action/spm-build/.build/release/Action'"
-GENERATED_BUILD_SCRIPT = "/swift3Action/spm-build/swiftbuildandlink.sh"
-SPM_DIRECTORY = "/swift3Action/spm-build"
-BUILD_COMMAND = ["swift", "build", "-v", "-c", "release"]
-
-# Build Swift package and capture step trace
-print("Building action")
-out = check_output(BUILD_COMMAND, cwd=SPM_DIRECTORY)
-print("action built. Decoding compile and link commands")
-
-# Look for compile and link commands in step trace
-compileCommand = None
-linkCommand = None
-
-buildInstructions = out.decode("utf-8").splitlines()
-
-for instruction in buildInstructions:
-    if instruction.startswith(COMPILE_PREFIX):
-        compileCommand = instruction
-
-        # add flag to quiet warnings
-        compileCommand += " -suppress-warnings"
-
-    elif instruction.startswith(LINKER_PREFIX):
-        linkCommand = instruction
-
-# if found, create build script, otherwise exit with error
-if compileCommand is not None and linkCommand is not None:
-    print("Generated OpenWhisk Compile command: %s" % compileCommand)
-    print("=========")
-    print("Generated OpenWhisk Link command: %s" % linkCommand)
-
-    with open(GENERATED_BUILD_SCRIPT, "a") as buildScript:
-        buildScript.write("#!/bin/bash\n")
-        buildScript.write("echo \"Compiling\"\n")
-        buildScript.write("%s\n" % compileCommand)
-        buildScript.write("swiftStatus=$?\n")
-        buildScript.write("echo swiftc status is $swiftStatus\n")
-        buildScript.write("if [[ \"$swiftStatus\" -eq \"0\" ]]; then\n")
-        buildScript.write("echo \"Linking\"\n")
-        buildScript.write("%s\n" % linkCommand)
-        buildScript.write("else\n")
-        buildScript.write(">2& echo \"Action did not compile\"\n")
-        buildScript.write("exit 1\n")
-        buildScript.write("fi")
-
-    os.chmod(GENERATED_BUILD_SCRIPT, 0o777)
-    sys.exit(0)
-else:
-    print("Cannot generate build script: compile or link command not found")
-    sys.exit(1)
diff --git a/core/swift3.1.1Action/epilogue.swift b/core/swift3.1.1Action/epilogue.swift
deleted file mode 100644
index fd1b6a8..0000000
--- a/core/swift3.1.1Action/epilogue.swift
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * 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.
- */
-
-// Deliberate whitespaces above.
-
-/* This code is appended to user-supplied action code.
- It reads from the standard input, deserializes into JSON and invokes the
- main function. Currently, actions print strings to stdout. This can evolve once
- JSON serialization is available in Foundation. */
-
-import Foundation
-
-#if os(Linux)
-    import Glibc
-#endif
-
-func _whisk_json2dict(txt: String) -> [String:Any]? {
-    if let data = txt.data(using: String.Encoding.utf8, allowLossyConversion: true) {
-        do {
-            return WhiskJsonUtils.jsonDataToDictionary(jsonData: data)
-        } catch {
-            return nil
-        }
-    }
-    return nil
-}
-
-
-func _run_main(mainFunction: ([String: Any]) -> [String: Any]) -> Void {
-    let env = ProcessInfo.processInfo.environment
-    let inputStr: String = env["WHISK_INPUT"] ?? "{}"
-
-    if let parsed = _whisk_json2dict(txt: inputStr) {
-        let result = mainFunction(parsed)
-
-        if result is [String:Any] {
-            do {
-                if let respString = WhiskJsonUtils.dictionaryToJsonString(jsonDict: result) {
-                    print("\(respString)")
-                } else {
-                    print("Error converting \(result) to JSON string")
-                    #if os(Linux)
-                        fputs("Error converting \(result) to JSON string", stderr)
-                    #endif
-                }
-            } catch {
-                print("Error serializing response \(error)")
-                #if os(Linux)
-                    fputs("Error serializing response \(error)", stderr)
-                #endif
-            }
-        } else {
-            print("Cannot serialize response: \(result)")
-            #if os(Linux)
-                fputs("Cannot serialize response: \(result)", stderr)
-            #endif
-        }
-    } else {
-        print("Error: couldn't parse JSON input.")
-        #if os(Linux)
-            fputs("Error: couldn't parse JSON input.", stderr)
-        #endif
-    }
-}
diff --git a/core/swift3.1.1Action/spm-build/Package.swift b/core/swift3.1.1Action/spm-build/Package.swift
deleted file mode 100644
index 3931ba4..0000000
--- a/core/swift3.1.1Action/spm-build/Package.swift
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * 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 PackageDescription
-
-let package = Package(
-    name: "Action",
-        dependencies: [
-            .Package(url: "https://github.com/IBM-Swift/CCurl.git", "0.2.3"),
-            .Package(url: "https://github.com/IBM-Swift/Kitura-net.git", "1.7.10"),
-            .Package(url: "https://github.com/IBM-Swift/SwiftyJSON.git", "15.0.1"),
-            .Package(url: "https://github.com/watson-developer-cloud/swift-sdk.git", "0.16.0")
-        ]
-)
diff --git a/core/swift3.1.1Action/spm-build/_Whisk.swift b/core/swift3.1.1Action/spm-build/_Whisk.swift
deleted file mode 100644
index 59efc78..0000000
--- a/core/swift3.1.1Action/spm-build/_Whisk.swift
+++ /dev/null
@@ -1,275 +0,0 @@
-/*
- * 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 KituraNet
-import Dispatch
-
-class Whisk {
-    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 {
-            sendWhiskRequest(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
-    }
-
-    /**
-     * Initializes with host, port and authKey determined from environment variables
-     * __OW_API_HOST and __OW_API_KEY, respectively.
-     */
-    private class func initializeCommunication() -> (httpType: String, host : String, port : Int16, authKey : String) {
-        let env = ProcessInfo.processInfo.environment
-
-        var edgeHost : String!
-        if let edgeHostEnv : String = env["__OW_API_HOST"] {
-            edgeHost = "\(edgeHostEnv)"
-        } else {
-            fatalError("__OW_API_HOST environment variable was not set.")
-        }
-
-        var protocolIndex = edgeHost.startIndex
-
-        //default to https
-        var httpType = "https://"
-        var port : Int16 = 443
-
-        // check if protocol is included in environment variable
-        if edgeHost.hasPrefix("https://") {
-            protocolIndex = edgeHost.index(edgeHost.startIndex, offsetBy: 8)
-        } else if edgeHost.hasPrefix("http://") {
-            protocolIndex = edgeHost.index(edgeHost.startIndex, offsetBy: 7)
-            httpType = "http://"
-            port = 80
-        }
-
-        let hostname = edgeHost.substring(from: protocolIndex)
-        let hostComponents = hostname.components(separatedBy: ":")
-
-        let host = hostComponents[0]
-
-        if hostComponents.count == 2 {
-            port = Int16(hostComponents[1])!
-        }
-
-        var authKey = "authKey"
-        if let authKeyEnv : String = env["__OW_API_KEY"] {
-            authKey = authKeyEnv
-        }
-
-        return (httpType, host, port, authKey)
-    }
-
-    // actually do the call to the specified OpenWhisk URI path
-    private class func sendWhiskRequest(uriPath: String, params : [String:Any], method: String, group: DispatchGroup, callback : @escaping([String:Any]) -> Void) {
-        let communicationDetails = initializeCommunication()
-
-        let loginData: Data = communicationDetails.authKey.data(using: String.Encoding.utf8, allowLossyConversion: false)!
-        let base64EncodedAuthKey  = loginData.base64EncodedString(options: NSData.Base64EncodingOptions(rawValue: 0))
-
-        let headers = ["Content-Type" : "application/json",
-                       "Authorization" : "Basic \(base64EncodedAuthKey)"]
-
-        guard let encodedPath = uriPath.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed) else {
-            callback(["error": "Error encoding uri path to make openwhisk REST call."])
-            return
-        }
-
-        // TODO vary the schema based on the port?
-        let requestOptions = [ClientRequest.Options.schema(communicationDetails.httpType),
-                              ClientRequest.Options.method(method),
-                              ClientRequest.Options.hostname(communicationDetails.host),
-                              ClientRequest.Options.port(communicationDetails.port),
-                              ClientRequest.Options.path(encodedPath),
-                              ClientRequest.Options.headers(headers),
-                              ClientRequest.Options.disableSSLVerification]
-
-        let request = HTTP.request(requestOptions) { response in
-
-            // exit group after we are done
-            defer {
-                group.leave()
-            }
-
-            if response != nil {
-                do {
-                    // this is odd, but that's just how KituraNet has you get
-                    // the response as NSData
-                    var jsonData = Data()
-                    try response!.readAllData(into: &jsonData)
-
-                    switch WhiskJsonUtils.getJsonType(jsonData: jsonData) {
-                    case .Dictionary:
-                        if let resp = WhiskJsonUtils.jsonDataToDictionary(jsonData: jsonData) {
-                            callback(resp)
-                        } else {
-                            callback(["error": "Could not parse a valid JSON response."])
-                        }
-                    case .Array:
-                        if WhiskJsonUtils.jsonDataToArray(jsonData: jsonData) != nil {
-                            callback(["error": "Response is an array, expecting dictionary."])
-                        } else {
-                            callback(["error": "Could not parse a valid JSON response."])
-                        }
-                    case .Undefined:
-                        callback(["error": "Could not parse a valid JSON response."])
-                    }
-
-                } catch {
-                    callback(["error": "Could not parse a valid JSON response."])
-                }
-            } else {
-                callback(["error": "Did not receive a response."])
-            }
-        }
-
-        // turn params into JSON data
-        if let jsonData = WhiskJsonUtils.dictionaryToJsonString(jsonDict: params) {
-            request.write(from: jsonData)
-            request.end()
-        } else {
-            callback(["error": "Could not parse parameters."])
-            group.leave()
-        }
-
-    }
-
-    /**
-     * This function is currently unused but ready when we want to switch to using URLSession instead of KituraNet.
-     */
-    private class func postUrlSession(uriPath: String, params : [String:Any], group: DispatchGroup, callback : @escaping([String:Any]) -> Void) {
-        let communicationDetails = initializeCommunication()
-
-        guard let encodedPath = uriPath.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed) else {
-            callback(["error": "Error encoding uri path to make openwhisk REST call."])
-            return
-        }
-
-        let urlStr = "\(communicationDetails.httpType)\(communicationDetails.host):\(communicationDetails.port)\(encodedPath)"
-
-        if let url = URL(string: urlStr) {
-            var request = URLRequest(url: url)
-            request.httpMethod = "POST"
-
-            do {
-                request.addValue("application/json", forHTTPHeaderField: "Content-Type")
-                request.httpBody = try JSONSerialization.data(withJSONObject: params)
-
-                let loginData: Data = communicationDetails.authKey.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(["error":error.localizedDescription])
-                    } else {
-
-                        if let data = data {
-                            do {
-                                let respJson = try JSONSerialization.jsonObject(with: data)
-                                if respJson is [String:Any] {
-                                    callback(respJson as! [String:Any])
-                                } else {
-                                    callback(["error":" response from server is not a dictionary"])
-                                }
-                            } catch {
-                                callback(["error":"Error creating json from response: \(error)"])
-                            }
-                        }
-                    }
-                })
-
-                task.resume()
-            } catch {
-                callback(["error":"Got error creating params body: \(error)"])
-            }
-        }
-    }
-
-    // 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 {
-            // allow both "/theName" and "theName"
-            let name = qualifiedName.hasPrefix(delimiter) ? segments[1] : segments[0]
-            return (defaultNamespace, name)
-        }
-    }
-}
diff --git a/core/swift3.1.1Action/spm-build/_WhiskJSONUtils.swift b/core/swift3.1.1Action/spm-build/_WhiskJSONUtils.swift
deleted file mode 100644
index 58fbe29..0000000
--- a/core/swift3.1.1Action/spm-build/_WhiskJSONUtils.swift
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * 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 SwiftyJSON
-
-enum WhiskJsonType {
-    case Dictionary
-    case Array
-    case Undefined
-}
-
-class WhiskJsonUtils {
-
-    class func getJsonType(jsonData: Data) -> WhiskJsonType {
-        do {
-            let json = try JSONSerialization.jsonObject(with: jsonData, options: [])
-            if json is [String:Any] {
-                return .Dictionary
-            } else if json is [Any] {
-                return .Array
-            } else {
-                return .Undefined
-            }
-        } catch {
-            print("Error converting JSON data to dictionary \(error)")
-            return .Undefined
-        }
-    }
-
-    class func jsonDataToArray(jsonData: Data) -> [Any]? {
-        do {
-            let arr = try JSONSerialization.jsonObject(with: jsonData, options: [])
-            return (arr as? [Any])
-        } catch {
-            print("Error converting JSON data to dictionary \(error)")
-            return nil
-        }
-    }
-
-    class func jsonDataToDictionary(jsonData: Data) -> [String:Any]? {
-        do {
-            let dic = try JSONSerialization.jsonObject(with: jsonData, options: [])
-            return dic as? [String:Any]
-        } catch {
-            print("Error converting JSON data to dictionary \(error)")
-            return nil
-        }
-    }
-
-    // use SwiftyJSON to serialize JSON object because of bug in Linux Swift 3.0
-    // https://github.com/IBM-Swift/SwiftRuntime/issues/230
-    class func dictionaryToJsonString(jsonDict: [String:Any]) -> String? {
-        if JSONSerialization.isValidJSONObject(jsonDict) {
-            do {
-                let jsonData = try JSONSerialization.data(withJSONObject: jsonDict, options: [])
-                if let jsonStr = String(data: jsonData, encoding: String.Encoding.utf8) {
-                    return jsonStr
-                } else {
-                    print("Error serializing data to JSON, data conversion returns nil string")
-                }
-            } catch {
-                print(("\(error)"))
-            }
-        } else {
-            print("Error serializing JSON, data does not appear to be valid JSON")
-        }
-        return nil
-    }
-
-    class func dictionaryToData(jsonDict: [String:Any]) -> Data? {
-        let json: JSON = JSON(jsonDict)
-
-        do {
-            let data: Data = try json.rawData()
-            return data
-        } catch {
-            print("Cannot convert Dictionary to Data")
-            return nil
-        }
-    }
-
-    class func arrayToJsonString(jsonArray: [Any]) -> String? {
-        let json: JSON = JSON(jsonArray)
-
-        if let jsonStr = json.rawString() {
-            let trimmed = jsonStr.replacingOccurrences(of: "\n", with: "").replacingOccurrences(of: "\r", with: "")
-            return trimmed
-        } else {
-            return nil
-        }
-    }
-
-    class func arrayToData(jsonArray: [Any]) -> Data? {
-        let json: JSON = JSON(jsonArray)
-
-        do {
-            let data: Data = try json.rawData()
-            return data
-        } catch {
-            print("Cannot convert Array to Data")
-            return nil
-        }
-    }
-
-    private class func escapeDict(json: [String:Any]) -> [String:Any] {
-        var escaped = [String:Any]()
-
-        for (k,v) in json {
-            if v is String {
-                let str = (v as! String).replacingOccurrences(of:"\"", with:"\\\"")
-                escaped[k] = str
-            } else if v is [String:Any] {
-                escaped[k] = escapeDict(json: v as! [String : Any])
-            } else if v is [Any] {
-                escaped[k] = escapeArray(json: v as! [Any])
-            } else {
-                escaped[k] = v
-            }
-        }
-        return escaped
-    }
-
-    private class func escapeArray(json: [Any]) -> [Any] {
-        var escaped = [Any]()
-
-        for v in json {
-            if v is String {
-                let str = (v as! String).replacingOccurrences(of:"\"", with:"\\\"")
-                escaped.append(str)
-            } else if v is [String:Any] {
-                let dic = escapeDict(json: v as! [String:Any])
-                escaped.append(dic)
-            } else if v is [Any] {
-                let arr = escapeArray(json: v as! [Any])
-                escaped.append(arr)
-            } else {
-                escaped.append(v)
-            }
-        }
-
-        return escaped
-    }
-
-    private class func escape(json: Any) -> Any? {
-        if json is [String:Any] {
-            let escapeObj = json as! [String:Any]
-            return escapeDict(json: escapeObj)
-        } else if json is [Any] {
-            let escapeObj = json as! [Any]
-            return escapeArray(json: escapeObj)
-        } else {
-            return nil
-        }
-    }
-}
diff --git a/core/swift3.1.1Action/swift3runner.py b/core/swift3.1.1Action/swift3runner.py
deleted file mode 100644
index f41456d..0000000
--- a/core/swift3.1.1Action/swift3runner.py
+++ /dev/null
@@ -1,114 +0,0 @@
-"""Python proxy to run Swift action.
-
-/*
- * 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 os
-import glob
-import sys
-import subprocess
-import codecs
-import json
-sys.path.append('../actionProxy')
-from actionproxy import ActionRunner, main, setRunner  # noqa
-
-SRC_EPILOGUE_FILE = '/swift3Action/epilogue.swift'
-DEST_SCRIPT_FILE = '/swift3Action/spm-build/main.swift'
-DEST_SCRIPT_DIR = '/swift3Action/spm-build'
-DEST_BIN_FILE = '/swift3Action/spm-build/.build/release/Action'
-
-BUILD_PROCESS = ['./swiftbuildandlink.sh']
-
-
-class Swift3Runner(ActionRunner):
-
-    def __init__(self):
-        ActionRunner.__init__(self, DEST_SCRIPT_FILE, DEST_BIN_FILE)
-
-    # remove pre-existing binary before receiving a new binary
-    def preinit(self):
-        try:
-            os.remove(self.binary)
-        except: pass
-
-    def epilogue(self, init_message):
-        # skip if executable already exists (was unzipped)
-        if os.path.isfile(self.binary):
-            return
-
-        if 'main' in init_message:
-            main_function = init_message['main']
-        else:
-            main_function = 'main'
-        # make sure there is a main.swift file
-        open(DEST_SCRIPT_FILE, 'a').close()
-
-        with codecs.open(DEST_SCRIPT_FILE, 'a', 'utf-8') as fp:
-            os.chdir(DEST_SCRIPT_DIR)
-            for file in glob.glob("*.swift"):
-                if file not in ["Package.swift", "main.swift", "_WhiskJSONUtils.swift", "_Whisk.swift"]:
-                    with codecs.open(file, 'r', 'utf-8') as f:
-                        fp.write(f.read())
-            with codecs.open(SRC_EPILOGUE_FILE, 'r', 'utf-8') as ep:
-                fp.write(ep.read())
-
-            fp.write('_run_main(mainFunction: %s)\n' % main_function)
-
-    def build(self, init_message):
-        # short circuit the build, if there already exists a binary
-        # from the zip file
-        if os.path.isfile(self.binary):
-            # file may not have executable permission, set it
-            os.chmod(self.binary, 0o555)
-            return
-
-        p = subprocess.Popen(
-            BUILD_PROCESS,
-            stdout=subprocess.PIPE,
-            stderr=subprocess.PIPE,
-            cwd=DEST_SCRIPT_DIR)
-
-        # run the process and wait until it completes.
-        # stdout/stderr will not be None because we passed PIPEs to Popen
-        (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')
-
-        if o:
-            sys.stdout.write(o)
-            sys.stdout.flush()
-
-        if e:
-            sys.stderr.write(e)
-            sys.stderr.flush()
-
-    def env(self, message):
-        env = ActionRunner.env(self, message)
-        args = message.get('value', {}) if message else {}
-        env['WHISK_INPUT'] = json.dumps(args)
-        return env
-
-
-if __name__ == '__main__':
-    setRunner(Swift3Runner())
-    main()
diff --git a/core/swift3.1.1Action/CHANGELOG.md b/core/swift42Action/CHANGELOG.md
similarity index 62%
rename from core/swift3.1.1Action/CHANGELOG.md
rename to core/swift42Action/CHANGELOG.md
index ff871fb..8d9137a 100644
--- a/core/swift3.1.1Action/CHANGELOG.md
+++ b/core/swift42Action/CHANGELOG.md
@@ -17,26 +17,10 @@
 #
 -->
 
-# Apache OpenWhisk Swift 3.1 Runtime Container
+# Apache OpenWhisk Swift 4.2 Runtime Container
 
-## 1.0.3
-Changes:
-  - Update base image to openwhisk/dockerskeleton:1.3.3
-
-## 1.0.2
-Changes:
-  - Update base image to openwhisk/dockerskeleton:1.3.2
-
-## 1.0.1
-Changes:
-  - Update base image to openwhisk/dockerskeleton:1.3.1
-
-## 1.0.0
-Initial Swift 3.1 image
-  - Image name: `openwhisk/action-swift-v3.1.1`
-  - Kind is: `swift:3.1.1`
-
-Swift runtime version: [3.1.1](https://github.com/IBM-Swift/swift-ubuntu-docker/blob/58ee2502030deaa7273e3924b9b59495a929b66f/swift-development/Dockerfile)
+## 1.13.0-incubating
+ - Initial Release
 
 Packages included:
   - No packages included, use Package.swift and pre-compile action.
diff --git a/core/swift51Action/CHANGELOG.md b/core/swift51Action/CHANGELOG.md
new file mode 100644
index 0000000..b55b5f5
--- /dev/null
+++ b/core/swift51Action/CHANGELOG.md
@@ -0,0 +1,21 @@
+<!--
+#
+# 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.1 Runtime Container
+
diff --git a/settings.gradle b/settings.gradle
index 75ce138..c3edc42 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -17,8 +17,6 @@
 
 include 'tests'
 
-include 'core:swift3.1.1Action'
-
 include 'core:swift41Action'
 
 include 'core:swift42Action'
diff --git a/tests/build.gradle b/tests/build.gradle
index 952f18a..1ae5a4b 100644
--- a/tests/build.gradle
+++ b/tests/build.gradle
@@ -42,13 +42,3 @@
 tasks.withType(ScalaCompile) {
     scalaCompileOptions.additionalParameters = gradle.scala.compileFlags
 }
-
-task testSwift4(type: Test) {
-    exclude 'runtime/sdk/Swift311**'
-    exclude 'runtime/actionContainers/Swift311**'
-}
-
-task testSwift5(type: Test) {
-    exclude 'runtime/sdk/Swift311**'
-    exclude 'runtime/actionContainers/Swift311**'
-}
diff --git a/tests/src/test/scala/runtime/actionContainers/Swift311ActionContainerTests.scala b/tests/src/test/scala/runtime/actionContainers/Swift311ActionContainerTests.scala
deleted file mode 100644
index dd26b96..0000000
--- a/tests/src/test/scala/runtime/actionContainers/Swift311ActionContainerTests.scala
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * 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 org.junit.runner.RunWith
-import org.scalatest.junit.JUnitRunner
-import spray.json.JsObject
-import spray.json.JsString
-@RunWith(classOf[JUnitRunner])
-class Swift311ActionContainerTests extends SwiftActionContainerTests {
-
-  override lazy val swiftContainerImageName = "action-swift-v3.1.1"
-  override lazy val swiftBinaryName = "tests/dat/build/swift311/HelloSwift3.zip"
-
-  // issue https://github.com/apache/openwhisk-runtime-swift/issues/74
-  override val testLargeInput = TestConfig("", skipTest = true)
-
-  lazy val watsonCode = """
-        | import AlchemyDataNewsV1
-        | import ConversationV1
-        | import DiscoveryV1
-        | import DocumentConversionV1
-        | import NaturalLanguageClassifierV1
-        | import NaturalLanguageUnderstandingV1
-        | import PersonalityInsightsV3
-        | import RetrieveAndRankV1
-        | import ToneAnalyzerV3
-        | import TradeoffAnalyticsV1
-        | import VisualRecognitionV3
-        |
-        | func main(args: [String:Any]) -> [String:Any] {
-        |     return ["message": "I compiled and was able to import Watson SDKs"]
-        | }
-    """.stripMargin
-
-  val httpCode = """
-         | import KituraNet
-         | import Foundation
-         | import Dispatch
-         | func main(args:[String: Any]) -> [String:Any] {
-         |       let retries = 3
-         |       var resp = [String:Any]()
-         |       var attempts = 0
-         |       if let url = args["getUrl"] as? String {
-         |           while attempts < retries {
-         |               let group = DispatchGroup()
-         |               let queue = DispatchQueue.global(qos: .default)
-         |               group.enter()
-         |               queue.async {
-         |                   HTTP.get(url, callback: { response in
-         |                       if let response = response {
-         |                           do {
-         |                               var jsonData = Data()
-         |                               try response.readAllData(into: &jsonData)
-         |                               if let dic = WhiskJsonUtils.jsonDataToDictionary(jsonData: jsonData) {
-         |                                   resp = dic
-         |                               } else {
-         |                                   resp = ["error":"response from server is not JSON"]
-         |                               }
-         |                           } catch {
-         |                              resp["error"] = error.localizedDescription
-         |                           }
-         |                       }
-         |                       group.leave()
-         |                   })
-         |               }
-         |            switch group.wait(timeout: DispatchTime.distantFuture) {
-         |                case DispatchTimeoutResult.success:
-         |                    resp["attempts"] = attempts
-         |                    return resp
-         |                case DispatchTimeoutResult.timedOut:
-         |                    attempts = attempts + 1
-         |            }
-         |        }
-         |     }
-         |     return ["status":"Exceeded \(retries) attempts, aborting."]
-         | }
-       """.stripMargin
-
-  it should "properly use KituraNet and Dispatch" in {
-    val (out, err) = withActionContainer() { c =>
-      val code = """
-          | import KituraNet
-          | import Foundation
-          | import Dispatch
-          | func main(args:[String: Any]) -> [String:Any] {
-          |       let retries = 3
-          |       var resp = [String:Any]()
-          |       var attempts = 0
-          |       if let url = args["getUrl"] as? String {
-          |           while attempts < retries {
-          |               let group = DispatchGroup()
-          |               let queue = DispatchQueue.global(qos: .default)
-          |               group.enter()
-          |               queue.async {
-          |                   HTTP.get(url, callback: { response in
-          |                       if let response = response {
-          |                           do {
-          |                               var jsonData = Data()
-          |                               try response.readAllData(into: &jsonData)
-          |                               if let dic = WhiskJsonUtils.jsonDataToDictionary(jsonData: jsonData) {
-          |                                   resp = dic
-          |                               } else {
-          |                                   resp = ["error":"response from server is not JSON"]
-          |                               }
-          |                           } catch {
-          |                              resp["error"] = error.localizedDescription
-          |                           }
-          |                       }
-          |                       group.leave()
-          |                   })
-          |               }
-          |            switch group.wait(timeout: DispatchTime.distantFuture) {
-          |                case DispatchTimeoutResult.success:
-          |                    resp["attempts"] = attempts
-          |                    return resp
-          |                case DispatchTimeoutResult.timedOut:
-          |                    attempts = attempts + 1
-          |            }
-          |        }
-          |     }
-          |     return ["status":"Exceeded \(retries) attempts, aborting."]
-          | }
-      """.stripMargin
-
-      val (initCode, _) = c.init(initPayload(code))
-
-      initCode should be(200)
-
-      val argss = List(JsObject("getUrl" -> JsString("https://openwhisk.ng.bluemix.net/api/v1")))
-
-      for (args <- argss) {
-        val (runCode, out) = c.run(runPayload(args))
-        runCode should be(200)
-      }
-    }
-
-    // in side try catch finally print (out file)
-    // in catch block an error has occurred, get docker logs and print
-    // throw
-
-    checkStreams(out, err, {
-      case (o, e) =>
-        if (enforceEmptyOutputStream) o shouldBe empty
-        e shouldBe empty
-    })
-  }
-
-  it should "make Watson SDKs available to action authors" in {
-    val (out, err) = withActionContainer() { c =>
-      val code = watsonCode
-
-      val (initCode, _) = c.init(initPayload(code))
-
-      initCode should be(200)
-
-      val (runCode, out) = c.run(runPayload(JsObject()))
-      runCode should be(200)
-    }
-
-    checkStreams(out, err, {
-      case (o, e) =>
-        if (enforceEmptyOutputStream) o shouldBe empty
-        e shouldBe empty
-    })
-  }
-
-  // TODO
-  // skip for swift 4.2, it responds with 502 on init, stderr doesn't contain compile errors
-  // compile errors are contained in result
-  it should "log compilation errors" in {
-    val (out, err) = withActionContainer() { c =>
-      val code = """
-                   | 10 PRINT "Hello!"
-                   | 20 GOTO 10
-                 """.stripMargin
-
-      val (initCode, _) = c.init(initPayload(code))
-      initCode should not be (200)
-    }
-
-    checkStreams(out, err, {
-      case (o, e) =>
-        if (enforceEmptyOutputStream) o shouldBe empty
-        e.toLowerCase should include("error")
-    })
-  }
-
-  // TODO
-  // swift 4.2 exceptions executable exiting doesn't return error from web proxy or ends container
-  // the action times out
-  it should "return some error on action error" in {
-    val (out, err) = withActionContainer() { c =>
-      val code = """
-                   | // You need an indirection, or swiftc detects the div/0
-                   | // at compile-time. Smart.
-                   | func div(x: Int, y: Int) -> Int {
-                   |     return x/y
-                   | }
-                   | func main(args: [String: Any]) -> [String: Any] {
-                   |     return [ "divBy0": div(x:5, y:0) ]
-                   | }
-                 """.stripMargin
-
-      val (initCode, _) = c.init(initPayload(code))
-      initCode should be(200)
-
-      val (runCode, runRes) = c.run(runPayload(JsObject()))
-      runCode should be(502)
-
-      runRes shouldBe defined
-      runRes.get.fields.get("error") shouldBe defined
-    }
-
-    checkStreams(out, err, {
-      case (o, e) =>
-        if (enforceEmptyOutputStream) o shouldBe empty
-        if (enforceEmptyOutputStream) e shouldBe empty
-    })
-  }
-}
diff --git a/tests/src/test/scala/runtime/sdk/Swift311SDKTests.scala b/tests/src/test/scala/runtime/sdk/Swift311SDKTests.scala
deleted file mode 100644
index 7cf9b06..0000000
--- a/tests/src/test/scala/runtime/sdk/Swift311SDKTests.scala
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * 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.sdk
-
-import org.junit.runner.RunWith
-import org.scalatest.junit.JUnitRunner
-
-@RunWith(classOf[JUnitRunner])
-class Swift311SDKTests extends SwiftSDKTests {
-  override lazy val actionKind = "swift:3.1.1"
-}
diff --git a/tools/build/compile.sh b/tools/build/compile.sh
index 42d5fca..f3ad0b7 100755
--- a/tools/build/compile.sh
+++ b/tools/build/compile.sh
@@ -27,13 +27,7 @@
     exit 2
 fi
 
-BASE_PATH="/swift3Action"
-DEST_SOURCE="$BASE_PATH/spm-build"
-RUNTIME="openwhisk/action-swift-v3.1.1"
-BUILD_FLAGS=""
-if [ ${2} == "swift:3.1.1" ]; then
-  OUTPUT_DIR="build/swift311"
-elif [ ${2} == "swift:4.1" ]; then
+if [ ${2} == "swift:4.1" ]; then
   RUNTIME="openwhisk/action-swift-v4.1"
   BASE_PATH="/swift4Action"
   DEST_SOURCE="/$BASE_PATH/spm-build/Sources/Action"
diff --git a/tools/travis/publish.sh b/tools/travis/publish.sh
index c7db0b0..6bfce5a 100755
--- a/tools/travis/publish.sh
+++ b/tools/travis/publish.sh
@@ -30,9 +30,7 @@
 RUNTIME_VERSION=$2
 IMAGE_TAG=$3
 
-if [ ${RUNTIME_VERSION} == "3.1.1" ]; then
-  RUNTIME="swift3.1.1Action"
-elif [ ${RUNTIME_VERSION} == "4.1" ]; then
+if [ ${RUNTIME_VERSION} == "4.1" ]; then
   RUNTIME="swift41Action"
 elif [ ${RUNTIME_VERSION} == "4.2" ]; then
   RUNTIME="swift42Action"
diff --git a/tools/travis/test.sh b/tools/travis/test.sh
index 5882ddf..a5b249d 100755
--- a/tools/travis/test.sh
+++ b/tools/travis/test.sh
@@ -27,4 +27,4 @@
 export OPENWHISK_HOME=$WHISKDIR
 cd ${ROOTDIR}
 TERM=dumb ./gradlew :tests:checkScalafmtAll
-TERM=dumb ./gradlew :tests:testSwift4
+TERM=dumb ./gradlew :tests:test