Skip to content

ci: Add SonarCloud code quality analysis#137

Draft
marclawclaw wants to merge 107 commits into
logos-co:mainfrom
marclawclaw:feature/sonarcloud-setup
Draft

ci: Add SonarCloud code quality analysis#137
marclawclaw wants to merge 107 commits into
logos-co:mainfrom
marclawclaw:feature/sonarcloud-setup

Conversation

@marclawclaw

Copy link
Copy Markdown
Contributor

Summary

Adds SonarCloud code quality analysis to the project:

  • sonar-project.properties: Configuration file with:

    • Source directories: spel-framework, spel-framework-core, spel-framework-macros, spel-cli, spel-client-gen
    • Test directory: tests
    • Rust language configuration with Cargo.toml manifest path
    • Appropriate exclusions for coverage, target, docs, etc.
  • .github/workflows/ci.yml: Added job that:

    • Runs on pull requests
    • Uses
    • Requires secret to be configured in the repository

Required Setup

The repository needs a secret configured with a SonarCloud user token. This can be generated at https://sonarcloud.io/account/security/.

jimmy-claw and others added 30 commits February 20, 2026 12:59
…logos-co#6)

The #[account(signer)] and #[account(init)] constraints now generate
runtime validation functions that are called before instruction dispatch:

- signer: checks is_authorized flag, returns NssaError::Unauthorized
- init: checks account == Account::default(), returns AccountAlreadyInitialized

Validation functions are named __validate_{instruction_name} and called
in the generated match arms.

Includes 5 integration tests covering:
- Authorized signer passes
- Unauthorized signer fails with correct error
- Uninitialized account passes init check
- Already initialized account fails
- Both checks run in order (init before signer)

Closes logos-co#4

Co-authored-by: Jimmy <jimmy-claw@users.noreply.github.com>
…n = "path")] (logos-co#5) (logos-co#7)

Programs can now bring their own Instruction enum instead of having the
macro generate one:

    #[nssa_program(instruction = "my_crate::Instruction")]
    mod my_program { ... }

When set, the macro generates `use path as Instruction;` instead of
deriving its own enum. This allows shared-type patterns where the
Instruction enum lives in a core crate used by both on-chain and CLI.

Includes 2 tests verifying external instruction serialization and
handler integration.

Closes logos-co#5

Co-authored-by: Jimmy <jimmy-claw@users.noreply.github.com>
…ogos-co#8)

The CLI PDA computation now handles all three seed types:
- const, account, arg (bytes32, u64, u128, string)
Multi-seed PDAs combined via XOR. 6 unit tests.

Partially addresses logos-co#1

Co-authored-by: Jimmy <jimmy-claw@users.noreply.github.com>
…ta> (logos-co#9)

* feat: support variable-length account lists via Vec<AccountWithMetadata> (logos-co#3)

Instructions can now accept a trailing Vec<AccountWithMetadata> parameter
for variable-length account lists (e.g., member lists in multisig):

    #[instruction]
    pub fn create_multisig(
        #[account(init, pda = ...)] state: AccountWithMetadata,
        members: Vec<AccountWithMetadata>,
        threshold: u64,
    ) -> NssaResult { ... }

Changes:
- Macro: detect Vec<AccountWithMetadata> params, generate split_at destructuring
- IDL: add "rest":true field to variable-length accounts
- Core: add rest field to IdlAccountItem with serde skip_serializing_if

Includes 4 tests for IDL serialization/deserialization of rest field.

Closes logos-co#3

* docs: add variable-length account list to README

---------

Co-authored-by: Jimmy <jimmy-claw@users.noreply.github.com>
- Make __validate_* functions pub so they are accessible from generated main()
- Add missing rest field to IdlAccountItem in generate_idl_fn
- Use .expect() instead of ? for validation calls (main returns (), not Result)

These bugs caused scaffolded projects to fail compilation.
…main (logos-co#13)

- Switch all Cargo.toml git deps to branch = "main"
- Update scaffolded project template in init.rs
- Fix type mismatch in tx.rs: get_pub_account_signing_key now takes AccountId by value

This aligns nssa-framework with the latest lssa main branch,
enabling use of sequencer_runner for e2e testing.

Co-authored-by: Jimmy <jimmy-claw@users.noreply.github.com>
Binary is at methods/guest/target/... not target/...

Co-authored-by: Jimmy <jimmy-claw@users.noreply.github.com>
- Auto-detect sequencer_runner from PATH, ~/bin, or ~/lssa/target
- Start sequencer with lssa configs, clean state
- Deploy scaffolded program via nssa-cli deploy
- Attempt transaction submit (graceful failure if args needed)
- Proper cleanup on exit

Co-authored-by: Jimmy <jimmy-claw@users.noreply.github.com>
…odegen (logos-co#15)

Also fix Vec account validation call to spread rest accounts
instead of trying to put Vec into array literal.

Co-authored-by: Jimmy <jimmy-claw@users.noreply.github.com>
Rename all crates and types:
- nssa-framework → lez-framework
- nssa-framework-core → lez-framework-core
- nssa-framework-macros → lez-framework-macros
- nssa-framework-cli → lez-cli
- NssaOutput → LezOutput, NssaError → LezError, NssaResult → LezResult
- NssaIdl → LezIdl
- nssa_program macro → lez_program macro
- nssa-cli binary → lez-cli binary

Upstream deps (nssa_core, nssa from logos-blockchain/lssa) unchanged.

Co-authored-by: Jimmy Claw <jimmy-claw@users.noreply.github.com>
…s-co#20)

Implements client and C FFI code generation from LEZ program IDL JSON.

- Typed Rust client with async methods per instruction
- Correct account ordering from IDL (fixes hand-written FFI bugs)
- PDA computation helpers generated from IDL seed specs
- C FFI exports (extern "C" JSON-in/JSON-out pattern)
- C header file generation
- Proper type handling:
  - ProgramId [u32;8] with little-endian byte order
  - AccountId with base58 (native) + hex fallback
- CLI tool: lez-client-gen --idl <path> --out-dir <dir>
- 7 unit tests covering codegen, FFI, headers, account order

Closes logos-co#19

Co-authored-by: Jimmy Claw <jimmy@claw.dev>
Extends the LEZ IDL format with fields from the lssa-lang IDL spec (discriminator, execution, variant, visibility, spec, metadata). All new fields are Optional/defaulted — fully backward compatible.
Wraps the #[lez_program] macro generated fn main() in #[cfg(not(test))] so guest programs can have inline #[cfg(test)] unit tests without hitting risc0 guest syscalls on the host.

Closes logos-co#21
Add AccountId alongside ProgramId as a known primitive type in the macro,
mapping to "account_id" in the IDL. Also update lez-client-gen/src/util.rs
to match "account_id" (snake_case) so client-gen correctly handles IDLs
produced by the updated macro.

Original fix by @danisharora099 in logos-co#26.
Closes logos-co#24
…logos-co#29)

Adds end-to-end tests covering the full LEZ program development workflow:
- Fixture program with initialize + transfer instructions and inline unit tests
- e2e_build: cargo build the fixture
- e2e_idl_generation: extract and validate IDL JSON
- e2e_ffi_build: run lez-client-gen, assert client/FFI/header output
- e2e_test: cargo test the fixture (validates cfg-gate fix from logos-co#25)

CI split into unit-tests (fast) and e2e-tests (with logos-blockchain-circuits).

Closes logos-co#27
…ogos-co#32)

* feat(ffi-codegen): emit tx-building FFI that calls generated client (closes issue logos-co#20 pattern)

Previously ffi_codegen.rs emitted stub FFI functions that only returned
{success: true, account_ids: [...], instruction_name: "..."} without
actually building or submitting any transaction.

Now the generated FFI:
- Imports the generated client module via `use super::client::*`
- Parses common connection args (sequencer_url, wallet_path, program_id)
- Parses instruction-specific args and accounts from JSON
- Builds the `{Instruction}Accounts` struct
- Instantiates `{Program}Client::new(&wallet, program_id)`
- Drives the async client method with `tokio::runtime::Runtime::new().block_on(...)`
- Returns {"success": true, "tx_hash": "..."} on success

This matches the pattern used in the hand-written lez-multisig-ffi/src/multisig.rs.
The key JSON field for the program id is now the uniform `program_id` (not prefixed).

Updated tests:
- test_ffi_generation: checks for client import, tokio runtime, block_on, tx_hash
- test_account_order_in_client: moved ordering check to client (where it lives now)
- test_ffi_calls_client_methods: new test verifying client method calls are emitted
- Removed obsolete checks for compute_pda/from_le_bytes in FFI (now in client)

* feat: ffi_codegen emits full transaction building via WalletCore (logos-co#31)

Generated FFI now includes:
- Instruction enum (all variants with typed fields)
- WalletCore init (wallet_path + sequencer_url from JSON args)
- PDA derivation via SHA-256 (inline, self-contained)
- Full async transaction: Message::try_new -> WitnessSet -> send_tx_public
- tokio::runtime::Runtime blocking wrapper
- Returns {"success": true, "tx_hash": "..."} JSON

Generated FFI is now self-contained — no dependency on the generated
Rust client module. Any LEZ program can get a fully functional C FFI
from its IDL alone, with zero manual code.

Closes logos-co#31

* feat: add parse_program_id helper for ProgramId-typed instruction args

Generates a parse_program_id() fn (alias for parse_program_id_hex) so that
IDL args typed as ProgramId are correctly parsed from hex strings in FFI.

* ffi_codegen: fix APIs + add instruction_type support

- Add instruction_type: Option<String> to LezIdl — lets programs specify
  their native instruction type (e.g. multisig_core::Instruction) so
  codegen imports it directly instead of generating a local enum
- Fix WalletCore::from_env() instead of non-existent ::new(url)
- Fix AccountId::new(arr) instead of ::from(arr)
- Fix error_json to use format! with properly escaped braces
- Closes logos-co#31

* ffi_codegen: fix error_json format string brace escaping

The generated error_json function now uses a split approach to avoid
nested brace escaping issues in format! strings.

* fix(macros): add instruction_type: None to LezIdl struct literal in __program_idl macro

---------

Co-authored-by: Jimmy Claw <jimmy@claw.dev>
Switch from branch="main" to pinned rev to ensure reproducible builds
and alignment with logos-scaffold template default lssa_pin.
fix: pin lssa deps to dee3f7fa (matches logos-scaffold template)
…os-co#35)

* fix: emit instruction_type in IDL when external instruction enum is used

When #[lez_program(instruction = "some::Path")] is used, the generated
IDL JSON and __program_idl() function now correctly populate instruction_type.

Previously instruction_type was always None/missing, breaking FFI codegen
which relies on this field to know the external instruction enum path.

Fixes:
- generate_idl_fn: emit instruction_type = Some(path) in __program_idl()
- generate_idl_json: append ,"instruction_type":"..." to JSON output
- expand_generate_idl: detect instruction= attr from source file, pass it through

* fix: include rest:true in generated IDL JSON for Vec<AccountWithMetadata> params

Previously Vec<AccountWithMetadata> parameters (variable-length trailing accounts)
were correctly detected as rest accounts in the code generation (is_rest: true)
but the rest field was omitted from the generated JSON IDL.

Now generates "rest":true in the JSON for these accounts, consistent with
the IdlAccountItem struct which has a rest: bool field.

* fix: pin fixture_program nssa_core to rev=767b5afd (was branch=main, causing duplicate dep)

---------

Co-authored-by: Jimmy Claw <jimmy@claw.dev>
)

Add generate_pda_helpers(idl: &LezIdl) -> String to ffi_codegen.rs.
The function emits one pub fn compute_{account}_pda(...) per unique
account that has a pda field in the IDL.

Seed handling:
- const seeds: inlined as UTF-8 bytes, padded to 32 bytes with 0x00
- arg seeds: become function parameters (e.g. create_key: &[u8; 32])
- account seeds: TODO comment, skipped for now

Multi-seed PDAs (>1 seed) use SHA-256(seed1 || seed2 || ...) to
combine seeds into a single 32-byte value — matching the on-chain
nssa derivation and lez-cli/src/pda.rs behaviour.

generate_ffi() calls generate_pda_helpers() and appends the result
so PDA helpers are part of the generated FFI output.

Tests added in tests.rs:
- test_pda_helpers_single_arg_seed: single arg seed generates direct
  PdaSeed (no SHA-256)
- test_pda_helpers_multi_seed: const+arg seeds use SHA-256 combiner
- test_pda_helpers_deduplication: same account across two instructions
  generates exactly one helper function
- test_pda_helpers_in_ffi_output: PDA helpers appear in generate_ffi()
  output

All 12 tests pass (cargo test -p lez-client-gen).

Co-authored-by: jimmy-claw <jimmy-claw@users.noreply.github.com>
* fix: emit instruction_type in IDL when external instruction enum is used

When #[lez_program(instruction = "some::Path")] is used, the generated
IDL JSON and __program_idl() function now correctly populate instruction_type.

Previously instruction_type was always None/missing, breaking FFI codegen
which relies on this field to know the external instruction enum path.

Fixes:
- generate_idl_fn: emit instruction_type = Some(path) in __program_idl()
- generate_idl_json: append ,"instruction_type":"..." to JSON output
- expand_generate_idl: detect instruction= attr from source file, pass it through

* fix: include rest:true in generated IDL JSON for Vec<AccountWithMetadata> params

Previously Vec<AccountWithMetadata> parameters (variable-length trailing accounts)
were correctly detected as rest accounts in the code generation (is_rest: true)
but the rest field was omitted from the generated JSON IDL.

Now generates "rest":true in the JSON for these accounts, consistent with
the IdlAccountItem struct which has a rest: bool field.

* fix: pin fixture_program nssa_core to rev=767b5afd (was branch=main, causing duplicate dep)

* feat: lez-client-gen supports u64 arg seeds in PDA helpers

Adds support for u64-typed arg seeds in generate_pda_helpers. Previously
only [u8;32] args were supported. u64 seeds are converted via .to_le_bytes()
before being included in the SHA-256 computation, matching the manual
implementation in lez-multisig-framework.

- u64 params are now passed by value (not by ref) in generated signatures
- Single u64 seed: padded into [u8; 32] via to_le_bytes()
- Multi u64 seed: hashed via hasher.update(&val.to_le_bytes())
- Adds tests: test_pda_helpers_u64_single_seed, test_pda_helpers_u64_multi_seed

---------

Co-authored-by: Jimmy Claw <jimmy@claw.dev>
* feat(lez-cli): add pda subcommand to compute PDAs from IDL (closes logos-co#46)

* feat(lez-cli): add pda subcommand to compute PDAs from IDL

Usage: <binary> --idl <IDL> --program <BIN> pda <account-name> [--<seed-arg> <value>]

Example:
  multisig --idl multisig_idl.json --program multisig.bin pda vault --create-key demo-abc123

Closes logos-co#46

* fix(lez-cli): pda command accepts --program-id hex instead of requiring binary

* fix(lez-cli): pda command accepts --program-id hex, no binary required

* feat(lez-cli): --program-id as global top-level flag, alternative to --program

* fix(lez-cli): --program-id skips binary loading for tx submission too

---------

Co-authored-by: Jimmy Claw <jimmy@claw.dev>
…ogos-co#49)

Usage: pda --program-id <hex> <seed1> [seed2] ...

No IDL needed. Seeds are hex (32 bytes) or strings (zero-padded).
Combined via SHA-256(seed1||seed2||...) matching on-chain derivation.

Example:
  multisig pda --program-id abc123... multisig_vault__ <create_key_hex>

Co-authored-by: Jimmy Claw <jimmy@claw.dev>
jimmy-claw and others added 26 commits April 1, 2026 14:17
Co-authored-by: Jimmy Claw <jimmy@claw.dev>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
logos-co#106)

Types annotated with #[account_type] are now included in the generated
IDL under `accounts`. Any types they reference transitively are collected
via BFS and placed in `types`, so the IDL is fully self-contained with
no file path references.

spel-cli's `inspect` command can now decode any annotated type by name:

  spel inspect <account-id> --idl program-idl.json --type TokenHolding

Changes:
- spel-framework-macros: add no-op #[account_type] proc-macro attribute
- spel-framework: re-export #[account_type] and add it to the prelude
- idl.rs: add `name` field to IdlTypeDef so types in `idl.types` can be
  looked up by name at decode time
- idl_gen.rs: implement collect_account_types — scans top-level items for
  #[account_type], populates idl.accounts, and resolves helper types into
  idl.types via BFS; comprehensive test suite added
- account_inspect.rs: find_type_def now searches both idl.accounts and
  idl.types; account_id treated as a 32-byte primitive alongside program_id
- README: document #[account_type] usage and spel inspect workflow
Co-authored-by: Jimmy Claw <jimmy@claw.dev>
Co-authored-by: Vaclav Pavlin <vaclav.pavlin@gmail.com>
…pat check (logos-co#107)

Co-authored-by: Jimmy Claw <jimmy@claw.dev>
…-co#108)

Co-authored-by: Jimmy Claw <jimmy-claw@users.noreply.github.com>
…o#109)

Co-authored-by: Jimmy Claw <jimmy-claw@users.noreply.github.com>
…gos-co#110)

Co-authored-by: Jimmy Claw <jimmy-claw@users.noreply.github.com>
- Check if lez-bump branch exists before creating (reuse not duplicate)
- Use --force-with-lease on push
- Use git commit --amend to keep one commit per update
- Fetch existing branch before rebasing in updated path

Co-authored-by: Jimmy Claw <jimmy-claw@users.noreply.github.com>
…-co#112)

- Replace github-script API call with gh pr create (more reliable)
- Replace github-script merge call with gh pr merge
- Uses GITHUB_TOKEN for authentication

Co-authored-by: Jimmy Claw <jimmy-claw@users.noreply.github.com>
)

Co-authored-by: Jimmy Claw <jimmy-claw@users.noreply.github.com>
logos-co#114)

Co-authored-by: Jimmy Claw <jimmy-claw@users.noreply.github.com>
)

Co-authored-by: Jimmy Claw <jimmy-claw@users.noreply.github.com>
- Use ONE persistent branch: lez-bump/main (no date suffix)
- Check if branch exists before creating (reuse not duplicate)
- Push branch first, then find/create PR via API
- Keep cargo check + auto-merge
- Remove verbose debug output

Co-authored-by: Jimmy Claw <jimmy-claw@users.noreply.github.com>
Co-authored-by: Jimmy Claw <jimmy-claw@users.noreply.github.com>
This workflow automates checking SPEL compatibility with LEZ updates:

  - Detects when LEZ has new commits
  - Updates dependencies automatically
  - Creates PR for review
  - Runs cargo check against new LEZ version
  - Creates issues on failure

Co-authored-by: waclaw-claw <waclaw@users.noreply.github.com>
Co-authored-by: Vaclav Pavlin <vaclav.pavlin@gmail.com>
* chore(bump): use LEZ v0.2.0-rc1 release tag

* fix: pass self_program_id and caller_program_id to ProgramOutput::new

* fix: use LEZ v0.2.0-rc1 and SPEL v0.2.0-rc.1 in spel init template

* feat: add --lez-tag, --spel-tag, --lez-rev, --spel-rev to spel init

* fix: use local spel-cli + [patch] to pin nssa_core in smoke test

- Build and use local spel-cli from PR instead of system binary
- Inject [patch] section after spel init to unify nssa_core versions
- Print LEZ version diagnostics
- Remove duplicate cargo generate-lockfile block in init.rs

* fix: add Claim arg to AccountPostState::new_claimed for LEZ v0.2.0-rc1

AccountPostState::new_claimed now requires a second Claim argument.
Updated all call sites (init template, smoke test, README) and added
Claim to the spel-framework prelude re-export.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: checkout LSSA to matching LEZ tag before building sequencer

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(smoke): use wallet for account gen, add signer, fix sequencer checks

- SPEL_TAG now uses refs/pull/122/head instead of published tag
- Changed --spel-tag to --spel-rev for PR ref
- Added signer to #[account(mut, signer)] for Claim::Authorized
- Replaced openssl rand with wallet account new public
- Fixed sequencer health check logic
- Removed unnecessary Cargo.toml patching
- Improved logging with RUST_LOG=info

* debug(smoke): add sequencer startup error logging

* cleanup: add init -h, remove sequencer build, streamline smoke test

Changes:
- Add --help/-h flag to spel init command
- Remove sequencer build from smoke test (CI handles it)
- Simplify LSSA verification to just check version
- Keep essential fixes: SPEL_TAG, --spel-rev, #[account(signer)]

---------

Co-authored-by: Vaclav Pavlin <vaclav.pavlin@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Jimmy Claw <jimmy-claw@users.noreply.github.com>
- Make LEZ_TAG required env var with no hardcoded default
- Add LSSA version verification to ensure sequencer matches expected LEZ
- Pass dynamic SPEL ref from CI (PR head or commit SHA)
- Fix sequencer caching to save regardless of test outcome
- Better error messages and version mismatch warnings

Fixes logos-co#125
* fix(cli): parse PDA seed args through IDL type system

compute_pda_command stored all seed args as ParsedValue::Str instead of
routing them through parse_value() with the IDL type. This meant [u8; 32]
args were never parsed as ByteArray, producing wrong PDA hashes and
serialization warnings.

Fix: look up the owning instruction's arg types and call parse_value()
for each seed arg so hex-encoded byte arrays are correctly decoded.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(macros): emit structured IdlType variants instead of Primitive for compound types

generate_idl_fn wrapped every arg type in IdlType::Primitive(string), so
[u8; 32] became Primitive("[u8; 32]") instead of Array{Primitive("u8"), 32}.
This caused parse_value to miss the Array dispatch, producing Raw values
that broke PDA seed computation.

Replace rust_type_to_idl_string with rust_type_to_idl_type_tokens that
emits correct IdlType variants (Array, Vec, Option, Defined) as token
streams. Add regression tests for the parse_value path.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* test(cli): add risc0 serde roundtrip tests for byte array serialization

Add 5 tests verifying spel's serialization matches the risc0 serde
contract used by nssa_core::program::read_nssa_inputs at LEZ v0.2.0-rc1.

Key finding: risc0 serde serializes each u8 as its own u32 word
(zero-extended), NOT packed 4-per-word. The roundtrip test deserializes
spel's output using risc0_zkvm::serde::Deserializer (the same code the
guest runs) to prove on-chain compatibility.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
feat: add SpelOutput::execute() with auto-claim and PDA verification
                                                                                                                                                                                                                                                                                                                                                                      
 Replaces the manual states_only() / with_chained_calls() API with a unified SpelOutput::execute() that auto-generates account claims from #[account(...)] attributes at compile time.
                                                                                                                                                                                                                                                                                                                                                                      
  - AutoClaim enum, IntoPostState trait, execute() / execute_with_claims() on SpelOutput                                                                                                                                                                                                                                                                              
  - #[lez_program] macro emits __claims_{fn}() per instruction and rewrites execute() calls via ExecuteTransformer — no manual claim helpers needed                                                                                                                                                                                                                   
  - Guest-side PDA verification: generate_validation() derives and checks expected account IDs at runtime for literal(), arg(), and account() seed types                                                                                                                                                                                                              
  - ToSeed trait and compute_pda_multi() for type-safe multi-part seeds (u64, u32, String, &str, [u8;32])                                                                                                                                                                                                                                                             
  - Filter non-owned, non-default accounts from dispatch output (LEZ rule 7)                                                                                                                                                                                                                                                                                          
  - account(...) PDA seeds in claim generation now use the runtime account ID, not seed_from_str(name) (was a silent correctness bug)                                                                                                                                                                                                                                 
  - Deprecate states_only() / with_chained_calls()
…onflicts

CLI flags (--idl, --program) and IDL-driven instruction arguments shared
a flat namespace, causing parsing conflicts. Fix by introducing spel.toml
config and standard -- separator.

Key changes:
- spel.toml with [program] (single) and [programs.<name>] (multi-program)
- --program accepts config name, 64-char hex program ID, or file path
- -- separator: everything after is passed through as instruction args
- --program-id kept as deprecated alias with warning
- Deprecation warning when mixing CLI and instruction args without -- or config
- spel init generates spel.toml alongside existing scaffolding
- Updated help output and error messages

Precedence: CLI flag > spel.toml > built-in default

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add sonar-project.properties with Rust analysis config
- Add SonarCloud scan job to CI workflow
@fryorcraken

Copy link
Copy Markdown
Contributor

rebase

@fryorcraken

Copy link
Copy Markdown
Contributor

Waiting for infra to confirm preferred approach/provider

@fryorcraken fryorcraken marked this pull request as draft April 21, 2026 01:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants