Skip to content

Commit 9d23b67

Browse files
authored
Merge branch 'main' into cancel-next-invocation
2 parents 7d5257c + 7aa746f commit 9d23b67

26 files changed

+906
-450
lines changed

Diff for: .github/workflows/integration_tests.yml

+13-2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ on:
1919
type: boolean
2020
description: "Boolean to enable the compilation of examples. Defaults to true."
2121
default: true
22+
archive_plugin_examples:
23+
type: string
24+
description: "The list of examples to run through the archive plugin test. Pass a String with a valid JSON array such as \"[ 'HelloWorld', 'APIGateway' ]\""
25+
required: true
26+
default: ""
2227
archive_plugin_enabled:
2328
type: boolean
2429
description: "Boolean to enable the test of the archive plugin. Defaults to true."
@@ -54,7 +59,7 @@ jobs:
5459
# We are using only one Swift version
5560
swift:
5661
- image: ${{ inputs.matrix_linux_swift_container_image }}
57-
swift_version: "6.0.1-amazonlinux2"
62+
swift_version: "6.0.3-amazonlinux2"
5863
container:
5964
image: ${{ matrix.swift.image }}
6065
steps:
@@ -98,6 +103,10 @@ jobs:
98103
name: Test archive plugin
99104
if: ${{ inputs.archive_plugin_enabled }}
100105
runs-on: ubuntu-latest
106+
strategy:
107+
fail-fast: false
108+
matrix:
109+
examples: ${{ fromJson(inputs.archive_plugin_examples) }}
101110
steps:
102111
- name: Checkout repository
103112
uses: actions/checkout@v4
@@ -107,8 +116,10 @@ jobs:
107116
# https://github.com/actions/checkout/issues/766
108117
run: git config --global --add safe.directory ${GITHUB_WORKSPACE}
109118
- name: Test the archive plugin
119+
env:
120+
EXAMPLE: ${{ matrix.examples }}
110121
run: |
111-
.github/workflows/scripts/check-archive-plugin.sh
122+
.github/workflows/scripts/check-archive-plugin.sh
112123
113124
check-foundation:
114125
name: No dependencies on Foundation

Diff for: .github/workflows/pull_request.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ jobs:
3636
# We pass the list of examples here, but we can't pass an array as argument
3737
# Instead, we pass a String with a valid JSON array.
3838
# The workaround is mentioned here https://github.com/orgs/community/discussions/11692
39-
examples: "[ 'APIGateway', 'APIGateway+LambdaAuthorizer', 'BackgroundTasks', 'HelloJSON', 'HelloWorld', 'S3_AWSSDK', 'S3_Soto', 'Streaming', 'Testing', 'Tutorial' ]"
40-
39+
examples: "[ 'APIGateway', 'APIGateway+LambdaAuthorizer', 'BackgroundTasks', 'HelloJSON', 'HelloWorld', 'ResourcesPackaging', 'S3_AWSSDK', 'S3_Soto', 'Streaming', 'Testing', 'Tutorial' ]"
40+
archive_plugin_examples: "[ 'HelloWorld', 'ResourcesPackaging' ]"
4141
archive_plugin_enabled: true
4242

4343
swift-6-language-mode:

Diff for: .github/workflows/scripts/check-archive-plugin.sh

+13-3
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,17 @@
1313
##
1414
##===----------------------------------------------------------------------===##
1515

16-
EXAMPLE=HelloWorld
16+
log() { printf -- "** %s\n" "$*" >&2; }
17+
error() { printf -- "** ERROR: %s\n" "$*" >&2; }
18+
fatal() { error "$@"; exit 1; }
19+
20+
test -n "${EXAMPLE:-}" || fatal "EXAMPLE unset"
21+
1722
OUTPUT_DIR=.build/plugins/AWSLambdaPackager/outputs/AWSLambdaPackager
1823
OUTPUT_FILE=${OUTPUT_DIR}/MyLambda/bootstrap
1924
ZIP_FILE=${OUTPUT_DIR}/MyLambda/MyLambda.zip
2025

21-
pushd Examples/${EXAMPLE} || exit 1
26+
pushd "Examples/${EXAMPLE}" || exit 1
2227

2328
# package the example (docker and swift toolchain are installed on the GH runner)
2429
LAMBDA_USE_LOCAL_DEPS=../.. swift package archive --allow-network-connections docker || exit 1
@@ -33,5 +38,10 @@ file "${OUTPUT_FILE}" | grep --silent ELF
3338
# does the ZIP file contain the bootstrap?
3439
unzip -l "${ZIP_FILE}" | grep --silent bootstrap
3540

36-
echo "✅ The archive plugin is OK"
41+
# if EXAMPLE is ResourcesPackaging, check if the ZIP file contains hello.txt
42+
if [ "$EXAMPLE" == "ResourcesPackaging" ]; then
43+
unzip -l "${ZIP_FILE}" | grep --silent hello.txt
44+
fi
45+
46+
echo "✅ The archive plugin is OK with example ${EXAMPLE}"
3747
popd || exit 1

