From 3dbe568e6979405814062e835e80853a9d0b7f2f Mon Sep 17 00:00:00 2001 From: Fabian Fett Date: Wed, 9 Oct 2024 19:57:58 +0200 Subject: [PATCH 1/5] Opt in more targets to swift 6 language mode (#401) --- Package.swift | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Package.swift b/Package.swift index eb78f9f9..69f5ff36 100644 --- a/Package.swift +++ b/Package.swift @@ -67,16 +67,14 @@ let package = Package( .byName(name: "AWSLambdaRuntimeCore"), .product(name: "NIOTestUtils", package: "swift-nio"), .product(name: "NIOFoundationCompat", package: "swift-nio"), - ], - swiftSettings: [.swiftLanguageMode(.v5)] + ] ), .testTarget( name: "AWSLambdaRuntimeTests", dependencies: [ .byName(name: "AWSLambdaRuntimeCore"), .byName(name: "AWSLambdaRuntime"), - ], - swiftSettings: [.swiftLanguageMode(.v5)] + ] ), // testing helper .target( From 65061a638c19f1a2757892350172897b06772d0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Stormacq?= Date: Thu, 10 Oct 2024 11:16:12 +0200 Subject: [PATCH 2/5] Remove docker compose files + add GH action to compile examples during CI (#397) * add GH action to compile examples on PR * remove old docker infrastructure --------- Co-authored-by: Fabian Fett --- .github/workflows/examples_matrix.yml | 60 +++++++++++++++++++++++++++ .github/workflows/pull_request.yml | 9 ++++ docker/Dockerfile | 20 --------- docker/docker-compose.al2.510.yaml | 18 -------- docker/docker-compose.al2.57.yaml | 18 -------- docker/docker-compose.al2.58.yaml | 18 -------- docker/docker-compose.al2.59.yaml | 18 -------- docker/docker-compose.al2.main.yaml | 18 -------- docker/docker-compose.yaml | 51 ----------------------- scripts/integration_tests.sh | 34 +++++++++++++++ 10 files changed, 103 insertions(+), 161 deletions(-) create mode 100644 .github/workflows/examples_matrix.yml delete mode 100644 docker/Dockerfile delete mode 100644 docker/docker-compose.al2.510.yaml delete mode 100644 docker/docker-compose.al2.57.yaml delete mode 100644 docker/docker-compose.al2.58.yaml delete mode 100644 docker/docker-compose.al2.59.yaml delete mode 100644 docker/docker-compose.al2.main.yaml delete mode 100644 docker/docker-compose.yaml create mode 100755 scripts/integration_tests.sh diff --git a/.github/workflows/examples_matrix.yml b/.github/workflows/examples_matrix.yml new file mode 100644 index 00000000..39ec1d26 --- /dev/null +++ b/.github/workflows/examples_matrix.yml @@ -0,0 +1,60 @@ +name: ExamplesMatrix + +on: + workflow_call: + inputs: + name: + type: string + description: "The name of the workflow used for the concurrency group." + required: true + # examples: + # type: sequence + # description: "The examples to run." + # required: true + matrix_linux_command: + type: string + description: "The command of the current Swift version linux matrix job to execute." + required: true + matrix_linux_swift_container_image: + type: string + description: "Container image for the matrix job. Defaults to matching latest Swift Ubuntu image." + default: "swift:latest" + +## We are cancelling previously triggered workflow runs +concurrency: + group: ${{ github.workflow }}-${{ github.ref }}-${{ inputs.name }} + cancel-in-progress: true + +jobs: + linux: + name: Example/${{ matrix.examples }} on Linux ${{ matrix.swift.swift_version }} + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + # This should be passed as an argument in input. Can we pass arrays as argument ? + examples : [ "HelloWorld", "APIGateway" ] + # examples: ${{ inputs.examples }} + + # We are using only one Swift version + swift: + - image: ${{ inputs.matrix_linux_swift_container_image }} + swift_version: "6.0.1-noble" + container: + image: ${{ matrix.swift.image }} + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + persist-credentials: false + - name: Mark the workspace as safe + # https://github.com/actions/checkout/issues/766 + run: git config --global --add safe.directory ${GITHUB_WORKSPACE} + - name: Run matrix job + env: + SWIFT_VERSION: ${{ matrix.swift.swift_version }} + COMMAND: ${{ inputs.matrix_linux_command }} + EXAMPLE: ${{ matrix.examples }} + run: | + apt-get -qq update && apt-get -qq -y install curl + ./scripts/integration_tests.sh \ No newline at end of file diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index f7522664..77f9a5af 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -24,6 +24,15 @@ jobs: linux_nightly_6_0_arguments_override: "--explicit-target-dependency-import-check error" linux_nightly_main_arguments_override: "--explicit-target-dependency-import-check error" + integration-tests: + name: Integration Tests + uses: ./.github/workflows/examples_matrix.yml + with: + # We should pass the list of examples here, but we can't pass an array as argument + # examples: [ "HelloWorld", "APIGateway" ] + name: "Integration tests" + matrix_linux_command: "LAMBDA_USE_LOCAL_DEPS=../.. swift build" + swift-6-language-mode: name: Swift 6 Language Mode uses: apple/swift-nio/.github/workflows/swift_6_language_mode.yml@main diff --git a/docker/Dockerfile b/docker/Dockerfile deleted file mode 100644 index ec97cef2..00000000 --- a/docker/Dockerfile +++ /dev/null @@ -1,20 +0,0 @@ -ARG swift_version=5.7 -ARG base_image=swift:$swift_version-amazonlinux2 -FROM $base_image -# needed to do again after FROM due to docker limitation -ARG swift_version - -# dependencies -RUN yum install -y wget perl-Digest-SHA -RUN yum install -y lsof dnsutils netcat-openbsd net-tools curl jq # used by integration tests - -# tools -RUN mkdir -p $HOME/.tools -RUN echo 'export PATH="$HOME/.tools:$PATH"' >> $HOME/.profile - -# swiftformat (until part of the toolchain) - -ARG swiftformat_version=0.50.1 -RUN git clone --branch $swiftformat_version --depth 1 https://github.com/nicklockwood/SwiftFormat $HOME/.tools/swift-format -RUN cd $HOME/.tools/swift-format && swift build -c release -RUN ln -s $HOME/.tools/swift-format/.build/release/swiftformat $HOME/.tools/swiftformat diff --git a/docker/docker-compose.al2.510.yaml b/docker/docker-compose.al2.510.yaml deleted file mode 100644 index a897f987..00000000 --- a/docker/docker-compose.al2.510.yaml +++ /dev/null @@ -1,18 +0,0 @@ -version: "3" - -services: - - runtime-setup: - image: swift-aws-lambda:al2-5.10 - build: - args: - base_image: "swiftlang/swift:nightly-5.10-amazonlinux2" - - test: - image: swift-aws-lambda:al2-5.10 - - test-examples: - image: swift-aws-lambda:al2-5.10 - - shell: - image: swift-aws-lambda:al2-5.10 diff --git a/docker/docker-compose.al2.57.yaml b/docker/docker-compose.al2.57.yaml deleted file mode 100644 index 1b19f1f0..00000000 --- a/docker/docker-compose.al2.57.yaml +++ /dev/null @@ -1,18 +0,0 @@ -version: "3" - -services: - - runtime-setup: - image: swift-aws-lambda:al2-5.7 - build: - args: - swift_version: "5.7" - - test: - image: swift-aws-lambda:al2-5.7 - - test-examples: - image: swift-aws-lambda:al2-5.7 - - shell: - image: swift-aws-lambda:al2-5.7 diff --git a/docker/docker-compose.al2.58.yaml b/docker/docker-compose.al2.58.yaml deleted file mode 100644 index 6127c65c..00000000 --- a/docker/docker-compose.al2.58.yaml +++ /dev/null @@ -1,18 +0,0 @@ -version: "3" - -services: - - runtime-setup: - image: swift-aws-lambda:al2-5.8 - build: - args: - swift_version: "5.8" - - test: - image: swift-aws-lambda:al2-5.8 - - test-examples: - image: swift-aws-lambda:al2-5.8 - - shell: - image: swift-aws-lambda:al2-5.8 diff --git a/docker/docker-compose.al2.59.yaml b/docker/docker-compose.al2.59.yaml deleted file mode 100644 index edea9327..00000000 --- a/docker/docker-compose.al2.59.yaml +++ /dev/null @@ -1,18 +0,0 @@ -version: "3" - -services: - - runtime-setup: - image: swift-aws-lambda:al2-5.9 - build: - args: - swift_version: "5.9" - - test: - image: swift-aws-lambda:al2-5.9 - - test-examples: - image: swift-aws-lambda:al2-5.9 - - shell: - image: swift-aws-lambda:al2-5.9 diff --git a/docker/docker-compose.al2.main.yaml b/docker/docker-compose.al2.main.yaml deleted file mode 100644 index b2f890c1..00000000 --- a/docker/docker-compose.al2.main.yaml +++ /dev/null @@ -1,18 +0,0 @@ -version: "3" - -services: - - runtime-setup: - image: swift-aws-lambda:al2-main - build: - args: - base_image: "swiftlang/swift:nightly-main-amazonlinux2" - - test: - image: swift-aws-lambda:al2-main - - test-examples: - image: swift-aws-lambda:al2-main - - shell: - image: swift-aws-lambda:al2-main diff --git a/docker/docker-compose.yaml b/docker/docker-compose.yaml deleted file mode 100644 index 32507dcf..00000000 --- a/docker/docker-compose.yaml +++ /dev/null @@ -1,51 +0,0 @@ -# this file is not designed to be run directly -# instead, use the docker-compose.. files -# eg docker-compose -f docker/docker-compose.yaml -f docker/docker-compose.al2.57.yaml run test -version: "3" - -services: - - runtime-setup: - image: swift-aws-lambda:default - build: - context: . - dockerfile: Dockerfile - - common: &common - image: swift-aws-lambda:default - depends_on: [runtime-setup] - volumes: - - ~/.ssh:/root/.ssh - - ..:/code:z - working_dir: /code - cap_drop: - - CAP_NET_RAW - - CAP_NET_BIND_SERVICE - - soundness: - <<: *common - command: /bin/bash -cl "./scripts/soundness.sh" - - test: - <<: *common - command: /bin/bash -cl "swift test -Xswiftc -warnings-as-errors $${SANITIZER_ARG-}" - - test-examples: - <<: *common - command: >- - /bin/bash -clx " - LAMBDA_USE_LOCAL_DEPS=true swift build --package-path Examples/Benchmark && - LAMBDA_USE_LOCAL_DEPS=true swift build --package-path Examples/Deployment && - LAMBDA_USE_LOCAL_DEPS=true swift build --package-path Examples/Echo && - LAMBDA_USE_LOCAL_DEPS=true swift build --package-path Examples/ErrorHandling && - LAMBDA_USE_LOCAL_DEPS=true swift build --package-path Examples/Foundation && - LAMBDA_USE_LOCAL_DEPS=true swift build --package-path Examples/JSON && - LAMBDA_USE_LOCAL_DEPS=true swift build --package-path Examples/LocalDebugging/MyLambda && - LAMBDA_USE_LOCAL_DEPS=true swift test --package-path Examples/Testing - " - - # util - - shell: - <<: *common - entrypoint: /bin/bash -l diff --git a/scripts/integration_tests.sh b/scripts/integration_tests.sh new file mode 100755 index 00000000..232d743d --- /dev/null +++ b/scripts/integration_tests.sh @@ -0,0 +1,34 @@ +#!/bin/bash +##===----------------------------------------------------------------------===## +## +## This source file is part of the SwiftAWSLambdaRuntime open source project +## +## Copyright (c) 2017-2018 Apple Inc. and the SwiftAWSLambdaRuntime project authors +## Licensed under Apache License v2.0 +## +## See LICENSE.txt for license information +## See CONTRIBUTORS.txt for the list of SwiftAWSLambdaRuntime project authors +## +## SPDX-License-Identifier: Apache-2.0 +## +##===----------------------------------------------------------------------===## + +set -euo pipefail + +log() { printf -- "** %s\n" "$*" >&2; } +error() { printf -- "** ERROR: %s\n" "$*" >&2; } +fatal() { error "$@"; exit 1; } + +test -n "${SWIFT_VERSION:-}" || fatal "SWIFT_VERSION unset" +test -n "${COMMAND:-}" || fatal "COMMAND unset" +test -n "${EXAMPLE:-}" || fatal "EXAMPLE unset" +swift_version="$SWIFT_VERSION" +command="$COMMAND" +example="$EXAMPLE" + +pushd Examples/"$example" > /dev/null + +log "Running command with Swift $SWIFT_VERSION" +eval "$command" + +popd From bb9ddfb5557aca5f6f0d6efe2234ba089bf58b89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Stormacq?= Date: Thu, 10 Oct 2024 11:31:14 +0200 Subject: [PATCH 3/5] do not force unwrap stdout (#398) * do not force unwrap Revert a change from #d2bd7f1aae1fc9455b208567ba5d85e42463c82c that caused the plugin to crash * test stdout for nil --------- Co-authored-by: Fabian Fett --- Plugins/AWSLambdaPackager/PluginUtils.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plugins/AWSLambdaPackager/PluginUtils.swift b/Plugins/AWSLambdaPackager/PluginUtils.swift index 11827200..e12e09dd 100644 --- a/Plugins/AWSLambdaPackager/PluginUtils.swift +++ b/Plugins/AWSLambdaPackager/PluginUtils.swift @@ -32,7 +32,7 @@ struct Utils { let fd = dup(1) let stdout = fdopen(fd, "rw") - defer { fclose(stdout!) } + defer { if let so = stdout { fclose(so) } } // We need to use an unsafe transfer here to get the fd into our Sendable closure. // This transfer is fine, because we write to the variable from a single SerialDispatchQueue here. From b4673d264b73fc3858d520e6dc04dc779862508c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Stormacq?= Date: Thu, 10 Oct 2024 13:08:31 +0200 Subject: [PATCH 4/5] Add AWS SDK and Soto examples (#396) * add aws sdk example * add soto example * use amazonlinux docker image instead of ubuntu * dynamically add runtime dependency based on env var * remove import of Foundation.ProcessInfo * workaround https://github.com/actions/checkout/issues/1487 --- .github/workflows/examples_matrix.yml | 39 +++++++++--- Examples/APIGateway/Package.swift | 39 +++++++----- Examples/APIGateway/README.md | 10 +-- Examples/APIGateway/template.yaml | 10 +-- Examples/HelloWorld/Package.swift | 32 ++++++---- Examples/S3_AWSSDK/.gitignore | 12 ++++ Examples/S3_AWSSDK/Package.swift | 63 +++++++++++++++++++ Examples/S3_AWSSDK/README.md | 89 +++++++++++++++++++++++++++ Examples/S3_AWSSDK/Sources/main.swift | 38 ++++++++++++ Examples/S3_AWSSDK/template.yaml | 43 +++++++++++++ Examples/S3_Soto/.gitignore | 12 ++++ Examples/S3_Soto/Package.swift | 64 +++++++++++++++++++ Examples/S3_Soto/README.md | 89 +++++++++++++++++++++++++++ Examples/S3_Soto/Sources/main.swift | 42 +++++++++++++ Examples/S3_Soto/template.yaml | 44 +++++++++++++ 15 files changed, 579 insertions(+), 47 deletions(-) create mode 100644 Examples/S3_AWSSDK/.gitignore create mode 100644 Examples/S3_AWSSDK/Package.swift create mode 100644 Examples/S3_AWSSDK/README.md create mode 100644 Examples/S3_AWSSDK/Sources/main.swift create mode 100644 Examples/S3_AWSSDK/template.yaml create mode 100644 Examples/S3_Soto/.gitignore create mode 100644 Examples/S3_Soto/Package.swift create mode 100644 Examples/S3_Soto/README.md create mode 100644 Examples/S3_Soto/Sources/main.swift create mode 100644 Examples/S3_Soto/template.yaml diff --git a/.github/workflows/examples_matrix.yml b/.github/workflows/examples_matrix.yml index 39ec1d26..15e4e859 100644 --- a/.github/workflows/examples_matrix.yml +++ b/.github/workflows/examples_matrix.yml @@ -18,7 +18,7 @@ on: matrix_linux_swift_container_image: type: string description: "Container image for the matrix job. Defaults to matching latest Swift Ubuntu image." - default: "swift:latest" + default: "swift:amazonlinux2" ## We are cancelling previously triggered workflow runs concurrency: @@ -33,28 +33,49 @@ jobs: fail-fast: false matrix: # This should be passed as an argument in input. Can we pass arrays as argument ? - examples : [ "HelloWorld", "APIGateway" ] + examples : [ "HelloWorld", "APIGateway", "S3_AWSSDK", "S3_Soto" ] # examples: ${{ inputs.examples }} # We are using only one Swift version swift: - image: ${{ inputs.matrix_linux_swift_container_image }} - swift_version: "6.0.1-noble" + swift_version: "6.0.1-amazonlinux2" container: image: ${{ matrix.swift.image }} steps: - - name: Checkout repository - uses: actions/checkout@v4 - with: - persist-credentials: false + + # GitHub checkout action has a dep on NodeJS 20 which is not running on Amazonlinux2 + # workaround is to manually checkout the repository + # https://github.com/actions/checkout/issues/1487 + - name: Manually Clone repository and checkout PR + env: + PR_NUMBER: ${{ github.event.pull_request.number }} + run: | + # Clone the repository + git clone https://github.com/${{ github.repository }} + cd ${{ github.event.repository.name }} + + # Fetch the pull request + git fetch origin +refs/pull/$PR_NUMBER/merge: + + # Checkout the pull request + git checkout -qf FETCH_HEAD + + # - name: Checkout repository + # uses: actions/checkout@v4 + # with: + # persist-credentials: false + - name: Mark the workspace as safe - # https://github.com/actions/checkout/issues/766 + working-directory: ${{ github.event.repository.name }} # until we can use action/checkout@v4 + # https://github.com/actions/checkout/issues/766 run: git config --global --add safe.directory ${GITHUB_WORKSPACE} + - name: Run matrix job + working-directory: ${{ github.event.repository.name }} # until we can use action/checkout@v4 env: SWIFT_VERSION: ${{ matrix.swift.swift_version }} COMMAND: ${{ inputs.matrix_linux_command }} EXAMPLE: ${{ matrix.examples }} run: | - apt-get -qq update && apt-get -qq -y install curl ./scripts/integration_tests.sh \ No newline at end of file diff --git a/Examples/APIGateway/Package.swift b/Examples/APIGateway/Package.swift index a2df5b73..ebaac99a 100644 --- a/Examples/APIGateway/Package.swift +++ b/Examples/APIGateway/Package.swift @@ -3,7 +3,6 @@ import PackageDescription // needed for CI to test the local version of the library -import class Foundation.ProcessInfo import struct Foundation.URL #if os(macOS) @@ -16,17 +15,16 @@ let package = Package( name: "swift-aws-lambda-runtime-example", platforms: platforms, products: [ - .executable(name: "APIGAtewayLambda", targets: ["APIGAtewayLambda"]) + .executable(name: "APIGatewayLambda", targets: ["APIGatewayLambda"]) ], dependencies: [ - // dependency on swift-aws-lambda-runtime is added dynamically below - // .package(url: "https://github.com/swift-server/swift-aws-lambda-runtime.git", branch: "main") - - .package(url: "https://github.com/swift-server/swift-aws-lambda-events.git", branch: "main") + // during CI, the dependency on local version of swift-aws-lambda-runtime is added dynamically below + .package(url: "https://github.com/swift-server/swift-aws-lambda-runtime.git", branch: "main"), + .package(url: "https://github.com/swift-server/swift-aws-lambda-events.git", branch: "main"), ], targets: [ .executableTarget( - name: "APIGAtewayLambda", + name: "APIGatewayLambda", dependencies: [ .product(name: "AWSLambdaRuntime", package: "swift-aws-lambda-runtime"), .product(name: "AWSLambdaEvents", package: "swift-aws-lambda-events"), @@ -36,20 +34,29 @@ let package = Package( ] ) -if let localDepsPath = ProcessInfo.processInfo.environment["LAMBDA_USE_LOCAL_DEPS"], +if let localDepsPath = Context.environment["LAMBDA_USE_LOCAL_DEPS"], localDepsPath != "", let v = try? URL(fileURLWithPath: localDepsPath).resourceValues(forKeys: [.isDirectoryKey]), - let _ = v.isDirectory + v.isDirectory == true { + // when we use the local runtime as deps, let's remove the dependency added above + let indexToRemove = package.dependencies.firstIndex { dependency in + if case .sourceControl( + name: _, + location: "https://github.com/swift-server/swift-aws-lambda-runtime.git", + requirement: _ + ) = dependency.kind { + return true + } + return false + } + if let indexToRemove { + package.dependencies.remove(at: indexToRemove) + } + + // then we add the dependency on LAMBDA_USE_LOCAL_DEPS' path (typically ../..) print("[INFO] Compiling against swift-aws-lambda-runtime located at \(localDepsPath)") package.dependencies += [ .package(name: "swift-aws-lambda-runtime", path: localDepsPath) ] - -} else { - print("[INFO] LAMBDA_USE_LOCAL_DEPS is not pointing to your local swift-aws-lambda-runtime code") - print("[INFO] This project will compile against the main branch of the Lambda Runtime on GitHub") - package.dependencies += [ - .package(url: "https://github.com/swift-server/swift-aws-lambda-runtime.git", branch: "main") - ] } diff --git a/Examples/APIGateway/README.md b/Examples/APIGateway/README.md index f534f9ba..be4c8b8c 100644 --- a/Examples/APIGateway/README.md +++ b/Examples/APIGateway/README.md @@ -26,7 +26,7 @@ swift package archive --allow-network-access docker ``` If there is no error, there is a ZIP file ready to deploy. -The ZIP file is located at `.build/plugins/AWSLambdaPackager/outputs/AWSLambdaPackager/MyLambda/MyLambda.zip` +The ZIP file is located at `.build/plugins/AWSLambdaPackager/outputs/AWSLambdaPackager/APIGatewayLambda/APIGatewayLambda.zip` ## Deploy @@ -40,9 +40,9 @@ To actually deploy your Lambda function and create the infrastructure, type the ```bash sam deploy \ -----resolve-s3 \ +--resolve-s3 \ --template-file template.yaml \ ---stack-name MyLambda \ +--stack-name APIGatewayLambda \ --capabilities CAPABILITY_IAM ``` @@ -53,8 +53,8 @@ The output is similar to this one. ----------------------------------------------------------------------------------------------------------------------------- Outputs ----------------------------------------------------------------------------------------------------------------------------- -Key APIGAtewayEndpoint -Description API Gateway endpoint UR" +Key APIGatewayEndpoint +Description API Gateway endpoint URL" Value https://a5q74es3k2.execute-api.us-east-1.amazonaws.com ----------------------------------------------------------------------------------------------------------------------------- ``` diff --git a/Examples/APIGateway/template.yaml b/Examples/APIGateway/template.yaml index 700c09b0..99a00da9 100644 --- a/Examples/APIGateway/template.yaml +++ b/Examples/APIGateway/template.yaml @@ -4,12 +4,12 @@ Description: SAM Template for QuoteService Resources: # Lambda function - APIGAtewayLambda: + APIGatewayLambda: Type: AWS::Serverless::Function Properties: - CodeUri: .build/plugins/AWSLambdaPackager/outputs/AWSLambdaPackager/APIGAtewayLambda/APIGAtewayLambda.zip + CodeUri: .build/plugins/AWSLambdaPackager/outputs/AWSLambdaPackager/APIGatewayLambda/APIGatewayLambda.zip Timeout: 60 - Handler: swift.bootstrap + Handler: swift.bootstrap # ignored by the Swift runtime Runtime: provided.al2 MemorySize: 512 Architectures: @@ -19,13 +19,13 @@ Resources: # by default, AWS Lambda runtime produces no log # use `LOG_LEVEL: debug` for for lifecycle and event handling information # use `LOG_LEVEL: trace` for detailed input event information - LOG_LEVEL: trace + LOG_LEVEL: debug Events: HttpApiEvent: Type: HttpApi Outputs: # print API Gateway endpoint - APIGAtewayEndpoint: + APIGatewayEndpoint: Description: API Gateway endpoint UR" Value: !Sub "https://${ServerlessHttpApi}.execute-api.${AWS::Region}.amazonaws.com" diff --git a/Examples/HelloWorld/Package.swift b/Examples/HelloWorld/Package.swift index 6468fb88..adb4b1f9 100644 --- a/Examples/HelloWorld/Package.swift +++ b/Examples/HelloWorld/Package.swift @@ -3,7 +3,6 @@ import PackageDescription // needed for CI to test the local version of the library -import class Foundation.ProcessInfo import struct Foundation.URL #if os(macOS) @@ -19,8 +18,8 @@ let package = Package( .executable(name: "MyLambda", targets: ["MyLambda"]) ], dependencies: [ - // dependency on swift-aws-lambda-runtime is added dynamically below - // .package(url: "https://github.com/swift-server/swift-aws-lambda-runtime.git", branch: "main") + // during CI, the dependency on local version of swift-aws-lambda-runtime is added dynamically below + .package(url: "https://github.com/swift-server/swift-aws-lambda-runtime.git", branch: "main") ], targets: [ .executableTarget( @@ -33,20 +32,29 @@ let package = Package( ] ) -if let localDepsPath = ProcessInfo.processInfo.environment["LAMBDA_USE_LOCAL_DEPS"], +if let localDepsPath = Context.environment["LAMBDA_USE_LOCAL_DEPS"], localDepsPath != "", let v = try? URL(fileURLWithPath: localDepsPath).resourceValues(forKeys: [.isDirectoryKey]), - let _ = v.isDirectory + v.isDirectory == true { + // when we use the local runtime as deps, let's remove the dependency added above + let indexToRemove = package.dependencies.firstIndex { dependency in + if case .sourceControl( + name: _, + location: "https://github.com/swift-server/swift-aws-lambda-runtime.git", + requirement: _ + ) = dependency.kind { + return true + } + return false + } + if let indexToRemove { + package.dependencies.remove(at: indexToRemove) + } + + // then we add the dependency on LAMBDA_USE_LOCAL_DEPS' path (typically ../..) print("[INFO] Compiling against swift-aws-lambda-runtime located at \(localDepsPath)") package.dependencies += [ .package(name: "swift-aws-lambda-runtime", path: localDepsPath) ] - -} else { - print("[INFO] LAMBDA_USE_LOCAL_DEPS is not pointing to your local swift-aws-lambda-runtime code") - print("[INFO] This project will compile against the main branch of the Lambda Runtime on GitHub") - package.dependencies += [ - .package(url: "https://github.com/swift-server/swift-aws-lambda-runtime.git", branch: "main") - ] } diff --git a/Examples/S3_AWSSDK/.gitignore b/Examples/S3_AWSSDK/.gitignore new file mode 100644 index 00000000..70799e05 --- /dev/null +++ b/Examples/S3_AWSSDK/.gitignore @@ -0,0 +1,12 @@ +.DS_Store +.aws-sam/ +.build +samtemplate.toml +*/build/* +/.build +/Packages +xcuserdata/ +DerivedData/ +.swiftpm/configuration/registries.json +.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata +.netrc \ No newline at end of file diff --git a/Examples/S3_AWSSDK/Package.swift b/Examples/S3_AWSSDK/Package.swift new file mode 100644 index 00000000..5417fbdd --- /dev/null +++ b/Examples/S3_AWSSDK/Package.swift @@ -0,0 +1,63 @@ +// swift-tools-version: 6.0 + +import PackageDescription + +// needed for CI to test the local version of the library +import struct Foundation.URL + +#if os(macOS) +let platforms: [PackageDescription.SupportedPlatform]? = [.macOS(.v15)] +#else +let platforms: [PackageDescription.SupportedPlatform]? = nil +#endif + +let package = Package( + name: "AWSSDKExample", + platforms: platforms, + products: [ + .executable(name: "AWSSDKExample", targets: ["AWSSDKExample"]) + ], + dependencies: [ + // during CI, the dependency on local version of swift-aws-lambda-runtime is added dynamically below + .package(url: "https://github.com/swift-server/swift-aws-lambda-runtime.git", branch: "main"), + .package(url: "https://github.com/swift-server/swift-aws-lambda-events", branch: "main"), + .package(url: "https://github.com/awslabs/aws-sdk-swift", from: "1.0.0"), + ], + targets: [ + .executableTarget( + name: "AWSSDKExample", + dependencies: [ + .product(name: "AWSLambdaRuntime", package: "swift-aws-lambda-runtime"), + .product(name: "AWSLambdaEvents", package: "swift-aws-lambda-events"), + .product(name: "AWSS3", package: "aws-sdk-swift"), + ] + ) + ] +) + +if let localDepsPath = Context.environment["LAMBDA_USE_LOCAL_DEPS"], + localDepsPath != "", + let v = try? URL(fileURLWithPath: localDepsPath).resourceValues(forKeys: [.isDirectoryKey]), + v.isDirectory == true +{ + // when we use the local runtime as deps, let's remove the dependency added above + let indexToRemove = package.dependencies.firstIndex { dependency in + if case .sourceControl( + name: _, + location: "https://github.com/swift-server/swift-aws-lambda-runtime.git", + requirement: _ + ) = dependency.kind { + return true + } + return false + } + if let indexToRemove { + package.dependencies.remove(at: indexToRemove) + } + + // then we add the dependency on LAMBDA_USE_LOCAL_DEPS' path (typically ../..) + print("[INFO] Compiling against swift-aws-lambda-runtime located at \(localDepsPath)") + package.dependencies += [ + .package(name: "swift-aws-lambda-runtime", path: localDepsPath) + ] +} diff --git a/Examples/S3_AWSSDK/README.md b/Examples/S3_AWSSDK/README.md new file mode 100644 index 00000000..58a7b83d --- /dev/null +++ b/Examples/S3_AWSSDK/README.md @@ -0,0 +1,89 @@ +# List Amazon S3 Buckets with the AWS SDK for Swift + +This is a simple example of an AWS Lambda function that uses the [AWS SDK for Swift](https://github.com/awslabs/aws-sdk-swift) to read data from Amazon S3. + +## Code + +The Lambda function reads all bucket names from your AWS account and returns them as a String. + +The code creates a `LambdaRuntime` struct. In it's simplest form, the initializer takes a function as argument. The function is the handler that will be invoked when the API Gateway receives an HTTP request. + +The handler is `(event: APIGatewayV2Request, context: LambdaContext) -> APIGatewayV2Response`. The function takes two arguments: +- the event argument is a `APIGatewayV2Request`. It is the parameter passed by the API Gateway. It contains all data passed in the HTTP request and some meta data. +- the context argument is a `Lambda Context`. It is a description of the runtime context. + +The function must return a `APIGatewayV2Response`. + +`APIGatewayV2Request` and `APIGatewayV2Response` are defined in the [Swift AWS Lambda Events](https://github.com/swift-server/swift-aws-lambda-events) library. + +The handler creates an S3 client and `ListBucketsInput` object. It passes the input object to the client and receives an output response. +It then extracts the list of bucket names from the output and creates a `\n`-separated list of names, as a `String` + +## Build & Package + +To build the package, type the following commands. + +```bash +swift build +swift package archive --allow-network-access docker +``` + +If there is no error, there is a ZIP file ready to deploy. +The ZIP file is located at `.build/plugins/AWSLambdaPackager/outputs/AWSLambdaPackager/AWSSDKExample/AWSSDKExample.zip` + +## Deploy + +The deployment must include the Lambda function and an API Gateway. We use the [Serverless Application Model (SAM)](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/what-is-sam.html) to deploy the infrastructure. + +**Prerequisites** : Install the [SAM CLI](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/install-sam-cli.html) + +The example directory contains a file named `template.yaml` that describes the deployment. + +To actually deploy your Lambda function and create the infrastructure, type the following `sam` command. + +```bash +sam deploy \ +--resolve-s3 \ +--template-file template.yaml \ +--stack-name AWSSDKExample \ +--capabilities CAPABILITY_IAM +``` + +At the end of the deployment, the script lists the API Gateway endpoint. +The output is similar to this one. + +``` +----------------------------------------------------------------------------------------------------------------------------- +Outputs +----------------------------------------------------------------------------------------------------------------------------- +Key APIGatewayEndpoint +Description API Gateway endpoint URL" +Value https://a5q74es3k2.execute-api.us-east-1.amazonaws.com +----------------------------------------------------------------------------------------------------------------------------- +``` + +## Invoke your Lambda function + +To invoke the Lambda function, use this `curl` command line. + +```bash +curl https://a5q74es3k2.execute-api.us-east-1.amazonaws.com +``` + +Be sure to replace the URL with the API Gateway endpoint returned in the previous step. + +This should print text similar to + +```bash +my_bucket_1 +my_bucket_2 +... +``` + +## Delete the infrastructure + +When done testing, you can delete the infrastructure with this command. + +```bash +sam delete +``` \ No newline at end of file diff --git a/Examples/S3_AWSSDK/Sources/main.swift b/Examples/S3_AWSSDK/Sources/main.swift new file mode 100644 index 00000000..6665893c --- /dev/null +++ b/Examples/S3_AWSSDK/Sources/main.swift @@ -0,0 +1,38 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftAWSLambdaRuntime open source project +// +// Copyright (c) 2024 Apple Inc. and the SwiftAWSLambdaRuntime project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftAWSLambdaRuntime project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import AWSLambdaEvents +import AWSLambdaRuntime +@preconcurrency import AWSS3 + +let client = try await S3Client() + +let runtime = LambdaRuntime { + (event: APIGatewayV2Request, context: LambdaContext) async throws -> APIGatewayV2Response in + + var response: APIGatewayV2Response + do { + // read the list of buckets + context.logger.debug("Reading list of buckets") + let output = try await client.listBuckets(input: ListBucketsInput()) + let bucketList = output.buckets?.compactMap { $0.name } + response = APIGatewayV2Response(statusCode: .ok, body: bucketList?.joined(separator: "\n")) + } catch { + context.logger.error("\(error)") + response = APIGatewayV2Response(statusCode: .internalServerError, body: "[ERROR] \(error)") + } + return response +} + +try await runtime.run() diff --git a/Examples/S3_AWSSDK/template.yaml b/Examples/S3_AWSSDK/template.yaml new file mode 100644 index 00000000..b1e02416 --- /dev/null +++ b/Examples/S3_AWSSDK/template.yaml @@ -0,0 +1,43 @@ +AWSTemplateFormatVersion: '2010-09-09' +Transform: AWS::Serverless-2016-10-31 +Description: SAM Template for AWS SDK Example + +Resources: + # Lambda function + AWSSDKExample: + Type: AWS::Serverless::Function + Properties: + CodeUri: .build/plugins/AWSLambdaPackager/outputs/AWSLambdaPackager/AWSSDKExample/AWSSDKExample.zip + Timeout: 60 + Handler: swift.bootstrap # ignored by the Swift runtime + Runtime: provided.al2 + MemorySize: 512 + Architectures: + - arm64 + Environment: + Variables: + # by default, AWS Lambda runtime produces no log + # use `LOG_LEVEL: debug` for for lifecycle and event handling information + # use `LOG_LEVEL: trace` for detailed input event information + LOG_LEVEL: debug + + # Handles all methods of the REST API + Events: + Api: + Type: HttpApi + + # Add an IAM policy to this function. + # It grants the function permissions to read the list of buckets in your account. + Policies: + - Statement: + - Sid: ListAllS3BucketsInYourAccount + Effect: Allow + Action: + - s3:ListAllMyBuckets + Resource: '*' + +# print API endpoint +Outputs: + SwiftAPIEndpoint: + Description: "API Gateway endpoint URL for your application" + Value: !Sub "https://${ServerlessHttpApi}.execute-api.${AWS::Region}.amazonaws.com" diff --git a/Examples/S3_Soto/.gitignore b/Examples/S3_Soto/.gitignore new file mode 100644 index 00000000..70799e05 --- /dev/null +++ b/Examples/S3_Soto/.gitignore @@ -0,0 +1,12 @@ +.DS_Store +.aws-sam/ +.build +samtemplate.toml +*/build/* +/.build +/Packages +xcuserdata/ +DerivedData/ +.swiftpm/configuration/registries.json +.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata +.netrc \ No newline at end of file diff --git a/Examples/S3_Soto/Package.swift b/Examples/S3_Soto/Package.swift new file mode 100644 index 00000000..4b4eead1 --- /dev/null +++ b/Examples/S3_Soto/Package.swift @@ -0,0 +1,64 @@ +// swift-tools-version: 6.0 + +import PackageDescription + +// needed for CI to test the local version of the library +import struct Foundation.URL + +#if os(macOS) +let platforms: [PackageDescription.SupportedPlatform]? = [.macOS(.v15)] +#else +let platforms: [PackageDescription.SupportedPlatform]? = nil +#endif + +let package = Package( + name: "SotoExample", + platforms: platforms, + products: [ + .executable(name: "SotoExample", targets: ["SotoExample"]) + ], + dependencies: [ + .package(url: "https://github.com/soto-project/soto.git", from: "7.0.0"), + + // during CI, the dependency on local version of swift-aws-lambda-runtime is added dynamically below + .package(url: "https://github.com/swift-server/swift-aws-lambda-runtime.git", branch: "main"), + .package(url: "https://github.com/swift-server/swift-aws-lambda-events", branch: "main"), + ], + targets: [ + .executableTarget( + name: "SotoExample", + dependencies: [ + .product(name: "SotoS3", package: "soto"), + .product(name: "AWSLambdaRuntime", package: "swift-aws-lambda-runtime"), + .product(name: "AWSLambdaEvents", package: "swift-aws-lambda-events"), + ] + ) + ] +) + +if let localDepsPath = Context.environment["LAMBDA_USE_LOCAL_DEPS"], + localDepsPath != "", + let v = try? URL(fileURLWithPath: localDepsPath).resourceValues(forKeys: [.isDirectoryKey]), + v.isDirectory == true +{ + // when we use the local runtime as deps, let's remove the dependency added above + let indexToRemove = package.dependencies.firstIndex { dependency in + if case .sourceControl( + name: _, + location: "https://github.com/swift-server/swift-aws-lambda-runtime.git", + requirement: _ + ) = dependency.kind { + return true + } + return false + } + if let indexToRemove { + package.dependencies.remove(at: indexToRemove) + } + + // then we add the dependency on LAMBDA_USE_LOCAL_DEPS' path (typically ../..) + print("[INFO] Compiling against swift-aws-lambda-runtime located at \(localDepsPath)") + package.dependencies += [ + .package(name: "swift-aws-lambda-runtime", path: localDepsPath) + ] +} diff --git a/Examples/S3_Soto/README.md b/Examples/S3_Soto/README.md new file mode 100644 index 00000000..c9c0e4a1 --- /dev/null +++ b/Examples/S3_Soto/README.md @@ -0,0 +1,89 @@ +# List Amazon S3 Buckets with Soto + +This is a simple example of an AWS Lambda function that uses the [Soto SDK for AWS](https://github.com/soto-project/soto) to read data from Amazon S3. + +## Code + +The Lambda function reads all bucket names from your AWS account and returns them as a String. + +The code creates a `LambdaRuntime` struct. In it's simplest form, the initializer takes a function as argument. The function is the handler that will be invoked when the API Gateway receives an HTTP request. + +The handler is `(event: APIGatewayV2Request, context: LambdaContext) -> APIGatewayV2Response`. The function takes two arguments: +- the event argument is a `APIGatewayV2Request`. It is the parameter passed by the API Gateway. It contains all data passed in the HTTP request and some meta data. +- the context argument is a `Lambda Context`. It is a description of the runtime context. + +The function must return a `APIGatewayV2Response`. + +`APIGatewayV2Request` and `APIGatewayV2Response` are defined in the [Swift AWS Lambda Events](https://github.com/swift-server/swift-aws-lambda-events) library. + +The handler creates two clients : an AWS client that manages the communication with AWS API and and the S3 client that expose the S3 API. Then, the handler calls `listBuckets()` on the S3 client and receives an output response. +Finally, the handler extracts the list of bucket names from the output to create a `\n`-separated list of names, as a `String`. + +## Build & Package + +To build the package, type the following command. + +```bash +swift build +swift package archive --allow-network-access docker +``` + +If there is no error, there is a ZIP file ready to deploy. +The ZIP file is located at `.build/plugins/AWSLambdaPackager/outputs/AWSLambdaPackager/SotoExample/SotoExample.zip` + +## Deploy + +The deployment must include the Lambda function and an API Gateway. We use the [Serverless Application Model (SAM)](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/what-is-sam.html) to deploy the infrastructure. + +**Prerequisites** : Install the [SAM CLI](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/install-sam-cli.html) + +The example directory contains a file named `template.yaml` that describes the deployment. + +To actually deploy your Lambda function and create the infrastructure, type the following `sam` command. + +```bash +sam deploy \ +--resolve-s3 \ +--template-file template.yaml \ +--stack-name SotoExample \ +--capabilities CAPABILITY_IAM +``` + +At the end of the deployment, the script lists the API Gateway endpoint. +The output is similar to this one. + +``` +----------------------------------------------------------------------------------------------------------------------------- +Outputs +----------------------------------------------------------------------------------------------------------------------------- +Key APIGatewayEndpoint +Description API Gateway endpoint URL" +Value https://a5q74es3k2.execute-api.us-east-1.amazonaws.com +----------------------------------------------------------------------------------------------------------------------------- +``` + +## Invoke your Lambda function + +To invoke the Lambda function, use this `curl` command line. + +```bash +curl https://a5q74es3k2.execute-api.us-east-1.amazonaws.com +``` + +Be sure to replace the URL with the API Gateway endpoint returned in the previous step. + +This should print text similar to + +```bash +my_bucket_1 +my_bucket_2 +... +``` + +## Delete the infrastructure + +When done testing, you can delete the infrastructure with this command. + +```bash +sam delete +``` \ No newline at end of file diff --git a/Examples/S3_Soto/Sources/main.swift b/Examples/S3_Soto/Sources/main.swift new file mode 100644 index 00000000..caa70116 --- /dev/null +++ b/Examples/S3_Soto/Sources/main.swift @@ -0,0 +1,42 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftAWSLambdaRuntime open source project +// +// Copyright (c) 2024 Apple Inc. and the SwiftAWSLambdaRuntime project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftAWSLambdaRuntime project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import AWSLambdaEvents +import AWSLambdaRuntime +import SotoS3 + +let client = AWSClient() +let s3 = S3(client: client, region: .useast1) + +func handler(event: APIGatewayV2Request, context: LambdaContext) async throws -> APIGatewayV2Response { + + var response: APIGatewayV2Response + do { + context.logger.debug("Reading list of buckets") + + // read the list of buckets + let bucketResponse = try await s3.listBuckets() + let bucketList = bucketResponse.buckets?.compactMap { $0.name } + response = APIGatewayV2Response(statusCode: .ok, body: bucketList?.joined(separator: "\n")) + } catch { + context.logger.error("\(error)") + response = APIGatewayV2Response(statusCode: .internalServerError, body: "[ERROR] \(error)") + } + return response +} + +let runtime = LambdaRuntime.init(body: handler) + +try await runtime.run() +try await client.shutdown() diff --git a/Examples/S3_Soto/template.yaml b/Examples/S3_Soto/template.yaml new file mode 100644 index 00000000..50093169 --- /dev/null +++ b/Examples/S3_Soto/template.yaml @@ -0,0 +1,44 @@ + +AWSTemplateFormatVersion: '2010-09-09' +Transform: AWS::Serverless-2016-10-31 +Description: SAM Template for AWS SDK Example + +Resources: + # Lambda function + SotoExample: + Type: AWS::Serverless::Function + Properties: + CodeUri: .build/plugins/AWSLambdaPackager/outputs/AWSLambdaPackager/SotoExample/SotoExample.zip + Timeout: 60 + Handler: swift.bootstrap # ignored by the Swift runtime + Runtime: provided.al2 + MemorySize: 512 + Architectures: + - arm64 + Environment: + Variables: + # by default, AWS Lambda runtime produces no log + # use `LOG_LEVEL: debug` for for lifecycle and event handling information + # use `LOG_LEVEL: trace` for detailed input event information + LOG_LEVEL: debug + + # Handles all methods of the REST API + Events: + Api: + Type: HttpApi + + # Add an IAM policy to this function. + # It grants the function permissions to read the list of buckets in your account. + Policies: + - Statement: + - Sid: ListAllS3BucketsInYourAccount + Effect: Allow + Action: + - s3:ListAllMyBuckets + Resource: '*' + +# print API endpoint +Outputs: + SwiftAPIEndpoint: + Description: "API Gateway endpoint URL for your application" + Value: !Sub "https://${ServerlessHttpApi}.execute-api.${AWS::Region}.amazonaws.com" From 59dd68adabf11e49c64716757f63a73acf41199a Mon Sep 17 00:00:00 2001 From: Franz Busch Date: Fri, 11 Oct 2024 15:49:34 +0200 Subject: [PATCH 5/5] [CI] Adopt soundess workflow from swiftlang (#405) --- .github/ISSUE_TEMPLATE/issue-report.yml | 4 +- .github/workflows/examples_matrix.yml | 73 ++++++++++++------------- .github/workflows/pull_request.yml | 63 ++++++++++----------- Examples/APIGateway/template.yaml | 4 +- Examples/S3_AWSSDK/template.yaml | 12 ++-- Examples/S3_Soto/template.yaml | 13 ++--- 6 files changed, 84 insertions(+), 85 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/issue-report.yml b/.github/ISSUE_TEMPLATE/issue-report.yml index e5f5d4e9..ae6e0ba3 100644 --- a/.github/ISSUE_TEMPLATE/issue-report.yml +++ b/.github/ISSUE_TEMPLATE/issue-report.yml @@ -17,7 +17,7 @@ body: attributes: label: Actual behavior description: What actually happened - placeholder: Describe + placeholder: Describe validations: required: true - type: textarea @@ -55,7 +55,7 @@ body: attributes: label: Swift version description: Swift environment version. - placeholder: | + placeholder: | Open a Terminal and execute the following command swift --version && uname -a diff --git a/.github/workflows/examples_matrix.yml b/.github/workflows/examples_matrix.yml index 15e4e859..fb9cca41 100644 --- a/.github/workflows/examples_matrix.yml +++ b/.github/workflows/examples_matrix.yml @@ -24,58 +24,57 @@ on: concurrency: group: ${{ github.workflow }}-${{ github.ref }}-${{ inputs.name }} cancel-in-progress: true - + jobs: linux: - name: Example/${{ matrix.examples }} on Linux ${{ matrix.swift.swift_version }} + name: Example/${{ matrix.examples }} on Linux ${{ matrix.swift.swift_version }} runs-on: ubuntu-latest strategy: fail-fast: false matrix: # This should be passed as an argument in input. Can we pass arrays as argument ? - examples : [ "HelloWorld", "APIGateway", "S3_AWSSDK", "S3_Soto" ] + examples: ["HelloWorld", "APIGateway", "S3_AWSSDK", "S3_Soto"] # examples: ${{ inputs.examples }} - # We are using only one Swift version + # We are using only one Swift version swift: - - image: ${{ inputs.matrix_linux_swift_container_image }} - swift_version: "6.0.1-amazonlinux2" + - image: ${{ inputs.matrix_linux_swift_container_image }} + swift_version: "6.0.1-amazonlinux2" container: image: ${{ matrix.swift.image }} steps: + # GitHub checkout action has a dep on NodeJS 20 which is not running on Amazonlinux2 + # workaround is to manually checkout the repository + # https://github.com/actions/checkout/issues/1487 + - name: Manually Clone repository and checkout PR + env: + PR_NUMBER: ${{ github.event.pull_request.number }} + run: | + # Clone the repository + git clone https://github.com/${{ github.repository }} + cd ${{ github.event.repository.name }} - # GitHub checkout action has a dep on NodeJS 20 which is not running on Amazonlinux2 - # workaround is to manually checkout the repository - # https://github.com/actions/checkout/issues/1487 - - name: Manually Clone repository and checkout PR - env: - PR_NUMBER: ${{ github.event.pull_request.number }} - run: | - # Clone the repository - git clone https://github.com/${{ github.repository }} - cd ${{ github.event.repository.name }} + # Fetch the pull request + git fetch origin +refs/pull/$PR_NUMBER/merge: - # Fetch the pull request - git fetch origin +refs/pull/$PR_NUMBER/merge: - - # Checkout the pull request - git checkout -qf FETCH_HEAD + # Checkout the pull request + git checkout -qf FETCH_HEAD - # - name: Checkout repository - # uses: actions/checkout@v4 - # with: - # persist-credentials: false + # - name: Checkout repository + # uses: actions/checkout@v4 + # with: + # persist-credentials: false - - name: Mark the workspace as safe - working-directory: ${{ github.event.repository.name }} # until we can use action/checkout@v4 - # https://github.com/actions/checkout/issues/766 - run: git config --global --add safe.directory ${GITHUB_WORKSPACE} + - name: Mark the workspace as safe + working-directory: ${{ github.event.repository.name }} # until we can use action/checkout@v4 + # https://github.com/actions/checkout/issues/766 + run: git config --global --add safe.directory ${GITHUB_WORKSPACE} - - name: Run matrix job - working-directory: ${{ github.event.repository.name }} # until we can use action/checkout@v4 - env: - SWIFT_VERSION: ${{ matrix.swift.swift_version }} - COMMAND: ${{ inputs.matrix_linux_command }} - EXAMPLE: ${{ matrix.examples }} - run: | - ./scripts/integration_tests.sh \ No newline at end of file + - name: Run matrix job + working-directory: ${{ github.event.repository.name }} # until we can use action/checkout@v4 + env: + SWIFT_VERSION: ${{ matrix.swift.swift_version }} + COMMAND: ${{ inputs.matrix_linux_command }} + EXAMPLE: ${{ matrix.examples }} + run: | + ./scripts/integration_tests.sh diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 77f9a5af..ad616cdc 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -1,38 +1,39 @@ name: PR on: - pull_request: - types: [opened, reopened, synchronize] + pull_request: + types: [opened, reopened, synchronize] jobs: - soundness: - name: Soundness - uses: apple/swift-nio/.github/workflows/soundness.yml@main - with: - license_header_check_project_name: "SwiftAWSLambdaRuntime" - shell_check_enabled: false - api_breakage_check_container_image: "swift:6.0-noble" - docs_check_container_image: "swift:6.0-noble" + soundness: + name: Soundness + uses: swiftlang/github-workflows/.github/workflows/soundness.yml@main + with: + license_header_check_project_name: "SwiftAWSLambdaRuntime" + shell_check_enabled: false + api_breakage_check_container_image: "swift:6.0-noble" + docs_check_container_image: "swift:6.0-noble" + format_check_container_image: "swiftlang/swift:nightly-6.0-jammy" - unit-tests: - name: Unit tests - uses: apple/swift-nio/.github/workflows/unit_tests.yml@main - with: - linux_5_8_enabled: false - linux_5_9_enabled: false - linux_5_10_enabled: false - linux_nightly_6_0_arguments_override: "--explicit-target-dependency-import-check error" - linux_nightly_main_arguments_override: "--explicit-target-dependency-import-check error" + unit-tests: + name: Unit tests + uses: apple/swift-nio/.github/workflows/unit_tests.yml@main + with: + linux_5_8_enabled: false + linux_5_9_enabled: false + linux_5_10_enabled: false + linux_nightly_6_0_arguments_override: "--explicit-target-dependency-import-check error" + linux_nightly_main_arguments_override: "--explicit-target-dependency-import-check error" - integration-tests: - name: Integration Tests - uses: ./.github/workflows/examples_matrix.yml - with: - # We should pass the list of examples here, but we can't pass an array as argument - # examples: [ "HelloWorld", "APIGateway" ] - name: "Integration tests" - matrix_linux_command: "LAMBDA_USE_LOCAL_DEPS=../.. swift build" - - swift-6-language-mode: - name: Swift 6 Language Mode - uses: apple/swift-nio/.github/workflows/swift_6_language_mode.yml@main + integration-tests: + name: Integration Tests + uses: ./.github/workflows/examples_matrix.yml + with: + # We should pass the list of examples here, but we can't pass an array as argument + # examples: [ "HelloWorld", "APIGateway" ] + name: "Integration tests" + matrix_linux_command: "LAMBDA_USE_LOCAL_DEPS=../.. swift build" + + swift-6-language-mode: + name: Swift 6 Language Mode + uses: apple/swift-nio/.github/workflows/swift_6_language_mode.yml@main diff --git a/Examples/APIGateway/template.yaml b/Examples/APIGateway/template.yaml index 99a00da9..0d7a6af4 100644 --- a/Examples/APIGateway/template.yaml +++ b/Examples/APIGateway/template.yaml @@ -9,7 +9,7 @@ Resources: Properties: CodeUri: .build/plugins/AWSLambdaPackager/outputs/AWSLambdaPackager/APIGatewayLambda/APIGatewayLambda.zip Timeout: 60 - Handler: swift.bootstrap # ignored by the Swift runtime + Handler: swift.bootstrap # ignored by the Swift runtime Runtime: provided.al2 MemorySize: 512 Architectures: @@ -22,7 +22,7 @@ Resources: LOG_LEVEL: debug Events: HttpApiEvent: - Type: HttpApi + Type: HttpApi Outputs: # print API Gateway endpoint diff --git a/Examples/S3_AWSSDK/template.yaml b/Examples/S3_AWSSDK/template.yaml index b1e02416..46e29ec8 100644 --- a/Examples/S3_AWSSDK/template.yaml +++ b/Examples/S3_AWSSDK/template.yaml @@ -9,7 +9,7 @@ Resources: Properties: CodeUri: .build/plugins/AWSLambdaPackager/outputs/AWSLambdaPackager/AWSSDKExample/AWSSDKExample.zip Timeout: 60 - Handler: swift.bootstrap # ignored by the Swift runtime + Handler: swift.bootstrap # ignored by the Swift runtime Runtime: provided.al2 MemorySize: 512 Architectures: @@ -30,11 +30,11 @@ Resources: # It grants the function permissions to read the list of buckets in your account. Policies: - Statement: - - Sid: ListAllS3BucketsInYourAccount - Effect: Allow - Action: - - s3:ListAllMyBuckets - Resource: '*' + - Sid: ListAllS3BucketsInYourAccount + Effect: Allow + Action: + - s3:ListAllMyBuckets + Resource: '*' # print API endpoint Outputs: diff --git a/Examples/S3_Soto/template.yaml b/Examples/S3_Soto/template.yaml index 50093169..bfc04d1e 100644 --- a/Examples/S3_Soto/template.yaml +++ b/Examples/S3_Soto/template.yaml @@ -1,4 +1,3 @@ - AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: SAM Template for AWS SDK Example @@ -10,7 +9,7 @@ Resources: Properties: CodeUri: .build/plugins/AWSLambdaPackager/outputs/AWSLambdaPackager/SotoExample/SotoExample.zip Timeout: 60 - Handler: swift.bootstrap # ignored by the Swift runtime + Handler: swift.bootstrap # ignored by the Swift runtime Runtime: provided.al2 MemorySize: 512 Architectures: @@ -31,11 +30,11 @@ Resources: # It grants the function permissions to read the list of buckets in your account. Policies: - Statement: - - Sid: ListAllS3BucketsInYourAccount - Effect: Allow - Action: - - s3:ListAllMyBuckets - Resource: '*' + - Sid: ListAllS3BucketsInYourAccount + Effect: Allow + Action: + - s3:ListAllMyBuckets + Resource: '*' # print API endpoint Outputs: