Skip to content

Commit

Permalink
refactor: switch action and types to new configuration (#5211)
Browse files Browse the repository at this point in the history
Depends-On: Mergifyio/engine#14088
Depends-On: Mergifyio/engine#14083

Change-Id: I7cddba47065c37b5ffbe9f647b6f839091301c7c
  • Loading branch information
jd authored Sep 27, 2024
1 parent 91c3eff commit db5c4e0
Show file tree
Hide file tree
Showing 28 changed files with 111 additions and 132 deletions.
3 changes: 1 addition & 2 deletions plugins/remark-algolia.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,7 @@ export function remarkAlgolia(): unified.Plugin<[], mdast.Root> {
const action = element.attributes.find(
(attr) => attr.type === 'mdxJsxAttribute' && attr.name === 'action'
).value;
const actionOptions =
configSchema?.$defs?.Actions?.properties?.[action]?.properties;
const actionOptions = configSchema?.$defs?.[action]?.properties;

tables.push({
node: JSON.stringify(element),
Expand Down
16 changes: 5 additions & 11 deletions src/components/Tables/ActionOptionsTable.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,11 @@
import configSchema from '../../../public/mergify-configuration-schema.json';
import configSchema from '../../../public/mergify-configuration-schema-future-version.json';

import { OptionDefinition } from './ConfigOptions';
import { OptionDefinition, Def } from './ConfigOptions';
import { OptionsTableBase } from './OptionsTable';

interface Props {
/** Action's name to retrieve its options */
action: keyof typeof configSchema.$defs.Actions.properties;
}

export default function ActionOptionsTable({ action }: Props) {
const options = configSchema.$defs.Actions.properties[action].properties as {
export default function ActionOptionsTable({ def }: Def) {
const options = configSchema.$defs[def].properties as {
[optionKey: string]: OptionDefinition;
};

return OptionsTableBase(options);
return OptionsTableBase(configSchema, options);
}
32 changes: 20 additions & 12 deletions src/components/Tables/ConfigOptions.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import jsonpointer from 'jsonpointer';
import configSchema from '../../../public/mergify-configuration-schema.json';
import configSchema from '../../../public/mergify-configuration-schema-future-version.json';
import { renderMarkdown } from './utils';

const valueTypeLinks: { [key: string]: string } = {
Expand All @@ -14,12 +14,17 @@ const valueTypeLinks: { [key: string]: string } = {
Commit: '/configuration/data-types#commit',
CommitAuthor: '/configuration/data-types#commit-author',
RuleCondition: '/configuration/conditions',
ListOfRuleConditions: '/configuration/conditions',
CommandRestrictionsConditionsModel: '/configuration/conditions',
PullRequestRuleConditionsModel: '/configuration/conditions',
QueueRuleMergeConditionsModel: '/configuration/conditions',
PriorityRuleConditionsModel: '/configuration/conditions',
Duration: '/configuration/data-types#duration',
Schedule: '/configuration/data-types#schedule',
PriorityRule: '/merge-queue/priority#how-to-define-priority-rules',
GitHubActionsWorkflow: '/workflow/actions/github_actions#workflow-action',
GitHubActionsWorkflowDispatch: '/workflow/actions/github_actions#workflow-action-dispatch',
CommandRestriction: '/commands/restrictions#command-restriction-format',
GhaActionModelWorkflow: '/workflow/actions/github_actions#workflow-action',
GhaActionModelDispatch: '/workflow/actions/github_actions#workflow-action-dispatch',
CommandRestrictionsModel: '/commands/restrictions#command-restriction-format',
QueueDequeueReason: '/configuration/data-types#queue-dequeue-reason',
ReportModeArray: '/configuration/data-types#report-modes',
};
Expand All @@ -31,6 +36,10 @@ export interface OptionDefinition {
$ref: any;
}

export interface Def {
def: keyof typeof configSchema.$defs;
}

/** We need to strip <em> tags when highlighted by algolia */
function splitRefPath($ref: string) {
return $ref
Expand Down Expand Up @@ -71,22 +80,21 @@ export function resolveSchema(schema: object, item: object): object {
}
}

function getTypeDescription(ref: object): string {
return getItemFromSchema(configSchema, resolveSchema(configSchema, ref)).description;
function getType(schema: object, ref: object): string {
return getItemFromSchema(schema, resolveSchema(schema, ref));
}

export function getValueType(definition: any): React.ReactElement {
export function getValueType(schema: object, definition: any): React.ReactElement {
let valueType = null;

if (definition.type === 'array') {
let typeLink: string;
let typeDescription: string;

if ('$ref' in definition.items) {
typeLink = getTypeLink(definition.items.$ref);
typeDescription = getTypeDescription(definition.items.$ref);
typeDescription = getType(schema, definition.items.$ref).title;
} else {
typeDescription = getValueType(definition.items);
typeDescription = getValueType(schema, definition.items);
}

if (typeLink !== undefined) {
Expand All @@ -105,7 +113,7 @@ export function getValueType(definition: any): React.ReactElement {
const typeLink = getTypeLink(definition.$ref);
const typeDescription = (
<div
dangerouslySetInnerHTML={{ __html: renderMarkdown(getTypeDescription(definition.$ref)) }}
dangerouslySetInnerHTML={{ __html: renderMarkdown(getType(schema, definition.$ref).title) }}
/>
);

Expand Down Expand Up @@ -133,7 +141,7 @@ export function getValueType(definition: any): React.ReactElement {

return (
<>
{getValueType(item)}
{getValueType(schema, item)}
{separator}
</>
);
Expand Down
127 changes: 54 additions & 73 deletions src/components/Tables/OptionsTable.tsx
Original file line number Diff line number Diff line change
@@ -1,41 +1,17 @@
import * as yaml from 'js-yaml';

import configSchema from '../../../public/mergify-configuration-schema.json';
import configSchema from '../../../public/mergify-configuration-schema-future-version.json';

import { getValueType, OptionDefinition, resolveSchema } from './ConfigOptions';
import { getValueType, OptionDefinition } from './ConfigOptions';
import { renderMarkdown } from './utils';
import Badge from '../Badge/Badge';

type ObjectWithProperties<T> = {
properties: T;
};
type KeysWithProperties<T> = {
[K in keyof T]: T[K] extends ObjectWithProperties<any> ? K : never;
}[keyof T];

interface Props {
/** Name to retrieve its options */
name: KeysWithProperties<typeof configSchema.$defs>;
options?: { [optionKey: string]: OptionDefinition };
}

interface RootProps {
/** Name to retrieve its options */
name: KeysWithProperties<typeof configSchema.properties>;
}

export function RootOptionsTable({ name }: RootProps) {
const def = resolveSchema(configSchema, configSchema.properties[name]);
return OptionsTableBase(def.properties);
}

export default function OptionsTable({ name }: Props) {
const options = configSchema.$defs[name].properties;

return OptionsTableBase(options as any);
export default function OptionsTable({ def }: Def) {
const options = configSchema.$defs[def].properties;
return OptionsTableBase(configSchema, options as any);
}

export function OptionsTableBase(options: OptionDefinition) {
export function OptionsTableBase(schema: object, options: OptionDefinition) {
const hasDefaultValue = (definition: OptionDefinition) => definition.default !== undefined;

const shouldHideDefaultColumn = Object.entries(options).every(
Expand All @@ -56,52 +32,57 @@ export function OptionsTableBase(options: OptionDefinition) {
</tr>
</thead>
<tbody>
{Object.entries(options).map(([optionKey, definition]) => {
const valueType = getValueType(definition);
const { deprecated } = definition;
{Object.entries(options)
.sort(([keyA], [keyB]) => keyA.localeCompare(keyB))
.map(([optionKey, definition]) => {
const valueType = getValueType(schema, definition);

return (
<>
<tr style={{ position: 'relative' }}>
<td style={{ whiteSpace: 'nowrap' }}>
<code>{optionKey}</code>
</td>
<td>{valueType}</td>
{!shouldHideDefaultColumn && (
<td>
{hasDefaultValue(definition) && (
<pre>
<code
dangerouslySetInnerHTML={{
__html: yaml.dump(definition.default, {
noCompatMode: true,
lineWidth: -1,
quotingType: '"',
noRefs: true,
}),
}}
/>
</pre>
)}
</td>
)}
{!shouldHideDeprecatedColumn && <td>{deprecated && <Badge>deprecated</Badge>}</td>}
</tr>
{definition.description !== undefined && (
<tr>
{/* FIXME: don't hardcode the border color like that */}
<td {...({ colSpan: shouldHideDefaultColumn ? '3' : '4' } as any)}>
<div
dangerouslySetInnerHTML={{
__html: renderMarkdown(definition.description),
}}
/>
const { deprecated } = definition;

return (
<>
<tr style={{ position: 'relative' }}>
<td style={{ whiteSpace: 'nowrap' }}>
<code>{optionKey}</code>
</td>
<td>{valueType}</td>
{!shouldHideDefaultColumn && (
<td>
{hasDefaultValue(definition) && (
<pre>
<code
dangerouslySetInnerHTML={{
__html: yaml.dump(definition.default, {
noCompatMode: true,
lineWidth: -1,
quotingType: '"',
noRefs: true,
}),
}}
/>
</pre>
)}
</td>
)}
{!shouldHideDeprecatedColumn && (
<td>{deprecated && <Badge>deprecated</Badge>}</td>
)}
</tr>
)}
</>
);
})}
{definition.description !== undefined && (
<tr>
{/* FIXME: don't hardcode the border color like that */}
<td {...({ colSpan: shouldHideDefaultColumn ? '3' : '4' } as any)}>
<div
dangerouslySetInnerHTML={{
__html: renderMarkdown(definition.description),
}}
/>
</td>
</tr>
)}
</>
);
})}
</tbody>
</table>
);
Expand Down
2 changes: 1 addition & 1 deletion src/components/Tables/PullRequestAttributes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export default function PullRequestAttributes({ staticAttributes }: Props) {
{attributes
.sort((a, b) => (a.key > b.key ? 1 : -1))
.map((attr) => {
const valueType = getValueType(attr);
const valueType = getValueType(configSchema, attr);

return (
<tr key={attr.key}>
Expand Down
5 changes: 2 additions & 3 deletions src/content/docs/commands/restrictions.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ description: Set limitations on who can execute specific Mergify commands.
---

import OptionsTable from '../../../components/Tables/OptionsTable';
import { RootOptionsTable } from '../../../components/Tables/OptionsTable';

Mergify commands can be a powerful tool to control and manage pull requests.
However, in some scenarios, you might want to restrict who can use these
Expand Down Expand Up @@ -54,8 +53,8 @@ commands_restrictions:
## Default Restrictions
<RootOptionsTable name="commands_restrictions" />
<OptionsTable def="CommandsRestrictionsRulesModel" />
### Command Restriction Format
<OptionsTable name="CommandRestriction" />
<OptionsTable def="CommandRestrictionsModel" />
4 changes: 2 additions & 2 deletions src/content/docs/configuration/data-types.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ configuration file.
A commit is an object that embeds several information about a [Git
commit](https://docs.github.com/en/pull-requests/committing-changes-to-your-project/creating-and-editing-commits/about-commits)

<OptionsTable name="Commit" />
<OptionsTable def="Commit" />

You can use a commit object in templates:

Expand All @@ -38,7 +38,7 @@ pull_request_rules:
## Commit Author
<OptionsTable name="CommitAuthor" />
<OptionsTable def="CommitAuthor" />
## Regular Expressions
Expand Down
10 changes: 4 additions & 6 deletions src/content/docs/configuration/file-format.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ The top-level key `pull_request_rules` allows to automate your workflow by
writing rules that execute actions. It must be a list of dictionary with the
following keys:

<OptionsTable name="PullRequestRule" />
<OptionsTable def="PullRequestRuleModel" />

Example:

Expand All @@ -93,22 +93,22 @@ pull_request_rules:
The top-level key `queue_rules` allows to define the rules that reign over your
[merge queues](/merge-queue).

<OptionsTable name="QueueRule" />
<OptionsTable def="QueueRuleModel" />

### Priority Rules

The top-level key `priority rules` allows to define the rules that will determine
which [priority](/merge-queue/priority) a pull request has when entering your merge queue.

<OptionsTable name="PriorityRule" />
<OptionsTable def="PriorityRuleModel" />

### Partition Rules

The top-level key `partition_rules` allows to split your repositories into
independent partitions. This is especially useful when using a [monorepo with
the merge queue](/merge-queue/partitions).

<OptionsTable name="PartitionRule" />
<OptionsTable def="PartitionRuleModel" />

### Defaults

Expand Down Expand Up @@ -191,8 +191,6 @@ duplication. This is achieved by using the `extends` keyword at the top of your
configuration file and specifying the source repository. See [Extending
Configuration Files](/configuration/sharing#extending-configuration-files).

{/* <OptionsTable name="Extend" /> */}

## JSON Schema Specification

For those interested in a more detailed and machine-readable description of the
Expand Down
2 changes: 1 addition & 1 deletion src/content/docs/merge-queue/partitions.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ queue_rules:
## Partition Rules Options
<OptionsTable name="PartitionRule" />
<OptionsTable def="PartitionRuleModel" />
## Using a Fallback Partition
Expand Down
2 changes: 1 addition & 1 deletion src/content/docs/merge-queue/priority.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ Defining priority rules is straightforward and involves the following steps:

Reference:

<OptionsTable name="PriorityRule" />
<OptionsTable def="PriorityRuleModel" />

The textual priorities have the following numerical values:

Expand Down
2 changes: 1 addition & 1 deletion src/content/docs/workflow/actions/assign.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pull requests that require their attention.

## Parameters

<ActionOptionsTable action="assign" />
<ActionOptionsTable def="AssignActionModel"/>

As the list of users in `add_users` or `remove_users` is based on
[templates](/configuration/data-types#template), you can use, e.g.,
Expand Down
2 changes: 1 addition & 1 deletion src/content/docs/workflow/actions/backport.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ The `backport` action takes a list of branches to which the changes from the
merged pull request will be backported. The branch names should be specified as
strings.

<ActionOptionsTable action="backport" />
<ActionOptionsTable def="BackportActionModel" />

As the title and body are templates, you can leverage any pull request
attributes to use as content, e.g., `{{author}}`.
Expand Down
Loading

0 comments on commit db5c4e0

Please sign in to comment.