Skip to content

Bootstrap the Stellar CLI image build#1

Merged
fnando merged 21 commits into
mainfrom
skeleton
May 26, 2026
Merged

Bootstrap the Stellar CLI image build#1
fnando merged 21 commits into
mainfrom
skeleton

Conversation

@fnando

@fnando fnando commented May 19, 2026

Copy link
Copy Markdown
Member

What

First piece of the new stellar-cli-docker repo. Lays the foundation for publishing trusted, SEP-58–compatible Stellar CLI images from this dedicated repo, replacing the unsigned rust:latest-based image currently built out of stellar/stellar-cli.

Adds:

  • Dockerfile — two-stage build. Both stages start from rust:${RUST_VERSION}-slim-bookworm@${RUST_IMAGE_DIGEST}. Builder installs stellar-cli via cargo install --locked --git ... --rev <sha>, then asserts stellar version --only-version matches the declared version so a ref/version mismatch in builds.json fails the build instead of shipping a wrong image. Runtime bakes RUSTUP_TOOLCHAIN=${RUST_VERSION} (so a consumer's rust-toolchain.toml can't silently swap the toolchain), preinstalls wasm32v1-none, sets WORKDIR /source and ENTRYPOINT ["stellar"] per SEP-58, and stamps a full set of OCI + org.stellar.* labels.
  • builds.json + builds.schema.json — single source of truth for what we publish. Each stellar_cli_versions[] entry explicitly declares its own rust_versions and default_rust; there is no cli×rust cross-product. The JSON Schema (draft 2020-12) is strict (additionalProperties: false) and pattern-checks SHAs and digests; cross-field constraints that JSON Schema can't express are enforced by validate-json.sh.
  • Scripts (all named-arg, all with --help):
    • scripts/validate-json.sh — alphabetical keys at every level on every *.json, schema check on builds.json, plus cross-field constraints (default_rust must appear in rust_versions; every referenced rust version must be a key in rust_image_digests).
    • scripts/build-image.sh — local single-image build; resolves all pins from builds.json; defaults --platform to the host's native arch.
    • scripts/refresh-rust-digests.sh — fills blank rust_image_digests entries from docker buildx imagetools inspect. Already-pinned digests are left alone; bumping requires --rust-version <v>.
    • scripts/refresh-stellar-cli-digests.sh — same shape, fills blank stellar_cli_versions[].ref entries from upstream v<version> tags (handles both lightweight and annotated tags).
    • scripts/lib/common.sh — shared helpers.
  • .github/workflows/lint.yml — two parallel jobs: JSON validation (installs check-jsonschema, runs validate-json.sh) and Dockerfile linting (hadolint). All uses: SHA-pinned to current latest (actions/checkout@v6.0.2, hadolint/hadolint-action@v3.3.0).
  • .hadolint.yaml — DL3008 (pin apt versions) silenced with rationale. Pinning apt in bookworm-slim would break the moment a security update lands (Debian removes the old version), and doesn't deliver bit-reproducibility on its own.
  • LICENSE (Apache-2.0), .dockerignore, expanded README.

Why

SEP-58 expects verifiable build images to ship CI provenance, SBOM, pinned bases, and a self-contained toolchain. The existing image meets none of that. Rather than retrofit the old build, we're standing up a dedicated repo where the build inputs, pinning policy, and publish flow are first-class. This PR is the foundation — everything else (publish workflow, SLSA provenance attestation, SBOM, WASM-repro tests, specialised variants, verifier docs) lands incrementally on top.

Notable choices

  • No cli×rust cross-product. Each stellar_cli_versions[] entry carries its own rust_versions list. Newer CLI versions frequently bump MSRV; a cross-product would produce irrelevant or broken images and grow CI cost.
  • Bit-reproducible image rebuilds are explicitly out of scope. SLSA provenance + SBOM (future PR) is the trust anchor. The current pins (base image digest, toolchain version, stellar-cli SHA, --locked) get us "byte-stable given the same builds.json", which is what bldimg verification actually needs.
  • :latest will exist (for casual CLI users who run via container), but verifiers must pin per-arch single-architecture digests. Documented in the README.

Out of scope (deliberate)

Publish workflow, SLSA provenance attestation, SBOM generation, WASM-reproducibility double-build, specialised variants support, and verifier documentation. Each ships as its own PR.

