Skip to content

Commit c4d08d0

Browse files
Add Support for Swift 5.7 (#153)
1 parent 2ddbd2d commit c4d08d0

File tree

32 files changed

+1822
-171
lines changed

32 files changed

+1822
-171
lines changed

.github/workflows/ci.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,8 @@ jobs:
101101
./gradlew :core:swift53Action:distDocker -PdockerRegistry=docker.io -PdockerImagePrefix=openwhisk -PdockerImageTag=$SHORT_COMMIT
102102
./gradlew :core:swift54Action:distDocker -PdockerRegistry=docker.io -PdockerImagePrefix=openwhisk -PdockerImageTag=nightly
103103
./gradlew :core:swift54Action:distDocker -PdockerRegistry=docker.io -PdockerImagePrefix=openwhisk -PdockerImageTag=$SHORT_COMMIT
104+
./gradlew :core:swift57Action:distDocker -PdockerRegistry=docker.io -PdockerImagePrefix=openwhisk -PdockerImageTag=nightly
105+
./gradlew :core:swift57Action:distDocker -PdockerRegistry=docker.io -PdockerImagePrefix=openwhisk -PdockerImageTag=$SHORT_COMMIT
104106
- name: Push Release Images
105107
if: ${{ env.PUSH_RELEASE == 'true' }}
106108
working-directory: runtime
@@ -113,5 +115,7 @@ jobs:
113115
RUNTIME="swift53Action"
114116
elif [ ${RUNTIME_VERSION} == "5.4" ]; then
115117
RUNTIME="swift54Action"
118+
elif [ ${RUNTIME_VERSION} == "5.7" ]; then
119+
RUNTIME="swift57Action"
116120
fi
117121
./gradlew :core:$RUNTIME:distDocker -PdockerRegistry=docker.io -PdockerImagePrefix=openwhisk -PdockerImageTag=$IMAGE_TAG

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,3 +81,6 @@ test.json
8181
*.done
8282
examples/*/*.zip
8383
ActionLoop/
84+
85+
#Swift
86+
**/.swiftpm/

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
#
1717

1818
sudo: required
19-
dist: xenial
19+
dist: jammy
2020
jdk: openjdk8
2121
language: java
2222
services:

README.md

Lines changed: 122 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
- [Swift 5.1 CHANGELOG.md](core/swift51Action/CHANGELOG.md)
2727
- [Swift 5.3 CHANGELOG.md](core/swift53Action/CHANGELOG.md)
2828
- [Swift 5.4 CHANGELOG.md](core/swift54Action/CHANGELOG.md)
29+
- [Swift 5.7 CHANGELOG.md](core/swift57Action/CHANGELOG.md)
2930

3031
## Quick Swift Action
3132
### Simple swift action hello.swift
@@ -45,7 +46,7 @@ func main(args: Any) -> Any {
4546

4647
For the return result, not only support `dictionary`, but also support `array`
4748

48-
So a very simple `hello array` function woule be:
49+
So a very simple `hello array` function would be:
4950

5051
```swift
5152
func main(args: Any) -> Any {
@@ -63,7 +64,7 @@ So the function can be:
6364
return args
6465
}
6566
```
66-
When invokes above action, we can pass an array object as the input parameter.
67+
When invoking the above action, we can pass an array object as the input parameter.
6768

6869
## Swift 5.x support
6970

@@ -85,13 +86,13 @@ func main(input: Employee, respondWith: (Employee?, Error?) -> Void) -> Void {
8586
respondWith(input, nil)
8687
}
8788
```
88-
```
89+
```bash
8990
wsk action update helloCodableAsync helloCodableAsync.swift swift:5.1
9091
```
91-
```
92+
```bash
9293
ok: updated action helloCodableAsync
9394
```
94-
```
95+
```bash
9596
wsk action invoke helloCodableAsync -r -p id 73 -p name Andrea
9697
```
9798
```json
@@ -125,13 +126,13 @@ func main(input: Employee, respondWith: (Employee?, Error?) -> Void) -> Void {
125126
}
126127
}
127128
```
128-
```
129+
```bash
129130
wsk action update helloCodableError helloCodableError.swift swift:5.1
130131
```
131-
```
132+
```bash
132133
ok: updated action helloCodableError
133134
```
134-
```
135+
```bash
135136
wsk action invoke helloCodableError -b -p id 51 -p name Carlos
136137
```
137138
```json
@@ -159,14 +160,125 @@ To avoid the cold-start delay, you can compile your Swift file into a binary and
159160

160161
Use the docker container and pass the single source file as stdin.
161162
Pass the name of the method to the flag `-compile`
162-
```
163+
```bash
163164
docker run -i openwhisk/action-swift-v5.1 -compile main <main.swift >../action.zip
164165
```
165166

166167
### Compiling Swift 5.1 multiple files with dependencies
167168
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`.
168-
```
169+
```bash
169170
zip - -r * | docker run -i openwhisk/action-swift-v5.1 -compile main >../action.zip
170171
```
171172

172173
For more build examples see [here](./examples/)
174+
175+
# Swift 5.7
176+
177+
In addition to previous ways of defining an action is now possible to use throwing async/await inside the action.
178+
179+
### Async throwing Action with Any Input and Any Output
180+
181+
```swift
182+
func action(args: Any) async throws -> Any {
183+
//async code sleep for 1 sec
184+
try await Task.sleep(nanoseconds: 1_000_000_000)
185+
186+
let newArgs = args as! [String:Any]
187+
if let name = newArgs["name"] as? String {
188+
return [ "greeting" : "Hello \(name)!" ]
189+
} else {
190+
return [ "greeting" : "Hello stranger!" ]
191+
}
192+
}
193+
```
194+
195+
### Async throwing Action with a Codable Input and a Codable Output
196+
197+
```swift
198+
struct Input: Codable {
199+
let name: String?
200+
}
201+
202+
struct Output: Codable {
203+
let count: Int
204+
}
205+
206+
func action(input: Input) async throws -> Output? {
207+
try await Task.sleep(nanoseconds: 1_000_000_000)
208+
if let name = input.name {
209+
return Output(count: name.count)
210+
} else {
211+
return Output(count: 0)
212+
}
213+
}
214+
```
215+
216+
### Async throwing Action with Codable Output
217+
218+
```swift
219+
struct Input: Codable {
220+
let name: String?
221+
}
222+
223+
struct Output: Codable {
224+
let count: Int
225+
}
226+
227+
func action() async throws -> Output? {
228+
try await Task.sleep(nanoseconds: 1_000_000_000)
229+
return Output(count: 0)
230+
}
231+
```
232+
233+
234+
### Example of an async throwing Action with a Codable Input and a Codable Output
235+
236+
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`.
237+
In case of failure, the runtime will return an error.
238+
239+
```swift
240+
import AsyncHTTPClient
241+
import Foundation
242+
import _Concurrency
243+
import NIOCore
244+
import NIOFoundationCompat
245+
246+
enum RequestError: Error {
247+
case requestError
248+
}
249+
struct AnInput: Codable {
250+
let url: String?
251+
}
252+
253+
struct AnOutput: Codable {
254+
let args: [String: String]
255+
let headers: [String: String]
256+
let origin: String
257+
let url: String
258+
}
259+
260+
let httpClient = HTTPClient(eventLoopGroupProvider: .createNew)
261+
let decoder = JSONDecoder()
262+
263+
func main(param: AnInput) async throws -> AnOutput {
264+
265+
let echoURL = param.url ?? "https://httpbin.org/get"
266+
let request = HTTPClientRequest(url: echoURL)
267+
let response = try await httpClient.execute(request, timeout: .seconds(3))
268+
if response.status == .ok {
269+
let bytes = try await response.body.collect(upTo: 1024 * 1024) // 1 MB Buffer
270+
let data = Data(buffer: bytes)
271+
return try decoder.decode(AnOutput.self, from: data)
272+
} else {
273+
throw RequestError.requestError
274+
}
275+
}
276+
```
277+
278+
The full swift package is [here](/tests/dat/actions/SwiftyRequestAsyncCodable57/).
279+
280+
Note that the package of this action contains a dependency from `AsynHTTPClient`, in such case, it's preferred to build the action.
281+
282+
```shell
283+
zip - -r * | docker run -i openwhisk/action-swift-v5.7 -compile main >../action.zip
284+
```

ansible/files/runtimes.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,20 @@
7171
"attachmentName": "codefile",
7272
"attachmentType": "text/plain"
7373
}
74+
},
75+
{
76+
"kind": "swift:5.7",
77+
"default": false,
78+
"image": {
79+
"prefix": "testing",
80+
"name": "action-swift-v5.7",
81+
"tag": "latest"
82+
},
83+
"deprecated": false,
84+
"attached": {
85+
"attachmentName": "codefile",
86+
"attachmentType": "text/plain"
87+
}
7488
}
7589
]
7690
},

