Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/integrations/github/rules_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ async def _validate_rules_yaml(repo: str, installation_id: int) -> dict[str, Any
"**How to set up rules:**\n"
"1. Create a file at `.watchflow/rules.yaml` in your repository root\n"
"2. Add your rules in the following format:\n"
" ```yaml\n rules:\n - id: pr-approval-required\n name: PR Approval Required\n description: All pull requests must have at least 2 approvals\n enabled: true\n severity: high\n event_types: [pull_request]\n parameters:\n min_approvals: 2\n ```\n\n"
" ```yaml\n rules:\n - description: All pull requests must have at least 2 approvals\n enabled: true\n severity: high\n event_types: [pull_request]\n parameters:\n min_approvals: 2\n ```\n\n"
"**Note:** Rules are currently read from the main branch only.\n\n"
"📖 [Read the documentation for more examples](https://github.com/warestack/watchflow/blob/main/docs/getting-started/configuration.md)\n\n"
"After adding the file, push your changes to re-run validation."
Expand All @@ -64,7 +64,7 @@ async def _validate_rules_yaml(repo: str, installation_id: int) -> dict[str, Any
"message": (
"❌ **Invalid `.watchflow/rules.yaml`: missing top-level `rules:` key**\n\n"
"Your file must start with a `rules:` key, like:\n"
"```yaml\nrules:\n - id: ...\n```\n"
"```yaml\nrules:\n - description: ...\n```\n"
f"[See configuration docs.]({DOCS_URL})"
),
}
Expand All @@ -74,7 +74,7 @@ async def _validate_rules_yaml(repo: str, installation_id: int) -> dict[str, Any
"message": (
"❌ **Invalid `.watchflow/rules.yaml`: `rules` must be a list**\n\n"
"Example:\n"
"```yaml\nrules:\n - id: my-rule\n description: ...\n```\n"
"```yaml\nrules:\n - description: my-rule\n```\n"
f"[See configuration docs.]({DOCS_URL})"
),
}
Expand All @@ -94,7 +94,7 @@ async def _validate_rules_yaml(repo: str, installation_id: int) -> dict[str, Any
return {
"success": False,
"message": (
f"❌ **Rule #{i + 1} (`{rule_data.get('id', 'N/A')}`) failed validation**\n\n"
f"❌ **Rule #{i + 1} (`{rule_data.get('description', 'N/A')}`) failed validation**\n\n"
f"Error: `{e}`\n\n"
"Please check your rule definition and fix the error above.\n\n"
f"[See rule schema docs.]({DOCS_URL})"
Expand Down
8 changes: 7 additions & 1 deletion src/presentation/github_formatter.py
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,13 @@ def format_violations_comment(violations: list[Violation]) -> str:
comment = f"### 🛡️ Watchflow Governance Checks\n**Status:** ❌ {len(violations)} Violations Found\n\n"
comment += _build_collapsible_violations_text(violations)
comment += "---\n"
comment += "💡 *Reply with `@watchflow ack [reason]` to override these rules, or `@watchflow help` for commands.*"
comment += (
"💡 *Reply with `@watchflow ack [reason]` to override these rules, or `@watchflow help` for commands.*\n\n"
)
comment += (
"Thanks for using [Watchflow](https://watchflow.dev)! It's completely free for OSS and private repositories. "
)
comment += "You can also [self-host it easily](https://github.com/warestack/watchflow)."

return comment

Expand Down
6 changes: 6 additions & 0 deletions src/rules/loaders/github_loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,12 @@ async def get_rules(self, repository: str, installation_id: int) -> list[Rule]:
try:
if not isinstance(rule_data, dict):
continue

# Skip disabled rules
if str(rule_data.get("enabled", True)).lower() == "false":
logger.info(f"Skipping disabled rule: {rule_data.get('description', 'unknown')}")
continue

rule = GitHubRuleLoader._parse_rule(rule_data)
if rule:
rules.append(rule)
Expand Down