codeclimate-config
Configure Code Climate Quality (now Qlty) for repository-wide quality gates - duplication, complexity, similar-code, exclude_patterns. Covers both legacy `.codeclimate.yml` (Code Climate Velocity / GitHub integration) and the new `.qlty/qlty.toml` per the Qlty platform migration. Use when a repo needs duplication and complexity thresholds enforced on PRs, or when an existing `.codeclimate.yml` must be migrated to Qlty without losing its plugin and exclude settings.
Install with skills.sh (any agent)
npx skills add testland/qa --skill codeclimate-configcodeclimate-config
Code Climate Quality has rebranded as Qlty (the docs.codeclimate.com URL now 301-redirects to docs.qlty.sh per the Qlty docs (opens in new window)). This skill configures both:
When to use
Step 1 - Install (Qlty CLI path)
# macOS / Linux
curl https://qlty.sh -o install-qlty.sh
sh install-qlty.sh
# Windows (PowerShell)
powershell -c "iwr https://qlty.sh | iex"Per the Qlty quickstart (opens in new window), CLI verifies via gh attestation verify if downloaded from GitHub releases.
Step 2 - Initialize config
qlty initGenerates .qlty/qlty.toml baseline scoped to detected file types.
Step 3 - Legacy .codeclimate.yml
For teams still on the GitHub Code Climate App:
version: "2"
plugins:
duplication:
enabled: true
config:
languages:
javascript:
mass_threshold: 50
python:
mass_threshold: 32
ruby:
mass_threshold: 18
fixme:
enabled: true
structure:
enabled: true
exclude_patterns:
- "config/"
- "db/"
- "dist/"
- "features/"
- "**/node_modules/"
- "script/"
- "**/spec/"
- "**/test/"
- "**/tests/"
- "**/vendor/"
- "**/*_test.go"
- "**/*.d.ts"Excluding **/test/** is required - qa-test-review owns test-code hygiene; qa-code-quality scopes production only.
Step 4 - Qlty .qlty/qlty.toml
Per the Qlty quickstart (opens in new window) structure:
config_version = "0"
[[source]]
name = "default"
default = true
[[plugin]]
name = "eslint"
[[plugin]]
name = "ruff"
[[plugin]]
name = "shellcheck"
# Per-tool exclude patterns
[[exclude]]
file_patterns = [
"node_modules/**",
"dist/**",
"**/*.test.ts",
"**/*.spec.ts",
"tests/**",
"vendor/**",
]Discover available plugins:
qlty plugins list
qlty plugins enable eslintStep 5 - Run analysis
# Lint changed files (default)
qlty check
# Lint everything
qlty check --all
# Just one tool
qlty check --all --filter=shellcheck
# Detect smells (duplication + complexity)
qlty smells --all
# Export top-complexity hotspots
qlty metrics --all --max-depth=2 --sort complexity --limit 10Verify: assert qlty smells --all returns a manageable count before wiring the gate. If it surfaces excess pre-existing issues, raise the per-language mass_threshold or scope with qlty check --upstream main, then re-run.
Step 6 - CI gate
# GitHub Actions
- name: Qlty install
run: curl https://qlty.sh -o install-qlty.sh && sh install-qlty.sh
- name: Qlty check
run: qlty check --upstream main
env:
QLTY_TOKEN: ${{ secrets.QLTY_TOKEN }}--upstream main scopes results to only the diff vs main - matches the "new issues only" workflow Qlty's PR feedback uses (per Qlty docs (opens in new window) section "Preventing new issues from merging").
Verify: run qlty check --upstream main locally (or open a test PR) and assert a newly introduced duplicate block fails while pre-existing findings stay green. If pre-existing issues also fail, confirm --upstream main is set and the base branch is correct, then re-run.
Worked example
A team runs a JS + Python monorepo with a legacy .codeclimate.yml (duplication mass_threshold 50 for javascript, 32 for python) and wants PR-scoped gating on Qlty.
Result: production code gets duplication and complexity gating on the diff only, tests are excluded, and the legacy .codeclimate.yml migrates to qlty.toml without losing its thresholds.
Anti-patterns
| Anti-pattern | Why it fails | Fix |
|---|---|---|
| Scan tests + production with same thresholds | Tests fail duplication checks (deliberate AAA repetition); team disables tool | Exclude **/tests/**, **/spec/** (Steps 3 - 4) |
Set duplication mass_threshold to default in brownfield | Hundreds of pre-existing duplications block all PRs | Use --upstream diff scope OR raise threshold initially + ratchet down |
Mix legacy .codeclimate.yml + new .qlty/qlty.toml | Both tools find different issues; PR comments contradict | Pick one platform; legacy .codeclimate.yml is consumed by Code Climate Velocity / GitHub App, .qlty/qlty.toml by Qlty CLI |
| Enable every plugin upfront | Noisy first PR scares team | Start with 2-3 plugins; add quarterly |
| Run only post-merge | No PR feedback loop | Run on PR (Step 6) |
Limitations
References
Related skills
knip-dead-code
Run Knip against a JS/TS project to detect unused files, unused dependencies, unused exports, and unused class/enum members. Scoped to production code; tests are entry-point-aware via Knip's framework plugins. Use after a feature or route is deleted and the project still compiles, or when `package.json` has accumulated dependencies nobody can account for.
lizard-complexity
Run Lizard against production source to enforce per-function cyclomatic complexity (CCN), NLOC, and parameter-count thresholds - language-agnostic (30+ languages). Scoped to production code via `-x"./tests/*"`; test complexity is reviewed separately. Use when a codebase spans several languages and needs one complexity gate across all of them, or when a function has grown unreviewable and the team wants a numeric threshold in CI.
madge-deps
Run Madge against a JS/TS production source tree to detect circular dependencies, find orphan modules, and visualize the module graph. Scoped to production code via `excludeRegExp` for test files. Use when a build compiles but throws `Cannot read property X of undefined` on a module that is clearly imported, or when a repo needs a CI gate that blocks new import cycles.
sonarqube-maintainability-gate
Run SonarQube/SonarCloud against production code to surface Code Smells, Bugs, and Maintainability ratings - the maintainability lens rather than the security lens. Production-only scope via sonar.exclusions; test code is reviewed separately. Use when a team wants maintainability and technical-debt ratings gating PRs, or when an existing SonarQube project reports numbers nobody has tied to a quality gate.