Skip to content

Commit

Permalink
Add AWS SDK and Soto examples (#396)
Browse files Browse the repository at this point in the history
* 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 actions/checkout#1487
  • Loading branch information
sebsto authored Oct 10, 2024
1 parent bb9ddfb commit b4673d2
Show file tree
Hide file tree
Showing 15 changed files with 579 additions and 47 deletions.
39 changes: 30 additions & 9 deletions .github/workflows/examples_matrix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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
39 changes: 23 additions & 16 deletions Examples/APIGateway/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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"),
Expand All @@ -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")
]
}
10 changes: 5 additions & 5 deletions Examples/APIGateway/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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
```

Expand All @@ -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
-----------------------------------------------------------------------------------------------------------------------------
```
Expand Down
10 changes: 5 additions & 5 deletions Examples/APIGateway/template.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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"
32 changes: 20 additions & 12 deletions Examples/HelloWorld/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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(
Expand All @@ -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")
]
}
12 changes: 12 additions & 0 deletions Examples/S3_AWSSDK/.gitignore
Original file line number Diff line number Diff line change
@@ -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
63 changes: 63 additions & 0 deletions Examples/S3_AWSSDK/Package.swift
Original file line number Diff line number Diff line change
@@ -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)
]
}
Loading

0 comments on commit b4673d2

Please sign in to comment.