Skip to content

[plugin] support for resources packaging on ubuntu #467

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Jan 21, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions .github/workflows/integration_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ on:
type: boolean
description: "Boolean to enable the compilation of examples. Defaults to true."
default: true
archive_plugin_examples:
type: string
description: "The list of examples to run through the archive plugin test. Pass a String with a valid JSON array such as \"[ 'HelloWorld', 'APIGateway' ]\""
required: true
default: ""
archive_plugin_enabled:
type: boolean
description: "Boolean to enable the test of the archive plugin. Defaults to true."
Expand Down Expand Up @@ -54,7 +59,7 @@ jobs:
# We are using only one Swift version
swift:
- image: ${{ inputs.matrix_linux_swift_container_image }}
swift_version: "6.0.1-amazonlinux2"
swift_version: "6.0.3-amazonlinux2"
container:
image: ${{ matrix.swift.image }}
steps:
Expand Down Expand Up @@ -98,6 +103,10 @@ jobs:
name: Test archive plugin
if: ${{ inputs.archive_plugin_enabled }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
examples: ${{ fromJson(inputs.archive_plugin_examples) }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
Expand All @@ -107,8 +116,10 @@ jobs:
# https://github.com/actions/checkout/issues/766
run: git config --global --add safe.directory ${GITHUB_WORKSPACE}
- name: Test the archive plugin
env:
EXAMPLE: ${{ matrix.examples }}
run: |
.github/workflows/scripts/check-archive-plugin.sh
.github/workflows/scripts/check-archive-plugin.sh

check-foundation:
name: No dependencies on Foundation
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/pull_request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ jobs:
# We pass the list of examples here, but we can't pass an array as argument
# Instead, we pass a String with a valid JSON array.
# The workaround is mentioned here https://github.com/orgs/community/discussions/11692
examples: "[ 'APIGateway', 'APIGateway+LambdaAuthorizer', 'BackgroundTasks', 'HelloJSON', 'HelloWorld', 'S3_AWSSDK', 'S3_Soto', 'Streaming', 'Testing', 'Tutorial' ]"

examples: "[ 'APIGateway', 'APIGateway+LambdaAuthorizer', 'BackgroundTasks', 'HelloJSON', 'HelloWorld', 'ResourcesPackaging', 'S3_AWSSDK', 'S3_Soto', 'Streaming', 'Testing', 'Tutorial' ]"
archive_plugin_examples: "[ 'HelloWorld', 'ResourcesPackaging' ]"
archive_plugin_enabled: true

swift-6-language-mode:
Expand Down
16 changes: 13 additions & 3 deletions .github/workflows/scripts/check-archive-plugin.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,17 @@
##
##===----------------------------------------------------------------------===##

EXAMPLE=HelloWorld
log() { printf -- "** %s\n" "$*" >&2; }
error() { printf -- "** ERROR: %s\n" "$*" >&2; }
fatal() { error "$@"; exit 1; }

test -n "${EXAMPLE:-}" || fatal "EXAMPLE unset"

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
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
Expand All @@ -33,5 +38,10 @@ file "${OUTPUT_FILE}" | grep --silent ELF
# does the ZIP file contain the bootstrap?
unzip -l "${ZIP_FILE}" | grep --silent bootstrap

echo "✅ The archive plugin is OK"
# if EXAMPLE is ResourcesPackaging, check if the ZIP file contains hello.txt
if [ "$EXAMPLE" == "ResourcesPackaging" ]; then
unzip -l "${ZIP_FILE}" | grep --silent hello.txt
fi

echo "✅ The archive plugin is OK with example ${EXAMPLE}"
popd || exit 1
3 changes: 2 additions & 1 deletion .licenseignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,5 @@ Package.resolved
*.yaml
*.yml
**/.npmignore
**/*.json
**/*.json
**/*.txt
8 changes: 8 additions & 0 deletions Examples/ResourcesPackaging/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.DS_Store
/.build
/Packages
xcuserdata/
DerivedData/
.swiftpm/configuration/registries.json
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
.netrc
57 changes: 57 additions & 0 deletions Examples/ResourcesPackaging/Package.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// swift-tools-version: 6.0
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

// needed for CI to test the local version of the library
import struct Foundation.URL

let package = Package(
name: "ResourcesPackaging",
platforms: [.macOS(.v15)],
products: [
.executable(name: "MyLambda", targets: ["MyLambda"])
],
dependencies: [
.package(url: "https://github.com/swift-server/swift-aws-lambda-runtime.git", branch: "main")
],
targets: [
.executableTarget(
name: "MyLambda",
dependencies: [
.product(name: "AWSLambdaRuntime", package: "swift-aws-lambda-runtime")
],
path: ".",
resources: [
.process("hello.txt")
]
)
]
)

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)
]
}
26 changes: 26 additions & 0 deletions Examples/ResourcesPackaging/Sources/main.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the SwiftAWSLambdaRuntime open source project
//
// Copyright (c) 2025 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 AWSLambdaRuntime
import Foundation

let runtime = LambdaRuntime {
(event: String, context: LambdaContext) in
guard let fileURL = Bundle.module.url(forResource: "hello", withExtension: "txt") else {
fatalError("no file url")
}
return try String(contentsOf: fileURL, encoding: .utf8)
}

try await runtime.run()
1 change: 1 addition & 0 deletions Examples/ResourcesPackaging/hello.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Hello World
28 changes: 23 additions & 5 deletions Plugins/AWSLambdaPackager/Plugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -249,11 +249,29 @@ struct AWSLambdaPackager: CommandPlugin {
let resourcesDirectoryName = artifactURL.lastPathComponent
let relocatedResourcesDirectory = workingDirectory.appending(path: resourcesDirectoryName)
if FileManager.default.fileExists(atPath: artifactURL.path()) {
try FileManager.default.copyItem(
atPath: artifactURL.path(),
toPath: relocatedResourcesDirectory.path()
)
arguments.append(resourcesDirectoryName)
do {
try FileManager.default.copyItem(
atPath: artifactURL.path(),
toPath: relocatedResourcesDirectory.path()
)
arguments.append(resourcesDirectoryName)
} catch let error as CocoaError {

// On Linux, when the build has been done with Docker,
// the source file are owned by root
// this causes a permission error **after** the files have been copied
// see https://github.com/swift-server/swift-aws-lambda-runtime/issues/449
// see https://forums.swift.org/t/filemanager-copyitem-on-linux-fails-after-copying-the-files/77282

// because this error happens after the files have been copied, we can ignore it
// this code checks if the destination file exists
// if they do, just ignore error, otherwise throw it up to the caller.
if !(error.code == CocoaError.Code.fileWriteNoPermission
&& FileManager.default.fileExists(atPath: relocatedResourcesDirectory.path()))
{
throw error
} // else just ignore it
}
}
}

Expand Down
70 changes: 70 additions & 0 deletions scripts/ubuntu-install-swift.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#!/bin/bash
##===----------------------------------------------------------------------===##
##
## This source file is part of the SwiftAWSLambdaRuntime open source project
##
## Copyright (c) 2025 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
##
##===----------------------------------------------------------------------===##

sudo apt update && sudo apt -y upgrade

# Install Swift 6.0.3
sudo apt-get -y install \
binutils \
git \
gnupg2 \
libc6-dev \
libcurl4-openssl-dev \
libedit2 \
libgcc-13-dev \
libncurses-dev \
libpython3-dev \
libsqlite3-0 \
libstdc++-13-dev \
libxml2-dev \
libz3-dev \
pkg-config \
tzdata \
unzip \
zip \
zlib1g-dev

wget https://download.swift.org/swift-6.0.3-release/ubuntu2404-aarch64/swift-6.0.3-RELEASE/swift-6.0.3-RELEASE-ubuntu24.04-aarch64.tar.gz

tar xfvz swift-6.0.3-RELEASE-ubuntu24.04-aarch64.tar.gz

export PATH=/home/ubuntu/swift-6.0.3-RELEASE-ubuntu24.04-aarch64/usr/bin:"${PATH}"

swift --version

# Install Docker
sudo apt-get update
sudo apt-get install -y ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

# Add the repository to Apt sources:
# shellcheck source=/etc/os-release
# shellcheck disable=SC1091
. /etc/os-release
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
$VERSION_CODENAME stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update

sudo apt-get -y install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

# Add the current user to the docker group
sudo usermod -aG docker "$USER"

# LOGOUT and LOGIN to apply the changes
exit 0
28 changes: 28 additions & 0 deletions scripts/ubuntu-test-plugin.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/bin/bash
##===----------------------------------------------------------------------===##
##
## This source file is part of the SwiftAWSLambdaRuntime open source project
##
## Copyright (c) 2025 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
##
##===----------------------------------------------------------------------===##

# Connect with ssh

export PATH=/home/ubuntu/swift-6.0.3-RELEASE-ubuntu24.04-aarch64/usr/bin:"${PATH}"

# clone a project
git clone https://github.com/swift-server/swift-aws-lambda-runtime.git

# be sure Swift is install.
# Youc an install swift with the following command: ./scripts/ubuntu-install-swift.sh

# build the project
cd swift-aws-lambda-runtime/Examples/ResourcesPackaging/ || exit 1
LAMBDA_USE_LOCAL_DEPS=../.. swift package archive --allow-network-connections docker
Loading