mirror of
https://github.com/swift-server/swift-aws-lambda-runtime.git
synced 2026-06-02 07:27:33 +00:00
WIP : init plugin
This commit is contained in:
@@ -0,0 +1 @@
|
||||
Plugins/AWSLambdaInitializer/Template.swift
|
||||
Executable
+39
@@ -0,0 +1,39 @@
|
||||
#!/bin/sh
|
||||
|
||||
# check if docker is installed
|
||||
which docker > /dev/null
|
||||
if [[ $? != 0 ]]; then
|
||||
echo "Docker is not installed. Please install Docker and try again."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# check if user has an access key and secret access key
|
||||
echo "This script creates and deploys a Lambda function on your AWS Account.
|
||||
|
||||
You must have an AWS account and know an AWS access key, secret access key, and an optional session token. These values are read from '~/.aws/credentials' or asked interactively.
|
||||
"
|
||||
|
||||
read -p "Are you ready to create your first Lambda function in Swift? [y/n] " continue
|
||||
if [[ continue != ^[Yy]$ ]]; then
|
||||
echo "OK, try again later when you feel ready"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "⚡️ Create your Swift command line project"
|
||||
swift package init --type executable --name MyLambda
|
||||
|
||||
echo "📦 Add the AWS Lambda Swift runtime to your project"
|
||||
swift package add-dependency https://github.com/swift-server/swift-aws-lambda-runtime.git --branch main
|
||||
swift package add-dependency https://github.com/swift-server/swift-aws-lambda-events.git --branch main
|
||||
swift package add-target-dependency AWSLambdaRuntime MyLambda --package swift-aws-lambda-runtime
|
||||
swift package add-target-dependency AWSLambdaEvents MyLambda --package swift-aws-lambda-events
|
||||
|
||||
echo "📝 Write the Swift code"
|
||||
swift package lambda-init --allow-writing-to-package-directory
|
||||
|
||||
echo "📦 Compile and package the function for deployment"
|
||||
swift package archive --allow-network-connections docker
|
||||
|
||||
echo "🚀 Deploy to AWS Lambda"
|
||||
|
||||
|
||||
@@ -16,15 +16,21 @@ let package = Package(
|
||||
.library(name: "AWSLambdaRuntime", targets: ["AWSLambdaRuntime"]),
|
||||
// this has all the main functionality for lambda and it does not link Foundation
|
||||
.library(name: "AWSLambdaRuntimeCore", targets: ["AWSLambdaRuntimeCore"]),
|
||||
// plugin to create a new Lambda function, based on a template
|
||||
.plugin(name: "AWSLambdaInitializer", targets: ["AWSLambdaInitializer"]),
|
||||
// plugin to package the lambda, creating an archive that can be uploaded to AWS
|
||||
// requires Linux or at least macOS v15
|
||||
.plugin(name: "AWSLambdaPackager", targets: ["AWSLambdaPackager"]),
|
||||
// plugin to deploy a Lambda function
|
||||
.plugin(name: "AWSLambdadeployer", targets: ["AWSLambdaDeployer"]),
|
||||
.executable(name: "AWSLambdaDeployerHelper", targets: ["AWSLambdaDeployerHelper"]),
|
||||
// for testing only
|
||||
.library(name: "AWSLambdaTesting", targets: ["AWSLambdaTesting"]),
|
||||
],
|
||||
dependencies: [
|
||||
.package(url: "https://github.com/apple/swift-nio.git", from: "2.72.0"),
|
||||
.package(url: "https://github.com/apple/swift-log.git", from: "1.5.4"),
|
||||
.package(url: "https://github.com/apple/swift-crypto.git", from: "3.9.1"),
|
||||
],
|
||||
targets: [
|
||||
.target(
|
||||
@@ -45,6 +51,19 @@ let package = Package(
|
||||
],
|
||||
swiftSettings: [.swiftLanguageMode(.v5)]
|
||||
),
|
||||
.plugin(
|
||||
name: "AWSLambdaInitializer",
|
||||
capability: .command(
|
||||
intent: .custom(
|
||||
verb: "lambda-init",
|
||||
description:
|
||||
"Create a new Lambda function in the current project directory."
|
||||
),
|
||||
permissions: [
|
||||
.writeToPackageDirectory(reason: "Create a file with an HelloWorld Lambda function.")
|
||||
]
|
||||
)
|
||||
),
|
||||
.plugin(
|
||||
name: "AWSLambdaPackager",
|
||||
capability: .command(
|
||||
@@ -61,6 +80,34 @@ let package = Package(
|
||||
]
|
||||
)
|
||||
),
|
||||
.plugin(
|
||||
name: "AWSLambdaDeployer",
|
||||
capability: .command(
|
||||
intent: .custom(
|
||||
verb: "deploy",
|
||||
description:
|
||||
"Deploy the Lambda function. You must have an AWS account and know an access key and secret access key."
|
||||
),
|
||||
permissions: [
|
||||
.allowNetworkConnections(
|
||||
scope: .all(ports: [443]),
|
||||
reason: "This plugin uses the AWS Lambda API to deploy the function."
|
||||
)
|
||||
]
|
||||
),
|
||||
dependencies: [
|
||||
.target(name: "AWSLambdaDeployerHelper")
|
||||
]
|
||||
),
|
||||
.executableTarget(
|
||||
name: "AWSLambdaDeployerHelper",
|
||||
dependencies: [
|
||||
.product(name: "NIOHTTP1", package: "swift-nio"),
|
||||
.product(name: "NIOCore", package: "swift-nio"),
|
||||
.product(name: "Crypto", package: "swift-crypto"),
|
||||
],
|
||||
swiftSettings: [.swiftLanguageMode(.v6)]
|
||||
),
|
||||
.testTarget(
|
||||
name: "AWSLambdaRuntimeCoreTests",
|
||||
dependencies: [
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This source file is part of the SwiftAWSLambdaRuntime open source project
|
||||
//
|
||||
// Copyright (c) 2022 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 Foundation
|
||||
import PackagePlugin
|
||||
|
||||
@main
|
||||
@available(macOS 15.0, *)
|
||||
struct AWSLambdaPackager: CommandPlugin {
|
||||
|
||||
let destFileName = "Sources/main.swift"
|
||||
|
||||
func performCommand(context: PackagePlugin.PluginContext, arguments: [String]) async throws {
|
||||
let configuration = try Configuration(context: context, arguments: arguments)
|
||||
|
||||
if configuration.help {
|
||||
self.displayHelpMessage()
|
||||
return
|
||||
}
|
||||
|
||||
let destFileURL = context.package.directoryURL.appendingPathComponent(destFileName)
|
||||
do {
|
||||
try functionWithUrlTemplate.write(to: destFileURL, atomically: true, encoding: .utf8)
|
||||
|
||||
if configuration.verboseLogging {
|
||||
Diagnostics.progress("✅ Lambda function written to \(destFileName)")
|
||||
Diagnostics.progress("📦 You can now package with: 'swift package archive'")
|
||||
}
|
||||
|
||||
} catch {
|
||||
Diagnostics.error("🛑Failed to create the Lambda function file: \(error)")
|
||||
}
|
||||
}
|
||||
|
||||
private func displayHelpMessage() {
|
||||
print(
|
||||
"""
|
||||
OVERVIEW: A SwiftPM plugin to scaffold a HelloWorld Lambda function.
|
||||
|
||||
USAGE: swift package lambda-init
|
||||
[--help] [--verbose]
|
||||
[--allow-writing-to-package-directory]
|
||||
|
||||
OPTIONS:
|
||||
--allow-writing-to-package-directory Don't ask for permissions to write files.
|
||||
--verbose Produce verbose output for debugging.
|
||||
--help Show help information.
|
||||
"""
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private struct Configuration: CustomStringConvertible {
|
||||
public let help: Bool
|
||||
public let verboseLogging: Bool
|
||||
|
||||
public init(
|
||||
context: PluginContext,
|
||||
arguments: [String]
|
||||
) throws {
|
||||
var argumentExtractor = ArgumentExtractor(arguments)
|
||||
let verboseArgument = argumentExtractor.extractFlag(named: "verbose") > 0
|
||||
let helpArgument = argumentExtractor.extractFlag(named: "help") > 0
|
||||
|
||||
// help required ?
|
||||
self.help = helpArgument
|
||||
|
||||
// verbose logging required ?
|
||||
self.verboseLogging = verboseArgument
|
||||
}
|
||||
|
||||
var description: String {
|
||||
"""
|
||||
{
|
||||
verboseLogging: \(self.verboseLogging)
|
||||
}
|
||||
"""
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This source file is part of the SwiftAWSLambdaRuntime open source project
|
||||
//
|
||||
// Copyright (c) 2022 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 Foundation
|
||||
|
||||
let functionWithUrlTemplate = #"""
|
||||
import AWSLambdaRuntime
|
||||
import AWSLambdaEvents
|
||||
|
||||
// in this example we receive a FunctionURLRequest and we return a FunctionURLResponse
|
||||
// https://docs.aws.amazon.com/lambda/latest/dg/urls-invocation.html#urls-payloads
|
||||
|
||||
let runtime = LambdaRuntime {
|
||||
(event: FunctionURLRequest, context: LambdaContext) -> FunctionURLResponse in
|
||||
|
||||
guard let name = event.queryStringParameters?["name"] else {
|
||||
return FunctionURLResponse(statusCode: .badRequest)
|
||||
}
|
||||
|
||||
return FunctionURLResponse(statusCode: .ok, body: #"{ "message" : "Hello \#\#(name)" } "#)
|
||||
}
|
||||
|
||||
try await runtime.run()
|
||||
"""#
|
||||
@@ -18,6 +18,17 @@
|
||||
|
||||
## TL;DR
|
||||
|
||||
The `Examples/_MyFirstFunction` contains a script that goes through the steps described in this section.
|
||||
|
||||
If you are really impatient, just type:
|
||||
|
||||
```bash
|
||||
cd Examples/_MyFirstFunction
|
||||
./create_and_deploy_function.sh
|
||||
```
|
||||
|
||||
Otherwise, continue reading.
|
||||
|
||||
1. Create a new Swift executable project
|
||||
|
||||
```bash
|
||||
@@ -64,7 +75,15 @@ swift package init --type executable
|
||||
)
|
||||
```
|
||||
|
||||
3. Edit `Sources/main.swift` file and replace the content with this code
|
||||
3. Scaffold a minimal Lambda function
|
||||
|
||||
The runtime comes with a plugin to generate the code of a simple AWS Lambda function:
|
||||
|
||||
```bash
|
||||
swift package lambda-init --allow-writing-to-package-directory
|
||||
```
|
||||
|
||||
Your `Sources/main.swift` file must look like this.
|
||||
|
||||
```swift
|
||||
import AWSLambdaRuntime
|
||||
@@ -81,12 +100,13 @@ try await runtime.run()
|
||||
|
||||
4. Build & archive the package
|
||||
|
||||
The runtime comes with a plugin to compile on Amazon Linux and create a ZIP archive:
|
||||
|
||||
```bash
|
||||
swift build
|
||||
swift package archive --allow-network-connections docker
|
||||
```
|
||||
|
||||
If there is no error, there is a ZIP file ready to deploy.
|
||||
If there is no error, the ZIP archive is ready to deploy.
|
||||
The ZIP file is located at `.build/plugins/AWSLambdaPackager/outputs/AWSLambdaPackager/MyLambda/MyLambda.zip`
|
||||
|
||||
5. Deploy to AWS
|
||||
|
||||
Reference in New Issue
Block a user