Deployment sources
Understand how folders, Git repositories, images, Compose files, and static sites become deployment input.
A deployment source answers what Appaloft should deploy. It can be a local folder, Git repository, Docker image, Compose file, or static site output.
The source is not a substitute for project, server, environment, or domain fields. Appaloft reads source evidence during detect and turns it into an explainable plan during plan.
Existing entrypoints should use the same source vocabulary. A Web source field, CLI positional source or --source, and API source input should all point here instead of redefining the concept.
Common kinds:
| Kind | Fits | User should confirm |
|---|---|---|
| Local folder | CLI local deployment and experiments. | Working directory, ignored files, build output. |
| Git repository | Repeatable deploys, CI, preview. | Repository URL, ref, base directory, access. |
| Docker/OCI image | Existing runtime artifact. | Image address, tag, exposed port. |
| Compose file | Multi-container or existing Compose setup. | Compose file path, service name, exposed port. |
| Static site | Frontend static output. | Build command and publish directory. |
If unsure, choose the kind closest to the artifact you already have. The runtime profile explains how Appaloft should run it.
Users should see whether the source is readable, whether the ref or path exists, whether the static output is clear, and whether the source conflicts with the resource runtime profile.
The Web console should warn before submit when fields like Git ref, base directory, or static output are missing. The CLI should report unreadable paths, inaccessible repositories, and empty source as input errors. The HTTP API should return structured validation errors with field names and recovery hints.
CLI source examples:
appaloft deploy ./apps/web --method static --publish-dir buildappaloft deploy ./dist --as static-siteappaloft deploy https://github.com/example/web \
--method static \
--publish-dir dist \
--resource-name webResource source profile example:
appaloft resource configure-source res_web \
--kind git-repository \
--locator https://github.com/example/web \
--git-ref main \
--base-directory apps/webWhen you already have a dist, build, or similar static output directory, pass that directory as
the Appaloft source:
appaloft deploy ./dist --as static-siteThis changes only the user-layer entry experience. It normalizes to a static-site Resource and an
ordinary deployment request; it does not add a quick-deploy.create operation or upload the
directory to an Appaloft hosted cloud. Unless you explicitly choose a hosted feature, the target is
still the server or environment you selected.
Once accepted, source becomes part of the deployment snapshot. Later resource source profile changes do not change completed or running deployments.
Deployment details should show a safe source summary, such as repository, ref, base directory, image tag, or static output directory. Secret tokens, private repository credentials, and sensitive local path fragments should not appear in logs or diagnostics.
Recovery examples:
- Local folder does not exist: check the CLI working directory or pass an absolute path.
- Git repository is inaccessible: check credentials, repository URL, ref, and network.
- Static output is empty: confirm the build command produced artifacts.
- Source and runtime profile conflict: update the runtime profile or choose a better source kind.
If the resource already points at an old source, use Deployment recovery.
Source auto-deploy turns a verified source event into an ordinary deployment request, without adding
branch, webhook, or delivery fields to deployments.create. The first active ingestion route is the
Resource-scoped generic signed webhook:
POST /api/resources/{resourceId}/source-events/generic-signedWhen enabled, the policy belongs to one Resource and is bound to that Resource's current source profile. If the Resource source changes later, the old policy becomes blocked until a user explicitly acknowledges that the new source should still trigger auto-deploy.
Git provider webhooks and generic signed webhooks must be verified before policy matching. Generic
signed webhooks use X-Appaloft-Signature with sha256=<hex> or bare HMAC SHA-256 hex. The policy
secret reference must use resource-secret:<KEY>, where <KEY> is a runtime secret variable on the
same Resource. Appaloft stores only safe reference metadata, not secret values, signature headers, or
raw payloads.
To rotate a secret, replace the underlying secret reference first, then acknowledge the auto-deploy policy when needed.
The source event is written to a durable record before deployment dispatch. Duplicate delivery uses the provider delivery id, generic idempotency key, or a bounded-window key over source, ref, revision, and event kind. Generic signed route dedupe is scoped to the route Resource.
A duplicate event must not create a second deployment. Users should be able to see deduped status
and the original source event id in the source event read model.
A verified event may still create no deployment. Common reasons include unmatched ref, no enabled policy, disabled policy, or a policy blocked pending acknowledgement after a source binding change.
source-events.list and source-events.show should display safe reason codes, matched Resources,
and created deployment ids. Logs and UI must not expose webhook secrets, provider tokens, or raw
payloads.
The first Phase 7 ingestion path records source event state and synchronous dispatch results; it does not promise automatic background retry. If dispatch fails, inspect source event detail first, then fix the source profile, secret reference, policy state, or runtime blocker.
After the fix, use appaloft source-event replay <sourceEventId> --resource <resourceId> or
POST /api/source-events/{sourceEventId}/replay to replay retained safe delivery facts. Replay
re-matches current Resource policy and uses ordinary deployments.create admission; it does not
read raw webhook payloads, signatures, provider tokens, or webhook secrets.
If a deployment was created, use ordinary deployment recovery/readiness, retry, redeploy, or rollback semantics rather than replaying the webhook payload.
Use appaloft source-event prune --before <iso> or POST /api/source-events/prune to inspect
retained source event deliveries before cleanup. Prune defaults to dry-run and returns matched
counts by status and source kind. Add --dry-run false only after the scope and cutoff are
reviewed.
Retention cleanup removes only persisted safe source event diagnostics. It does not delete Resources, deployments, webhook secrets, provider tokens, raw payloads, or replay capability for events outside the selected cutoff and filters.