Verification

  • ./scripts/validate-json.sh passes.
  • ./scripts/build-image.sh --stellar-cli-version 26.0.0 --rust-version 1.94.0 builds locally on host-native arch.
  • docker run --rm stellar-cli:26.0.0-rust1.94.0 --version reports stellar 26.0.0.
  • docker run --rm stellar-cli:26.0.0-rust1.94.0 contract build --help works fully offline.
  • All 20 OCI + org.stellar.* labels render via docker inspect.
  • Local hadolint --config .hadolint.yaml Dockerfile is clean.

Copilot AI review requested due to automatic review settings May 19, 2026 18:53

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Introduces the initial foundation for the stellar-cli-docker repository to build and lint SEP-58-oriented Docker images for the Stellar CLI, with build inputs pinned and centrally defined in builds.json.

Changes:

  • Added a pinned, two-stage Dockerfile that installs stellar-cli from an upstream git SHA and validates the installed CLI version during build.
  • Added builds.json plus a strict JSON Schema, along with scripts to validate JSON structure/key ordering and refresh pinned digests/refs.
  • Added CI lint workflow for JSON validation and Dockerfile linting (hadolint), plus supporting repo metadata/docs.

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
Dockerfile Two-stage build producing a pinned Rust + Stellar CLI runtime image with OCI/org.stellar labels.
builds.json Declares the published (cli,rust) pairings and pinned Rust base image digests.
builds.schema.json Draft 2020-12 JSON Schema to validate builds.json structure strictly.
scripts/lib/common.sh Shared helper functions for repo scripts (paths, jq helpers, assertions).
scripts/validate-json.sh Validates JSON key ordering and enforces schema + cross-field constraints.
scripts/build-image.sh Local builder for a single declared (stellar-cli,rust) pair using pinned inputs.
scripts/refresh-rust-digests.sh Maintainer tool to resolve/update rust image digests in builds.json.
scripts/refresh-stellar-cli-digests.sh Maintainer tool to resolve/update stellar-cli git SHAs in builds.json.
.github/workflows/lint.yml CI jobs to validate JSON (schema + constraints) and lint the Dockerfile.
.hadolint.yaml Hadolint configuration (explicitly ignores DL3008 with rationale).
.dockerignore Trims Docker build context to essentials.
README.md Documents image goals (SEP-58), usage, and repo layout.
LICENSE Adds Apache-2.0 licensing text.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread scripts/validate-json.sh Outdated
Comment thread scripts/validate-json.sh Outdated
Comment thread scripts/validate-json.sh
Comment thread scripts/build-image.sh Outdated
Comment thread scripts/build-image.sh
Comment thread scripts/refresh-rust-digests.sh Outdated
Comment thread README.md
@fnando fnando changed the title Add Dockerfile, builds.json, and validation scripts Bootstrap the Stellar CLI image build May 19, 2026
@fnando fnando self-assigned this May 19, 2026
@fnando fnando added this to DevX May 19, 2026
@github-project-automation github-project-automation Bot moved this to Backlog (Not Ready) in DevX May 19, 2026
@fnando fnando moved this from Backlog (Not Ready) to Needs Review in DevX May 19, 2026
@fnando fnando requested review from leighmcculloch and mootz12 May 19, 2026 19:18

@leighmcculloch leighmcculloch left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nice.

Wow that's a lot of bash. Fwiw when we wrote similar scripts for the quickstart repo, we used python3 scripts for things that required more complex manipulation of json, it resulted in more readable code.

Nice use of hadolint and json schema.

Some tweaks inline.

Comment thread Dockerfile Outdated
Comment thread Dockerfile Outdated
Comment thread Dockerfile Outdated
Comment thread Dockerfile Outdated
Comment thread LICENSE Outdated
Comment thread README.md Outdated
Comment thread README.md Outdated
fnando and others added 3 commits May 26, 2026 09:48
Co-authored-by: Leigh <351529+leighmcculloch@users.noreply.github.com>
@fnando

fnando commented May 26, 2026

Copy link
Copy Markdown
Member Author

Fwiw when we wrote similar scripts for the quickstart repo, we used python3 scripts for things that required more complex manipulation of json, it resulted in more readable code.

@leighmcculloch fair point. I'd rather not retrofit the existing scripts right now, but I'll revisit them as soon as the thing is working end-to-end.

@fnando fnando merged commit 22f5939 into main May 26, 2026
7 checks passed
@github-project-automation github-project-automation Bot moved this from Needs Review to Done in DevX May 26, 2026
@fnando fnando deleted the skeleton branch May 26, 2026 17:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

3 participants