diff --git a/.github/workflows/integration_tests.yml b/.github/workflows/integration_tests.yml index baf78508..468fc295 100644 --- a/.github/workflows/integration_tests.yml +++ b/.github/workflows/integration_tests.yml @@ -23,6 +23,10 @@ on: type: boolean description: "Boolean to enable the test of the archive plugin. Defaults to true." default: true + check_foundation_enabled: + type: boolean + description: "Boolean to enable the check for Foundation dependency. Defaults to true." + default: true matrix_linux_command: type: string description: "The command of the current Swift version linux matrix job to execute." @@ -88,15 +92,12 @@ jobs: COMMAND: ${{ inputs.matrix_linux_command }} EXAMPLE: ${{ matrix.examples }} run: | - ./scripts/integration_tests.sh - echo "✅ The examples compile correctly" + .github/workflows/scripts/integration_tests.sh test-archive-plugin: name: Test archive plugin if: ${{ inputs.archive_plugin_enabled }} runs-on: ubuntu-latest - strategy: - fail-fast: false steps: - name: Checkout repository uses: actions/checkout@v4 @@ -106,25 +107,21 @@ jobs: # https://github.com/actions/checkout/issues/766 run: git config --global --add safe.directory ${GITHUB_WORKSPACE} - name: Test the archive plugin - env: - EXAMPLE: HelloWorld - OUTPUT_FILE: .build/plugins/AWSLambdaPackager/outputs/AWSLambdaPackager/MyLambda/bootstrap - ZIP_FILE: .build/plugins/AWSLambdaPackager/outputs/AWSLambdaPackager/MyLambda/MyLambda.zip run: | - pushd Examples/${EXAMPLE} + .github/workflows/scripts/check-archive-plugin.sh - # package the example (docker and swift toolchain are installed on the GH runner) - LAMBDA_USE_LOCAL_DEPS=../.. swift package archive --allow-network-connections docker - - # did the plugin generated a Linux binary? - [ -f ${OUTPUT_FILE} ] - file ${OUTPUT_FILE} | grep --silent ELF - - # did the plugin created a ZIP file? - [ -f ${ZIP_FILE} ] - - # does the ZIP file contain the bootstrap? - unzip -l ${ZIP_FILE} | grep --silent bootstrap - - echo "✅ The archive plugin is OK" - popd + check-foundation: + name: No dependencies on Foundation + if: ${{ inputs.check_foundation_enabled }} + runs-on: ubuntu-latest + 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: Check for Foundation or ICU dependency + run: | + .github/workflows/scripts/check-link-foundation.sh diff --git a/.github/workflows/scripts/check-archive-plugin.sh b/.github/workflows/scripts/check-archive-plugin.sh new file mode 100755 index 00000000..3a15c138 --- /dev/null +++ b/.github/workflows/scripts/check-archive-plugin.sh @@ -0,0 +1,37 @@ +#!/bin/bash +##===----------------------------------------------------------------------===## +## +## This source file is part of the SwiftAWSLambdaRuntime open source project +## +## Copyright (c) 2017-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 +## +##===----------------------------------------------------------------------===## + +EXAMPLE=HelloWorld +OUTPUT_DIR=.build/plugins/AWSLambdaPackager/outputs/AWSLambdaPackager +OUTPUT_FILE=${OUTPUT_DIR}/MyLambda/bootstrap +ZIP_FILE=${OUTPUT_DIR}/MyLambda/MyLambda.zip + +pushd Examples/${EXAMPLE} || exit 1 + +# package the example (docker and swift toolchain are installed on the GH runner) +LAMBDA_USE_LOCAL_DEPS=../.. swift package archive --allow-network-connections docker || exit 1 + +# did the plugin generated a Linux binary? +[ -f "${OUTPUT_FILE}" ] +file "${OUTPUT_FILE}" | grep --silent ELF + +# did the plugin created a ZIP file? +[ -f "${ZIP_FILE}" ] + +# does the ZIP file contain the bootstrap? +unzip -l "${ZIP_FILE}" | grep --silent bootstrap + +echo "✅ The archive plugin is OK" +popd || exit 1 diff --git a/.github/workflows/scripts/check-link-foundation.sh b/.github/workflows/scripts/check-link-foundation.sh new file mode 100755 index 00000000..be84116c --- /dev/null +++ b/.github/workflows/scripts/check-link-foundation.sh @@ -0,0 +1,60 @@ +#!/bin/bash +##===----------------------------------------------------------------------===## +## +## This source file is part of the SwiftAWSLambdaRuntime open source project +## +## Copyright (c) 2017-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 +## +##===----------------------------------------------------------------------===## + +log() { printf -- "** %s\n" "$*" >&2; } +error() { printf -- "** ERROR: %s\n" "$*" >&2; } +fatal() { error "$@"; exit 1; } + +EXAMPLE=APIGateway +OUTPUT_DIR=.build/release +OUTPUT_FILE=${OUTPUT_DIR}/APIGatewayLambda +LIBS_TO_CHECK="libFoundation.so libFoundationInternationalization.so lib_FoundationICU.so" + +pushd Examples/${EXAMPLE} || fatal "Failed to change directory to Examples/${EXAMPLE}." + +# recompile the example without the --static-swift-stdlib flag +LAMBDA_USE_LOCAL_DEPS=../.. swift build -c release -Xlinker -s || fatal "Failed to build the example." + +# check if the binary exists +if [ ! -f "${OUTPUT_FILE}" ]; then + error "❌ ${OUTPUT_FILE} does not exist." +fi + +# Checking for Foundation or ICU dependencies +echo "Checking for Foundation or ICU dependencies in ${OUTPUT_DIR}/${OUTPUT_FILE}." +LIBRARIES=$(ldd ${OUTPUT_FILE} | awk '{print $1}') +for LIB in ${LIBS_TO_CHECK}; do + echo -n "Checking for ${LIB}... " + + # check if the binary has a dependency on Foundation or ICU + echo "${LIBRARIES}" | grep "${LIB}" # return 1 if not found + + # 1 is success (grep failed to find the lib), 0 is failure (grep successly found the lib) + SUCCESS=$? + if [ "$SUCCESS" -eq 0 ]; then + log "❌ ${LIB} found." && break + else + log "✅ ${LIB} not found." + fi +done + +popd || fatal "Failed to change directory back to the root directory." + +# exit code is the opposite of the grep exit code +if [ "$SUCCESS" -eq 0 ]; then + fatal "❌ At least one foundation lib was found, reporting the error." +else + log "✅ No foundation lib found, congrats!" && exit 0 +fi \ No newline at end of file diff --git a/scripts/integration_tests.sh b/.github/workflows/scripts/integration_tests.sh similarity index 100% rename from scripts/integration_tests.sh rename to .github/workflows/scripts/integration_tests.sh diff --git a/Examples/APIGateway/Sources/main.swift b/Examples/APIGateway/Sources/main.swift index 2d5707d6..f7662d1c 100644 --- a/Examples/APIGateway/Sources/main.swift +++ b/Examples/APIGateway/Sources/main.swift @@ -15,13 +15,6 @@ import AWSLambdaEvents import AWSLambdaRuntime -#if canImport(FoundationEssentials) -import FoundationEssentials -#else -import Foundation -#endif - -let encoder = JSONEncoder() let runtime = LambdaRuntime { (event: APIGatewayV2Request, context: LambdaContext) -> APIGatewayV2Response in @@ -31,10 +24,7 @@ let runtime = LambdaRuntime { header["content-type"] = "application/json" // echo the request in the response - let data = try encoder.encode(event) - let response = String(decoding: data, as: Unicode.UTF8.self) - - return APIGatewayV2Response(statusCode: .ok, headers: header, body: response) + return try APIGatewayV2Response(statusCode: .ok, headers: header, encodableBody: event) } try await runtime.run()