Skip to content

Conversation

@Chris-Moller
Copy link
Contributor

@Chris-Moller Chris-Moller commented Dec 17, 2025

Goals

  • Build from public GitHub source via a remote verifiable build service.
  • Print provenance verification (repo/ref/image/digest + signature).
  • Deploy/upgrade without local Docker layering when using verifiable builds or prebuilt verifiable images.
  • Expose app releases including build + dependency builds.

SDK: Build module

Entry

  • createBuildModule(config: BuildModuleConfig): BuildModule

BuildModuleConfig

  • environment?: string (default: sepolia)
  • privateKey?: string (required for submit/logs; not required for public reads)
  • verbose?: boolean
  • clientId?: string
  • skipTelemetry?: boolean

API

  • submit(request: SubmitBuildRequest): Promise<{ buildId: string }> (requires private key)
  • submitAndWait(request, { onLog?, onProgress?, pollIntervalMs?, timeoutMs? }?): Promise<Build>
  • waitForBuild(buildId, { onLog?, onProgress?, pollIntervalMs?, timeoutMs? }?): Promise<Build>
  • get(buildId: string): Promise<Build>
  • getByDigest(digest: string): Promise<Build>
  • verify(identifier: string): Promise<VerifyProvenanceResult>
  • getLogs(buildId: string): Promise<string> (requires private key)
  • streamLogs(buildId: string, pollIntervalMs?: number): AsyncGenerator<LogChunk>

Key types

SubmitBuildRequest

  • repoUrl: string
  • gitRef: string (40-char commit SHA recommended)
  • dockerfilePath?: string (default: Dockerfile)
  • buildContextPath?: string (default: .)
  • dependencies?: string[] (each sha256:<64hex>)
  • caddyfilePath?: string (path inside repo, relative to build context; if omitted, no Caddyfile is copied)

Build

  • buildId, repoUrl, gitRef, status, buildType, imageName, imageUrl?, imageDigest?,
    provenanceJson?, provenanceSignature?, errorMessage?, createdAt, updatedAt,
    dependencies?: Record<string, Build>

Errors (not exhaustive)

  • AuthRequiredError, BuildFailedError, TimeoutError

CLI: Build commands (ecloud compute build ...)

Common flags

  • --environment (ECLOUD_ENV)
  • --rpc-url (ECLOUD_RPC_URL)
  • --private-key (ECLOUD_PRIVATE_KEY) (only required when needed)
  • --verbose

compute build submit

Submits a verifiable build from GitHub source, optionally follows logs and verifies.

Flags

  • --repo (ECLOUD_BUILD_REPO) (prompts if missing)
  • --commit (ECLOUD_BUILD_COMMIT) (prompts if missing)
  • --dockerfile (ECLOUD_BUILD_DOCKERFILE, default: Dockerfile) (prompt default)
  • --context (ECLOUD_BUILD_CONTEXT, default: .) (prompt default)
  • --dependencies sha256:... (repeatable; prompt supports comma-separated)
  • --build-caddyfile (ECLOUD_BUILD_CADDYFILE) (optional)
  • --no-follow (submit and exit)
  • --json

Behavior

  • With --no-follow: prints/returns buildId.
  • Without --no-follow: streams logs, waits for completion, then calls verify() and prints a concise provenance summary.

compute build status <buildId>

  • Fetches the build and prints status (--json prints raw JSON).

compute build logs <buildId> [--follow]

  • Prints build logs; --follow polls and appends.

compute build verify <identifier>

  • Calls verify endpoint and prints verified provenance info.

compute build info <buildId>

  • Calls get(buildId) and prints full build details, including dependencies recursively (--json prints raw JSON).

CLI: App commands (ecloud compute app ...)

compute app deploy / compute app upgrade

Both support a normal flow and a verifiable flow.

Normal flow (no --verifiable)

  • Existing behavior:
    • Build locally from Dockerfile and push, or deploy an existing image ref.
    • Uses --env-file / ECLOUD_ENVFILE_PATH for env vars.

Verifiable flow (either by --verifiable or interactive prompt)

