monochange 0.6.8

Manage versions and releases for your multiplatform, multilanguage monorepo
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
{#
  monochange.toml.template -- minijinja template for mc init

  Compiled into the binary via include_str! and rendered at runtime with
  context from package discovery.  Edit this file directly when config
  options change.

  Template context:
    packages         -- list of { id, path, type, changelog? }
    has_group        -- true when more than one package was discovered
    package_ids_toml -- pre-formatted TOML array contents
    has_cargo / has_npm / has_deno / has_dart / has_python -- ecosystem detected flags
#}
#:schema https://monochange.github.io/monochange/schemas/monochange.schema.json
# =============================================================================
# monochange.toml — repository configuration for monochange
# =============================================================================
#
# This file is the single source of truth for release planning, CLI commands,
# changelog generation, and automation flows in this monorepo.
#
# Run `mc step:validate` to check this file against the workspace.
# Run `mc init` to generate a starter config from detected packages.

# =============================================================================
# [defaults] — repository-wide defaults applied to every package unless
# overridden at the package or group level.
# =============================================================================

[defaults]
# Bump severity applied to transitive dependents when a dependency changes.
# When package A depends on package B, and B gets a minor bump, A receives
# whichever bump is configured here.
#
# Options: "none", "patch", "minor", "major"
# Default: "patch"
parent_bump = "patch"

# Whether to include private packages (publish = false) in discovery and
# release planning. When false, private packages are discovered but excluded
# from release plans and version bumps.
#
# Default: false
include_private = false

# Emit a warning when version-group members have mismatched current versions.
# Helps catch accidental version drift in grouped packages.
#
# Default: true
warn_on_group_mismatch = true

# Default package type for all packages that don't declare their own `type`.
# Setting this avoids repeating `type = "cargo"` on every [package.*] entry.
#
# Options: "cargo", "npm", "deno", "dart", "flutter", "python"
# Default: none (each package must declare its own type)
# package_type = "cargo"

# Default changelog configuration applied to every package that doesn't
# declare its own `changelog` field.
#
# Accepts three forms:
{% raw -%}
#   true                           → use "{{ path }}/CHANGELOG.md" for every package
#   false                          → disable changelogs by default
#   "{{ path }}/changelog.md"      → pattern where {{ path }} is replaced with each package path
#
# As a table, you can set path, format, and the initial header used when
# monochange creates a changelog from empty content:
#   [defaults.changelog]
#   path = "{{ path }}/changelog.md"
#   format = "keep_a_changelog"
#   initial_header = """
#   # Changelog
#
#   All notable changes to this project will be documented in this file.
#   """
{% endraw -%}
#
# Supported formats: "monochange" (default), "keep_a_changelog"
# Default: none (changelogs are disabled unless configured)
# [defaults.changelog]
{% raw -%}
# path = "{{ path }}/changelog.md"
{% endraw -%}
# format = "keep_a_changelog"
# initial_header = """
# # Changelog
#
# All notable changes to this project will be documented in this file.
#
# This changelog is managed by [monochange](https://github.com/monochange/monochange).
# """

# Default changelog configuration. When [changelog] is not specified,
# built-in defaults provide standard sections (Major, Breaking Change, Added,
# Minor, Changed, Fixed, Patch, Testing, Refactor, Documentation, Security,
# Performance, None) and corresponding types. See [changelog] section below
# for customization.
# [changelog] — workspace-wide changelog configuration
# 
# Controls templates, sections, and types for changelog rendering.
# When omitted, built-in defaults provide standard sections and types.
#
# [changelog]
# templates — Templates that control how individual change entries render.
# Each template is tried in order; the first one whose required variables are
# all present wins. If none match, falls back to "- {{ summary }}".
#
# sections — Named changelog sections with heading and priority (lower = first).
# The built-in defaults provide standard sections matching the commented example.
#
# section_thresholds — Optional rendering cutoffs based on section priority.
# Use these to collapse lower-priority sections into markdown <details> blocks
# or omit them entirely.
#
# types — Change type definitions mapping changeset types to section and bump severity.
# Each type key references a section key and declares a default bump severity.
# The built-in defaults provide standard types matching the commented example.

# [changelog.templates]
# Add custom templates if the defaults don't match your style.

# [changelog.sections]
# major = { heading = "Major", description = "Major version bumps", priority = 5 }
# breaking = { heading = "Breaking Change", description = "API changes requiring migration", priority = 10 }
# minor = { heading = "Minor", description = "Minor version bumps", priority = 15 }
# feat = { heading = "Added", description = "New features added", priority = 20 }
# change = { heading = "Changed", description = "Changes to existing functionality", priority = 25 }
# fix = { heading = "Fixed", description = "Bug fixes", priority = 30 }
# patch = { heading = "Patch", description = "Patch version bumps", priority = 35 }
# test = { heading = "Testing", description = "Changes that only modify tests", priority = 40 }
# refactor = { heading = "Refactor", description = "Code refactoring without functional changes", priority = 40 }
# docs = { heading = "Documentation", description = "Changes that only modify documentation", priority = 40 }
# security = { heading = "Security", description = "Security-related changes", priority = 40 }
# perf = { heading = "Performance", description = "Performance improvements", priority = 40 }
# none = { heading = "None", description = "No version bump", priority = 50 }

# [changelog.section_thresholds]
# collapse = 127
# ignored = 127

# [changelog.types]
# breaking = { section = "breaking", bump = "major" }
# major = { section = "major", bump = "major" }
# feat = { section = "feat", bump = "minor" }
# minor = { section = "minor", bump = "minor" }
# change = { section = "change", bump = "minor" }
# fix = { section = "fix", bump = "patch" }
# patch = { section = "patch", bump = "patch" }
# test = { section = "test" }
# none = { section = "none" }
# docs = { section = "docs" }
# security = { section = "security" }
# refactor = { section = "refactor", bump = "patch" }
# perf = { heading = "perf" }


# Default empty_update_message applied when a package is bumped but has no
# direct changeset entries (e.g. transitive dependency bumps or group
# synchronization). Template placeholders are interpolated at render time
# using minijinja syntax.
#
# Available placeholders:
{% raw -%}
#   {{ package }}, {{ package_name }}, {{ package_id }}
#   {{ group }}, {{ group_name }}, {{ group_id }}
#   {{ version }}, {{ new_version }}, {{ current_version }}, {{ previous_version }}
#   {{ bump }}, {{ trigger }}, {{ ecosystem }}
#   {{ release_owner }}, {{ release_owner_kind }}
#   {{ members }}, {{ member_count }}  (group changelogs only)
#   {{ reasons }}
{% endraw -%}
#
# Precedence: package → group → defaults → built-in message
# Default: built-in message varies by grouped/ungrouped context
#
{% raw -%}
# empty_update_message = "No direct changes; {{ package }} updated to {{ version }}."
{% endraw %}

# Default release_title applied when creating provider releases.
# This is a plain-text title used for GitHub, GitLab, and Gitea releases.
#
# Available placeholders:
{% raw -%}
#   {{ version }}, {{ id }}, {{ date }}, {{ time }}, {{ datetime }}
#   {{ changes_count }}, {{ tag_url }}, {{ compare_url }}
{% endraw -%}
#
# Defaults:
#   Primary versioning:    "{{ version }} ({{ date }})"
#   Namespaced versioning: "{{ id }} {{ version }} ({{ date }})"
#
{% raw -%}
# release_title = "{{ version }} ({{ date }})"
{% endraw %}

# Default changelog_version_title controls how changelog version headings render.
# This is markdown-capable and supports links.
#
# Available placeholders: same as release_title above.
#
# Defaults:
#   Primary:    "[{{ version }}]({{ tag_url }}) ({{ date }})" (linked when source configured)
#   Namespaced: "{{ id }} [{{ version }}]({{ tag_url }}) ({{ date }})"
#
# To restore headings without dates (the previous default), set:
{% raw -%}
#   changelog_version_title = "{{ version }}"
{% endraw -%}
#
{% raw -%}
# changelog_version_title = "[{{ version }}]({{ tag_url }}) ({{ date }})"
{% endraw %}

# =============================================================================
# [changelog] — workspace-wide changelog configuration
# =============================================================================

# [changelog]
# Templates that control how individual change entries render in changelogs.
# Each template is tried in order; the first one whose required variables are
# all present wins (uses minijinja strict mode — all referenced variables must
{% raw -%}
# be defined). If none match, falls back to "- {{ summary }}".
#
# Available variables:
#   {{ summary }}       — the change summary from the changeset
#   {{ details }}       — optional multi-line details block
#   {{ package }}       — package name
#   {{ version }}       — planned version
#   {{ target_id }}     — release owner id (package or group)
#   {{ bump }}          — bump severity (none, patch, minor, major)
#   {{ type }}          — optional change type (e.g. "security", "note")
#   {{ context }}       — rendered context context block
#   {{ context }}    — alias for {{ context }}
#   {{ changeset_path }} — path to the changeset file
#   {{ change_owner }}, {{ change_owner_link }}
#   {{ review_request }}, {{ review_request_link }}
#   {{ introduced_commit }}, {{ introduced_commit_link }}
#   {{ last_updated_commit }}, {{ last_updated_commit_link }}
#   {{ related_issues }}, {{ related_issue_links }}
#   {{ closed_issues }}, {{ closed_issue_links }}
#
# Default: ["#### {{ summary }}\n\n{{ details }}", "- {{ summary }}"]
# templates = [
#   "#### {{ summary }}\n\n{{ details }}\n\n{{ context }}",
#   "#### {{ summary }}\n\n{{ context }}",
#   "#### {{ summary }}\n\n{{ details }}",
#   "- {{ summary }}",
# ]
{% endraw %}

# =============================================================================
# [package.*] — declare each release-managed package explicitly
# =============================================================================
#
# Required fields:
#   path  — relative path from repo root to the package directory
#
# Optional fields:
#   type                    — "cargo", "npm", "deno", "dart", "flutter", "python"
#                             (not needed when defaults.package_type is set)
#   changelog               — true, false, "path/to/changelog.md", or a table
#                             with { path, format, initial_header }; overrides
#                             [defaults.changelog]
#   excluded_changelog_types — list of changelog type keys to exclude from this target
#   empty_update_message    — per-package fallback text for transitive bumps
#   versioned_files         — additional files to update with the new version
#                             package-scoped string entries infer the package ecosystem,
#                             e.g. ["Cargo.toml"] or ["**/crates/*/Cargo.toml"]
#                             explicit typed entries remain supported, e.g.
#                             [{ path = "group.toml", type = "cargo" }]
#                             typed manifest entries can update dependency
#                             sections and arbitrary string fields inside TOML
#                             or JSON manifests, e.g.
#                             [{ path = "Cargo.toml", type = "cargo", fields = ["workspace.metadata.bin.monochange.version"], prefix = "" }]
#                             regex entries update plain-text files and must include a
#                             named `version` capture group, e.g.
#                             [{ path = "README.md", regex = 'v(?<version>\d+\.\d+\.\d+)' }]
#                             regex entries cannot set `type`, `prefix`, `fields`, or `name`
#                             lockfiles can still be listed explicitly, but
#                             ecosystem-level lockfile refresh now prefers
#                             [ecosystems.<name>].lockfile_commands
#   ignore_ecosystem_versioned_files — opt out of inherited [ecosystems.<name>].versioned_files
#                             defaults for this package (default: false)
#   ignored_paths           — glob patterns for paths within this package to
#                             exclude from changeset verification
#   additional_paths        — glob patterns for paths outside the package
#                             directory that should trigger changeset verification
#   publish                 — package publishing settings; package values
#                             override inherited [ecosystems.<name>].publish
#                             defaults
#     enabled               — include this package in managed publishing
#                             flows (default: true)
#     mode                  — "builtin" for monochange-managed publishing to
#                             the default public registry for the ecosystem, or
#                             "external" when your CI or scripts handle
#                             publishing themselves (default: "builtin").
#                             npm-family workspaces use the detected workspace
#                             manager for built-in publish commands, so pnpm
#                             workspaces publish via `pnpm publish`.
#     registry              — registry override. Built-in publishing only
#                             supports the default public registry for each
#                             ecosystem: "crates_io", "npm", "jsr", or
#                             "pub_dev". Custom/private registries must use
#                             mode = "external".
#     trusted_publishing    — whether this package is expected to use registry
#                             trusted/OIDC publishing flows when available.
#                             Set `trusted_publishing = true` for defaults, or
#                             use a table to override GitHub trust metadata:
#                             enabled, repository, workflow, environment
#                             (default: enabled)
#     rate_limits.enforce   — block built-in publish runs when the selected
#                             package set requires more than one known registry
#                             rate-limit window. Use `mc publish-plan` to inspect
#                             batches first. (default: false)
#     placeholder.readme    — inline README text to use when publishing a
#                             placeholder package for the first bootstrap
#                             release
#     placeholder.readme_file — workspace-relative path to a README file used
#                             for placeholder publishing. Set either
#                             placeholder.readme or placeholder.readme_file.
#   tag                     — whether to create a git tag for this package (default: false)
#   release                 — whether to create a provider release (default: false)
#   version_format          — "namespaced" (default: "pkg/v1.0.0") or
#                             "primary" (just "v1.0.0"); only one package/group
#                             may use "primary"

{% for pkg in packages %}
[package.{{ pkg.id }}]
path = "{{ pkg.path }}"
type = "{{ pkg.type }}"
{% if pkg.changelog %}
changelog = "{{ pkg.changelog }}"
{% endif %}
# [package.{{ pkg.id }}.publish]
# enabled = true
# mode = "builtin"
# trusted_publishing = true
# [package.{{ pkg.id }}.publish.trusted_publishing]
# enabled = true
# repository = "owner/repo"
# workflow = "publish.yml"
# environment = "release"
# registry = "{{ pkg.type == "cargo" and "crates_io" or pkg.type == "npm" and "npm" or pkg.type == "deno" and "jsr" or "pub_dev" }}"

# [package.{{ pkg.id }}.publish.placeholder]
# readme = "This package is a placeholder published by monochange until the first real release."
# readme_file = "docs/{{ pkg.id }}-placeholder.md"

{% endfor %}
# =============================================================================
# [group.*] — version groups that share a single release identity
# =============================================================================
#
# When packages belong to a group, they share a synchronized version and a
# single release tag/identity. If any member bumps, all members bump to the
# group's highest severity.
#
# Required fields:
#   packages — list of [package.*] ids that belong to this group
#
# Optional fields:
#   changelog               — path or table for the group-level changelog;
#                             tables may also set `include = "all"`,
#                             `include = "group-only"`, or
#                             `include = ["package-id"]` to control which
#                             member-targeted changesets appear in the group
#                             changelog (direct group-targeted changesets are
#                             always included; default: "all")
#   excluded_changelog_types — list of changelog type keys to exclude from this target
#   empty_update_message    — fallback text when the group bumps but a
#                             specific member has no direct changeset entries
#   versioned_files         — additional files to version-bump with the group
#                             groups must use explicit typed entries because the
#                             ecosystem cannot be inferred from a bare string;
#                             regex entries are also supported, e.g.
#                             [{ path = "**/install.sh", regex = 'SDK_VERSION="(?<version>\d+\.\d+\.\d+)"' }]
#   tag                     — create a git tag for the group release (default: false)
#   release                 — create a provider release for the group (default: false)
#   version_format          — "namespaced" (default) or "primary"
#
# Rules:
#   - group members must be declared under [package.*]
#   - package and group ids share one namespace (no collisions)
#   - a package may belong to only one group
#   - only one package or group may use version_format = "primary"
#   - group tag/release/version_format override member package settings
#   - prefer package ids in authored changesets when possible; dependents and
#     grouped members propagate automatically, so group ids are best for
#     intentionally group-owned releases

{% if has_group %}
[group.main]
packages = [{{ package_ids_toml }}]
tag = true
release = true
version_format = "primary"
# [group.main.changelog]
# path = "changelog.md"
# include = ["package-id"]
{% endif %}

# =============================================================================
# [[deployments]] — deployment intent definitions
# =============================================================================
#
# Deployments are structured intents emitted in the release manifest so
# downstream CI can decide when and how to execute them. monochange does not
# run deployments directly — it declares them.
#
# Fields:
#   name            — unique deployment name
#   trigger         — when to deploy: "workflow" (manual), "release_pr_merge",
#                     or "release_published"
#   workflow        — CI workflow to trigger
#   environment     — target environment name (optional)
#   release_targets — which release targets activate this deployment (default: all)
#   requires        — dependencies that must be met before deploying
#   metadata        — arbitrary key-value pairs passed to the workflow
#
# Example:
# [[deployments]]
# name = "docs"
# trigger = "release_published"
# workflow = "docs-release"
# environment = "github-pages"
# release_targets = ["main"]
# requires = ["main"]
# metadata = { site = "github-pages" }

# =============================================================================
# [ecosystems.*] — per-ecosystem discovery and publishing settings
# =============================================================================
#
# Each supported ecosystem can be configured independently.
#
# Fields:
#   enabled  — opt-in/opt-out of discovery for this ecosystem (default: none,
#              meaning discovery runs when manifests are found)
#   roots    — restrict discovery to specific directories (default: scan entire repo)
#   exclude  — glob patterns to exclude from discovery
#   dependency_version_prefix — default dependency prefix for typed versioned_files
#   versioned_files — ecosystem-wide default versioned_files inherited by matching packages;
#                     entries may be typed manifest updates (including
#                     arbitrary TOML/JSON field paths) or plain-text regex
#                     replacements with a named `version` capture, e.g.
#                     [{ path = "src/lib.rs", regex = 'VERSION: &str = "(?<version>\d+\.\d+\.\d+)"' }]
#   lockfile_commands — optional escape-hatch commands that refresh ecosystem
#                       lockfiles after a release updates manifest versions.
#                       By default monochange rewrites supported lockfiles
#                       directly from the release plan so `mc release` stays on
#                       the fast path. Cargo is not re-run automatically anymore,
#                       so incomplete Cargo.lock files should be refreshed with
#                       explicit commands here or manually afterwards. When set,
#                       these commands fully own lockfile refresh for that ecosystem.
#   publish          — ecosystem-wide publishing defaults inherited by matching
#                      packages unless the package overrides them
#     enabled        — enable managed publishing for the ecosystem (default: true)
#     mode           — "builtin" or "external" (default: "builtin")
#     registry       — default public registry for this ecosystem. Built-in
#                      publishing only supports the ecosystem’s canonical public
#                      registry.
#     trusted_publishing — whether packages in this ecosystem should default to
#                      trusted/OIDC publishing flows when available. Set
#                      `trusted_publishing = true` for defaults, or use a table
#                      with enabled/repository/workflow/environment to inherit
#                      trust metadata into matching packages (default: enabled)
#     rate_limits.enforce — block built-in publish runs for matching packages
#                      when the selected package set exceeds a known single
#                      registry window. (default: false)
#     placeholder.readme / placeholder.readme_file — default placeholder README
#                      source inherited by packages during bootstrap publishing

# =============================================================================
# [lints] — manifest lint configuration
# =============================================================================
#
# Configure lint presets, global rules, and scoped overrides for package
# manifests. Lint suites live in ecosystem crates, but configuration lives in
# this top-level section.
#
# [lints]
# use = ["cargo/recommended", "npm/recommended"]
# include = ["crates/**", "packages/**"]
# exclude = ["examples/**"]
# disable_gitignore = false
#
# Fields:
#   use               — preset ids enabled globally
#   include           — optional glob patterns that opt specific manifest paths
#                       into linting; when omitted, every non-gitignored
#                       manifest is considered
#   exclude           — glob patterns removed from linting after include/default
#                       selection
#   disable_gitignore — set true to lint gitignored manifests too; this is not
#                       recommended for normal repositories
#
# [lints.rules]
# "cargo/internal-dependency-workspace" = "error"
# "npm/workspace-protocol" = "error"
#
# [[lints.scopes]]
# name = "published cargo packages"
# match = { ecosystems = ["cargo"], managed = true, publishable = true }
# use = ["cargo/recommended"]
# rules = { "cargo/required-package-fields" = "error" }
#
# Scope selector fields inside `match`:
#   ecosystems  — ecosystem ids like cargo, npm, or dart
#   paths       — glob patterns against manifest paths relative to the workspace root
#   package_ids — configured package ids to target directly
#   group_ids   — configured group ids to target via group membership
#   managed     — include only managed/unmanaged packages when set
#   private     — include only private/public packages when set
#   publishable — include only publishable/non-publishable packages when set

{% if has_cargo %}
[ecosystems.cargo]
enabled = true
{% else %}
# [ecosystems.cargo]
# enabled = true
{% endif %}
# [ecosystems.cargo.publish]
# enabled = true
# mode = "builtin"
# trusted_publishing = true
# [ecosystems.cargo.publish.trusted_publishing]
# enabled = true
# workflow = "publish.yml"
# registry = "crates_io"

{% if has_npm %}
[ecosystems.npm]
enabled = true
{% else %}
# [ecosystems.npm]
# enabled = true
{% endif %}
# [ecosystems.npm.publish]
# enabled = true
# mode = "builtin"
# trusted_publishing = true
# [ecosystems.npm.publish.trusted_publishing]
# enabled = true
# workflow = "publish.yml"
# registry = "npm"

{% if has_deno %}
[ecosystems.deno]
enabled = true
{% else %}
# [ecosystems.deno]
# enabled = true
{% endif %}
# [ecosystems.deno.publish]
# enabled = true
# mode = "builtin"
# trusted_publishing = true
# [ecosystems.deno.publish.trusted_publishing]
# enabled = true
# workflow = "publish.yml"
# registry = "jsr"

{% if has_dart %}
[ecosystems.dart]
enabled = true
{% else %}
# [ecosystems.dart]
# enabled = true
{% endif %}
# [ecosystems.dart.publish]
# enabled = true
# mode = "builtin"
# trusted_publishing = true
# [ecosystems.dart.publish.trusted_publishing]
# enabled = true
# workflow = "publish.yml"
# registry = "pub_dev"

{% if has_python %}
[ecosystems.python]
enabled = true
{% else %}
# [ecosystems.python]
# enabled = true
{% endif %}

# =============================================================================
# [source] — source-control provider configuration
# =============================================================================
#
# Configures the repository host for release automation: creating releases,
# opening release pull requests, and evaluating changeset policy.
#
# Required fields:
#   provider — "github", "gitlab", or "gitea"
#   owner    — repository owner or organization
#   repo     — repository name
#
# Optional fields:
#   host    — custom host URL for self-hosted instances
#   api_url — custom API URL (e.g. for GitHub Enterprise)
{% if provider %}

[source]
provider = "{{ provider }}"
owner = "{{ owner }}"
repo = "{{ repo }}"

# [source.releases] — provider release settings and release branch policy
#
# Controls whether and how releases are created on the provider when the
# PublishRelease CLI step runs. Release refs are verified by commit reachability.
# Tags and publish steps are enforced by default; commit-release stays flexible
# unless you opt in.
[source.releases]
enabled = true
source = "monochange"
branches = ["main"]
enforce_for_tags = true
enforce_for_publish = true
enforce_for_commit = false
changeset_context_timeout_seconds = 120

# [source.pull_requests] — release pull request settings
#
# Controls the OpenReleaseRequest CLI step which creates or updates a release
# PR with version bumps, changelog updates, and changeset cleanup.
[source.pull_requests]
enabled = true
branch_prefix = "monochange/release"
base = "main"
title = "chore(release): prepare release"
labels = ["release", "automated"]
auto_merge = false
{% else %}
#
# [source]
# provider = "github"
# owner = "your-org"
# repo = "your-repo"

# [source.releases] — provider release settings and release branch policy
#
# Controls whether and how releases are created on the provider when the
# PublishRelease CLI step runs. Release refs are verified by commit reachability.
# Tags and publish steps are enforced by default; commit-release stays flexible
# unless you opt in.
#
# Fields:
#   enabled             — enable/disable release creation (default: true)
#   draft               — create releases as drafts (default: false)
#   prerelease          — mark releases as pre-releases (default: false)
#   generate_notes      — ask the provider to auto-generate release notes (default: false)
#   source              — release notes source: "monochange" (use monochange-rendered
#                         notes) or "github_generated" (use provider-generated notes)
#                         Default: "monochange"
#   branches            — release branch names or globs, e.g. ["main", "release/*"]
#   enforce_for_tags    — reject unsafe tag-release refs (default: true)
#   enforce_for_publish — reject unsafe publish refs (default: true)
#   enforce_for_commit  — reject unsafe commit-release refs (default: false)
#   changeset_context_timeout_seconds — hosted-source enrichment timeout (default: 120)
#
# [source.releases]
# enabled = true
# draft = false
# prerelease = false
# source = "monochange"
# branches = ["main"]
# enforce_for_tags = true
# enforce_for_publish = true
# enforce_for_commit = false
# changeset_context_timeout_seconds = 120

# [source.pull_requests] — release pull request settings
#
# Controls the OpenReleaseRequest CLI step which creates or updates a release
# PR with version bumps, changelog updates, and changeset cleanup.
#
# Fields:
#   enabled       — enable/disable release PR creation (default: true)
#   branch_prefix — branch name prefix for release PRs (default: "monochange/release")
#   base          — target branch for the release PR (default: "main")
#   title         — PR title template (default: "chore(release): prepare release")
#   labels        — labels applied to the release PR (default: ["release", "automated"]
#   auto_merge    — enable auto-merge on the PR when supported (default: false)
#
# [source.pull_requests]
# enabled = true
# branch_prefix = "monochange/release"
# base = "main"
# title = "chore(release): prepare release"
# labels = ["release", "automated"]
# auto_merge = false

{% endif %}

# =============================================================================
# [changesets.affected] — changeset verification settings
# =============================================================================
#
# Controls the `AffectedPackages` CLI step which checks whether pull requests
# include changeset files that cover all changed packages.
#
# This section works independently of any source provider.

[changesets.affected]
# Whether changeset verification is enabled. When false, the AffectedPackages
# step will refuse to run.
# Default: true
enabled = true

# Whether a missing changeset is treated as a failure (true) or just a
# warning (false).
# Default: true
required = true

# Pull-request labels that skip verification entirely. When any label on the
# PR matches an entry here, the verify step returns "skipped" instead of
# evaluating coverage.
# Default: []
skip_labels = []

# Whether to render a failure comment body in the evaluation output for
# CI integrations to post back to the pull request.
# Default: true
comment_on_failure = true

# Additional non-package root-level paths that should also trigger changeset
# requirements when changed. Package directories are included automatically.
# Default: []
changed_paths = []

# Files that should not trigger changeset requirements.
# Default: []
ignored_paths = []

# =============================================================================
# [cli.*] — optional user-defined CLI commands
# =============================================================================
#
# `mc init` intentionally leaves the starter config without [cli.*] command
# tables. Most built-in operations are available directly as immutable
# `mc step:*` commands, so new projects do not need generated workflow aliases
# just to validate, discover, release, publish, or inspect diagnostics.
#
# Add [cli.<name>] tables only for project-specific workflows that combine
# multiple steps, add custom shell commands, or provide organization-specific
# command names. Each table becomes a top-level `mc <name>` command.
#
# See the configuration guide for the full [cli.*] schema, input types, and
# step definition examples.