Documentation
¶
Overview ¶
Package build provides application build and packaging logic for Celerity application deployments.
Index ¶
- Constants
- func ReadHandlerDependencies(registry *Registry, runtime, appDir string) (map[string][]string, error)
- func UploadManifest(ctx context.Context, uploader ArtifactUploader, manifest *Manifest, ...) error
- func WriteManifest(manifest *Manifest) error
- type Artifact
- type ArtifactUploader
- type BuildParams
- type CommandExecutor
- type DependencyInstaller
- type ExecCommandExecutor
- type HandlerArtifacts
- type HandlerBootstrap
- type HandlerDependencyReader
- type HandlerInfo
- type LambdaHandlerArtifacts
- type LambdaManifest
- type LambdaNodeBootstrap
- type LambdaPythonBootstrap
- type LambdaStrategy
- type Manifest
- type NodeDependencyInstaller
- type NodeHandlerDependencyReader
- type NodePackageManager
- type NodeSourceCompiler
- type PythonDependencyInstaller
- type PythonHandlerDependencyReader
- type Registry
- func (r *Registry) GetDependencyInstaller(runtime string) (DependencyInstaller, error)
- func (r *Registry) GetHandlerDependencyReader(runtime string) HandlerDependencyReader
- func (r *Registry) GetSourceCompiler(runtime string) SourceCompiler
- func (r *Registry) GetStrategy(deployTarget string) (Strategy, error)
- func (r *Registry) RegisterDependencyInstaller(runtimePrefix string, i DependencyInstaller)
- func (r *Registry) RegisterHandlerDependencyReader(runtimePrefix string, reader HandlerDependencyReader)
- func (r *Registry) RegisterSourceCompiler(runtimePrefix string, c SourceCompiler)
- func (r *Registry) RegisterStrategy(deployTarget string, s Strategy)
- type S3ArtifactUploader
- type SourceCompiler
- type Strategy
Constants ¶
const ( ArtifactTypeLambdaArchive = buildmanifest.ArtifactTypeLambdaArchive ArtifactTypeLambdaLayer = buildmanifest.ArtifactTypeLambdaLayer LayerSizeWarning int64 = 200 * 1024 * 1024 // 200MB LayerSizeLimit int64 = 250 * 1024 * 1024 // 250MB )
const ( ManifestVersion = buildmanifest.Version ManifestFile = buildmanifest.FileName ArtifactTypeContainerImage = buildmanifest.ArtifactTypeContainerImage // ResourceLinksFilename is the name of the blueprint-derived resource // links JSON file bundled into the Lambda app archive. The SDK reads // it from the handler's module directory on cold start, removing the // need to pass the payload through environment variables (which have // a tight 4 KB total limit on AWS Lambda). ResourceLinksFilename = buildmanifest.ResourceLinksFilename // HandlerScopeFilename is the per-handler resource scope file bundled // alongside the resource links. HandlerScopeFilename = buildmanifest.HandlerScopeFilename )
const ( // MaintenanceRunnerBinaryEnvVar names a prebuilt maintenance runner binary // to package. // // Until releases publish the runner, this is how one is supplied. The // resolver is written to take a second source without anything downstream // changing, since the build manifest records an artefact either way. MaintenanceRunnerBinaryEnvVar = "CELERITY_MAINTENANCE_RUNNER_BINARY" )
Variables ¶
This section is empty.
Functions ¶
func ReadHandlerDependencies ¶
func ReadHandlerDependencies(registry *Registry, runtime, appDir string) (map[string][]string, error)
ReadHandlerDependencies reads per-handler dependency declarations from the language-appropriate manifest in appDir. Returns nil if no declarations exist.
func UploadManifest ¶
func UploadManifest( ctx context.Context, uploader ArtifactUploader, manifest *Manifest, instanceName string, ) error
UploadManifest serialises the manifest and uploads it via the given uploader, stamping the returned URL onto manifest.RemoteURL.
Callers must call this before persisting the manifest locally with WriteManifest so the RemoteURL is part of the on-disk copy but not of the uploaded bytes. The upload happens before the stamping, so the S3 object holds no self-reference.
A nil uploader is a no-op that leaves manifest.RemoteURL empty, which lets deploy targets without artifact upload share the same call site.
func WriteManifest ¶
WriteManifest writes the build manifest to buildmanifest.FileName. Thin re-export of buildmanifest.Write so internal/build call sites are unchanged.
Types ¶
type Artifact ¶
type Artifact = buildmanifest.Artifact
The build manifest wire types are defined once in the public buildmanifest package (the single source of truth shared with the Celerity transformer) and re-exported here as aliases so existing internal/build call sites are unchanged.
type ArtifactUploader ¶
type ArtifactUploader interface {
Upload(ctx context.Context, artifact *Artifact, key string) error
UploadManifest(ctx context.Context, data []byte, instanceName string) (string, error)
}
ArtifactUploader uploads build artifacts to remote storage.
func ResolveUploader ¶
func ResolveUploader(deployTarget string, providerConfig map[string]any) ArtifactUploader
ResolveUploader returns the appropriate artifact uploader for the deploy target, or nil if the target doesn't require pre-upload (e.g. Azure).
type BuildParams ¶
type BuildParams struct {
AppDir string
Runtime string
DeployTarget string
Handlers []HandlerInfo
HandlerDependencies map[string][]string
OutputDir string
Uploader ArtifactUploader
InstanceName string
Logger *zap.Logger
// Blueprint is the merged blueprint used to derive build-time artifacts
// like the resource links file bundled into the Lambda app archive.
Blueprint *schema.Blueprint
// ToolOutput is the writer for tool output (npm, pip, tsc).
// In interactive mode this should be a log file; in headless/standalone
// mode it should be os.Stdout.
ToolOutput io.Writer
// Toolchain builds the handlers executable for an OS-only runtime, and is
// nil for a runtime that hosts the language itself. Its presence is what
// selects the compiled packaging path.
Toolchain handlertoolchain.Toolchain
}
BuildParams holds the inputs needed to execute a build.
type CommandExecutor ¶
type CommandExecutor interface {
Run(ctx context.Context, dir string, toolOutput io.Writer, name string, args ...string) error
}
CommandExecutor runs external commands. The default implementation uses os/exec; tests can substitute a stub.
type DependencyInstaller ¶
type DependencyInstaller interface {
InstallDependencies(ctx context.Context, appDir, targetDir string, packages []string, toolOutput io.Writer) error
}
DependencyInstaller installs dependencies into a target directory. When packages is nil, all production dependencies are installed. When packages is non-nil, only those packages are installed. toolOutput receives tool stdout/stderr (npm, pip output).
type ExecCommandExecutor ¶
type ExecCommandExecutor struct{}
ExecCommandExecutor is the default CommandExecutor that shells out to external tools via os/exec.
func (*ExecCommandExecutor) Run ¶
func (e *ExecCommandExecutor) Run( ctx context.Context, dir string, toolOutput io.Writer, name string, args ...string, ) error
Run invokes a sub-process and writes all output to the provided toolOutput writer. The command is resolved to an absolute path via PATH and an error is returned if it cannot be found.
type HandlerArtifacts ¶
type HandlerArtifacts = buildmanifest.HandlerArtifacts
The build manifest wire types are defined once in the public buildmanifest package (the single source of truth shared with the Celerity transformer) and re-exported here as aliases so existing internal/build call sites are unchanged.
type HandlerBootstrap ¶
type HandlerBootstrap interface {
Generate(stagingDir string) (entryPoint string, err error)
// RequiredPackage names the adapter package the generated entry file
// imports, so the build can check the app actually depends on it.
//
// Declared here rather than checked elsewhere because the import and the
// requirement have to move together. A bootstrap whose import changed
// while a check somewhere else kept naming the old package would produce
// handlers that provision cleanly and then fail on their first
// invocation, a long way from the mistake.
RequiredPackage() string
}
HandlerBootstrap writes a per-language entry point file that wraps the developer's app in the appropriate Celerity SDK serverless adapter for the deploy target. Returns the entry point string that the strategy should record on its target-specific sub-manifest.
Generate is called once per build rather than once per handler, since the bootstrap is identical across all handlers in a project and the shared app code bundle contains a single copy of it.
Implementations are strategy-specific (e.g. LambdaNodeBootstrap wraps the app for AWS Lambda). A future GCP strategy would ship its own implementations targeting the GCP serverless adapter.
type HandlerDependencyReader ¶
type HandlerDependencyReader interface {
ReadHandlerDependencies(appDir string) (map[string][]string, error)
}
HandlerDependencyReader reads per-handler dependency declarations from a language-specific manifest file.
type HandlerInfo ¶
HandlerInfo describes a handler to be built.
type LambdaHandlerArtifacts ¶
type LambdaHandlerArtifacts = buildmanifest.LambdaHandlerArtifacts
The build manifest wire types are defined once in the public buildmanifest package (the single source of truth shared with the Celerity transformer) and re-exported here as aliases so existing internal/build call sites are unchanged.
type LambdaManifest ¶
type LambdaManifest = buildmanifest.LambdaManifest
The build manifest wire types are defined once in the public buildmanifest package (the single source of truth shared with the Celerity transformer) and re-exported here as aliases so existing internal/build call sites are unchanged.
type LambdaNodeBootstrap ¶
type LambdaNodeBootstrap struct {
AppDir string
}
LambdaNodeBootstrap is the Lambda-specific HandlerBootstrap for Node.js. It wraps the developer's app in the Celerity Node SDK's AWS Lambda adapter.
The generated file imports from the `/handler` subpath of @celerity-sdk/serverless-aws rather than the package root so only the lean entry module is pulled in at cold start, not the full package index.
func (*LambdaNodeBootstrap) Generate ¶
func (n *LambdaNodeBootstrap) Generate(stagingDir string) (string, error)
Generate respects an existing entry file of either variant in stagingDir so developers can opt out of the generated bootstrap regardless of the project's module system.
func (*LambdaNodeBootstrap) RequiredPackage ¶
func (n *LambdaNodeBootstrap) RequiredPackage() string
RequiredPackage returns the adapter package the generated entry file imports.
type LambdaPythonBootstrap ¶
type LambdaPythonBootstrap struct{}
LambdaPythonBootstrap is the Lambda-specific HandlerBootstrap for Python. It wraps the developer's app in the Celerity Python SDK's AWS Lambda adapter (celerity.serverless.aws.create_lambda_handler).
func (*LambdaPythonBootstrap) Generate ¶
func (p *LambdaPythonBootstrap) Generate(stagingDir string) (string, error)
Generate respects an existing entry file in stagingDir so developers can opt out of the generated bootstrap by writing their own.
func (*LambdaPythonBootstrap) RequiredPackage ¶
func (p *LambdaPythonBootstrap) RequiredPackage() string
RequiredPackage returns the distribution the generated entry file imports from.
type LambdaStrategy ¶
type LambdaStrategy struct {
Registry *Registry
// Bootstraps maps runtime prefixes (e.g. "nodejs", "python") to the
// Lambda-specific handler bootstrap for that language. Kept on the
// strategy rather than the shared registry because bootstraps are
// deploy-target-specific, and a future GCP strategy would ship its own
// mapping with different SDK imports.
Bootstraps map[string]HandlerBootstrap
}
LambdaStrategy packages a Celerity application for AWS Lambda as a single shared app code bundle (referenced by every handler's Lambda function) plus a shared or per-handler dependency layer. Per-handler dep layers are opt-in via handlerDependencies declarations in the developer's package manifest.
func (*LambdaStrategy) Build ¶
func (s *LambdaStrategy) Build(ctx context.Context, params *BuildParams) (*Manifest, error)
type Manifest ¶
type Manifest = buildmanifest.Manifest
The build manifest wire types are defined once in the public buildmanifest package (the single source of truth shared with the Celerity transformer) and re-exported here as aliases so existing internal/build call sites are unchanged.
func ReadManifest ¶
ReadManifest reads the build manifest from buildmanifest.FileName, returning nil if the file does not exist. Thin re-export of buildmanifest.Read.
type NodeDependencyInstaller ¶
type NodeDependencyInstaller struct {
Exec CommandExecutor
PM NodePackageManager
}
NodeDependencyInstaller installs Node.js production dependencies using the project's package manager.
type NodeHandlerDependencyReader ¶
type NodeHandlerDependencyReader struct{}
NodeHandlerDependencyReader reads celerity.handlerDependencies from package.json.
func (*NodeHandlerDependencyReader) ReadHandlerDependencies ¶
func (r *NodeHandlerDependencyReader) ReadHandlerDependencies(appDir string) (map[string][]string, error)
type NodePackageManager ¶
type NodePackageManager string
NodePackageManager represents a detected Node.js package manager.
const ( NodePMNpm NodePackageManager = "npm" NodePMYarn NodePackageManager = "yarn" NodePMPnpm NodePackageManager = "pnpm" )
func DetectNodePackageManager ¶
func DetectNodePackageManager(appDir string) NodePackageManager
DetectNodePackageManager determines the Node.js package manager from the packageManager field in package.json or lock files on disk.
func (NodePackageManager) ExecPrefix ¶
func (pm NodePackageManager) ExecPrefix() []string
ExecPrefix returns the command prefix for running a locally installed binary via the package manager (e.g. ["pnpm", "exec"] or ["yarn"]).
func (NodePackageManager) InstallCommand ¶
func (pm NodePackageManager) InstallCommand() []string
InstallCommand returns the command to install production dependencies in a clean, reproducible way.
func (NodePackageManager) LockFiles ¶
func (pm NodePackageManager) LockFiles() []string
LockFiles returns the lock file names to copy for reproducible installs.
type NodeSourceCompiler ¶
type NodeSourceCompiler struct {
Exec CommandExecutor
PM NodePackageManager
}
NodeSourceCompiler compiles TypeScript source to JavaScript using tsc, preserving the directory structure for readability in cloud provider consoles. If no tsconfig.json is found, it assumes the project is plain JavaScript and does nothing.
type PythonDependencyInstaller ¶
type PythonDependencyInstaller struct {
Exec CommandExecutor
}
PythonDependencyInstaller installs Python production dependencies using pip.
type PythonHandlerDependencyReader ¶
type PythonHandlerDependencyReader struct{}
PythonHandlerDependencyReader reads [tool.celerity.handlerDependencies] from pyproject.toml.
func (*PythonHandlerDependencyReader) ReadHandlerDependencies ¶
func (r *PythonHandlerDependencyReader) ReadHandlerDependencies(appDir string) (map[string][]string, error)
type Registry ¶
type Registry struct {
// contains filtered or unexported fields
}
Registry holds build components keyed by deploy target or runtime prefix.
func NewDefaultRegistry ¶
NewDefaultRegistry creates a registry pre-populated with the standard build strategies and per-runtime components. appDir is used to detect the Node.js package manager from the project.
func NewRegistry ¶
func NewRegistry() *Registry
func NewRegistryWithExecutor ¶
func NewRegistryWithExecutor(exec CommandExecutor, appDir string) *Registry
NewRegistryWithExecutor creates a registry using the provided command executor. This allows tests to inject a stub executor.
func (*Registry) GetDependencyInstaller ¶
func (r *Registry) GetDependencyInstaller(runtime string) (DependencyInstaller, error)
func (*Registry) GetHandlerDependencyReader ¶
func (r *Registry) GetHandlerDependencyReader(runtime string) HandlerDependencyReader
func (*Registry) GetSourceCompiler ¶
func (r *Registry) GetSourceCompiler(runtime string) SourceCompiler
GetSourceCompiler returns nil if no compiler is registered (source is deployed as-is, e.g. Python).
func (*Registry) GetStrategy ¶
func (*Registry) RegisterDependencyInstaller ¶
func (r *Registry) RegisterDependencyInstaller(runtimePrefix string, i DependencyInstaller)
func (*Registry) RegisterHandlerDependencyReader ¶
func (r *Registry) RegisterHandlerDependencyReader(runtimePrefix string, reader HandlerDependencyReader)
func (*Registry) RegisterSourceCompiler ¶
func (r *Registry) RegisterSourceCompiler(runtimePrefix string, c SourceCompiler)
func (*Registry) RegisterStrategy ¶
type S3ArtifactUploader ¶
type S3ArtifactUploader struct {
// contains filtered or unexported fields
}
S3ArtifactUploader uploads build artifacts to an S3 bucket. The bucket is auto-created with a conventional name if it doesn't exist.
func (*S3ArtifactUploader) UploadManifest ¶
func (u *S3ArtifactUploader) UploadManifest( ctx context.Context, data []byte, instanceName string, ) (string, error)
UploadManifest uploads the serialised build manifest JSON to the same bucket used for artifacts and returns the s3:// URL. Unlike Upload, this always overwrites the existing object. The manifest at a fixed per-instance key is mutable by design, since every build supersedes the previous one.
type SourceCompiler ¶
type SourceCompiler interface {
Compile(ctx context.Context, srcDir, outDir string, toolOutput io.Writer) error
}
SourceCompiler compiles or transpiles source code for deployment, preserving the directory structure for readability. toolOutput receives compiler stdout/stderr (tsc output).