Skip to content

Commit 9a9221a

Browse files
zachfedorwillemnealclaude
authored
Feat/reporter extension (#463)
* feat: add initial reporter extension * feat: add deploy, codegen, and dev hooks * feat: add config parsing for extensions * feat: add documentation * feat: clean up build output and allow verbose flag * feat: test all extension hooks * chore: add tests for reporter * chore: format * chore: fix Rust versions * fix: deprecated cargo_bin macro * fix: add workaround for reporter dependency in tests * chore: move Reporter tests to own crate * fix: build hook test * fix: reporter integration test * feat: add unchanged deploy state * fix: address review findings on reporter extension (#472) - state::save now returns io::Result and callers log on failure via a save_state helper, instead of silently dropping state writes - read_stdin returns Option<T>; the reporter logs a diagnostic and degrades gracefully on bad input instead of panicking and surfacing as a non-zero extension exit - HookName and DeployKind are marked #[non_exhaustive] so adding a hook or deploy kind in the future is not a breaking change for external extension authors consuming stellar-scaffold-ext-types - Drop unused thiserror dependency from the reporter crate - Remove a stale TODO comment in report.rs whose behavior is already correct Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: ensure post-codegen hook fires on error and propagate codegen failures `generate_contract_bindings` previously short-circuited via `?` inside the rebuild block, so PostCodegen was skipped whenever any inner step (bindings typescript, npm install/build, fs ops, create_contract_template) returned Err. Combined with `handle_contracts` swallowing per-contract errors, this made the build exit 0 while a hook that consumers rely on never fired — exactly the failure mode of `extension_hooks_fire_in_order`. Restructure so PostCodegen always fires after the fallible work, then propagate the error via a new CodegenStepFailed variant. `handle_contracts` now counts failures and returns ContractClientFailures so a broken codegen step can no longer masquerade as a successful build. Adds a regression test that shims npm to fail and asserts both pre- and post-codegen still appear. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * revert: restore non-fatal handle_contracts; drop ContractClientFailures Reverts the handle_contracts change from 590a1a5. That commit made per-contract codegen failures propagate as a build error, but `build_clients::contracts::contracts_with_failures_show_summary` explicitly asserts `build.success()` while showing per-contract success/fail messages — non-fatal contract failures are documented behavior, not an oversight. Propagation also surfaced pre-existing real codegen failures in several example contracts (case_02_account, case_17, case_18) that had been silently swallowed; restoring or expecting those is out of scope for this fix. The PostCodegen-on-error fix and its regression test remain. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Willem Wyndham <willem@ahalabs.dev> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 3af770e commit 9a9221a

23 files changed

Lines changed: 1819 additions & 272 deletions

File tree

.github/workflows/tests.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,13 @@ jobs:
4141
- run: just build
4242
- run: just build-cli-test-contracts
4343
- name: Create nextest archive
44-
run: cargo nextest archive --archive-file nextest-archive.tar.zst --package stellar-scaffold-cli --package stellar-registry-cli --features integration-tests
44+
run: cargo nextest archive --archive-file nextest-archive.tar.zst --package stellar-scaffold-cli --package stellar-registry-cli --package stellar-scaffold-reporter --features integration-tests
4545
- name: Package runtime artifacts
4646
run: |
4747
tar -cf - \
4848
target/debug/stellar-scaffold \
4949
target/debug/stellar-registry \
50+
target/debug/stellar-scaffold-reporter \
5051
target/stellar/local/ \
5152
crates/stellar-scaffold-test/fixtures/soroban-init-boilerplate/target/stellar/local/ \
5253
| zstd -1 -o runtime-artifacts.tar.zst
@@ -81,6 +82,8 @@ jobs:
8182
filter: "test-integration-scaffold-examples-2"
8283
- name: registry-cli
8384
filter: "test-integration-registry"
85+
- name: reporter
86+
filter: "test-integration-reporter"
8487
env:
8588
STELLAR_RPC_URL: http://localhost:8000/soroban/rpc
8689
STELLAR_NETWORK_PASSPHRASE: "Standalone Network ; February 2017"

Cargo.lock

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
**Scaffold Stellar** is a developer toolkit for building decentralized applications (dApps) and smart contracts on the [**Stellar** blockchain](https://stellar.org).
77

8-
It helps you go from **idea** to **working full-stack dApp** faster by providing CLI tools, reusable contract templates, a smart contract registry, and a modern frontend.
8+
It helps you go from **idea** to **working full-stack dApp** faster by providing CLI tools, reusable contract templates, a smart contract registry, and a modern frontend.
99

1010
---
1111

@@ -143,6 +143,28 @@ stellar registry install my-contract-instance # Instal
143143
> Use `--help` on any command for usage instructions.
144144
145145
---
146+
147+
## Extensions
148+
149+
Scaffold Stellar's build pipeline supports extensions by calling binaries on your PATH that tap into lifecycle hooks fired before and after each compile, deploy, codegen, and watch cycle.
150+
151+
The built-in **[Scaffold Reporter](./crates/stellar-scaffold-reporter/)** extension is included in every new project. It logs compile times, WASM sizes, deploy durations, and total build cycle time directly to your console.
152+
153+
Register extensions in `environments.toml`:
154+
155+
```toml
156+
[development]
157+
extensions = ["reporter"]
158+
159+
# Optional per-extension config:
160+
[development.ext.reporter]
161+
warn_size_kb = 128
162+
```
163+
164+
See the [Extensions Guide](https://scaffoldstellar.com/docs/extensions) to learn how the hook system works and how to build your own extension.
165+
166+
---
167+
146168
## Smart Contract Deployment
147169

148170
### 1. Publish Your Contract
@@ -248,7 +270,7 @@ Ask questions in the repo Discussions tab
248270

249271
Search [DeepWiki](https://deepwiki.org/)
250272

251-
Or just open an issue — we're happy to help!
273+
Or just open an issue. We're happy to help!
252274

253275
Happy hacking!
254276
---
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,23 @@
11
fn main() {
22
crate_git_revision::init();
3+
4+
// cargo_bin!("stellar-scaffold-reporter") in integration tests expands to
5+
// env!("CARGO_BIN_EXE_stellar-scaffold-reporter"), which Cargo sets for
6+
// same-package binaries and dev-dependency binaries during `cargo test` but
7+
// NOT during `cargo clippy --tests`. Emitting it here ensures it is always
8+
// present at compile time regardless of how the crate is being built.
9+
let out_dir = std::env::var("OUT_DIR").unwrap();
10+
// OUT_DIR = target/<profile>/build/<hash>/out — 3 levels up is target/<profile>/
11+
let target_dir = std::path::Path::new(&out_dir).ancestors().nth(3).unwrap();
12+
let exe_suffix = if cfg!(target_os = "windows") {
13+
".exe"
14+
} else {
15+
""
16+
};
17+
println!(
18+
"cargo:rustc-env=CARGO_BIN_EXE_stellar-scaffold-reporter={}",
19+
target_dir
20+
.join(format!("stellar-scaffold-reporter{exe_suffix}"))
21+
.display()
22+
);
323
}

0 commit comments

Comments
 (0)