Skip to content

Commit 2128558

Browse files
committed
docs: document the variable-substitution templating language
Document each templated field's variable set as a named data type in data-types.mdx (Message template, Copy title template, Copy body template, Workflow input template), each rendering its variables from the JSON schema via a new TemplateVariablesTable component that reads the x-mergify-template-variables annotation. The simple-template field type in each action's Parameters table shows its data-type title and links to it (getValueType: title->anchor, plus 'map of' for the github_actions inputs map), so feature pages reference the variable set rather than replicating a table. Adds a Variable substitution concept section with a Jinja2 migration cheat-sheet, and re-scopes the legacy Jinja2 Template section to the fields that still use it (post_check, merge). Change-Id: I530a11f43adb18ff3fdc964199e00d52d105a2b7
1 parent 79c379e commit 2128558

13 files changed

Lines changed: 277 additions & 41 deletions

File tree

src/components/Tables/ConfigOptions.tsx

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,20 @@ const valueTypeLinks: { [key: string]: string } = {
1818
};
1919

2020
const valueTypeFormatLinks: { [key: string]: string } = {
21-
template: '/configuration/data-types#template',
21+
template: '/configuration/data-types#legacy-template',
2222
'date-time': '/configuration/data-types#timestamp',
2323
duration: '/configuration/data-types#duration',
2424
};
2525

26+
// A simple-template field carries a per-set title (e.g. "Message template"); render
27+
// the title as the field type, linking to the matching data-types section.
28+
const simpleTemplateTitleLinks: { [key: string]: string } = {
29+
'Message template': '/configuration/data-types#message-template',
30+
'Copy title template': '/configuration/data-types#copy-title-template',
31+
'Copy body template': '/configuration/data-types#copy-body-template',
32+
'Workflow input template': '/configuration/data-types#workflow-input-template',
33+
};
34+
2635
export type OptionDefinitionRef = string;
2736

2837
export interface OptionDefinitionProperties {
@@ -189,6 +198,19 @@ export function getValueType(schema: object, definition: any): React.ReactElemen
189198
);
190199
} else if ('const' in definition) {
191200
valueType = <HighlightCode>{definition.const}</HighlightCode>;
201+
} else if (definition.format === 'simple-template') {
202+
// A simple-template field IS a named data type: show its title and link to the
203+
// matching data-types section, like Template/Timestamp/Duration.
204+
const title: string = definition.title ?? 'simple-template';
205+
const titleLink = simpleTemplateTitleLinks[title];
206+
valueType =
207+
titleLink !== undefined ? (
208+
<a color="primary" style={{ textDecoration: 'underline' }} href={titleLink}>
209+
{title}
210+
</a>
211+
) : (
212+
<HighlightCode>{title}</HighlightCode>
213+
);
192214
} else if ('format' in definition) {
193215
const formatLink = valueTypeFormatLinks[definition.format];
194216
if (formatLink !== undefined) {
@@ -198,6 +220,13 @@ export function getValueType(schema: object, definition: any): React.ReactElemen
198220
</a>
199221
);
200222
}
223+
} else if (
224+
definition.additionalProperties &&
225+
typeof definition.additionalProperties === 'object'
226+
) {
227+
// A map field (e.g. github_actions inputs): show "map of <value type>" so the
228+
// templated value type still links to its data-types section.
229+
valueType = <>map of {getValueType(schema, definition.additionalProperties)}</>;
201230
} else {
202231
valueType = <HighlightCode>{definition.type}</HighlightCode>;
203232
}

src/components/Tables/OptionsTable.tsx

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as yaml from 'js-yaml';
22

