Repository navigation
feat: config-driven builds with per-checkout deployment state - #630
Merged
Merged
Conversation
Run as `stellar scaffold`, stellar-cli copies its `network use` default into STELLAR_NETWORK, so builds labelled it as an explicit choice. `config show` now resolves the network the same way `build` does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QhmaWLv4yExX8LahP5UtUb
A version 2 scaffold.yml declares what each network deploys and binds, so `build` and `watch` always follow it; `--build-clients` is noted as no longer needed. environments.toml projects still opt in with the flag. `init` without a frontend and `upgrade` only compile, and "Not deploying" now names the network. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QhmaWLv4yExX8LahP5UtUb
Drop `--build-clients` from version 2 examples, explain the network precedence, and stop pairing STELLAR_NETWORK with PUBLIC_* values now that the frontend reads its network from the generated clients. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QhmaWLv4yExX8LahP5UtUb
Records the contract ID and alias Scaffold saved for each contract, per network, with the network's passphrase so a name that now points at another chain is treated as empty. The directory writes its own .gitignore. Aliases are prefixed with the workspace directory's name so separate checkouts, like git worktrees, don't share them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QhmaWLv4yExX8LahP5UtUb
…ases stellar-cli's contract aliases are machine-wide, so two projects with a contract of the same name shared one: the second build adopted, or upgraded, the first project's contract. `build` now looks up what this checkout deployed in .scaffold/state.json and records each deploy there. It still saves a stellar-cli alias for hand-run commands, prefixed with the directory name, and only when the alias is free or already Scaffold's, so one made by hand is never overwritten. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QhmaWLv4yExX8LahP5UtUb
`clean` removes the aliases recorded in .scaffold/state.json, while they still point at the recorded contracts, then the file itself. It no longer deletes identities: keys are machine-wide, so another project may depend on them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QhmaWLv4yExX8LahP5UtUb
Describe how build records deployments per checkout, the `<directory>-<contract>` alias it saves for hand-run commands, and that `clean` keeps keys. The tutorial's scaffold.yml now matches the template: testnet points at a deliberate deployment instead of deploying from the dev loop. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QhmaWLv4yExX8LahP5UtUb
Builds now find earlier deployments only through .scaffold/state.json, so the first build after upgrading deploys every contract again and the old contract-name aliases are left in the stellar-cli config. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QhmaWLv4yExX8LahP5UtUb
chadoh
approved these changes
Oct 16, 2026
chadoh
left a comment
Contributor
There was a problem hiding this comment.
Goooood shyt.
Only thing I noticed that might be worth changing before merge is the "don't make the json pretty" suggestion below
zachfedor
added a commit
to stellar-scaffold/ui
that referenced
this pull request
Oct 17, 2026
Companion to stellar-scaffold/cli#630. The templates now rely on `scaffold.yml` to decide what gets deployed where, use stellar-cli's global config, and treat testnet as staging. **Merge after the CLI release that includes #630.** This PR carries the `cross-repo` label, so its CI builds the CLI from `feat/config-driven-network`. ## Changes **`app-lib`** - Reads the network (passphrase and RPC URL) from the generated clients rather than from separate env settings. - Fetches balances over RPC. - **Breaking:** `MappedBalances` changes shape. **`scaffold.yml`** - Testnet is staging: it no longer deploys automatically on every build. - A commented `testnet-dev` example shows how to opt in to automatic testnet deploys. **Templates** - `start` runs `stellar scaffold watch` without `--build-clients`, since `scaffold.yml` now decides. CI keeps the flag. - `.env.example` drops `XDG_CONFIG_HOME`/`STELLAR_CONFIG_HOME`, so keys and aliases live in stellar-cli's global config. It keeps a commented `STELLAR_NETWORK`, a slot for secrets, and a note on `PUBLIC_` variables. - `.scaffold` (the CLI's machine-local deployment record) is added to `.gitignore` so Prettier skips it. - READMEs, CONTRIBUTING and `CLAUDE.md` are updated. ## Known follow-ups - `STELLAR_NETWORK=testnet npm start` fails until a testnet `type: contract` entry exists, because testnet no longer deploys. - `build.yml` still writes `.config/stellar/identity/me.toml`, which nothing reads now. - `dapp-ipfs.yml` is out of date. - The committed `Cargo.lock` doesn't match the contracts: a build bumps the contract crates from 0.0.1 to 0.0.2. This predates this PR. ## Testing - Against clients generated by the CLI branch, these pass: - `npm run lint` and `npm run format:check` - the `app-lib` typecheck - the React build - the Svelte typecheck and build - End to end with the CLI branch: - The first build deployed and saved `ui-*` aliases. - The second build reported up to date. - Invoking by alias worked. - `clean` removed the aliases and the state file. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01QhmaWLv4yExX8LahP5UtUb --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Chad Ostrowski <221614+chadoh@users.noreply.github.com>
Merged
7 tasks
chadoh
added a commit
that referenced
this pull request
Oct 21, 2026
Note: needed because in #630 Zach and I made `--build-clients` the default Officially encouraged Stellar Scaffold deploy process: 1. Build Wasm binaries for testnet 2. Publish & deploy them with Stellar Registry CLI 3. Update `testnet` sections of `scaffold.yml` to point at deployed instances (using contract IDs or Registry names) By default, version 2 builds also deploy contracts and generate clients. That prevents compiling Wasm independently when testnet client generation depends on contracts that have not been deployed yet. Expose the existing --compile-only flag so users can build Wasm before publishing and deploying it through Stellar Registry CLI, without triggering Scaffold deployment or client generation. --compile-only still validates scaffold.yml, including settings for all declared networks. Contract IDs and Registry names must be syntactically valid, but their referenced contracts need not exist yet: this build skips the deployment/client-generation steps that would attempt to use them.
chadoh
pushed a commit
that referenced
this pull request
Oct 21, 2026
## 🤖 New release
* `stellar-scaffold-ext-types`: 0.0.4 -> 0.0.5 (✓ API compatible
changes)
* `stellar-scaffold-cli`: 0.0.30 -> 0.0.31 (⚠ API breaking changes)
* `stellar-scaffold-reporter`: 0.1.3 -> 0.1.4
### ⚠ `stellar-scaffold-cli` breaking changes
```text
--- failure constructible_struct_adds_field: struct exhaustively constructible through public API adds field ---
Description:
A pub struct that could be exhaustively constructed with a literal using only public API has a new pub field, breaking existing exhaustive literals.
ref: https://doc.rust-lang.org/reference/expressions/struct-expr.html
impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.51.0/src/lints/constructible_struct_adds_field.ron
Failed in:
field Command.compile_only in /tmp/.tmp7uanvi/cli/crates/stellar-scaffold-cli/src/commands/build/mod.rs:38
--- failure enum_variant_added: enum variant added on exhaustive enum ---
Description:
A publicly-visible enum without #[non_exhaustive] has a new variant.
ref: https://doc.rust-lang.org/cargo/reference/semver.html#enum-variant-new
impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.51.0/src/lints/enum_variant_added.ron
Failed in:
variant Error:State in /tmp/.tmp7uanvi/cli/crates/stellar-scaffold-cli/src/commands/build/clients.rs:153
--- failure enum_variant_missing: pub enum variant removed or renamed ---
Description:
A publicly-visible enum has at least one variant that is no longer available under its prior name. It may have been renamed or removed entirely.
ref: https://doc.rust-lang.org/cargo/reference/semver.html#item-remove
impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.51.0/src/lints/enum_variant_missing.ron
Failed in:
variant Error::NetworkConfig, previously in file /tmp/.tmpdxkV6L/stellar-scaffold-cli/src/commands/clean.rs:26
variant Error::EnvToml, previously in file /tmp/.tmpdxkV6L/stellar-scaffold-cli/src/commands/clean.rs:29
```
<details><summary><i><b>Changelog</b></i></summary><p>
## `stellar-scaffold-ext-types`
<blockquote>
##
[0.0.5](stellar-scaffold-ext-types-v0.0.4...stellar-scaffold-ext-types-v0.0.5)
- 2026-10-21
### Added
- config-driven builds with per-checkout deployment state
([#630](#630))
</blockquote>
## `stellar-scaffold-cli`
<blockquote>
##
[0.0.31](stellar-scaffold-cli-v0.0.30...stellar-scaffold-cli-v0.0.31)
- 2026-10-21
### Added
- config-driven builds with per-checkout deployment state
([#630](#630))
### Fixed
- *(stellar-scaffold-cli)* expose `build --compile-only` flag
([#637](#637))
</blockquote>
## `stellar-scaffold-reporter`
<blockquote>
##
[0.1.4](stellar-scaffold-reporter-v0.1.3...stellar-scaffold-reporter-v0.1.4)
- 2026-10-21
### Other
- updated the following local packages: stellar-scaffold-ext-types
</blockquote>
</p></details>
---
This PR was generated with
[release-plz](https://github.com/release-plz/release-plz/).
Co-authored-by: aha-release-plz[bot] <211513279+aha-release-plz[bot]@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Restores Scaffold's local-first model: local is for experimenting freely, testnet is staging and a deliberate dry run, and mainnet is copied over when it's ready.
buildfollowsscaffold.ymlinstead of flags, and each checkout of a project keeps its own record of what it deployed, so projects and worktrees that share stellar-cli's global config no longer reuse each other's contracts.Companion UI PR: stellar-scaffold/ui#282 (same branch,
feat/config-driven-network). Both PRs carry thecross-repolabel so each one's CI builds against the other.Changes
Network selection
--network, thenSTELLAR_NETWORK, thenstellar network use, thenlocal.buildnow says when the network came fromstellar network use, andconfig showresolves the network the same waybuilddoes.buildwith a version 2scaffold.yml--build-clientsis accepted but only prints a note.initwithout a frontend andupgradeonly compile..scaffold/state.json(newstatemodule)scaffold.yml's..scaffold/ignores itself with its own.gitignore. Writes are atomic.builddecides between deploying, upgrading and reusing from this record, not from stellar-cli's global aliases.Aliases
<directory>-<contract>(e.g.my-app-guess_the_number) and no longer passes--aliastostellar contract deploy. Separate checkouts and worktrees get separate aliases.stellar contract alias removecommand.cleanstate.json.Docs
Upgrading (release note)
Known limitations
state.json.docs/site/i18n/esstill use the old paths and aliases.Testing
cargo fmt,cargo clippy --workspace --all-targets --all-features, and the unit tests (239) pass, including new tests for the state file, alias naming, alias ownership, andclean.checkouts_sharing_a_stellar_config_keep_their_own_contracts, which fails onmainbecause the second checkout reports the first checkout's contract as up to date.stellar scaffold build:ui-*aliases.contract invoke --id <alias>worked.cleanremoved the aliases and the state file and kept the keys.🤖 Generated with Claude Code
https://claude.ai/code/session_01QhmaWLv4yExX8LahP5UtUb