core/swift57Action/CHANGELOG.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<!--
2+
#
3+
# Licensed to the Apache Software Foundation (ASF) under one or more
4+
# contributor license agreements. See the NOTICE file distributed with
5+
# this work for additional information regarding copyright ownership.
6+
# The ASF licenses this file to You under the Apache License, Version 2.0
7+
# (the "License"); you may not use this file except in compliance with
8+
# the License. You may obtain a copy of the License at
9+
#
10+
# http://www.apache.org/licenses/LICENSE-2.0
11+
#
12+
# Unless required by applicable law or agreed to in writing, software
13+
# distributed under the License is distributed on an "AS IS" BASIS,
14+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
# See the License for the specific language governing permissions and
16+
# limitations under the License.
17+
#
18+
-->
19+
20+
# Apache OpenWhisk Swift 5.7 Runtime Container
21+
22+
- Support for swift async/await
23+
24+
## 1.17.0
25+
- Next Apache Release

core/swift57Action/Dockerfile

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
#
2+
# Licensed to the Apache Software Foundation (ASF) under one or more
3+
# contributor license agreements. See the NOTICE file distributed with
4+
# this work for additional information regarding copyright ownership.
5+
# The ASF licenses this file to You under the Apache License, Version 2.0
6+
# (the "License"); you may not use this file except in compliance with
7+
# the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
#
17+
18+
# build go proxy from source
19+
FROM golang:1.18 AS builder_source
20+
ARG GO_PROXY_GITHUB_USER=apache
21+
ARG GO_PROXY_GITHUB_BRANCH=master
22+
RUN git clone --branch ${GO_PROXY_GITHUB_BRANCH} \
23+
https://github.com/${GO_PROXY_GITHUB_USER}/openwhisk-runtime-go /src ; \
24+
cd /src ; env GO111MODULE=on CGO_ENABLED=0 go build main/proxy.go && \
25+
mv proxy /bin/proxy
26+
27+
# or build it from a release
28+
FROM golang:1.18 AS builder_release
29+
ARG GO_PROXY_RELEASE_VERSION=1.18@1.20.0
30+
RUN curl -sL https://github.com/apache/openwhisk-runtime-go/archive/{$GO_PROXY_RELEASE_VERSION}.tar.gz | tar xzf - \
31+
&& cd openwhisk-runtime-go-*/main \
32+
&& GO111MODULE=on CGO_ENABLED=0 go build -o /bin/proxy
33+
34+
FROM swift:5.7.2
35+
36+
# select the builder to use
37+
ARG GO_PROXY_BUILD_FROM=release
38+
39+
RUN rm -rf /var/lib/apt/lists/* \
40+
&& apt-get clean && apt-get -qq update \
41+
&& apt-get install -y --no-install-recommends locales python3 vim libssl-dev libicu-dev \
42+
&& rm -rf /var/lib/apt/lists/* \
43+
&& locale-gen en_US.UTF-8
44+
45+
ENV LANG="en_US.UTF-8" \
46+
LANGUAGE="en_US:en" \
47+
LC_ALL="en_US.UTF-8"
48+
49+
RUN mkdir -p /swiftAction
50+
WORKDIR /swiftAction
51+
52+
COPY --from=builder_source /bin/proxy /bin/proxy_source
53+
COPY --from=builder_release /bin/proxy /bin/proxy_release
54+
RUN mv /bin/proxy_${GO_PROXY_BUILD_FROM} /bin/proxy
55+
ADD swiftbuild.py /bin/compile
56+
ADD swiftbuild.py.launcher.swift /bin/compile.launcher.swift
57+
COPY _Whisk.swift /swiftAction/Sources/
58+
COPY Package.swift /swiftAction/
59+
COPY swiftbuildandlink.sh /swiftAction/
60+
COPY main.swift /swiftAction/Sources/
61+
RUN swift build -c release; \
62+
touch /swiftAction/Sources/main.swift; \
63+
rm /swiftAction/.build/release/Action
64+
65+
ENV OW_COMPILER=/bin/compile
66+
ENTRYPOINT [ "/bin/proxy" ]

core/swift57Action/Package.swift

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// swift-tools-version:5.7
2+
// The swift-tools-version declares the minimum version of Swift required to build this package.
3+
4+
/*
5+
* Licensed to the Apache Software Foundation (ASF) under one or more
6+
* contributor license agreements. See the NOTICE file distributed with
7+
* this work for additional information regarding copyright ownership.
8+
* The ASF licenses this file to You under the Apache License, Version 2.0
9+
* (the "License"); you may not use this file except in compliance with
10+
* the License. You may obtain a copy of the License at
11+
*
12+
* http://www.apache.org/licenses/LICENSE-2.0
13+
*
14+
* Unless required by applicable law or agreed to in writing, software
15+
* distributed under the License is distributed on an "AS IS" BASIS,
16+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17+
* See the License for the specific language governing permissions and
18+
* limitations under the License.
19+
*/
20+
21+
import PackageDescription
22+
23+
let package = Package(
24+
name: "Action",
25+
platforms: [
26+
.macOS(.v12),
27+
],
28+
products: [
29+
.executable(
30+
name: "Action",
31+
targets: ["Action"]
32+
)
33+
],
34+
targets: [
35+
.executableTarget(
36+
name: "Action",
37+
path: "."
38+
)
39+
]
40+
)

0 commit comments

Comments
 (0)