Short answer
There is no built-in Qodana Cloud trigger that decides a change is "trivial" and skips analysis while keeping the baseline valid. Skipping is a CI-level concern: you gate the job in your pipeline (path filters, event triggers), and the baseline stays valid simply because it is a committed artifact that only changes when a scan actually runs. Baseline consistency across runners with different resources is preserved as long as the linter image version, inspection profile, and analyzed file set are identical — memory limits affect whether a scan completes, not what it reports.
What is confirmed vs. likely
Confirmed behavior: Qodana runs as a Dockerized linter; the baseline (qodana.sarif.json) suppresses known issues so only new problems fail the quality gate, but a full analysis still executes — the baseline shortens triage, not scan time. Results upload to Qodana Cloud for history, so skipping runs does not corrupt historical tracking; there is simply a gap.
Likely, version-sensitive: exact config keys, environment variables, and heap-tuning flags have changed across Qodana releases. Verify against the release notes for your pinned linter image tag before relying on any specific flag name.
A practical setup for low-traffic repos
- Trigger on events, not schedules. Run on pushes/merge requests to protected branches. Drop nightly cron scans — on an inactive repo they produce identical results at real cost.
- Gate on paths in CI. Skip the job when the diff touches only docs, assets, or config, using your CI system's path filters (e.g.,
changes: rules or a diff check step). This is the "trivial change" mechanism — it lives in your pipeline, not in Qodana. - Use ephemeral runners. Autoscaled agents that terminate after the job eliminate idle cost, which dominates for infrequent scans. Accept the cold-start penalty; for small repos it may exceed scan time, so measure once.
- Persist the cache. Cache the Qodana cache directory (dependencies, indexes) between runs. For infrequent scans, cold-start download/index time often exceeds actual analysis time.
- Scope analysis in qodana.yaml. Exclude generated code, vendored dependencies, and tests you do not want inspected, and trim the inspection profile. This reduces both memory and wall time per run — but be careful: aggressive exclusions silently skip code you meant to analyze.
Baseline consistency across heterogeneous runners
The baseline is a function of (linter image + inspection profile + source set), not of runner hardware. Two risks to control:
- OOM-killed scans. A memory-constrained runner that dies mid-analysis can produce partial output or fail the pipeline. Cap the JVM heap below the container limit rather than letting the JVM size itself against host memory. Measure peak usage first with
docker stats or CI metrics on one default run before tuning. - Version drift. If different runners pull different image tags, the same commit can yield different findings and churn the baseline. Pin the linter image digest everywhere.
Balancing full scans vs. baseline
Because the baseline does not reduce analysis work, there is no resource trade-off between "full scan" and "baseline scan" — every run is a full scan. The real lever is run frequency. A reasonable policy for low-traffic repos: scan every merge to the main branch, regenerate the baseline deliberately (never automatically) when you intentionally accept existing debt, and let Qodana Cloud accumulate history from those events alone.
Verify before committing to the setup
# Peak memory of one default scan
docker stats qodana-container
# Wall time with and without a warm cache directory
# (run twice, compare)
Also trigger one no-op change (e.g., a README edit) to confirm the path filter skips the job as intended. If your scans still OOM after heap capping, the one detail that changes the recommendation is your codebase size and language mix — JVM-language monorepos may genuinely need 4–8 GB, at which point a larger ephemeral runner class is cheaper than engineering around the limit.