Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@ Each image:
- Ships with the `wasm32v1-none` target preinstalled.
- Sets `WORKDIR /source` and `ENTRYPOINT ["stellar"]`.

## IMPORTANT

This is a fork of [stellar-cli-docker](https://github.com/stellar/stellar-cli-docker) as I wanted to make build images for a large set of existing deployed contracts. You should consider this a testbed (bleeding edge) and work with the upstream repo for commits.

We have published a large set of images (everything from [builds.json](./builds.json)) to [Docker Hub under `vrfier/stellar-cli`](https://hub.docker.com/repository/docker/vrfier/stellar-cli/general)

Feel free to run those, or add some more images to `builds.json` and run `./scripts/build_all.py` to generate them locally.

## Quick start

Pull a published image (per-host arch):
Expand Down
127 changes: 124 additions & 3 deletions builds.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,147 @@
"stellar_cli_versions": [
{
"cli_rust_version": "1.90.0-slim-bookworm@sha256:64232e656c058f4468e8d024e990acff04f0fd5a5c0a88a574dc37773d7325c9",
"ref": "8c559e832fd969aa469784b66e70891fadf94f0a",
"rust_versions": [
"1.88.0-slim-trixie@sha256:9a7159329166b45f453351a077367f501aa3e98378f7e327530e7966a139d05f",
"1.90.0-slim-trixie@sha256:7fa728f3678acf5980d5db70960cf8491aff9411976789086676bdf0c19db39e",
"1.91.1-slim-trixie@sha256:f75071363e7f4771769d4cf81b1b7b290e607f4d4459e8731f6abdcee9982dc8",
"1.92.0-slim-trixie@sha256:bf3368a992915f128293ac76917ab6e561e4dda883273c8f5c9f6f8ea37a378e",
"1.94.0-slim-trixie@sha256:f7bf1c266d9e48c8d724733fd97ba60464c44b743eb4f46f935577d3242d81d0"
],
"version": "23.2.0"
},
{
"cli_rust_version": "1.90.0-slim-bookworm@sha256:64232e656c058f4468e8d024e990acff04f0fd5a5c0a88a574dc37773d7325c9",
"ref": "496ac35be7a7d8d923fcde9bbbc650ee593d1f6f",
"rust_versions": [
"1.85.0-slim-bookworm@sha256:1829c432be4a592f3021501334d3fcca24f238432b13306a4e62669dec538e52",
"1.86.0-slim-bookworm@sha256:57d415bbd61ce11e2d5f73de068103c7bd9f3188dc132c97cef4a8f62989e944",
"1.87.0-slim-bookworm@sha256:437507c3e719e4f968033b88d851ffa9f5aceeb2dcc2482cc6cb7647811a55eb",
"1.89.0-slim-trixie@sha256:8cffb8fe4e8a95cf0d6a2060375e5a28aff4c752155aa9f1f9193530769bdf66",
"1.90.0-slim-trixie@sha256:7fa728f3678acf5980d5db70960cf8491aff9411976789086676bdf0c19db39e",
"1.91.1-slim-trixie@sha256:f75071363e7f4771769d4cf81b1b7b290e607f4d4459e8731f6abdcee9982dc8",
"1.95.0-slim-trixie@sha256:e14e87345b4d5964ddcc3491d27ee046a0f23820f340c3c1e24da6880141f7c0"
],
"version": "23.2.1"
},
{
"cli_rust_version": "1.90.0-slim-bookworm@sha256:64232e656c058f4468e8d024e990acff04f0fd5a5c0a88a574dc37773d7325c9",
"ref": "08473ac20016c369067ce0dbca91d9595e72d6d4",
"rust_versions": [
"1.85.0-slim-bookworm@sha256:1829c432be4a592f3021501334d3fcca24f238432b13306a4e62669dec538e52",
"1.88.0-slim-trixie@sha256:9a7159329166b45f453351a077367f501aa3e98378f7e327530e7966a139d05f",
"1.89.0-slim-trixie@sha256:8cffb8fe4e8a95cf0d6a2060375e5a28aff4c752155aa9f1f9193530769bdf66",
"1.90.0-slim-trixie@sha256:7fa728f3678acf5980d5db70960cf8491aff9411976789086676bdf0c19db39e",
"1.91.1-slim-trixie@sha256:f75071363e7f4771769d4cf81b1b7b290e607f4d4459e8731f6abdcee9982dc8",
"1.92.0-slim-trixie@sha256:bf3368a992915f128293ac76917ab6e561e4dda883273c8f5c9f6f8ea37a378e",
"1.93.1-slim-trixie@sha256:c0a38f5662afdb298898da1d70b909af4bda4e0acff2dc52aea6360a9b9c6956"
],
"version": "23.3.0"
},
{
"cli_rust_version": "1.95.0-slim-trixie@sha256:e14e87345b4d5964ddcc3491d27ee046a0f23820f340c3c1e24da6880141f7c0",
"ref": "fc6745f3d4e90d1ef68d14d0ae947404768fa5c0",
"rust_versions": [
"1.85.0-slim-bookworm@sha256:1829c432be4a592f3021501334d3fcca24f238432b13306a4e62669dec538e52",
"1.88.0-slim-trixie@sha256:9a7159329166b45f453351a077367f501aa3e98378f7e327530e7966a139d05f",
"1.89.0-slim-trixie@sha256:8cffb8fe4e8a95cf0d6a2060375e5a28aff4c752155aa9f1f9193530769bdf66",
"1.90.0-slim-trixie@sha256:7fa728f3678acf5980d5db70960cf8491aff9411976789086676bdf0c19db39e",
"1.91.1-slim-trixie@sha256:f75071363e7f4771769d4cf81b1b7b290e607f4d4459e8731f6abdcee9982dc8",
"1.92.0-slim-trixie@sha256:bf3368a992915f128293ac76917ab6e561e4dda883273c8f5c9f6f8ea37a378e",
"1.93.0-slim-trixie@sha256:760ad1d638d70ebbd0c61e06210e1289cbe45ff6425e3ea6e01241de3e14d08e",
"1.93.1-slim-trixie@sha256:c0a38f5662afdb298898da1d70b909af4bda4e0acff2dc52aea6360a9b9c6956",
"1.95.0-slim-trixie@sha256:e14e87345b4d5964ddcc3491d27ee046a0f23820f340c3c1e24da6880141f7c0"
],
"version": "23.4.0"
},
{
"cli_rust_version": "1.95.0-slim-trixie@sha256:e14e87345b4d5964ddcc3491d27ee046a0f23820f340c3c1e24da6880141f7c0",
"ref": "a152ec2488c25136808ad28277c24b3a0765ffd4",
"rust_versions": [
"1.85.0-slim-bookworm@sha256:1829c432be4a592f3021501334d3fcca24f238432b13306a4e62669dec538e52",
"1.86.0-slim-bookworm@sha256:57d415bbd61ce11e2d5f73de068103c7bd9f3188dc132c97cef4a8f62989e944",
"1.89.0-slim-trixie@sha256:8cffb8fe4e8a95cf0d6a2060375e5a28aff4c752155aa9f1f9193530769bdf66",
"1.90.0-slim-trixie@sha256:7fa728f3678acf5980d5db70960cf8491aff9411976789086676bdf0c19db39e",
"1.91.1-slim-trixie@sha256:f75071363e7f4771769d4cf81b1b7b290e607f4d4459e8731f6abdcee9982dc8",
"1.92.0-slim-trixie@sha256:bf3368a992915f128293ac76917ab6e561e4dda883273c8f5c9f6f8ea37a378e",
"1.93.0-slim-trixie@sha256:760ad1d638d70ebbd0c61e06210e1289cbe45ff6425e3ea6e01241de3e14d08e",
"1.93.1-slim-trixie@sha256:c0a38f5662afdb298898da1d70b909af4bda4e0acff2dc52aea6360a9b9c6956"
],
"version": "23.4.1"
},
{
"cli_rust_version": "1.95.0-slim-trixie@sha256:e14e87345b4d5964ddcc3491d27ee046a0f23820f340c3c1e24da6880141f7c0",
"ref": "a64925e9391c3d3b3ef8e53dc60c23db9e6a82e4",
"rust_versions": [
"1.87.0-slim-bookworm@sha256:437507c3e719e4f968033b88d851ffa9f5aceeb2dcc2482cc6cb7647811a55eb",
"1.90.0-slim-trixie@sha256:7fa728f3678acf5980d5db70960cf8491aff9411976789086676bdf0c19db39e",
"1.92.0-slim-trixie@sha256:bf3368a992915f128293ac76917ab6e561e4dda883273c8f5c9f6f8ea37a378e",
"1.93.0-slim-trixie@sha256:760ad1d638d70ebbd0c61e06210e1289cbe45ff6425e3ea6e01241de3e14d08e",
"1.93.1-slim-trixie@sha256:c0a38f5662afdb298898da1d70b909af4bda4e0acff2dc52aea6360a9b9c6956"
],
"version": "25.0.0"
},
{
"cli_rust_version": "1.95.0-slim-trixie@sha256:e14e87345b4d5964ddcc3491d27ee046a0f23820f340c3c1e24da6880141f7c0",
"ref": "a048a57a75762458b487052e0021ea704a926bee",
"rust_versions": [
"1.90.0-slim-bookworm@sha256:64232e656c058f4468e8d024e990acff04f0fd5a5c0a88a574dc37773d7325c9"
"1.86.0-slim-bookworm@sha256:57d415bbd61ce11e2d5f73de068103c7bd9f3188dc132c97cef4a8f62989e944",
"1.87.0-slim-bookworm@sha256:437507c3e719e4f968033b88d851ffa9f5aceeb2dcc2482cc6cb7647811a55eb",
"1.88.0-slim-trixie@sha256:9a7159329166b45f453351a077367f501aa3e98378f7e327530e7966a139d05f",
"1.89.0-slim-trixie@sha256:8cffb8fe4e8a95cf0d6a2060375e5a28aff4c752155aa9f1f9193530769bdf66",
"1.90.0-slim-trixie@sha256:7fa728f3678acf5980d5db70960cf8491aff9411976789086676bdf0c19db39e",
"1.91.1-slim-trixie@sha256:f75071363e7f4771769d4cf81b1b7b290e607f4d4459e8731f6abdcee9982dc8",
"1.92.0-slim-trixie@sha256:bf3368a992915f128293ac76917ab6e561e4dda883273c8f5c9f6f8ea37a378e",
"1.93.0-slim-trixie@sha256:760ad1d638d70ebbd0c61e06210e1289cbe45ff6425e3ea6e01241de3e14d08e",
"1.93.1-slim-trixie@sha256:c0a38f5662afdb298898da1d70b909af4bda4e0acff2dc52aea6360a9b9c6956",
"1.94.0-slim-trixie@sha256:f7bf1c266d9e48c8d724733fd97ba60464c44b743eb4f46f935577d3242d81d0",
"1.94.1-slim-trixie@sha256:cf09adf8c3ebaba10779e5c23ff7fe4df4cccdab8a91f199b0c142c53fef3e1a",
"1.95.0-slim-trixie@sha256:e14e87345b4d5964ddcc3491d27ee046a0f23820f340c3c1e24da6880141f7c0",
"1.96.0-slim-trixie@sha256:26abcef3d79b8d890c4ceb17093154573e1f6479cf6dd7c1450043b8458350f6"
],
"version": "25.1.0"
},
{
"cli_rust_version": "1.95.0-slim-trixie@sha256:e14e87345b4d5964ddcc3491d27ee046a0f23820f340c3c1e24da6880141f7c0",
"ref": "28484880988199233a7e8e87c97cb12dac323cb3",
"rust_versions": [
"1.86.0-slim-bookworm@sha256:57d415bbd61ce11e2d5f73de068103c7bd9f3188dc132c97cef4a8f62989e944",
"1.89.0-slim-trixie@sha256:8cffb8fe4e8a95cf0d6a2060375e5a28aff4c752155aa9f1f9193530769bdf66",
"1.90.0-slim-trixie@sha256:7fa728f3678acf5980d5db70960cf8491aff9411976789086676bdf0c19db39e",
"1.91.1-slim-trixie@sha256:f75071363e7f4771769d4cf81b1b7b290e607f4d4459e8731f6abdcee9982dc8",
"1.92.0-slim-trixie@sha256:bf3368a992915f128293ac76917ab6e561e4dda883273c8f5c9f6f8ea37a378e",
"1.93.0-slim-trixie@sha256:760ad1d638d70ebbd0c61e06210e1289cbe45ff6425e3ea6e01241de3e14d08e",
"1.93.1-slim-trixie@sha256:c0a38f5662afdb298898da1d70b909af4bda4e0acff2dc52aea6360a9b9c6956",
"1.94.0-slim-trixie@sha256:f7bf1c266d9e48c8d724733fd97ba60464c44b743eb4f46f935577d3242d81d0",
"1.94.1-slim-trixie@sha256:cf09adf8c3ebaba10779e5c23ff7fe4df4cccdab8a91f199b0c142c53fef3e1a",
"1.95.0-slim-trixie@sha256:e14e87345b4d5964ddcc3491d27ee046a0f23820f340c3c1e24da6880141f7c0"
],
"version": "25.2.0"
},
{
"cli_rust_version": "1.95.0-slim-trixie@sha256:e14e87345b4d5964ddcc3491d27ee046a0f23820f340c3c1e24da6880141f7c0",
"ref": "60f7458e7ecffddf2f2d91dc6d0d2db4fab03ecc",
"rust_versions": [
"1.85.0-slim-bookworm@sha256:1829c432be4a592f3021501334d3fcca24f238432b13306a4e62669dec538e52",
"1.88.0-slim-trixie@sha256:9a7159329166b45f453351a077367f501aa3e98378f7e327530e7966a139d05f",
"1.90.0-slim-trixie@sha256:7fa728f3678acf5980d5db70960cf8491aff9411976789086676bdf0c19db39e",
"1.92.0-slim-trixie@sha256:bf3368a992915f128293ac76917ab6e561e4dda883273c8f5c9f6f8ea37a378e",
"1.93.0-slim-trixie@sha256:760ad1d638d70ebbd0c61e06210e1289cbe45ff6425e3ea6e01241de3e14d08e",
"1.94.0-slim-trixie@sha256:f7bf1c266d9e48c8d724733fd97ba60464c44b743eb4f46f935577d3242d81d0"
"1.93.1-slim-trixie@sha256:c0a38f5662afdb298898da1d70b909af4bda4e0acff2dc52aea6360a9b9c6956",
"1.94.0-slim-trixie@sha256:f7bf1c266d9e48c8d724733fd97ba60464c44b743eb4f46f935577d3242d81d0",
"1.94.1-slim-trixie@sha256:cf09adf8c3ebaba10779e5c23ff7fe4df4cccdab8a91f199b0c142c53fef3e1a",
"1.95.0-slim-trixie@sha256:e14e87345b4d5964ddcc3491d27ee046a0f23820f340c3c1e24da6880141f7c0"
],
"version": "26.0.0"
},
{
"cli_rust_version": "1.95.0-slim-trixie@sha256:e14e87345b4d5964ddcc3491d27ee046a0f23820f340c3c1e24da6880141f7c0",
"ref": "1228cff8022b804659750b94b315932b0e0f3f6a",
"rust_versions": [
"1.95.0-slim-trixie@sha256:e14e87345b4d5964ddcc3491d27ee046a0f23820f340c3c1e24da6880141f7c0"
"1.89.0-slim-trixie@sha256:8cffb8fe4e8a95cf0d6a2060375e5a28aff4c752155aa9f1f9193530769bdf66",
"1.95.0-slim-trixie@sha256:e14e87345b4d5964ddcc3491d27ee046a0f23820f340c3c1e24da6880141f7c0",
"1.96.0-slim-trixie@sha256:26abcef3d79b8d890c4ceb17093154573e1f6479cf6dd7c1450043b8458350f6"
],
"version": "26.1.0"
}
Expand Down
171 changes: 171 additions & 0 deletions scripts/build_all.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
#!/usr/bin/env -S uv run python
"""Build and publish every (cli, rust base) pair declared in builds.json.

This is the local, all-in-one equivalent of the `publish` GitHub workflow:
for each stellar-cli version it walks the same `resolve_matrix.py` rows
(latest pin per rust label) and builds+pushes each pair to the registry.

Two arch modes:
* single-arch (default, --arch amd64): build one platform and push it
straight to the final pull tag `<registry>:<cli>-rust<key>` — no
per-arch suffix, no manifest list to assemble.
* --arch all: build both amd64 and arm64 as per-arch tags
`<registry>:<cli>-rust<key>-<arch>`, then assemble the multi-arch
manifest list with `publish_manifests.py` (mirrors the CI workflow).

Optionally re-points the moving `:<cli>` / `:latest` aliases via
`publish_aliases.py`.

Defaults target the vrfier fork:
registry ghcr.io/vrfier/stellar-cli
source-repo vrfier/stellar-cli-docker
arch amd64 (single-arch)

Pushing is an outward-facing action: run with --dry-run first to print the
exact commands, and make sure you are logged in to the registry
(e.g. `docker login ghcr.io`) before a real run.
"""

import argparse
import sys

import build_image
import publish_aliases
import publish_manifests
import resolve_matrix
import tag_names
from lib import builds, common

DEFAULT_REGISTRY = "docker.io/vrfier/stellar-cli"
DEFAULT_SOURCE_REPO = "vrfier/stellar-cli-docker"


def build_parser() -> argparse.ArgumentParser:
parser = argparse.ArgumentParser(description=__doc__.splitlines()[0])
parser.add_argument("--registry", default=DEFAULT_REGISTRY, metavar="REF")
parser.add_argument("--source-repo", default=DEFAULT_SOURCE_REPO, metavar="SLUG")
parser.add_argument(
"--stellar-cli-version",
default="",
metavar="V",
help="Limit to one cli version (default: every version in builds.json).",
)
parser.add_argument(
"--arch",
choices=("amd64", "arm64", "all"),
default="amd64",
help=(
"Architecture(s) to build. Default 'amd64' is single-arch: the image "
"is pushed straight to <cli>-rust<key> with no manifest list. 'all' "
"builds amd64+arm64 per-arch tags and assembles the multi-arch list."
),
)
parser.add_argument(
"--aliases",
action="store_true",
help="Also re-point the moving :<cli> and :latest aliases.",
)
parser.add_argument(
"--skip-manifests",
action="store_true",
help="With --arch all, only push per-arch images; skip the multi-arch lists.",
)
parser.add_argument(
"--dry-run",
action="store_true",
help="Print every build/manifest command without running anything.",
)
return parser


def clis_to_build(data: dict, only_cli: str) -> list[str]:
versions = [entry["version"] for entry in data.get("stellar_cli_versions", [])]
if not only_cli:
return versions
if only_cli not in versions:
common.die(f"stellar-cli {only_cli} is not declared in builds.json")
return [only_cli]


def build_one_cli(cli: str, args: argparse.Namespace) -> None:
"""Build + push every image for one cli version's matrix rows.

Single-arch (--arch amd64/arm64) keeps only the matching rows and pushes
each straight to the final `<cli>-rust<key>` pull tag. --arch all keeps
both arches and pushes per-arch `<cli>-rust<key>-<arch>` tags that
publish_manifests.py later stitches into a multi-arch list.
"""
single_arch = args.arch != "all"
data = builds.load()
rows = resolve_matrix.build_matrix(data, only_cli=cli)["include"]
if single_arch:
rows = [r for r in rows if r["platform"] == f"linux/{args.arch}"]
common.log(f"::group::build {cli} ({len(rows)} image(s), arch={args.arch})")
for row in rows:
# Single-arch pushes straight to the list tag (no -<arch> suffix) since
# there is no second arch to stitch together; --arch all keeps the
# per-arch suffix for the manifest step.
tag = tag_names.compose_tag(
stellar_cli_version=row["stellar_cli_version"],
rust_version=row["rust_base_key"],
platform="" if single_arch else row["platform"],
)
build_argv = [
"--stellar-cli-version",
row["stellar_cli_version"],
"--rust-version",
row["rust_base_key"],
"--rust-image-digest",
row["rust_image_digest"],
"--platform",
row["platform"],
"--tag",
f"{args.registry}:{tag}",
"--source-repo",
args.source_repo,
"--push",
]
if args.dry_run:
common.log("build_image.py " + " ".join(build_argv))
else:
rc = build_image.main(build_argv)
if rc != 0:
common.die(f"build_image failed for {cli} {tag} (exit {rc})")
common.log("::endgroup::")


def main(argv: list[str] | None = None) -> int:
args = build_parser().parse_args(argv)
common.preflight_checks(["buildx"])

data = builds.load()
clis = clis_to_build(data, args.stellar_cli_version)
common.log(f"building {len(clis)} cli version(s) into {args.registry}")
common.log(f"source-repo {args.source_repo}")
if args.dry_run:
common.log("(dry run — no images will be built or pushed)")

for cli in clis:
build_one_cli(cli, args)

# Single-arch already pushed straight to the list tag, so there is no
# per-arch list to assemble — only --arch all needs the manifest step.
if args.arch == "all" and not args.skip_manifests:
manifest_argv = ["--stellar-cli-version", cli, "--registry", args.registry]
if args.dry_run:
manifest_argv.append("--dry-run")
publish_manifests.main(manifest_argv)

if args.aliases:
alias_argv = ["--stellar-cli-version", cli, "--registry", args.registry]
if args.dry_run:
alias_argv.append("--dry-run")
publish_aliases.main(alias_argv)

common.log("")
common.log(f"done: {len(clis)} cli version(s) processed")
return 0


if __name__ == "__main__":
sys.exit(main())
12 changes: 11 additions & 1 deletion scripts/build_image.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,15 @@ def build_parser() -> argparse.ArgumentParser:
parser.add_argument("--platform", default="", metavar="P")
parser.add_argument("--tag", default="", metavar="REF")
parser.add_argument("--source-repo", default="stellar/stellar-cli-docker", metavar="SLUG")
parser.add_argument(
"--push",
action="store_true",
help=(
"Push the built image to its registry-qualified --tag instead of "
"loading it into the local docker (--load). Required for cross-arch "
"builds, which cannot be loaded into the host docker."
),
)
return parser


Expand Down Expand Up @@ -53,12 +62,13 @@ def main(argv: list[str] | None = None) -> int:
common.log(f" cli-build rust ({cli_rust_digest})")
common.log(f" base rust:{parsed.version}-{parsed.suffix}")
common.log(f" platform {args.platform or '<host native>'}")
common.log(f" output {'push to registry' if args.push else 'load into local docker'}")

cmd = ["docker", "buildx", "build"]
if args.platform:
cmd += ["--platform", args.platform]
cmd += [
"--load",
"--push" if args.push else "--load",
"--build-arg",
f"RUST_VERSION={parsed.version}",
"--build-arg",
Expand Down
Loading