Skip to content

Use single invalid-title label for both title and commit-message rules#4

Merged
andamasov merged 2 commits into
productionfrom
yuriy/unify-invalid-title-label
May 12, 2026
Merged

Use single invalid-title label for both title and commit-message rules#4
andamasov merged 2 commits into
productionfrom
yuriy/unify-invalid-title-label

Conversation

@andamasov
Copy link
Copy Markdown
Member

Change Summary

Both Flag PR title not matching T-ID format and Flag commit message not matching T-ID format check the same ^(([a-zA-Z0-9\-_.]+:\s)?)T\d+:\s+[^\s]+.* headline regex — one against the PR title, one against each commit's first line. They label invalid-title and invalid-commit-title respectively.

The two labels are near-identical and add no signal: a PR that fails one usually fails the other, and the author's fix in both cases is "rewrite the headline." Splitting them just produces two near-identical labels on the same PR.

This PR collapses both rules onto a single invalid-title label. The two rules stay separate so an operator scanning Mergify rule logs can still tell which surface tripped, but the user-facing label surface gets one entry.

Rollout impact

  • Affects every consumer of extends: mergify (the org-wide central baseline).
  • PRs currently labeled invalid-commit-title will keep that label until something removes it. Once this merges, the rule that toggles invalid-commit-title no longer exists in the central config, so the label is orphaned (Mergify won't re-evaluate it). Manual cleanup or a one-shot label removal is fine — the label stops appearing on new PRs immediately.
  • Repos that override the Flag commit message not matching T-ID format rule by name (e.g. vyos-documentation#2009) are unaffected — they replace the rule entirely, so the parent's label choice doesn't reach them.

Related Task(s)

Related PR(s)

  • vyos-documentation#2008 — example PR labeled both invalid-title and invalid-commit-title, surfacing the duplication.
  • vyos-documentation#2009 — repo-specific override that disables both rules entirely for vyos-documentation; independent of this change.

🤖 Generated by robots

The two PR-message-format rules check the same `T<digits>: <text>`
headline regex against two surfaces — the PR title and each commit's
first line. Splitting that into two labels (`invalid-title` +
`invalid-commit-title`) creates near-identical labels on the same PR
and adds no information for the author: the fix in both cases is
"rewrite the headline to match the format."

Collapse onto `invalid-title`. The two rules stay separate so an
operator scanning rule logs can still see which surface tripped, but
the user-facing surface gets one label.

🤖 Generated by [robots](https://vyos.io)
@andamasov
Copy link
Copy Markdown
Member Author

@copilot review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 12, 2026

Review Change Stack
No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Central YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 45368858-fe97-4f7e-af92-30de0c943cc4

📥 Commits

Reviewing files that changed from the base of the PR and between 618d166 and 890a369.

📒 Files selected for processing (1)
  • .mergify.yml
🚧 Files skipped from review as they are similar to previous changes (1)
  • .mergify.yml
📜 Recent review details
🧰 Additional context used
🔍 Remote MCP Context7

Relevant findings for reviewing the PR

  • Mergify supports a label action toggle that adds the label when a rule's conditions match and removes it when they don't; this replaces the older add/remove rule-pair pattern.
  • The docs explicitly warn against having rule pairs that flip the same label indefinitely: "Avoid rule pairs that flip the same label indefinitely... the label toggles back and forth." They recommend scoping conditions so they become mutually exclusive or collapse into a single toggle rule.
  • A changelog entry documents the toggle option as intended to let a single rule manage a label's presence instead of dual inverse rules; collapsing title+commit-first-line checks into one or rule with a single toggle: - invalid-title aligns with that guidance.
  • Library metadata (for reference): Context7 library entry resolved for Mergify: /websites/mergify (high reputation; many code snippets).

Sources used: Context7 documentation and changelog for Mergify (label action / toggle guidance).


📝 Walkthrough

Summary by CodeRabbit

  • Chores
    • Consolidated PR validation into a single rule that validates PR title and commit-first-line together and uses one shared "invalid-title" label for failures.
    • Updated inline documentation/comments to describe the combined validation behavior and shared headline/regex handling.

Walkthrough

Consolidates separate PR title and commit-first-line headline checks into a single pull_request_rules entry using an or condition; both checks now toggle the shared invalid-title label. Header comments in .mergify.yml were updated to describe the combined behavior.

Changes

Mergify label consolidation

Layer / File(s) Summary
Header comment updates
.mergify.yml (lines 49–51)
Update section header comments to indicate the PR-message format rule now replaces prior split checks.
Combined title and commit-headline rule
.mergify.yml (lines 66–92)
Replace two separate rules with one pull_request_rules entry that uses or to validate PR title or any commit first line; on commit-message failure toggle invalid-title (replaces invalid-commit-title) and update rule description to reflect shared headline regex.

Possibly related PRs

  • vyos/mergify#1: Introduced the earlier invalid-commit-title label that this PR consolidates into invalid-title.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title directly and specifically describes the main change: consolidating two separate label rules into a single invalid-title label for both PR title and commit-message validation checks.
Description check ✅ Passed The description thoroughly explains the rationale for the change, the technical details of the consolidation, rollout impact, and references related tasks and PRs—all directly relevant to the changeset.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch yuriy/unify-invalid-title-label

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@andamasov andamasov marked this pull request as ready for review May 12, 2026 12:53
Copy link
Copy Markdown

Copilot AI commented May 12, 2026

@copilot review

Review findings for commit 618d166

The change is clean and achieves its stated goal. One thing worth confirming:

⚠️ Toggle conflict on mixed-state PRs

Both rules now independently toggle: invalid-title. Mergify's toggle removes the label when a rule's conditions are not met. This creates a potential issue in the (admittedly unusual) edge case where the two conditions disagree — e.g., a PR whose title is malformed but all commits are well-formed (or vice versa):

  • Title rule: conditions true → adds invalid-title
  • Commit rule: conditions false → removes invalid-title

Depending on which rule Mergify evaluates last, the label may be incorrectly cleared. In practice this edge case is rare (authors who fix commits usually fix the title too), and a subsequent push re-triggers evaluation, but it's a subtle gotcha.

A fully safe alternative would be using separate add + remove rules (or a single combined OR condition) so only one rule owns the label's lifecycle. That said, if Mergify evaluates all rules atomically per event (add wins over remove in the same pass), this is a non-issue in practice.

Everything else looks good:

  • Regex and conditions are unchanged — no regression risk.
  • The description clearly explains the rationale and the operator/user split.
  • The migration note (orphaned invalid-commit-title labels) is accurate and the scope is well-defined.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.mergify.yml (1)

83-99: ⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Multiple rules toggling invalid-title with different conditions may produce indeterminate label states.

Rules at lines 70–81 (title check) and 83–99 (commit message check) both toggle invalid-title based on different conditions. Mergify documentation warns that "multiple toggles can conflict, the outcome may be indeterminate without explicit rule ordering, which is not documented." When one rule matches and the other doesn't (e.g., valid title but invalid commit), the final label state becomes unpredictable.

Recommended fixes:

  • Use mutually exclusive conditions so only one rule can match, or
  • Replace toggle with explicit add and remove actions with clearly defined precedence
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.mergify.yml around lines 83 - 99, The two rules ("Flag commit message not
matching T-ID format" which uses condition
'commits[*].commit_message~=^(?!(([a-zA-Z0-9\-_.]+:\s)?)T\d+:\s+[^\s]+).*' and
the title-check rule that also toggles the invalid-title label) both use toggle
on the same label and can conflict; update the commit-message rule to avoid
indeterminate state by either making its conditions mutually exclusive with the
title rule (so only one rule can match), or replace the toggle action with
explicit add/remove actions (use label:add invalid-title when match and
label:remove invalid-title in a complementary rule or via an else-style rule) so
label state is deterministic and precedence is clear.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In @.mergify.yml:
- Around line 83-99: The two rules ("Flag commit message not matching T-ID
format" which uses condition
'commits[*].commit_message~=^(?!(([a-zA-Z0-9\-_.]+:\s)?)T\d+:\s+[^\s]+).*' and
the title-check rule that also toggles the invalid-title label) both use toggle
on the same label and can conflict; update the commit-message rule to avoid
indeterminate state by either making its conditions mutually exclusive with the
title rule (so only one rule can match), or replace the toggle action with
explicit add/remove actions (use label:add invalid-title when match and
label:remove invalid-title in a complementary rule or via an else-style rule) so
label state is deterministic and precedence is clear.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Central YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 3daf0ef2-009e-4c48-93a5-b278e2206a2b

📥 Commits

Reviewing files that changed from the base of the PR and between 82a0cef and 618d166.

📒 Files selected for processing (1)
  • .mergify.yml
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: copilot
🧰 Additional context used
🔍 Remote MCP

I'll search for relevant information about Mergify configuration and best practices that would help in reviewing this PR effectively.Based on the gathered information from Mergify documentation and best practices, here's the relevant context for reviewing this PR:

Mergify Label Configuration Context

Label Action Functionality

The label action allows Mergify to automatically add or remove labels from a pull request based on the conditions specified in your rules, making your workflow more organized and efficient. The consolidation from two labels to one is a valid approach.

Pull Request Rules Structure

The Mergify configuration file consists of two primary components: rules and actions. Rules define the conditions under which specific actions should be triggered, while actions specify the automated tasks to be performed on the pull requests. The PR maintains this separation by keeping two distinct rules while consolidating their labeling behavior.

Regex Pattern Support

Mergify leverages Python regular expressions to match rules, and regex101, PyRegex, or Pythex can be used to test regular expressions. This is relevant since the PR references a shared regex pattern applied to both PR titles and commit messages.

Best Practices for Label Consolidation

You can set up rules to automatically update dependencies, rebase branches, and label PRs based on specific conditions. Having these standard processes reduces mistakes and makes it much easier to handle lots of PRs efficiently. Consolidating labels aligns with this principle of streamlined automation.

Configuration Management

Instead of defining the same options repeatedly for different rules, you can specify them once in the defaults section. If a particular option is directly defined under pull_request_rules or queue_rules, it will take precedence; otherwise, the system resorts to the values defined in the defaults section. This pattern may be relevant for understanding how the shared invalid-title label is applied.

@andamasov
Copy link
Copy Markdown
Member Author

Code review

Found 1 issue:

  1. Two toggle rules now target the same label (invalid-title), which the Mergify changelog for the toggle option describes as a single-rule pattern: "The new toggle option allows a single rule to manage the label's presence, adding it when conditions match and removing it when they don't." Every example in the docs shows exactly one rule per toggled label.

    The two rules in this file evaluate independently — when the title is conforming but a commit is not (or vice versa), one rule's toggle wants to remove invalid-title while the other wants to add it. Resulting label state is order-dependent and likely flaps as Mergify re-evaluates the PR on push/edit. The previous design (one label per rule) avoided this.

    Suggested shape: collapse to a single rule with or-combined conditions, or keep the two diagnostic rules but switch one to explicit label.add and pair it with a single toggle rule for the cleanup case. Sketch:

    - name: Flag T-ID format violation in PR title or commit messages
      conditions:
        - '-closed'
        - '-merged'
        - or:
          - '-title~=^(([a-zA-Z0-9\-_.]+:\s)?)T\d+:\s+[^\s]+.*'
          - 'commits[*].commit_message~=^(?!(([a-zA-Z0-9\-_.]+:\s)?)T\d+:\s+[^\s]+).*'
      actions:
        label:
          toggle:
            - invalid-title

    That keeps the single-label outcome the PR is going for, without the dual-toggle race. Operators lose the "which surface failed" signal at the label layer, but the PR's own argument (description tells the operator how to fix it; both fixes are the same — rewrite the headline) already accepts that tradeoff.

mergify/.mergify.yml

Lines 78 to 100 in 618d166

actions:
label:
toggle:
- invalid-title
- name: Flag commit message not matching T-ID format
description: >
Each commit's first line must match `T<digits>: <text>`, optionally
prefixed with `scope: `. Replaces the commit-message half of
vyos/.github:check-pr-message.yml. Shares the `invalid-title` label
with the title rule — both surfaces fail the same headline regex, so
splitting into two labels (`invalid-title` + `invalid-commit-title`)
was noise; the rule name still tells the operator which surface
tripped.
conditions:
- '-closed'
- '-merged'
- 'commits[*].commit_message~=^(?!(([a-zA-Z0-9\-_.]+:\s)?)T\d+:\s+[^\s]+).*'
actions:
label:
toggle:
- invalid-title

🤖 Generated with Claude Code

- If this code review was useful, please react with 👍. Otherwise, react with 👎.

The previous revision of this PR moved both rules' `toggle` action to
the same `invalid-title` label but kept them as two separate rules.
That has a structural conflict: each `toggle` rule fires in both
directions on every evaluation (add when condition true, remove when
false). When the title conforms but a commit doesn't (or vice versa),
the two rules issue conflicting add/remove operations on the same
label — order-dependent and likely to flap.

Mergify's `toggle` docs frame the action as a single-rule pattern
that subsumes the earlier two-rule "add on match / remove on
inverse" idiom (mergify changelog 2022-11-15). Using `toggle` on two
rules pointing at the same label is outside the documented use case.

Collapse the title-check condition and the commit-message-check
condition into one rule with an `or`-combined condition. One rule,
one label, one toggle — no conflict. The diagnostic separation
between "title failed" vs "commits failed" was already given up when
the label was unified; the rule description still lists both
surfaces so an operator reading the rule log knows what to look at.

🤖 Generated by [robots](https://vyos.io)
@andamasov
Copy link
Copy Markdown
Member Author

andamasov commented May 12, 2026

Verified the structural conflict — Mergify’s toggle is documented as the single-rule replacement for the earlier two-rule add/remove-with-inverse-conditions idiom, so two rules toggling the same label is outside the documented pattern and the add/remove ops would race.

Collapsed both checks into one rule with or-combined conditions in 890a369. The diagnostic split between "title failed" vs "commits failed" was already given up the moment the labels were unified; the rule description still names both surfaces so the operator knows what to inspect.

@andamasov
Copy link
Copy Markdown
Member Author

@coderabbitai addressed in 890a369 — collapsed the two toggle rules into one rule with or-combined title and commit-message conditions, so one toggle: invalid-title action manages the label deterministically. Your finding matches the issue surfaced in the human review on this PR.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 12, 2026

Tip

For best results, initiate chat on the files or code changes.

@andamasov: Confirmed — 890a369 resolves the dual-toggle race. Single rule with or-combined title and commits[*].commit_message conditions feeding one toggle: invalid-title is the correct structure per Mergify's documented pattern.

ᓚᘏᗢ ✓


If you found this review helpful, would you consider giving us a shout-out on X?

Thank you for using CodeRabbit!

@andamasov andamasov merged commit 4dd2af0 into production May 12, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants