[plugin] Refactor lambda-build into pluggable build backends + thin-layer plugin args#679
Merged
Conversation
sebsto
added a commit
that referenced
this pull request
Jun 29, 2026
…andler deprecation warning (#680) Two small follow-ups on top of the build-backend refactor (#679). ### 1. Move the cross-compile backend factory onto `BuilderConfiguration` The call site read circularly: ```swift backend = try configuration.crossCompileMethod.makeBackend(configuration: configuration) ``` — reaching *through* the configuration to get the method, then handing the configuration straight back. The factory needs three values that the configuration already owns (`crossCompileToolPath`, `baseDockerImage`, `disableDockerImageUpdate`) plus the method, so it belongs on the configuration. - `CrossCompileMethod` is now purely the parsed user choice (`parse` + cases + `description`); its `makeBackend(...)` is gone. - `BuilderConfiguration` gains `makeCrossCompileBackend() -> any BuildBackend`, which reads everything it needs from `self`. - The call site becomes `backend = try configuration.makeCrossCompileBackend()`. No behaviour change. Also adopts explicit `any` (`any BuildBackend`, `any ContainerCLI`). The backend-selection tests now drive through `BuilderConfiguration(...).makeCrossCompileBackend()` (passing `--cross-compile`). The old "unsupported methods throw" test on the factory was dropped: unsupported methods (`swift-static-sdk`, `custom-sdk`) are now rejected earlier, at `BuilderConfiguration.init` via `CrossCompileMethod.parse`, and that behaviour is already covered by `UnsupportedCrossCompileMethodsPropertyTests`. ### 2. Fix a deprecation warning in the test log handler swift-log 1.13 added a `log(event:)` requirement to `LogHandler` and deprecated the old `log(level:message:source:...)` method. `CollectEverythingLogHandler` (test helper) still implemented the deprecated method, so it fell back to the deprecated default implementation of `log(event:)`, producing a build warning. It now implements `log(event:)` directly. (`JSONLogHandler` in the library already did.) ### Verification - Clean build of products **and** tests: no compiler warnings originate from our sources (`Sources/`, `Tests/`); remaining output is only unrelated `ld:` macOS dylib-version notes and the pre-existing Docs.docc "unhandled file" note. - All tests pass: 140 `AWSLambdaRuntimeTests`, 83 `AWSLambdaPluginHelperTests`. - `swift format lint --strict` clean.
sebsto
added a commit
that referenced
this pull request
Jun 29, 2026
…end (ZIP today, OCI-ready) (#681) ### Summary Introduces a pluggable **archive backend** abstraction for `lambda-build`, mirroring the existing build-backend design (#679). Packaging the built binaries into a deployable artifact was hard-coded to ZIP inside `Builder.swift`; it is now behind an `ArchiveBackend` protocol with one implementation today (ZIP, the existing code moved verbatim) and a stubbed seam for OCI images in the future. Internal refactor: the default behaviour is unchanged (ZIP), no public Swift API changes, and the output ZIP layout / path is identical. ### What changed - **`ArchiveBackend` protocol** (`ArchiveBackends/ArchiveBackend.swift`) — owns *what kind of artifact* is produced from the built binaries. It's the packaging counterpart to `BuildBackend` (which owns *how the binaries are built*); `Builder` selects and sequences the two. - **`ZipArchiveBackend`** (`ArchiveBackends/ZipArchiveBackend.swift`) — the existing `Builder.package(...)` body, moved unchanged, with `zipToolPath` injected via init. - **`ArchiveFormat` enum** (`ArchiveFormat.swift`) — the parsed `--archive-format` value (`zip` | `oci`), mirroring `CrossCompileMethod`: `parse(...)` (defaults to `zip`, case-insensitive), `isSupported` (`oci` → false), and a new `BuilderErrors.unsupportedArchiveFormat` case. - **`--archive-format zip|oci` flag** — parsed into `BuilderConfiguration`, with a `makeArchiveBackend()` factory (following the same on-configuration factory convention as `makeCrossCompileBackend()`). `oci` is recognised but throws a "not yet supported" error. Help text and the verbose config dump updated. - **`Builder.build(...)`** now ends with `configuration.makeArchiveBackend().archive(...)` instead of the inline `package(...)` method (which is removed). - **Directory rename**: `Backends/` → `BuildBackends/`, so the two families read as parallel siblings: `BuildBackends/` and `ArchiveBackends/`. ### Adding OCI later Add `OCIArchiveBackend: ArchiveBackend` under `ArchiveBackends/`, then flip the `oci` case in `ArchiveFormat.isSupported` and `makeArchiveBackend()`. No other changes. ### Testing - New `ArchiveBackendTests.swift`: `ArchiveFormat.parse` (default/case-insensitive/ oci-unsupported/unknown), `makeArchiveBackend()` selection (zip → `ZipArchiveBackend`), and `ZipArchiveBackend.archive` run against a temp build dir asserting the `.zip` and relocated `bootstrap` are produced. - All `AWSLambdaPluginHelperTests` pass (90 tests); `swift build` and `swift format lint --strict` clean. - End-to-end: `--archive-format oci` fails fast with the stub error; zip/default produce a byte-for-byte identical artifact to before.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Refactors the internals of the
lambda-buildbuild path into a pluggable backendarchitecture, and tidies the plugin→helper argument plumbing. This is an internal
refactor: no user-facing flag, no
--cross-compilevalue, no output ZIP path, andno public Swift API changes. Behaviour is identical; the goal is to make adding new
cross-compilation backends (podman, finch, colima, swift-static-sdk, custom-sdk, …)
a localised, additive change.
1. Pluggable build backends (
lambda-build)The build logic in
Builder.swiftwas a hard-coded native-vs-docker/containerbranch with an enum (
CrossCompileMethod) that carried both the parsed user choiceand the argv-building logic. It's now split along two independent axes:
BuildBackendprotocol — how a build runs:NativeBuildBackend(on anAmazon Linux host) and
ContainerBuildBackend(inside a container).ContainerCLIprotocol — the argument flavor of a container runtime:DockerCLIandAppleContainerCLI. A singleContainerBuildBackendserves both(and future runtimes) since only the argv spelling differs, not the build flow.
CrossCompileMethodkeeps only the parsed value,parse(...), and amakeBackend(configuration:)factory; itspullArguments/runArguments(and thefatalErrorSDK stubs) are gone.Builder.build(...)is now select-and-delegate(~8 lines);
Builder.swiftshrinks from ~700 to ~460 lines.No shared argv helper between CLIs — by design. Each
ContainerCLIbuilds itscomplete argument vector independently (no base struct, no default implementation,
no shared closure). docker and Apple
containerargv may diverge in future CLIversions, and future runtimes may not be compatible at all; a shared helper is
exactly the coupling that caused the earlier docker/container mix-up (#678). Each
CLI is covered by its own golden-argv tests with no shared fixtures.
Adding a backend later is now additive: a new
*CLI.swift+ aCrossCompileMethodcase + one line in
makeBackend(container runtimes), or a newBuildBackendtype(SDK methods). No edits to
Builderor existing CLIs.File layout:
2. Thin-layer plugin argument plumbing
The plugins are meant to be the thinnest possible layer: resolve only the values
that need
PluginContext/ the package graph, then forward everything else to thehelper.
lambda-buildand the deprecatedarchive(Swift 6.4 passthrough) werere-appending the original arguments after extracting some, so options like
--productsreached the helper twice (and, for--products, caused the product tobe built twice). Both now forward
argumentExtractor.remainingArguments, so aconsumed option is never forwarded again.
The same one-line bug (
+ arguments→+ argumentExtractor.remainingArguments) isfixed in
lambda-deploy, which had it too.The internal plugin→helper flag
--docker-tool-pathis renamed to--cross-compile-tool-path(and the config fielddockerToolPath→crossCompileToolPath) so it no longer implies docker — it can carry anycross-compile tool. This flag is internal (plugin→helper), not user-facing.
Testing
BuildBackendTests.swift: separate golden-argv tests forDockerCLIandAppleContainerCLI(no shared fixtures), plusmakeBackendfactory tests(docker → DockerCLI, container → AppleContainerCLI, SDK methods throw).
AWSLambdaPluginHelperTestspass (84 tests);swift buildandswift format lint --strictclean.lambda-builddefault (docker) and--cross-compile containeremit byte-for-byte identical argv to before therefactor;
--productsis no longer doubled.