Shared Analysis Configuration
This document outlines the capabilities available in Qlty CLI and Qlty Cloud to support sharing of analysis configuration across multiple repositories within a single workspace.
Goals
- Simplify the set up and maintenance of static analysis configuration across a large number of GitHub repositories
- Provide partial or full standardization of static analysis configuration for the organization
Custom Sources
The primary method of sharing analysis configuration across multiple repositories is through defining a custom Source. A Source is a Git repository that stores version controlled static analysis configuration settings which can be re-used by other repositories.
Custom Sources were designed to replace the delegated configuration feature of Code Climate Quality while adding new capabilities.
Features of Custom Sources
- Create and share new, custom Plugin Definitions
- Example: Define a custom plugin to check that all
package.jsonfiles specify an acceptablelicensevalue
- Example: Define a custom plugin to check that all
- Customize out-of-the-box Plugin Definitions
- Example: Override the default definition of the Prettier auto-formatter to avoid rewriting
*.mdxfiles
- Example: Override the default definition of the Prettier auto-formatter to avoid rewriting
- Share maintainability analysis settings
- Example: Increase the complexity threshold for the “High Function Complexity” code smell
- Example: Add a code filter to exclude common boilerplate from an internally developed framework from duplication detection
- Share file path exclusions
- Example: Exclude all files matching
**/our_generator/**
- Example: Exclude all files matching
- Share issue triage rules
- Example: Downgrade the
levelof issues found by Trivy in thesandbox/**folder tolow
- Example: Downgrade the
- Automatically enable plugins
- Example: Always run the Shellcheck for any shell scripts in all repositories
- Share linter configuration files
- Example: Provide a base
rubocop.ymlconfiguration that can be extended for each project
- Example: Provide a base
Advantages of Custom Sources
- Settings provided by the Source can be further customized with the Project’s
qlty.tomlconfiguration file (layered configuration) - Sources can be declared as pinned (with Git tags) or floating to a branch
- Custom sources work on Qlty CLI and Qlty Cloud
Example
To use a Custom Source, each repository would declare it from the .qlty/qlty.toml file:
Why are both sources needed? The default source provides all the built-in Qlty plugin definitions. Your custom source adds overrides and customizations on top. Without the default source, Qlty wouldn’t know how to run the standard plugins.
To pin your source to a specific version instead of floating to a branch, use tag:
Source Repository Structure
The custom Source is a regular Git repository which follows a conventional structure:
- A
source.tomlfile at the root of the repository provides settings - Plugins can be defined or modified in files matching the patterns
plugins/linters/*/plugin.toml - Linter configuration files can be placed at the root to be shared with child repos via
exported_config_paths
Configuration Merging
Notably, Qlty uses the same TOML configuration syntax in every configuration file. This allows for taking advantage of the same configuration options — from plugin declaration settings to tuning maintainability smells — in any *.toml file read by Qlty.
Configuration is applied in the following order from lowest precedence to highest precedence:
plugin.tomlfiles in Sourcessource.tomlfile at the root of Sourcesqlty.tomlin the project
As the final, merged configuration is assembled, the last setting wins.
The full, merged configuration can be viewed as YAML by running qlty config show.
Sharing Linter Configuration Files
Linter plugins often use their own configuration files (e.g., .eslintrc.js, rubocop.yml, .prettierrc). You can share these files from your custom source repository so that all child repos use the same configuration.
To share a linter configuration file:
- Commit the linter configuration file to your custom source repository.
- Within the
source.toml, use theexported_config_pathsproperty to specify which files should be copied to child repos at runtime.
How it works: When Qlty runs analysis on a child repo, it copies the files listed in exported_config_paths from your source repository into the child repo’s working directory. The linter then finds and uses these configuration files as if they were committed directly to the child repo.
If exported_config_paths is not set, config files in the source repo are NOT shared. The linter will use config files from the child repo if present, otherwise it falls back to its defaults.
config_files vs exported_config_paths
These two properties work together but serve different purposes:
Example in source.toml:
You may place plugin configuration files anywhere within your custom source repo. The exported_config_paths must be relative to the location of your source.toml.
Sharing Linter Extensions
If a shared plugin configuration file utilizes linter extensions, you’ll need to define these using the extra_packages property within your source.toml. For example:
Private Custom Sources
Custom sources can be private repos, provided they are in the same GitHub Org and the user has installed the Qlty GitHub App.
Qlty Cloud: HTTPS URLs work automatically. The GitHub App handles authentication.
Qlty CLI (local): For private repos, use SSH URLs since the CLI doesn’t have access to Qlty Cloud authentication:
Complete Example
Here’s a complete working example of sharing configuration between repositories.
Source Repository
source.toml:
Child Repository
.qlty/qlty.toml:
The child repository does not need its own linter configuration files — they will be inherited from the source repository when Qlty runs.