If --verifiable is not provided and you didn’t explicitly pass --dockerfile, you’ll be prompted:

  • Build from verifiable source? (Yes/No)
    • No → normal flow
    • Yes → choose source type:
      • Git source (public GitHub): prompts for repo/commit/dockerfile/context/deps, runs build + verify, then deploys/upgrades without local layering.
      • Prebuilt verifiable image: prompts for docker.io/eigenlayer/eigencloud-containers:<tag>, resolves digest, verifies provenance, then deploys/upgrades as-is.

If --verifiable is provided:

  • Git source mode: --repo + --commit (+ optional build flags)
  • Prebuilt mode: --image-ref docker.io/eigenlayer/eigencloud-containers:<tag>

TLS + Caddyfile behavior (verifiable git mode)

  • After git inputs are collected, the CLI reads DOMAIN from the selected --env-file:
    • If DOMAIN is set and not localhost, it submits the build with caddyfile_path: "Caddyfile" (unless a Caddyfile path was already provided).
  • This prevents TLS-enabled workloads from missing /etc/caddy/Caddyfile in verifiable builds.

CLI: App releases

compute app releases [app-id]

  • Calls GET /apps/:id via UserApiClient.getApp() and prints releases.
  • Prints per-release fields (e.g. rmsReleaseId, publicEnv, upgradeByTime, createdAt, createdAtBlock) plus attached build and dependency builds.
  • Prints oldest → newest so the newest release is at the bottom of terminal output.

import { isTlsEnabledFromEnvFile } from "../../../utils/tls";
import type { SubmitBuildRequest } from "@layr-labs/ecloud-sdk";

export default class AppDeploy extends Command {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

appears this isn't a new bug, but can't deploy in dev without explicitly passing the sepolia-dev environment flag because otherwise it defaults to sepolia, which is not available.

const environment = flags.environment || "sepolia";

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yea this needs to be fixed separately

@solimander
Copy link
Collaborator

solimander commented Dec 19, 2025

an ecloud compute build list command feels necessary (similar to ecloud compute app list), which shows the 10 or 20 most recent builds, including:

  • Build ID
  • Status
  • Repo URL
  • Repo Commit
  • Image URL
  • Created At
  • Provenance, if can be displayed concisely

Right now, it's unclear how I'd get the info to deploy a build if I closed the terminal after submitting it

@solimander
Copy link
Collaborator

solimander commented Dec 19, 2025

Related to the above, it would be nice if ecloud compute build info and similar commands that take a build id would fallback to interactive if no build id is passed, listing the 20 most recent builds, similar to how the app commands work

@solimander
Copy link
Collaborator

After building, it wasn't very clear what the build ID actually is as it's not listed at the bottom of the output after building.

Screenshot 2025-12-19 at 2 02 08 PM

I had to scroll all the way up to the beginning of the logs to see:

starting build "4a833151-b5a2-4d01-a249-9a6424ca0c40"

@solimander
Copy link
Collaborator

Should do some quick UUID validation on the passed build ID before passing to the API. For example, removing one character from the end of a build ID returns Build not found from the API, but it should be a "Invalid build ID" error

@solimander
Copy link
Collaborator

Can we extract the repo name as the suggested app name here? Right now, it's trying to default to eigencloud-containers:

Screenshot 2025-12-19 at 2 09 32 PM

return `${status} ${repoName}@${shortSha} ${shortId} ${created}`;
}

export async function promptBuildIdFromRecentBuilds(options: {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you hook this up to ecloud compute build verify as well pls

});
}

export default class AppReleases extends Command {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be able to view releases for inactive apps as well. need to add "view releases for" to isEligible

this.log(ruleLine);

for (const r of rows) {
this.log(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: for future, should just use a lib for this and app list. cli-table3, table, or console-table-printer

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ahhh yeah will fix it now


verifiableImageUrl = imageRef;
verifiableImageDigest = digest;
suggestedAppBaseName = suggestAppBaseNameFromRepoUrl(verify.repoUrl);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: for prebuilt verifiable images, verify.repoUrl points to the shared eigencloud-containers repo, so the suggested app name isn't useful - we should probably just prompt without a default here

solimander
solimander previously approved these changes Jan 5, 2026
@Chris-Moller Chris-Moller merged commit 539e4d9 into master Jan 5, 2026
3 checks passed
@Chris-Moller Chris-Moller deleted the cm/vbuild-support branch January 5, 2026 16:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants