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
51 changes: 49 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,61 @@ jobs:
- run: cargo test --workspace --all-features


coverage:
name: Coverage
runs-on: ubuntu-latest
env:
CARGO_INCREMENTAL: 0
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: dtolnay/rust-toolchain@b725eda525362e7cf34af9a7243cac1e3f01a7ec # stable
with:
components: llvm-tools-preview
- uses: Swatinem/rust-cache@d1527c8f67ef9af357290475d4af4b0fab8f12e0 # v2
- uses: taiki-e/install-action@86f7a0ffb25f40114606501a311ebcfaf882ea32 # v2
with:
tool: cargo-llvm-cov
- name: Generate coverage
run: |
mkdir -p target/coverage
cargo llvm-cov --workspace --all-features \
--lcov --output-path target/coverage/lcov.info
cargo llvm-cov report --summary-only \
| tee target/coverage/summary.txt
{
echo "## Test coverage"
echo
echo '```'
cat target/coverage/summary.txt
echo '```'
echo
echo "Coverage is reported but not enforced yet. See docs/testing.md."
} >> "$GITHUB_STEP_SUMMARY"
- name: Apply advisory coverage floor (non-blocking)
continue-on-error: true
env:
# Kept at zero until a baseline is agreed. Raise this value later;
# the step is non-blocking, so it never fails a pull request yet.
COVERAGE_ADVISORY_MIN_LINES: "0"
run: cargo llvm-cov report --fail-under-lines "$COVERAGE_ADVISORY_MIN_LINES"
- name: Upload coverage artifact
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: coverage
path: |
target/coverage/lcov.info
target/coverage/summary.txt
if-no-files-found: error
retention-days: 14

msrv:
name: MSRV (1.85.0)
name: MSRV (1.88.0)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- uses: dtolnay/rust-toolchain@1.85.0
- uses: dtolnay/rust-toolchain@1.88.0
- uses: Swatinem/rust-cache@d1527c8f67ef9af357290475d4af4b0fab8f12e0 # v2
- run: cargo build --workspace --locked
- run: cargo test --workspace --all-features --locked
Expand Down
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,24 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
`observatory-cli`, binary `stellar-contract-platform`) and state explicitly
that no crates.io package or prebuilt binary exists yet. See
`docs/installation.md`.
### Security

- Replace the unsound, unmaintained `serde_yml` parser (which pulled in
`noyalib` 0.0.5, RUSTSEC-2026-0333) with the maintained `serde_yaml_ng`
fork. YAML project configuration parsing is unchanged.

### Changed

- Raise the workspace MSRV from 1.85 to 1.88 so the locked dependency set
(`wasmparser` 0.259, `stellar-strkey` 0.0.18, `serde_with` 3.23) resolves and
the MSRV CI job matches the workspace `rust-version`.

### Added

- CI: report test coverage with `cargo-llvm-cov` on pull requests. The job
writes a summary to the workflow run, uploads an `lcov.info` artifact, and
keeps the coverage floor advisory (`continue-on-error`). See
`docs/testing.md`.
- Deployment: opt-in, bounded, per-run `LedgerEntryCache` with cached
`inspect_with_cache` and `deployed_wasm_with_cache` lookups; repeated ledger
keys reuse one `getLedgerEntries` call. See `docs/deployment.md`.
Expand Down
50 changes: 20 additions & 30 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ authors = ["StellarFoundry"]
repository = "https://github.com/StellarFoundry/stellar-contract-platform"
homepage = "https://github.com/StellarFoundry/stellar-contract-platform"
description = "Contract intelligence, inspection, interface analysis, compatibility, deployment verification, and reproducibility tooling for Stellar and Soroban contracts."
rust-version = "1.85"
rust-version = "1.88"

[workspace.dependencies]
serde = { version = "1", features = ["derive"] }
Expand All @@ -42,7 +42,7 @@ stellar-xdr = { version = "28.0.0", features = ["serde", "base64", "alloc"] }
stellar-strkey = "0.0.18"
base64 = "0.22"
getrandom = "0.2"
serde_yml = "0.0.13"
serde_yaml_ng = "0.10"
toml = "0.8"
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
Expand Down
2 changes: 1 addition & 1 deletion crates/observatory-platform/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ observatory-audit.workspace = true
observatory-output.workspace = true
serde.workspace = true
serde_json.workspace = true
serde_yml.workspace = true
serde_yaml_ng.workspace = true
toml.workspace = true
sha2.workspace = true
hex.workspace = true
Expand Down
2 changes: 1 addition & 1 deletion crates/observatory-platform/src/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ impl ProjectConfig {
/// Parse configuration text in the given format.
pub fn parse(input: &str, format: ConfigFormat) -> Result<Self> {
let parsed = match format {
ConfigFormat::Yaml => serde_yml::from_str(input).map_err(|error| error.to_string()),
ConfigFormat::Yaml => serde_yaml_ng::from_str(input).map_err(|error| error.to_string()),
ConfigFormat::Toml => toml::from_str(input).map_err(|error| error.to_string()),
ConfigFormat::Json => serde_json::from_str(input).map_err(|error| error.to_string()),
};
Expand Down
7 changes: 7 additions & 0 deletions docs/ci.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,13 @@ jobs:
contract.wasm --contract C... --rpc-fixture ci/rpc.json --network testnet
```

## Coverage

The `Coverage` CI job runs `cargo-llvm-cov` on pull requests and pushes to
`main`, writes a summary to the job summary, and uploads an `lcov.info` artifact.
The coverage floor is advisory (`continue-on-error`) while a baseline is
established. See [testing.md](testing.md#coverage) for the exact commands.

## JSON reports

Every command supports `--json`. Reports are wrapped in a versioned envelope:
Expand Down
36 changes: 36 additions & 0 deletions docs/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,42 @@ cargo test --workspace
| Event fixtures | `observatory-events` test helpers (base64 `ScVal`) |
| Ledger entries | `stellar-xdr` `LedgerEntryData` encoded in tests |

## Coverage

CI reports line coverage with [`cargo-llvm-cov`](https://github.com/taiki-e/cargo-llvm-cov),
which uses LLVM's source-based instrumentation. The `Coverage` job runs on every
pull request and on pushes to `main`:

```bash
mkdir -p target/coverage
cargo llvm-cov --workspace --all-features \
--lcov --output-path target/coverage/lcov.info
cargo llvm-cov report --summary-only | tee target/coverage/summary.txt
```

The job:

- writes a readable summary to the GitHub Actions job summary (visible from the
pull request checks page),
- uploads `target/coverage/lcov.info` and `target/coverage/summary.txt` as the
`coverage` artifact,
- runs an advisory coverage floor with `continue-on-error: true`. The floor is
`0` while a baseline is established, so coverage is **reported but not
enforced**. Raise `COVERAGE_ADVISORY_MIN_LINES` in `.github/workflows/ci.yml`
once a sensible baseline is agreed.

Run the same commands locally after installing the tool:

```bash
rustup component add llvm-tools-preview
cargo install cargo-llvm-cov --locked
cargo llvm-cov --workspace --all-features --open
```

`cargo llvm-cov` merges the workspace test run, so the numbers include unit,
integration, and CLI tests. Doc tests are not instrumented. Failed tests still
fail the job; only the coverage floor is advisory.

## Adding tests

- Decoding changes must include malformed-input tests.
Expand Down