From ffc62c121d3002de30f341277aa6b74dab450a1a Mon Sep 17 00:00:00 2001 From: Zhe Li Date: Thu, 9 Jul 2026 12:36:46 +0200 Subject: [PATCH 1/2] docs: add canonical installer script and wire CI check Point install instructions at the new root install.sh that downloads canton-devkit releases, and validate the script syntax in CI so installer regressions are caught early. --- .github/workflows/ci.yml | 5 ++ README.md | 18 +++-- docs/getting-started.md | 16 ++--- docs/homebrew.md | 4 +- docs/packaging.md | 6 ++ install.sh | 143 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 176 insertions(+), 16 deletions(-) create mode 100644 install.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 266ba94f..46006e09 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,6 +7,7 @@ on: - "go.mod" - "go.sum" - ".github/workflows/ci.yml" + - "install.sh" - "docs/design/mockups/**.jsx" - "frontend/**" - "Makefile" @@ -26,6 +27,7 @@ on: - "go.mod" - "go.sum" - ".github/workflows/ci.yml" + - "install.sh" - "docs/design/mockups/**.jsx" - "frontend/**" - "Makefile" @@ -56,6 +58,9 @@ jobs: go-version-file: go.mod cache: false + - name: Validate install.sh syntax + run: sh -n install.sh + - name: Build run: go build ./... diff --git a/README.md b/README.md index 5be6023b..7c0955c0 100644 --- a/README.md +++ b/README.md @@ -52,16 +52,20 @@ components: then `dpm install package` and use it as `dpm localnet `. -For a standalone binary, use the quick-install script: +For a quick standalone install on macOS arm64 or Linux amd64: -```bash -curl -fsSL https://raw.githubusercontent.com/bitdynamics-ab/homebrew-canton-devkit/main/install.sh | sh +```sh +curl -fsSL https://raw.githubusercontent.com/bitdynamics-ab/canton-devkit/main/install.sh | sh ``` -Homebrew, APT for -Debian/Ubuntu, manual platform downloads, and `go install` are also -supported — the [installation guide](docs/getting-started.md) covers each -path step by step. +As a standalone binary, you can also download the archive for your +platform (macOS arm64, Linux amd64, Windows amd64) from the +[releases page](https://github.com/bitdynamics-ab/canton-devkit/releases) +and verify it against the `SHA256SUMS` file published with each release. +Homebrew (`brew install bitdynamics-ab/canton-devkit/canton-devkit`), an APT +repository for Debian/Ubuntu, and `go install` are also supported — the +[installation guide](docs/getting-started.md) covers each path +step by step. Both paths ship the same binary; `dpm localnet ` and `canton-devkit localnet ` are interchangeable everywhere below. diff --git a/docs/getting-started.md b/docs/getting-started.md index 99e51874..81081c04 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -77,29 +77,28 @@ contains the `canton-devkit` binary plus `LICENSE` and `README.md`. Every release also publishes a single `SHA256SUMS` file covering all archives. ### Quick install (macOS arm64 / Linux amd64) - ```bash -curl -fsSL https://raw.githubusercontent.com/bitdynamics-ab/homebrew-canton-devkit/main/install.sh | sh +curl -fsSL https://raw.githubusercontent.com/bitdynamics-ab/canton-devkit/main/install.sh | sh ``` Or with `wget`: ```bash -wget -qO- https://raw.githubusercontent.com/bitdynamics-ab/homebrew-canton-devkit/main/install.sh | sh +wget -qO- https://raw.githubusercontent.com/bitdynamics-ab/canton-devkit/main/install.sh | sh ``` Options (pass as environment variables): ```bash # Pin a specific version -curl -fsSL https://raw.githubusercontent.com/bitdynamics-ab/homebrew-canton-devkit/main/install.sh | VERSION=0.12.2 sh +curl -fsSL https://raw.githubusercontent.com/bitdynamics-ab/canton-devkit/main/install.sh | VERSION=0.12.2 sh # Custom install directory -curl -fsSL https://raw.githubusercontent.com/bitdynamics-ab/homebrew-canton-devkit/main/install.sh | INSTALL_DIR=/usr/local/bin sh +curl -fsSL https://raw.githubusercontent.com/bitdynamics-ab/canton-devkit/main/install.sh | INSTALL_DIR=/usr/local/bin sh ``` The installer detects your platform, downloads the matching archive from -the [releases page](https://github.com/bitdynamics-ab/homebrew-canton-devkit/releases), +the [releases page](https://github.com/bitdynamics-ab/canton-devkit/releases), verifies the SHA-256 checksum, and installs to `~/.local/bin` by default. It warns when that directory is not on your `PATH`. @@ -122,8 +121,9 @@ brew update brew upgrade canton-devkit ``` -The formula downloads platform-specific release tarballs from the -[distribution repo releases page](https://github.com/bitdynamics-ab/homebrew-canton-devkit/releases). +The formula downloads platform-specific release tarballs from the tap +repository release page: +[`bitdynamics-ab/homebrew-canton-devkit/releases`](https://github.com/bitdynamics-ab/homebrew-canton-devkit/releases). > See the [Homebrew guide](homebrew.md) for the tap layout and how the > formula is kept in sync on each release. diff --git a/docs/homebrew.md b/docs/homebrew.md index c8aef06e..5a902119 100644 --- a/docs/homebrew.md +++ b/docs/homebrew.md @@ -8,7 +8,9 @@ following the standard Homebrew tap layout. This source repository does not keep a `Formula/` directory. Homebrew distribution files are maintained in `homebrew-canton-devkit`; this repository only -keeps the release helper script and docs that describe the process. +keeps the canonical `install.sh` script and docs that describe the process. +The tap repository keeps the Homebrew formula, APT repository metadata, +and a redirecting `install.sh` for backward compatibility. ## Install diff --git a/docs/packaging.md b/docs/packaging.md index 0277c12a..bf2da65d 100644 --- a/docs/packaging.md +++ b/docs/packaging.md @@ -35,6 +35,12 @@ tar -xzf canton-devkit_v0.7.0_linux_amd64.tar.gz ./canton-devkit localnet --help ``` +For macOS arm64 and Linux amd64, a scripted installer is also available: + +```sh +curl -fsSL https://raw.githubusercontent.com/bitdynamics-ab/canton-devkit/main/install.sh | sh +``` + > **Version-string asymmetry:** the standalone archive filenames keep the > `v` prefix (`canton-devkit_v0.7.0_linux_amd64.tar.gz`), matching the > git tag, while the DPM/OCI tag strips it diff --git a/install.sh b/install.sh new file mode 100644 index 00000000..2b2a2bb8 --- /dev/null +++ b/install.sh @@ -0,0 +1,143 @@ +#!/bin/sh +# Canton DevKit installer +# Usage: curl -fsSL https://raw.githubusercontent.com/bitdynamics-ab/canton-devkit/main/install.sh | sh +# +# Environment variables: +# VERSION - pin a specific version (e.g. VERSION=0.12.2) +# INSTALL_DIR - override install location (default: ~/.local/bin) + +set -eu + +REPO="bitdynamics-ab/canton-devkit" +GITHUB_API="https://api.github.com/repos/${REPO}/releases/latest" +GITHUB_DL="https://github.com/${REPO}/releases/download" +DEFAULT_INSTALL_DIR="${HOME}/.local/bin" + +info() { printf '[canton-devkit] %s\n' "$*"; } +error() { printf '[canton-devkit] ERROR: %s\n' "$*" >&2; exit 1; } + +fetch() { + if command -v curl >/dev/null 2>&1; then + curl -fsSL "$1" + elif command -v wget >/dev/null 2>&1; then + wget -qO- "$1" + else + error "need 'curl' or 'wget' to download files" + fi +} + +detect_platform() { + os="$(uname -s)" + arch="$(uname -m)" + + case "${os}" in + Darwin) os="darwin" ;; + Linux) os="linux" ;; + *) error "unsupported OS: ${os} (supported: macOS, Linux)" ;; + esac + + case "${arch}" in + arm64 | aarch64) arch="arm64" ;; + x86_64 | amd64) arch="amd64" ;; + *) error "unsupported architecture: ${arch} (supported: arm64, amd64)" ;; + esac + + if [ "${os}" = "darwin" ] && [ "${arch}" != "arm64" ]; then + error "macOS builds are only available for Apple Silicon (arm64), got: ${arch}" + fi + if [ "${os}" = "linux" ] && [ "${arch}" != "amd64" ]; then + error "Linux builds are only available for x86_64 (amd64), got: ${arch}" + fi + + PLATFORM="${os}_${arch}" +} + +resolve_version() { + if [ -n "${VERSION:-}" ]; then + info "using pinned version: ${VERSION}" + return + fi + + info "fetching latest version from GitHub..." + VERSION=$( + fetch "${GITHUB_API}" | sed -n 's/.*"tag_name"[[:space:]]*:[[:space:]]*"v\{0,1\}\([^"]*\)".*/\1/p' + ) + + if [ -z "${VERSION}" ]; then + error "could not determine latest version from GitHub API" + fi + + info "latest version: ${VERSION}" +} + +download_and_verify() { + TARBALL="canton-devkit_v${VERSION}_${PLATFORM}.tar.gz" + TARBALL_URL="${GITHUB_DL}/v${VERSION}/${TARBALL}" + CHECKSUMS_URL="${GITHUB_DL}/v${VERSION}/SHA256SUMS" + + TMPDIR="$(mktemp -d)" + trap 'rm -rf "${TMPDIR}"' EXIT + + info "downloading ${TARBALL}..." + fetch "${TARBALL_URL}" >"${TMPDIR}/${TARBALL}" || error "download failed: ${TARBALL_URL}" + + info "downloading SHA256SUMS..." + fetch "${CHECKSUMS_URL}" >"${TMPDIR}/SHA256SUMS" || error "download failed: ${CHECKSUMS_URL}" + + info "verifying checksum..." + EXPECTED=$(grep " ${TARBALL}\$" "${TMPDIR}/SHA256SUMS" | awk '{print $1}') + if [ -z "${EXPECTED}" ]; then + error "no checksum found for ${TARBALL} in SHA256SUMS" + fi + + if command -v sha256sum >/dev/null 2>&1; then + ACTUAL=$(sha256sum "${TMPDIR}/${TARBALL}" | awk '{print $1}') + elif command -v shasum >/dev/null 2>&1; then + ACTUAL=$(shasum -a 256 "${TMPDIR}/${TARBALL}" | awk '{print $1}') + else + error "need 'sha256sum' or 'shasum' to verify download" + fi + + if [ "${EXPECTED}" != "${ACTUAL}" ]; then + error "checksum mismatch!\n expected: ${EXPECTED}\n actual: ${ACTUAL}" + fi + info "checksum verified." +} + +install_binary() { + INSTALL_DIR="${INSTALL_DIR:-${DEFAULT_INSTALL_DIR}}" + + mkdir -p "${INSTALL_DIR}" + + info "extracting canton-devkit to ${INSTALL_DIR}..." + tar -xzf "${TMPDIR}/${TARBALL}" -C "${TMPDIR}" + mv "${TMPDIR}/canton-devkit" "${INSTALL_DIR}/canton-devkit" + chmod +x "${INSTALL_DIR}/canton-devkit" + + info "installed canton-devkit v${VERSION} to ${INSTALL_DIR}/canton-devkit" + + case ":${PATH}:" in + *":${INSTALL_DIR}:"*) ;; + *) + printf '\n' + info "WARNING: ${INSTALL_DIR} is not in your PATH." + info "Add this to your shell profile (~/.bashrc, ~/.zshrc, etc.):" + printf '\n export PATH="%s:$PATH"\n\n' "${INSTALL_DIR}" + ;; + esac +} + +main() { + info "Canton DevKit Installer" + printf '\n' + + detect_platform + resolve_version + download_and_verify + install_binary + + printf '\n' + info "Done. Run 'canton-devkit --help' to get started." +} + +main From 92d68569a4f1265b62efc6df51dc281d4a5c9fdd Mon Sep 17 00:00:00 2001 From: Zhe Li Date: Thu, 9 Jul 2026 13:04:02 +0200 Subject: [PATCH 2/2] docs: fix DPM install example and ignore tmp/ Add daml-script to the README daml.yaml example and ignore tmp/ so local scratch directories stay out of commits. --- .gitignore | 2 ++ README.md | 27 ++++++++++++++++----------- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/.gitignore b/.gitignore index 13d35e53..5cde9d7a 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,5 @@ internal/ui/dist/* # worktrunk configs .config/wt.toml + +tmp/ diff --git a/README.md b/README.md index 7c0955c0..61b4e326 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,7 @@ recommended) and 10 GB of free disk — see the ## Install Through the dpm ([Daml Package Manager](https://docs.canton.network/sdks-tools/cli-tools/dpm)), in a project's `daml.yaml`. Ensure you remove the sdk-version field from the file. For example, if your current daml.yaml file is: + ```yaml sdk-version: 3.5.2 name: daml-test-1 @@ -35,6 +36,7 @@ dependencies: ``` You should use the following daml.yaml file: + ```yaml #sdk-version: 3.5.2 name: daml-test-1 @@ -47,12 +49,13 @@ dependencies: - daml-script components: - damlc:3.5.2 + - daml-script:3.5.2 - oci://ghcr.io/bitdynamics-ab/canton-devkit:latest ``` then `dpm install package` and use it as `dpm localnet `. -For a quick standalone install on macOS arm64 or Linux amd64: +For a quick standalone install on macOS or Linux: ```sh curl -fsSL https://raw.githubusercontent.com/bitdynamics-ab/canton-devkit/main/install.sh | sh @@ -82,16 +85,18 @@ canton-devkit localnet down demo The command surface covers the full development loop: -| Area | Commands | -|------|----------| -| Lifecycle | `up` `down` `stop` `start` `restart` `pause` `resume` `clean` `list` `status` `logs` | -| Host checks | `doctor` — the same preflight `up` runs, with remediation hints | -| App wiring | `env` `creds` — endpoints, party IDs, and JWTs for tests and CI | -| DAR management | `dar upload / list / info / download / diff / remove / build-upload / watch` | -| Ledger inspection | `contracts ls / watch` · `tx ls / replay` | -| Tokens | `token create / mint / transfer / burn / balance` | -| State | `snapshot` / `restore` — a portable `.tgz` of a network's full state | -| Versions | `versions` — pinned Splice releases, keyed by commit SHA | + +| Area | Commands | +| ----------------- | ------------------------------------------------------------------------------------ | +| Lifecycle | `up` `down` `stop` `start` `restart` `pause` `resume` `clean` `list` `status` `logs` | +| Host checks | `doctor` — the same preflight `up` runs, with remediation hints | +| App wiring | `env` `creds` — endpoints, party IDs, and JWTs for tests and CI | +| DAR management | `dar upload / list / info / download / diff / remove / build-upload / watch` | +| Ledger inspection | `contracts ls / watch` · `tx ls / replay` | +| Tokens | `token create / mint / transfer / burn / balance` | +| State | `snapshot` / `restore` — a portable `.tgz` of a network's full state | +| Versions | `versions` — pinned Splice releases, keyed by commit SHA | + Token commands support both Canton token-standard generations, routed per instrument: [CIP-0056](https://github.com/global-synchronizer-foundation/cips/blob/main/cip-0056/cip-0056.md)