Diff for: .licenseignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,5 @@ Package.resolved
3333
*.yaml
3434
*.yml
3535
**/.npmignore
36-
**/*.json
36+
**/*.json
37+
**/*.txt

Diff for: Examples/CDK/infra/package-lock.json

+11-11
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: Examples/ResourcesPackaging/.gitignore

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
.DS_Store
2+
/.build
3+
/Packages
4+
xcuserdata/
5+
DerivedData/
6+
.swiftpm/configuration/registries.json
7+
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
8+
.netrc

Diff for: Examples/ResourcesPackaging/Package.swift

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// swift-tools-version: 6.0
2+
// The swift-tools-version declares the minimum version of Swift required to build this package.
3+
4+
import PackageDescription
5+
6+
// needed for CI to test the local version of the library
7+
import struct Foundation.URL
8+
9+
let package = Package(
10+
name: "ResourcesPackaging",
11+
platforms: [.macOS(.v15)],
12+
products: [
13+
.executable(name: "MyLambda", targets: ["MyLambda"])
14+
],
15+
dependencies: [
16+
.package(url: "https://github.com/swift-server/swift-aws-lambda-runtime.git", branch: "main")
17+
],
18+
targets: [
19+
.executableTarget(
20+
name: "MyLambda",
21+
dependencies: [
22+
.product(name: "AWSLambdaRuntime", package: "swift-aws-lambda-runtime")
23+
],
24+
path: ".",
25+
resources: [
26+
.process("hello.txt")
27+
]
28+
)
29+
]
30+
)
31+
32+
if let localDepsPath = Context.environment["LAMBDA_USE_LOCAL_DEPS"],
33+
localDepsPath != "",
34+
let v = try? URL(fileURLWithPath: localDepsPath).resourceValues(forKeys: [.isDirectoryKey]),
35+
v.isDirectory == true
36+
{
37+
// when we use the local runtime as deps, let's remove the dependency added above
38+
let indexToRemove = package.dependencies.firstIndex { dependency in
39+
if case .sourceControl(
40+
name: _,
41+
location: "https://github.com/swift-server/swift-aws-lambda-runtime.git",
42+
requirement: _
43+
) = dependency.kind {
44+
return true
45+
}
46+
return false
47+
}
48+
if let indexToRemove {
49+
package.dependencies.remove(at: indexToRemove)
50+
}
51+
52+
// then we add the dependency on LAMBDA_USE_LOCAL_DEPS' path (typically ../..)
53+
print("[INFO] Compiling against swift-aws-lambda-runtime located at \(localDepsPath)")
54+
package.dependencies += [
55+
.package(name: "swift-aws-lambda-runtime", path: localDepsPath)
56+
]
57+
}

Diff for: Examples/ResourcesPackaging/Sources/main.swift

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the SwiftAWSLambdaRuntime open source project
4+
//
5+
// Copyright (c) 2025 Apple Inc. and the SwiftAWSLambdaRuntime project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
// See CONTRIBUTORS.txt for the list of SwiftAWSLambdaRuntime project authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
import AWSLambdaRuntime
16+
import Foundation
17+
18+
let runtime = LambdaRuntime {
19+
(event: String, context: LambdaContext) in
20+
guard let fileURL = Bundle.module.url(forResource: "hello", withExtension: "txt") else {
21+
fatalError("no file url")
22+
}
23+
return try String(contentsOf: fileURL, encoding: .utf8)
24+
}
25+
26+
try await runtime.run()

Diff for: Examples/ResourcesPackaging/hello.txt

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Hello World

Diff for: Package.swift

+3-3
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ let package = Package(
1717
.library(name: "AWSLambdaTesting", targets: ["AWSLambdaTesting"]),
1818
],
1919
dependencies: [
20-
.package(url: "https://github.com/apple/swift-nio.git", from: "2.76.0"),
20+
.package(url: "https://github.com/apple/swift-nio.git", from: "2.77.0"),
2121
.package(url: "https://github.com/apple/swift-log.git", from: "1.5.4"),
2222
],
2323
targets: [
@@ -89,11 +89,11 @@ let package = Package(
8989
.executableTarget(
9090
name: "MockServer",
9191
dependencies: [
92+
.product(name: "Logging", package: "swift-log"),
9293
.product(name: "NIOHTTP1", package: "swift-nio"),
9394
.product(name: "NIOCore", package: "swift-nio"),
9495
.product(name: "NIOPosix", package: "swift-nio"),
95-
],
96-
swiftSettings: [.swiftLanguageMode(.v5)]
96+
]
9797
),
9898
]
9999
)

Diff for: Plugins/AWSLambdaPackager/Plugin.swift

+23-5
Original file line numberDiff line numberDiff line change
@@ -249,11 +249,29 @@ struct AWSLambdaPackager: CommandPlugin {
249249
let resourcesDirectoryName = artifactURL.lastPathComponent
250250
let relocatedResourcesDirectory = workingDirectory.appending(path: resourcesDirectoryName)
251251
if FileManager.default.fileExists(atPath: artifactURL.path()) {
252-
try FileManager.default.copyItem(
253-
atPath: artifactURL.path(),
254-
toPath: relocatedResourcesDirectory.path()
255-
)
256-
arguments.append(resourcesDirectoryName)
252+
do {
253+
try FileManager.default.copyItem(
254+
atPath: artifactURL.path(),
255+
toPath: relocatedResourcesDirectory.path()
256+
)
257+
arguments.append(resourcesDirectoryName)
258+
} catch let error as CocoaError {
259+
260+
// On Linux, when the build has been done with Docker,
261+
// the source file are owned by root
262+
// this causes a permission error **after** the files have been copied
263+
// see https://github.com/swift-server/swift-aws-lambda-runtime/issues/449
264+
// see https://forums.swift.org/t/filemanager-copyitem-on-linux-fails-after-copying-the-files/77282
265+
266+
// because this error happens after the files have been copied, we can ignore it
267+
// this code checks if the destination file exists
268+
// if they do, just ignore error, otherwise throw it up to the caller.
269+
if !(error.code == CocoaError.Code.fileWriteNoPermission
270+
&& FileManager.default.fileExists(atPath: relocatedResourcesDirectory.path()))
271+
{
272+
throw error
273+
} // else just ignore it
274+
}
257275
}
258276
}
259277

0 commit comments

Comments
 (0)