|
| 1 | +--- |
| 2 | +title: "rules" |
| 3 | +date: 2025-01-28T12:00:00+01:00 |
| 4 | +anchor: "rules" |
| 5 | +weight: |
| 6 | +--- |
| 7 | + |
| 8 | +## Configuration |
| 9 | + |
| 10 | +<div className="config-wrapper"><div className="config">__name__: rules</div> |
| 11 | +<div className="config">__type__: array</div> |
| 12 | +<div className="config">__default__: []</div></div> |
| 13 | + |
| 14 | +```json showLineNumbers |
| 15 | +{ |
| 16 | + "name": "company/project", |
| 17 | + "extra": { |
| 18 | + "violinist": { |
| 19 | +// highlight-next-line |
| 20 | + "rules": [] |
| 21 | + } |
| 22 | + } |
| 23 | +} |
| 24 | +``` |
| 25 | + |
| 26 | +Define package-specific configuration rules that override the default settings. |
| 27 | + |
| 28 | +## Explanation |
| 29 | + |
| 30 | +The `rules` option allows you to apply different configuration settings to different groups of packages. This is useful when you want to handle certain packages differently from your default configuration. For example, you might want to apply security-only updates to development tools while allowing all updates for production dependencies. |
| 31 | + |
| 32 | +Rules are evaluated in order, and when a package matches a rule, the configuration from that rule is merged with your default configuration. |
| 33 | + |
| 34 | +## Structure |
| 35 | + |
| 36 | +Rules is an array of rule objects. Each rule object has the following structure: |
| 37 | + |
| 38 | +```json showLineNumbers |
| 39 | +{ |
| 40 | + "rules": [ |
| 41 | + { |
| 42 | + "name": "Human readable name", |
| 43 | + "slug": "machine-readable-slug", |
| 44 | + "matchRules": [ |
| 45 | + { |
| 46 | + "type": "names", |
| 47 | + "values": ["vendor/*", "!vendor/excluded-package"] |
| 48 | + } |
| 49 | + ], |
| 50 | + "config": { |
| 51 | + "blocklist": [], |
| 52 | + "branch_prefix": "deps/", |
| 53 | + "security_updates_only": 1 |
| 54 | + } |
| 55 | + } |
| 56 | + ] |
| 57 | +} |
| 58 | +``` |
| 59 | + |
| 60 | +### Rule Properties |
| 61 | + |
| 62 | +| Property | Type | Description | |
| 63 | +|----------|------|-------------| |
| 64 | +| `name` | string | A human-readable name for the rule (for documentation purposes) | |
| 65 | +| `slug` | string | A machine-readable identifier for the rule | |
| 66 | +| `matchRules` | array | An array of match rule objects that determine which packages this rule applies to | |
| 67 | +| `config` | object | Configuration options to apply when a package matches | |
| 68 | + |
| 69 | +## Match Rules |
| 70 | + |
| 71 | +Match rules determine which packages a rule applies to. Each match rule has a `type` and associated properties. |
| 72 | + |
| 73 | +### Type: `names` |
| 74 | + |
| 75 | +Match packages by name using [fnmatch](https://www.php.net/manual/en/function.fnmatch.php) patterns. |
| 76 | + |
| 77 | +| Pattern | Description | |
| 78 | +|---------|-------------| |
| 79 | +| `vendor/*` | Match all packages from a vendor | |
| 80 | +| `vendor/package` | Match a specific package | |
| 81 | +| `vendor/prefix-*` | Match packages with a specific prefix | |
| 82 | +| `!vendor/package` | Exclude a specific package (negative match) | |
| 83 | + |
| 84 | +When using negative matches (`!`), the package is excluded from the rule even if it matches a positive pattern. This allows you to select a broad group of packages and then exclude specific ones. |
| 85 | + |
| 86 | +```json showLineNumbers |
| 87 | +{ |
| 88 | + "matchRules": [ |
| 89 | + { |
| 90 | + "type": "names", |
| 91 | + "values": [ |
| 92 | + "drupal/*", |
| 93 | + "!drupal/core-recommended", |
| 94 | + "!drupal/core-composer-scaffold" |
| 95 | + ] |
| 96 | + } |
| 97 | + ] |
| 98 | +} |
| 99 | +``` |
| 100 | + |
| 101 | +This example matches all `drupal/*` packages except `drupal/core-recommended` and `drupal/core-composer-scaffold`. |
| 102 | + |
| 103 | +## Config Overrides |
| 104 | + |
| 105 | +Within a rule's `config` object, you can override most configuration options. The configuration from matching rules is merged with your default configuration. |
| 106 | + |
| 107 | +### Overridable Options |
| 108 | + |
| 109 | +The following options can be used within rules: |
| 110 | + |
| 111 | +- [allow_list](/configuration/allow_list) |
| 112 | +- [allow_update_indirect_with_direct](/configuration/allow_update_indirect_with_direct) |
| 113 | +- [allow_updates_beyond_constraint](/configuration/allow_updates_beyond_constraint) |
| 114 | +- [always_allow_direct_dependencies](/configuration/always_allow_direct_dependencies) |
| 115 | +- [always_update_all](/configuration/always_update_all) |
| 116 | +- [assignees](/configuration/assignees) |
| 117 | +- [automerge](/configuration/automerge) |
| 118 | +- [automerge_method](/configuration/automerge_method) |
| 119 | +- [automerge_method_security](/configuration/automerge_method_security) |
| 120 | +- [automerge_security](/configuration/automerge_security) |
| 121 | +- [blocklist](/configuration/blocklist) |
| 122 | +- [branch_prefix](/configuration/branch_prefix) |
| 123 | +- [bundled_packages](/configuration/bundled_packages) |
| 124 | +- [check_only_direct_dependencies](/configuration/check_only_direct_dependencies) |
| 125 | +- [commit_message_convention](/configuration/commit_message_convention) |
| 126 | +- [composer_outdated_flag](/configuration/composer_outdated_flag) |
| 127 | +- [default_branch](/configuration/default_branch) |
| 128 | +- [default_branch_security](/configuration/default_branch_security) |
| 129 | +- [ignore_platform_requirements](/configuration/ignore_platform_requirements) |
| 130 | +- [labels](/configuration/labels) |
| 131 | +- [labels_security](/configuration/labels_security) |
| 132 | +- [one_pull_request_per_package](/configuration/one_pull_request_per_package) |
| 133 | +- [run_scripts](/configuration/run_scripts) |
| 134 | +- [security_updates_only](/configuration/security_updates_only) |
| 135 | +- [update_dev_dependencies](/configuration/update_dev_dependencies) |
| 136 | +- [update_with_dependencies](/configuration/update_with_dependencies) |
| 137 | + |
| 138 | +### Root-level Only Options |
| 139 | + |
| 140 | +The following options cannot be overridden in rules and only apply at the root configuration level: |
| 141 | + |
| 142 | +- [number_of_concurrent_updates](/configuration/number_of_concurrent_updates) |
| 143 | +- [allow_security_updates_on_concurrent_limit](/configuration/allow_security_updates_on_concurrent_limit) |
| 144 | +- [timeframe_disallowed](/configuration/timeframe_disallowed) |
| 145 | +- [timezone](/configuration/timezone) |
| 146 | + |
| 147 | +## Examples |
| 148 | + |
| 149 | +### Security-only updates for dev dependencies |
| 150 | + |
| 151 | +Only receive security updates for development tools while allowing all updates for production dependencies: |
| 152 | + |
| 153 | +```json showLineNumbers |
| 154 | +{ |
| 155 | + "name": "company/project", |
| 156 | + "extra": { |
| 157 | + "violinist": { |
| 158 | +// highlight-start |
| 159 | + "rules": [ |
| 160 | + { |
| 161 | + "name": "Dev tools - security only", |
| 162 | + "slug": "dev-tools-security", |
| 163 | + "matchRules": [ |
| 164 | + { |
| 165 | + "type": "names", |
| 166 | + "values": ["phpunit/*", "phpstan/*", "squizlabs/*", "friendsofphp/*"] |
| 167 | + } |
| 168 | + ], |
| 169 | + "config": { |
| 170 | + "security_updates_only": 1 |
| 171 | + } |
| 172 | + } |
| 173 | + ] |
| 174 | +// highlight-end |
| 175 | + } |
| 176 | + } |
| 177 | +} |
| 178 | +``` |
| 179 | + |
| 180 | +### Bundling Drupal Core packages |
| 181 | + |
| 182 | +Bundle all Drupal core packages together so they update in a single pull request: |
| 183 | + |
| 184 | +```json showLineNumbers |
| 185 | +{ |
| 186 | + "name": "company/drupal-project", |
| 187 | + "extra": { |
| 188 | + "violinist": { |
| 189 | +// highlight-start |
| 190 | + "rules": [ |
| 191 | + { |
| 192 | + "name": "Drupal Core packages", |
| 193 | + "slug": "drupal-core", |
| 194 | + "matchRules": [ |
| 195 | + { |
| 196 | + "type": "names", |
| 197 | + "values": ["drupal/core-recommended"] |
| 198 | + } |
| 199 | + ], |
| 200 | + "config": { |
| 201 | + "bundled_packages": { |
| 202 | + "drupal/core-recommended": [ |
| 203 | + "drupal/core-composer-scaffold", |
| 204 | + "drupal/core-project-message" |
| 205 | + ] |
| 206 | + } |
| 207 | + } |
| 208 | + } |
| 209 | + ], |
| 210 | + "blocklist": [ |
| 211 | + "drupal/core-composer-scaffold", |
| 212 | + "drupal/core-project-message" |
| 213 | + ] |
| 214 | +// highlight-end |
| 215 | + } |
| 216 | + } |
| 217 | +} |
| 218 | +``` |
| 219 | + |
| 220 | +### Custom branch prefixes per package group |
| 221 | + |
| 222 | +Use different branch prefixes for different types of dependencies: |
| 223 | + |
| 224 | +```json showLineNumbers |
| 225 | +{ |
| 226 | + "name": "company/project", |
| 227 | + "extra": { |
| 228 | + "violinist": { |
| 229 | +// highlight-start |
| 230 | + "rules": [ |
| 231 | + { |
| 232 | + "name": "Framework updates", |
| 233 | + "slug": "framework", |
| 234 | + "matchRules": [ |
| 235 | + { |
| 236 | + "type": "names", |
| 237 | + "values": ["symfony/*", "laravel/*"] |
| 238 | + } |
| 239 | + ], |
| 240 | + "config": { |
| 241 | + "branch_prefix": "deps/framework/" |
| 242 | + } |
| 243 | + }, |
| 244 | + { |
| 245 | + "name": "Testing tools", |
| 246 | + "slug": "testing", |
| 247 | + "matchRules": [ |
| 248 | + { |
| 249 | + "type": "names", |
| 250 | + "values": ["phpunit/*", "mockery/*", "fakerphp/*"] |
| 251 | + } |
| 252 | + ], |
| 253 | + "config": { |
| 254 | + "branch_prefix": "deps/testing/" |
| 255 | + } |
| 256 | + } |
| 257 | + ] |
| 258 | +// highlight-end |
| 259 | + } |
| 260 | + } |
| 261 | +} |
| 262 | +``` |
| 263 | + |
| 264 | +### Disable dev dependency updates for Drupal contrib |
| 265 | + |
| 266 | +Update dev dependencies by default but disable them for Drupal contrib modules: |
| 267 | + |
| 268 | +```json showLineNumbers |
| 269 | +{ |
| 270 | + "name": "company/drupal-project", |
| 271 | + "extra": { |
| 272 | + "violinist": { |
| 273 | + "update_dev_dependencies": 1, |
| 274 | +// highlight-start |
| 275 | + "rules": [ |
| 276 | + { |
| 277 | + "name": "Drupal Contrib", |
| 278 | + "slug": "drupal-contrib", |
| 279 | + "matchRules": [ |
| 280 | + { |
| 281 | + "type": "names", |
| 282 | + "values": [ |
| 283 | + "drupal/*", |
| 284 | + "!drupal/core-*" |
| 285 | + ] |
| 286 | + } |
| 287 | + ], |
| 288 | + "config": { |
| 289 | + "update_dev_dependencies": 0 |
| 290 | + } |
| 291 | + } |
| 292 | + ] |
| 293 | +// highlight-end |
| 294 | + } |
| 295 | + } |
| 296 | +} |
| 297 | +``` |
| 298 | + |
| 299 | +### Automerge minor updates for specific packages |
| 300 | + |
| 301 | +Automatically merge minor updates for well-tested packages while requiring manual review for others: |
| 302 | + |
| 303 | +```json showLineNumbers |
| 304 | +{ |
| 305 | + "name": "company/project", |
| 306 | + "extra": { |
| 307 | + "violinist": { |
| 308 | +// highlight-start |
| 309 | + "rules": [ |
| 310 | + { |
| 311 | + "name": "Trusted packages - automerge", |
| 312 | + "slug": "trusted-automerge", |
| 313 | + "matchRules": [ |
| 314 | + { |
| 315 | + "type": "names", |
| 316 | + "values": ["psr/*", "symfony/polyfill-*"] |
| 317 | + } |
| 318 | + ], |
| 319 | + "config": { |
| 320 | + "automerge": 1, |
| 321 | + "composer_outdated_flag": "minor" |
| 322 | + } |
| 323 | + } |
| 324 | + ] |
| 325 | +// highlight-end |
| 326 | + } |
| 327 | + } |
| 328 | +} |
| 329 | +``` |
| 330 | + |
| 331 | +## Rule Precedence |
| 332 | + |
| 333 | +When a package matches multiple rules, the configurations are merged in order. Later rules can override settings from earlier rules. If you have overlapping patterns, place more specific rules after more general ones. |
| 334 | + |
| 335 | +> **Note:** Root-level configuration is always applied first, then rules are evaluated and merged in the order they appear. |
0 commit comments