diff --git a/.github/workflows/sonar.yml b/.github/workflows/sonar.yml new file mode 100644 index 0000000..f745133 --- /dev/null +++ b/.github/workflows/sonar.yml @@ -0,0 +1,64 @@ +name: Sonar + +on: + push: + branches: + - main + pull_request: + +permissions: + contents: read + pull-requests: read + +concurrency: + group: sonar-${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + +jobs: + sonar: + runs-on: ubuntu-latest + env: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + steps: + - name: Checkout code + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 + with: + # Full history so SonarQube Cloud can attribute new code / blame. + fetch-depth: 0 + + # --- Rust coverage (coverage/rust-lcov.info) --- + # rust-toolchain.toml uses `profile = "minimal"`, so the llvm-tools-preview + # component (required by cargo-llvm-cov) is not present by default. + - name: Add llvm-tools-preview component + run: rustup component add llvm-tools-preview + + - name: Install cargo-llvm-cov + uses: taiki-e/install-action@9e1e5806d4a4822de933115878265be9aaa786d9 # v2 + with: + tool: cargo-llvm-cov + + - name: Test with coverage (Rust) + # #[ignore] (network-gated) tests are excluded by default, keeping this + # offline (see ADR-0004). --all-features mirrors the Rust CI gate. + run: | + mkdir -p coverage + cargo llvm-cov --workspace --locked --all-features --lcov --output-path coverage/rust-lcov.info + + - name: Upload Rust coverage to Codecov + uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0 + with: + files: ./coverage/rust-lcov.info + flags: rust + fail_ci_if_error: false + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + + # --- SonarQube Cloud analysis --- + # On pull_request runs from forks the SONAR_TOKEN secret isn't exposed, so + # skip the scan there instead of blocking external PRs. On push (main) the + # scan always runs — a missing token then fails loudly so a misconfigured + # Sonar setup is surfaced rather than silently skipped. (env is checked + # because the `secrets` context isn't available in step `if:` conditions.) + - name: SonarQube Cloud scan + if: ${{ github.event_name != 'pull_request' || env.SONAR_TOKEN != '' }} + uses: SonarSource/sonarqube-scan-action@713881670b6b3676cda39549040e2d88c70d582e # v8.2.0 diff --git a/README.ko.md b/README.ko.md index 0d9c747..b8e526c 100644 --- a/README.ko.md +++ b/README.ko.md @@ -9,6 +9,7 @@ npm version crates.io version Coverage + Quality Gate Status Socket Badge License - MIT diff --git a/README.md b/README.md index 2076871..45072dd 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ npm version crates.io version Coverage + Quality Gate Status Socket Badge License - MIT diff --git a/codecov.yml b/codecov.yml index ec0e8f5..3586f8a 100644 --- a/codecov.yml +++ b/codecov.yml @@ -16,8 +16,26 @@ coverage: informational: true comment: - layout: 'reach, diff, flags, files' + layout: 'reach, diff, flags, components, files' require_changes: false -# Coverage is generated by `bun test --coverage` (lcov). Test files are already -# excluded from the lcov report, so only product source is measured. +# Upload-time flag. sonar.yml uploads Rust coverage with `flags: rust`. +# carryforward keeps the last known coverage when the workflow doesn't run on a +# given commit. (The TypeScript implementation under src/ has been removed.) +flags: + rust: + paths: + - crates/ + carryforward: true + +# Component grouping by path at display time (independent of upload flags), +# surfacing the Rust crate coverage as a named component in the Codecov UI. +component_management: + individual_components: + - component_id: rust + name: Rust + paths: + - crates/** + +# Coverage is generated by `cargo llvm-cov` (Rust, lcov). Test code is excluded +# from the lcov report, so only product source is measured. diff --git a/sonar-project.properties b/sonar-project.properties new file mode 100644 index 0000000..084719d --- /dev/null +++ b/sonar-project.properties @@ -0,0 +1,18 @@ +# SonarQube Cloud (sonarcloud.io) configuration. +# +# Analysis runs from CI (.github/workflows/sonar.yml). For this to work the +# SonarCloud project must have Automatic Analysis DISABLED and a SONAR_TOKEN +# secret configured in the repository (or org) settings. +sonar.projectKey=pleaseai_code-search +sonar.organization=pleaseai + +# The implementation is the Rust workspace under crates/ (the deprecated TS port +# that lived in src/ has been removed). +sonar.sources=crates + +# Keep the npm launcher, build output, and dependency/target dirs out of analysis +# (npm/** mirrors the .codacy.yaml exclusion). +sonar.exclusions=npm/**,dist/**,target/**,node_modules/** + +# Coverage report (LCOV), generated by `cargo llvm-cov` in CI before the scan step. +sonar.rust.lcov.reportPaths=coverage/rust-lcov.info