-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathconfig.yaml.example
More file actions
391 lines (372 loc) · 21.2 KB
/
config.yaml.example
File metadata and controls
391 lines (372 loc) · 21.2 KB
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
# RelEasy config.yaml — stable infrastructure for ONE project.
#
# Three files make up a project's on-disk footprint:
#
# 1. config.yaml — this file. Origin, target branch, AI
# settings, notifications, pr_policy. Rarely
# edited once a project is set up.
# 2. <name>.session.yaml — per-effort source data: the `features:`
# list and `pr_sources:` selectors. Edit this
# between runs as your target work changes.
# Lives next to config.yaml by default; point
# elsewhere with `session_file:` below or
# `--session-file` on the CLI.
# 3. <name>.state.yaml — runtime progress. Managed by RelEasy; lives
# in ${XDG_STATE_HOME:-~/.local/state}/releasy/.
#
# `releasy --stateless` (e.g. `address-review --stateless`) loads THIS file
# (overridable with `--config`) but skips the session and state files.
# ── Project identity (required) ─────────────────────────────────────
# Unique slug for this project on this machine. Doubles as the filename
# of the per-project state file and (by default) the session file:
# state: ${XDG_STATE_HOME:-~/.local/state}/releasy/<name>.state.yaml
# session: <dir-of-this-config>/<name>.session.yaml
# Allowed characters: A-Z a-z 0-9 . _ - (1-64 chars). Pick something
# stable like the target branch you are porting onto. Renaming this
# orphans the old state file — use `releasy adopt` to rebind state to a
# moved/renamed config.
name: antalya-26.3
# ── Session file (optional override) ────────────────────────────────
# By default the session file lives at `<config-dir>/<name>.session.yaml`.
# Set this to point somewhere else (absolute or relative to this file's
# directory). The CLI `--session-file <path>` always takes precedence.
# session_file: sessions/antalya-26.3.session.yaml
# ── Push & PR control ───────────────────────────────────────────────
# Push branches to origin and open PRs.
# Default is false — everything stays local until you enable this.
# push: true
# ── Sequential mode ─────────────────────────────────────────────────
# When true, RelEasy processes the merged-time-sorted PR queue one PR
# per `releasy run` / `releasy continue` invocation:
# 1. The first invocation ports the earliest-merged PR, pushes it,
# opens a rebase PR, and exits.
# 2. You review the PR; once CI is green you approve & merge it
# manually into target_branch.
# 3. The next `releasy continue` checks GitHub: if the previous
# rebase PR was merged, it ports the next PR (created from the
# now-updated target_branch). If not yet merged, it exits with a
# non-zero status and changes nothing.
#
# Default: false (batch mode — every discovered PR is ported in one go).
# Incompatible with `pr_sources.groups` in the session file (session
# load will fail).
# sequential: false
# ── Conflict handling ───────────────────────────────────────────────
# When a cherry-pick conflicts and the AI resolver is disabled or gives
# up (after exhausting `ai_resolve.max_iterations` build attempts), the
# pipeline:
# * Singleton PR or first-of-group: aborts the cherry-pick, deletes the
# local port branch (it has no useful commits), records the entry as
# "Conflict" in the GitHub Project. No push, no PR.
# * Group with N>=1 successful prior picks: aborts the failed pick,
# pushes the branch as-is, opens a DRAFT PR labelled
# `ai-needs-attention` with a banner explaining what failed, and
# records "Conflict" in the GitHub Project. Remaining PRs in
# the group are not attempted.
# Either way the pipeline keeps going with the next unit.
# ── Existing-PR behaviour ───────────────────────────────────────────
# When a PR for the port branch already exists on GitHub:
# false (default) — leave it exactly as-is. Don't try to create a new
# one (avoids GitHub 422s) and don't touch its
# title/body/labels. You can still edit the PR
# manually on GitHub.
# true — reuse the same PR but overwrite its title and body
# with what releasy would have set (source-PR refs,
# combined group body, ai-resolved prefix, …). Handy
# when source PR descriptions changed or you tweaked
# the body format and want the rebase PR to reflect
# it.
# update_existing_prs: false
# ── Merged-port label (optional) ────────────────────────────────────
# When set, releasy applies this label to the rebase (port) PR once it
# has been merged into target_branch, and strips the same label from
# every source PR the port was cherry-picked from. Useful for marking
# "this PR has been ported into release X" with a single label that
# moves automatically as ports land.
#
# Source-PR cleanup is best-effort and only touches PRs hosted on the
# configured origin — source PRs on a different repo are skipped (RelEasy
# never writes outside origin). The label is auto-created on origin the
# first time a merged port is observed.
#
# Each tracked unit is processed exactly once: a per-feature flag on
# the state file (`merged_label_applied`) prevents re-hitting GitHub on
# every subsequent `releasy run`. Renaming the label here does NOT
# auto-relabel previously-processed units.
#
# Requires push: true to take effect. Unset / empty disables the feature.
# merged_label: port-antalya
# merged_label_color: "8B5CF6" # 6-hex color used when releasy creates
# # the label on origin (default: purple).
# ── Work directory ──────────────────────────────────────────────────
# Where to clone/find the origin repo for git operations.
# If it points to an existing git repo, it will be reused (no clone).
# If omitted, uses the current working directory.
# Can also be overridden with --work-dir on the CLI.
# work_dir: /path/to/ClickHouse
# ── Session log (optional) ───────────────────────────────────────
# Append a full transcript of the process (stdout and stderr: Rich
# output, ``click`` messages, ``logging`` warnings, tracebacks) to a file
# for post-run analysis. Relative paths resolve against the directory
# that contains this config file.
# log_file: .releasy/releasy.log
# ── Origin (required) ──────────────────────────────────────────────
# The repo you work against. This is the only repo RelEasy tracks
# as a configured remote.
origin:
remote: https://github.com/Altinity/ClickHouse.git
remote_name: origin
# ── Project & target branch ────────────────────────────────────────
# Short project identifier — used to name port branches as
# feature/<base>/<feature-id>
project: antalya
# The base/target branch PRs are opened into. Two ways to set it:
#
# 1. Explicit (recommended): set 'target_branch' here. --onto becomes
# optional and you don't need a tag-based name derivation.
#
# 2. Derived: leave 'target_branch' unset and pass --onto <ref> on
# the CLI. The base branch is then '<project>-<version>', where
# <version> is parsed from --onto (e.g. v26.3.4.234-lts → 26.3,
# yielding 'antalya-26.3').
#
# The base branch must already exist on origin before running.
target_branch: antalya-26.3
# ── PR policy ──────────────────────────────────────────────────────
# Policy knobs that apply to EVERY discovered unit (by_labels entries,
# explicit include_prs, groups, …). These live here — not in the
# session file — because they're stable infrastructure: what to do
# with branches, when to retry, whether to open PRs. Edit the session
# file to change *what* to port; edit pr_policy to change *how*.
#
# All values shown below are defaults; omit pr_policy entirely to
# accept them all.
#
# pr_policy:
# if_exists: skip
# # When the port branch already exists locally AND no rebase PR has
# # been opened for it yet:
# # "skip" (default) — leave the local branch alone; don't re-process.
# # Also: refuse to start if a cherry-pick / merge
# # / rebase is still in progress in the work dir.
# # "recreate" — delete the local branch and rebuild from base.
# # Also: if a cherry-pick / merge / rebase is in
# # progress at startup, abort it and start fresh.
# # "append" — cherry-pick any declared PRs that aren't on the
# # existing branch onto its tip and update the
# # rebase PR body to match the declared group
# # order. Use when you've added a PR to a group
# # that already shipped through a prior run and
# # you want to top up the existing branch / PR
# # rather than rebuild from scratch.
# # Detection uses the ``Source-PR:`` commit
# # trailers releasy writes; falls back to ``skip``
# # with a warning if the existing commits don't
# # match a prefix of the declared group.
# # Mostly for groups (singletons have one PR, so
# # there's nothing to top up). The remote-already-
# # exists safety lock is bypassed in this mode
# # since appending is the explicit user opt-in.
# #
# # ONCE A REBASE PR IS OPEN: if_exists no longer controls whether the
# # branch is rebuilt — it never is. `releasy run` switches to
# # merging origin/<base> into the PR branch (the same flow
# # `releasy refresh` uses): clean merge → leave PR alone, conflict →
# # AI-resolve and plain push. Pass --merge-target on the CLI to
# # push a fresh merge commit even on clean merges. The only setting
# # that still touches an open PR's branch directly is `append`,
# # which cherry-picks newly declared PRs on top.
# #
# # Note: if the branch already exists on the REMOTE without a tracked
# # rebase PR, it is ALWAYS skipped in "skip"/"recreate" modes (resolve
# # those manually so you don't clobber someone else's work).
# # Individual session entries (pr_sources.by_labels[] /
# # pr_sources.groups[]) can override this default per-entry with
# # their own if_exists.
# auto_pr: true
# # When true (the default), every pushed port branch gets a PR opened
# # against the base. Set to false to push branches only and open PRs
# # manually. Requires push: true to have any effect.
# retry_failed: true
# # When a PR unit has a `conflict` entry in state from a previous run:
# # true (default) — process the unit again on this run, per the
# # unit's `if_exists` value (see above). For units
# # WITHOUT an open rebase PR, retry can rebuild
# # from base (`recreate`), append, or skip per
# # if_exists. For units WITH an open rebase PR,
# # retry routes through merge-target instead —
# # an open PR's history is never blown away.
# # false — leave the conflicted entry exactly as-is; no
# # cherry-pick, no PR side-effects.
# # CLI flag `--retry-failed / --no-retry-failed` overrides per-invocation.
# recreate_closed_prs: false
# # When true, if state has a rebase_pr_url and that GitHub PR is closed
# # (not merged), allocate `<canonical>-1`, `-2`, … for the port branch
# # name and cherry-pick + open a fresh PR. Off by default: a closed
# # rebase PR just leaves the branch skipped on subsequent runs.
# ── PR sources and features ─────────────────────────────────────────
# These live in the session file, not here. Look for
# `<name>.session.yaml` next to this config (or wherever `session_file:`
# above points). The session file is where you edit:
#
# * `features:` — the static list of feature branches to rebase.
# * `pr_sources:` — label-based discovery, explicit include/exclude,
# author filters, groups, etc.
#
# See the bundled session template for the full reference.
# ── GitHub Project board ────────────────────────────────────────────
# Sync branch status to a GitHub Project v2 board (optional).
# Only active when push: true.
#
# One-time setup:
# 1. Create a GitHub Project (or run: releasy setup-project)
# 2. Copy the project URL below
# 3. Ensure RELEASY_GITHUB_TOKEN has repo + project scopes
#
# Or auto-setup (creates project + Status field):
# releasy setup-project
#
# Each rebase gets its own view (tab) in the project, named after
# the base branch (e.g. antalya-26.3). Cards are managed automatically.
notifications:
github_project: https://github.com/orgs/Altinity/projects/1
# ── AI conflict resolver (Claude) ───────────────────────────────────
# Optional. When enabled, releasy invokes `claude` to resolve cherry-
# pick conflicts, build, and commit. If Claude prints UNRESOLVED or
# BUILD FAILED (after exhausting `max_iterations` build attempts) or
# fails outright, releasy treats the unit as "Conflict" — see
# the "Conflict handling" section above.
#
# ai_resolve:
# enabled: false
# command: claude
# prompt_file: prompts/resolve_conflict.md
# # Prompt template used by `releasy refresh` when Claude has to
# # drive a `git merge` to completion (keeping an open rebase PR
# # current with its target branch). Same placeholder vocabulary as
# # prompt_file; the difference is the in-progress operation
# # (merge vs cherry-pick) and how to conclude it.
# merge_prompt_file: prompts/resolve_merge_conflict.md
# # Hard cap (passed into the prompt) on how many build attempts
# # Claude is allowed to make per conflict before giving up.
# max_iterations: 5
# timeout_seconds: 7200
# build_command: cd build && ninja
# # Label automatically applied to PRs whose conflicts Claude
# # resolved cleanly.
# label: ai-resolved
# label_color: "8B5CF6"
# # Label applied to DRAFT PRs released by partial-group failures
# # (singleton failures don't get a PR — the local branch is dropped).
# needs_attention_label: ai-needs-attention
# needs_attention_label_color: "D93F0B"
# # How many times to re-invoke Claude when the Anthropic streaming
# # API drops the turn with a transient error (idle timeout, overload,
# # connection reset, …). Each retry is a fresh turn — independent of
# # `max_iterations`.
# api_retries: 3
# api_retry_backoff_seconds: 15
# ── AI changelog entry synthesis (Claude) ────────────────────────────
# Optional. When enabled, multi-PR groups get a single user-facing
# CHANGELOG entry composed by Claude based on the constituent PRs'
# titles + bodies. Singletons (one PR per port branch) ALWAYS reuse
# the source PR's `Changelog entry` verbatim — Claude is never invoked
# in that case, so the singleton flow has zero API cost.
#
# The synthesizer is told to:
# - drop intermediate fix-ups inside the group (B fixes a bug A
# introduced earlier in the same group → the user never saw the
# bug, so it doesn't belong in the changelog),
# - drop refactors / internal cleanup with no user-visible effect,
# - keep the entry to one or two terse, imperative-present-tense
# sentences matching typical CHANGELOG.md tone.
#
# Failures are non-fatal: the per-PR fallback (first-PR-in-group's own
# changelog entry) is used and a warning is logged.
#
# ai_changelog:
# enabled: false
# command: claude
# prompt_file: prompts/synthesize_changelog.md
# timeout_seconds: 300
# # Per-PR body trimmed to this many characters before being inlined
# # into the prompt (keeps payloads bounded for chatty source PRs).
# max_pr_body_chars: 3000
# ─────────────────────────────────────────────────────────────────────
# REVIEW RESPONSE (`releasy address-review`)
#
# Reads review comments left on a PR and lets the AI make code
# changes addressing the feedback. Off by default because it spends
# Anthropic tokens every call and writes to your PR branch.
#
# Runs in two modes:
# * Default — loads this config, takes the project lock,
# records timestamps in state for tracked PRs.
# * `--stateless` — loads this config, but skips session/state/lock.
# CLI flags (--origin / --build-command / ...)
# override anything in config.
#
# Every comment is filtered to an explicit allowlist of trusted
# reviewers BEFORE the AI sees it — untrusted commenters cannot smuggle
# instructions into the run. The allowlist here is unioned with
# `--reviewer` on the CLI; if both are empty, the command refuses to
# run.
#
# Linear history is a hard rule: the AI only appends commits (it uses
# `git revert` to retract anything, never amend / rebase / reset).
# RelEasy pushes with plain `git push` at the end.
#
# review_response:
# trusted_reviewers:
# - alice
# - bob
# # Reply in-thread (with a bot footer) on every comment classified as
# # non-actionable. Set to false for a silent run that only reports
# # via the AI's terminal narration. Override per-invocation with
# # --reply / --no-reply.
# reply_to_non_addressable: true
# # Optional: post one extra top-level summary comment on the PR
# # describing what was done (distinct from per-comment replies).
# post_summary_comment: false
# # Advanced overrides — the defaults below are already sensible.
# # command: claude
# # prompt_file: prompts/address_review.md
# # max_iterations: 15
# # timeout_seconds: 7200
# ─────────────────────────────────────────────────────────────────────
# WORKFLOW
#
# The base branch must already exist on origin. The pipeline then ports
# each discovered PR / feature onto it:
#
# releasy run --onto v26.3.4.234-lts # (or just: releasy run, when
# # target_branch is set above)
# → creates "feature/antalya-26.3/<id>" for each PR / feature
# → opens PRs into antalya-26.3 (if push + pr_policy.auto_pr)
#
# On unresolved conflict:
# * Singleton / first-of-group: nothing local survives — the entry is
# marked "Conflict" in the GitHub Project. Resolve manually
# in the source PR and re-run releasy.
# * Partial group: a draft PR is opened, labelled `ai-needs-attention`.
# Fix the conflict on that branch, push, mark the PR ready.
#
# The pipeline never stalls on a single bad unit anymore — it just
# flags it and moves on.
#
# Once a batch of rebase PRs is open, the target branch keeps moving as
# other work lands. Some PRs will eventually conflict with the new tip:
#
# releasy refresh
# → strictly maintenance: never opens new PRs, never creates new
# branches, never discovers new sources. Only refreshes entries
# already in the per-project state file.
# → for each tracked PR with a branch + rebase PR URL:
# fetch latest tips, attempt `git merge --no-ff origin/<base>`
# into the PR branch. Clean merge: leave the PR alone. Conflict
# + AI resolves: push the resolved merge commit. Conflict + AI
# gives up: abort the merge, reset, mark the entry "Conflict".
# → uses `ai_resolve.merge_prompt_file` (same machinery as cherry-pick
# resolution; different in-progress operation and prompt framing).
# → exits 1 if any PR ended up in conflict — suitable for cron / CI.
# ─────────────────────────────────────────────────────────────────────