33
import configSchema from '../../util/sanitizedConfigSchema';
4+
import { extractTemplateVariables } from '../../util/templateVariables';
45
import Badge from '../Badge/Badge';
56
import {
67
ConfigSchema,
@@ -50,6 +51,19 @@ export function OptionsTableBase(
5051
: '';
5152
const defaultIsMultiline = hasDefault && defaultDump.includes('\n');
5253
const isDeprecated = Boolean(definition.deprecated);
54+
// A simple-template field's description carries an "Allowed variables: …"
55+
// list. Once the schema publishes x-mergify-template-variables, the data
56+
// type renders a richer <TemplateVariablesTable>, so the duplicate list is
57+
// stripped here. Until that annotation is synced in, keep the list — it is
58+
// the only variable reference readers have.
59+
const rawDescription = (definition as OptionDefinition).description;
60+
const hasPublishedVariables =
61+
definition.format === 'simple-template' &&
62+
extractTemplateVariables(definition).length > 0;
63+
const description =
64+
hasPublishedVariables && typeof rawDescription === 'string'
65+
? rawDescription.replace(/\s*Allowed variables:.*$/s, '').trim()
66+
: rawDescription;
5367
const id = `${idPrefix}${optionKey}`;
5468
const href = `#${encodeURIComponent(id)}`;
5569

@@ -86,11 +100,11 @@ export function OptionsTableBase(
86100
<code>{defaultDump}</code>
87101
</pre>
88102
)}
89-
{definition.description !== undefined && (
103+
{description !== undefined && (
90104
<div
91105
className={styles.description}
92106
dangerouslySetInnerHTML={{
93-
__html: renderMarkdown(definition.description),
107+
__html: renderMarkdown(description),
94108
}}
95109
/>
96110
)}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import configSchema from '../../util/sanitizedConfigSchema';
2+
import { extractTemplateVariables } from '../../util/templateVariables';
3+
4+
import { ConfigSchema, Def } from './ConfigOptions';
5+
import { renderMarkdown } from './utils';
6+
7+
interface TemplateVariablesTableProps extends Def {
8+
field: string;
9+
}
10+
11+
export default function TemplateVariablesTable({ def, field }: TemplateVariablesTableProps) {
12+
const schema = configSchema as unknown as ConfigSchema;
13+
const definition = schema.$defs[def]?.properties?.[field];
14+
const variables = extractTemplateVariables(definition);
15+
16+
// Astro's React SSR rejects a component that conditionally returns null/undefined,
17+
// so render an empty fragment (not null) when the field has no published variables
18+
// — the graceful state before the engine schema with x-mergify-template-variables
19+
// is synced into the docs.
20+
if (variables.length === 0) {
21+
return <></>;
22+
}
23+
24+
return (
25+
<div className="table-wrap">
26+
<table>
27+
<thead>
28+
<tr>
29+
<th>Variable</th>
30+
<th>Description</th>
31+
</tr>
32+
</thead>
33+
<tbody>
34+
{variables.map((variable) => (
35+
<tr key={variable.name}>
36+
<td>
37+
<code>{`{{ ${variable.name} }}`}</code>
38+
</td>
39+
<td dangerouslySetInnerHTML={{ __html: renderMarkdown(variable.description) }} />
40+
</tr>
41+
))}
42+
</tbody>
43+
</table>
44+
</div>
45+
);
46+
}

src/content/docs/configuration/data-types.mdx

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ description: The different data types you can find in Mergify configuration file
44
---
55

66
import OptionsTable from '../../../components/Tables/OptionsTable';
7+
import TemplateVariablesTable from '../../../components/Tables/TemplateVariablesTable';
78

89
When using templates or conditions, data are made of different types. You will
910
find below the different data types that are available and exposed in Mergify
@@ -256,7 +257,67 @@ priority_rules:
256257
priority: 550
257258
```
258259

259-
## Template
260+
## Templates
261+
262+
Some fields are rendered as templates before Mergify uses them. Most accept
263+
*variable substitution* (short `{{ name }}` placeholders filled with pull
264+
request data); a few still use the legacy [Jinja2](#legacy-template) language.
265+
266+
### Variable substitution
267+
268+
Several fields let you insert pull request data using variables:
269+
270+
```text
271+
Thank you {{ author }} for your contribution!
272+
```
273+
274+
renders to:
275+
276+
```text
277+
Thank you jd for your contribution!
278+
```
279+
280+
when the pull request author login is `jd`.
281+
282+
A variable is written as `{{ name }}` (surrounding spaces are optional). Every
283+
other character is kept as-is. Each templated field accepts a specific set of
284+
variables, documented as its data type below.
285+
286+
### Message template
287+
288+
Used by the [`comment`](/workflow/actions/comment),
289+
[`review`](/workflow/actions/review) and [`close`](/workflow/actions/close)
290+
message fields.
291+
292+
<TemplateVariablesTable def="CommentActionModel" field="message" />
293+
294+
### Copy title template
295+
296+
Used by the [`copy`](/workflow/actions/copy) and
297+
[`backport`](/workflow/actions/backport) `title` field.
298+
299+
<TemplateVariablesTable def="CopyActionModel" field="title" />
300+
301+
### Copy body template
302+
303+
Used by the [`copy`](/workflow/actions/copy) and
304+
[`backport`](/workflow/actions/backport) `body` field.
305+
306+
<TemplateVariablesTable def="CopyActionModel" field="body" />
307+
308+
### Workflow input template
309+
310+
Used by the [`github_actions`](/workflow/actions/github_actions) workflow input
311+
values.
312+
313+
<TemplateVariablesTable def="GhaActionModelDispatch" field="inputs" />
314+
315+
### Legacy template
316+
317+
:::note
318+
Jinja2 is deprecated for fields that support [variable
319+
substitution](#variable-substitution) and stops working on 2026-09-30.
320+
:::
260321

261322
The template data type is a regular string that is rendered using the [Jinja2
262323
template language](https://jinja.palletsprojects.com/templates/).

src/content/docs/workflow/actions/assign.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ pull requests that require their attention.
1717
<ActionOptionsTable def="AssignActionModel"/>
1818

1919
As the list of users in `add_users` or `remove_users` is based on
20-
[templates](/configuration/data-types#template), you can use, e.g.,
20+
[templates](/configuration/data-types#legacy-template), you can use, e.g.,
2121
`{{author}}` to assign the pull request to its author.
2222

2323
:::caution

src/content/docs/workflow/actions/backport.mdx

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -32,19 +32,6 @@ strings.
3232

3333
<ActionOptionsTable def="BackportActionModel" />
3434

35-
As the title and body are templates, you can leverage any pull request
36-
attributes to use as content, e.g., `{{author}}`.
37-
38-
Note that the `commits` attribute here will be the list of cherry
39-
picked commits.
40-
41-
On top of that, you can also use the following additional variables:
42-
43-
- `{{ destination_branch }}`: the name of the destination branch.
44-
45-
- `{{ cherry_pick_error }}`: the cherry pick error message if any (only
46-
available in body).
47-
4835
<BackportLimitations />
4936

5037
## Examples
@@ -101,10 +88,11 @@ In this configuration, a pull request is backported when it has the label `backp
10188
Then, when the backport is created and passes the check named
10289
`continuous-integration`, it will be automatically merged.
10390

104-
### Implementing `-x` option
91+
### Including the cherry-picked commits
10592

106-
If you are used to the `-x` option of `git cherry-pick` that includes which
107-
commits has been cherry-picked, you can implement the same thing with Mergify:
93+
To record which commits were cherry-picked (similar to the `-x` option of `git
94+
cherry-pick`), include their SHAs in the backport body with the
95+
`{{ cherry_picked_commits }}` variable:
10896

10997
```yaml
11098
pull_request_rules:
@@ -116,9 +104,7 @@ pull_request_rules:
116104
body: |
117105
{{ body }}
118106
119-
{% for c in commits %}
120-
(cherry picked from commit {{ c.sha }})
121-
{% endfor %}
107+
{{ cherry_picked_commits }}
122108
branches:
123109
- stable
124110
```

src/content/docs/workflow/actions/copy.mdx

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -34,19 +34,6 @@ request will be copied. The branch names should be specified as strings.
3434

3535
<ActionOptionsTable def="CopyActionModel" />
3636

37-
As the title and body are templates, you can leverage any pull request
38-
attributes to use as content, e.g., `{{author}}`.
39-
40-
Note that the `commits` attribute here will be the list of cherry
41-
picked commits.
42-
43-
On top of that, you can also use the following additional variables:
44-
45-
- `{{ destination_branch }}`: the name of the destination branch.
46-
47-
- `{{ cherry_pick_error }}`: the cherry pick error message if any (only
48-
available in body).
49-
5037
<CopyLimitations />
5138

5239
## Examples

src/content/docs/workflow/actions/github_actions.mdx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ following rule.
4040

4141
Here, the `hello_world_workflow.yaml` workflow accepts two
4242
inputs, which are defined as `name` and `age`. The `dynamic_workflow.yaml`
43-
takes the [template](/configuration/data-types#template) input `author`.
43+
takes the `author` input, set with [variable
44+
substitution](/configuration/data-types#variable-substitution).
4445

4546
```yaml
4647
pull_request_rules:

src/content/docs/workflow/actions/merge.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ commit_message_format:
247247
### Migrating from `commit_message_template`
248248

249249
The legacy `commit_message_template` setting is a
250-
[template](/configuration/data-types#template) that renders the entire
250+
[template](/configuration/data-types#legacy-template) that renders the entire
251251
commit message. `commit_message_format` covers the common patterns
252252
declaratively, with predictable output and no template engine.
253253

src/content/docs/workflow/actions/post_check.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ status of a pull request based on Mergify's evaluation.
7474
<ActionOptionsTable def="PostCheckActionModel" />
7575

7676
As the `title` and `summary` are
77-
[templates](/configuration/data-types#template), you can benefit from any [pull
77+
[templates](/configuration/data-types#legacy-template), you can benefit from any [pull
7878
request attributes](/configuration/conditions#attributes-list), e.g. `{{author}}`,
7979
and also these additional variables:
8080

0 commit comments

Comments
 (0)