This migrates from zig 0.13 to 0.15.2. In addition to dealing with breaking changes in the build system and standard library APIs, the architecture was changed substantially. We now build a standalone CLI, and use that to execute the commands. This avoids sandboxing issues related to TLS and enables easier testing. The commit also includes a simple zip implementation (store only, single file) which avoids the platform restriction (i.e. this build can now theoretically work on Windows).
112 lines
4.2 KiB
Zig
112 lines
4.2 KiB
Zig
//! Lambda Build Integration for Zig Build System
|
|
//!
|
|
//! This module provides build steps for packaging and deploying Lambda functions.
|
|
//! It builds the lambda-build CLI tool and invokes it for each operation.
|
|
|
|
const std = @import("std");
|
|
|
|
/// Configure Lambda build steps for a Zig project.
|
|
///
|
|
/// Adds the following build steps:
|
|
/// - awslambda_package: Package the function into a zip file
|
|
/// - awslambda_iam: Create/verify IAM role
|
|
/// - awslambda_deploy: Deploy the function to AWS
|
|
/// - awslambda_run: Invoke the deployed function
|
|
pub fn configureBuild(
|
|
b: *std.Build,
|
|
lambda_build_dep: *std.Build.Dependency,
|
|
exe: *std.Build.Step.Compile,
|
|
) !void {
|
|
// Get the lambda-build CLI artifact from the dependency
|
|
const cli = lambda_build_dep.artifact("lambda-build");
|
|
|
|
// Get configuration options
|
|
const function_name = b.option([]const u8, "function-name", "Function name for Lambda") orelse "zig-fn";
|
|
const region = b.option([]const u8, "region", "AWS region") orelse null;
|
|
const profile = b.option([]const u8, "profile", "AWS profile") orelse null;
|
|
const role_name = b.option(
|
|
[]const u8,
|
|
"role-name",
|
|
"IAM role name (default: lambda_basic_execution)",
|
|
) orelse "lambda_basic_execution";
|
|
const payload = b.option(
|
|
[]const u8,
|
|
"payload",
|
|
"Lambda invocation payload",
|
|
) orelse "{}";
|
|
|
|
// Determine architecture for Lambda
|
|
const target_arch = exe.root_module.resolved_target.?.result.cpu.arch;
|
|
const arch_str = blk: {
|
|
switch (target_arch) {
|
|
.aarch64 => break :blk "aarch64",
|
|
.x86_64 => break :blk "x86_64",
|
|
else => {
|
|
std.log.warn("Unsupported architecture for Lambda: {}, defaulting to x86_64", .{target_arch});
|
|
break :blk "x86_64";
|
|
},
|
|
}
|
|
};
|
|
|
|
// Package step - output goes to cache based on input hash
|
|
const package_cmd = b.addRunArtifact(cli);
|
|
package_cmd.step.name = try std.fmt.allocPrint(b.allocator, "{s} package", .{cli.name});
|
|
package_cmd.addArgs(&.{ "package", "--exe" });
|
|
package_cmd.addFileArg(exe.getEmittedBin());
|
|
package_cmd.addArgs(&.{"--output"});
|
|
const zip_output = package_cmd.addOutputFileArg("function.zip");
|
|
package_cmd.step.dependOn(&exe.step);
|
|
|
|
const package_step = b.step("awslambda_package", "Package the Lambda function");
|
|
package_step.dependOn(&package_cmd.step);
|
|
|
|
// IAM step
|
|
const iam_cmd = b.addRunArtifact(cli);
|
|
iam_cmd.step.name = try std.fmt.allocPrint(b.allocator, "{s} iam", .{cli.name});
|
|
if (profile) |p| iam_cmd.addArgs(&.{ "--profile", p });
|
|
if (region) |r| iam_cmd.addArgs(&.{ "--region", r });
|
|
iam_cmd.addArgs(&.{ "iam", "--role-name", role_name });
|
|
|
|
const iam_step = b.step("awslambda_iam", "Create/verify IAM role for Lambda");
|
|
iam_step.dependOn(&iam_cmd.step);
|
|
|
|
// Deploy step (depends on package)
|
|
const deploy_cmd = b.addRunArtifact(cli);
|
|
deploy_cmd.step.name = try std.fmt.allocPrint(b.allocator, "{s} deploy", .{cli.name});
|
|
if (profile) |p| deploy_cmd.addArgs(&.{ "--profile", p });
|
|
if (region) |r| deploy_cmd.addArgs(&.{ "--region", r });
|
|
deploy_cmd.addArgs(&.{
|
|
"deploy",
|
|
"--function-name",
|
|
function_name,
|
|
"--zip-file",
|
|
});
|
|
deploy_cmd.addFileArg(zip_output);
|
|
deploy_cmd.addArgs(&.{
|
|
"--role-name",
|
|
role_name,
|
|
"--arch",
|
|
arch_str,
|
|
});
|
|
deploy_cmd.step.dependOn(&package_cmd.step);
|
|
|
|
const deploy_step = b.step("awslambda_deploy", "Deploy the Lambda function");
|
|
deploy_step.dependOn(&deploy_cmd.step);
|
|
|
|
// Invoke/run step (depends on deploy)
|
|
const invoke_cmd = b.addRunArtifact(cli);
|
|
invoke_cmd.step.name = try std.fmt.allocPrint(b.allocator, "{s} invoke", .{cli.name});
|
|
if (profile) |p| invoke_cmd.addArgs(&.{ "--profile", p });
|
|
if (region) |r| invoke_cmd.addArgs(&.{ "--region", r });
|
|
invoke_cmd.addArgs(&.{
|
|
"invoke",
|
|
"--function-name",
|
|
function_name,
|
|
"--payload",
|
|
payload,
|
|
});
|
|
invoke_cmd.step.dependOn(&deploy_cmd.step);
|
|
|
|
const run_step = b.step("awslambda_run", "Invoke the deployed Lambda function");
|
|
run_step.dependOn(&invoke_cmd.step);
|
|
}
|