Support frontmatter in pymarkdown sanity test (#87164)

* Fix formatting of skill markdown

* Support frontmatter in pymarkdown sanity test

* Allow .github/ to use frontmatter
This commit is contained in:
Matt Clay
2026-06-24 11:12:00 -05:00
committed by GitHub
parent 9cc7281c69
commit 6922432ecd
4 changed files with 99 additions and 15 deletions
+8 -5
View File
@@ -6,21 +6,23 @@ user-invocable: true
# System Instructions
When this skill is invoked, read the AGENTS.md file from the repository root (`@../../../AGENTS.md`) and load its content into context. This provides comprehensive Ansible development guidelines.
When this skill is invoked, read the AGENTS.md file from the repository root (`@../../../AGENTS.md`) and load its content into context.
This provides comprehensive Ansible development guidelines.
After loading AGENTS.md, provide the user with confirmation that the context has been loaded and is available for answering questions or guiding development work.
If AGENTS.md cannot be found, inform the user and suggest they may be in a directory without the full ansible-core repository.
# Usage
## Usage
Invoke this skill to load Ansible development context:
```
```claude
/context
```
The skill provides all guidelines and conventions that would normally be in AGENTS.md, making them available even when working outside the ansible-core repository or in environments where AGENTS.md is not accessible.
The skill provides all guidelines and conventions that would normally be in AGENTS.md,
making them available even when working outside the ansible-core repository or in environments where AGENTS.md is not accessible.
## When to Use
@@ -31,7 +33,8 @@ The skill provides all guidelines and conventions that would normally be in AGEN
## What This Skill Does
This skill is informational only - it loads comprehensive Ansible development knowledge into context but performs no actions. After invocation, all subsequent responses will have access to:
This skill is informational only - it loads comprehensive Ansible development knowledge into context but performs no actions.
After invocation, all subsequent responses will have access to:
- Testing commands
- PR review processes and checklists
-1
View File
@@ -6,5 +6,4 @@ labels: [core-internal]
assignees: ''
---
@ansibot bot_skip
+91 -5
View File
@@ -7,19 +7,107 @@ import re
import subprocess
import sys
import yaml
try:
from yaml import CSafeLoader as SafeLoader
except ImportError:
from yaml import SafeLoader
import typing as t
def main() -> None:
paths = sys.argv[1:] or sys.stdin.read().splitlines()
self_dir = pathlib.Path(__file__).parent
base_dir = self_dir.parent.parent.parent
config_path = self_dir / 'pymarkdown.config.json'
# This regex is intentionally a very loose check for potential frontmatter.
# There's no good reason for a non-frontmatter containing file to match this pattern.
frontmatter_pattern = re.compile(r'^\s*--')
frontmatter_allowed_prefixes = [
".claude/",
".github/",
]
frontmatter_paths = []
other_paths = []
results = []
for path in paths:
content = pathlib.Path(path).read_text()
has_frontmatter = frontmatter_pattern.search(content)
allow_frontmatter = any(path.startswith(prefix) for prefix in frontmatter_allowed_prefixes)
# When potential frontmatter is detected, check it before running the document through pymarkdown.
# This avoids treating frontmatter issues as Markdown issues, which would otherwise lead to confusing error messages.
if allow_frontmatter:
if has_frontmatter and (issues := check_frontmatter(path, content)):
results.extend(issues)
else:
frontmatter_paths.append(path)
else:
if has_frontmatter:
results.append(f'{path}:1:1: frontmatter-not-allowed: frontmatter is not allowed in this document')
else:
other_paths.append(path)
results.extend(run_pymarkdown(frontmatter_paths, config_path, base_dir, enable_frontmatter=True))
results.extend(run_pymarkdown(other_paths, config_path, base_dir, enable_frontmatter=False))
if results:
print('\n'.join(results))
def check_frontmatter(path: str, content: str) -> list[str]:
"""
Check frontmatter formatting.
Use only after detecting signs of frontmatter usage.
This supplements the frontmatter support in pymarkdown, which is less aggressive about detecting potential frontmatter.
"""
match = re.search(r"^(?P<content>---\n.*?)\n---\n", content, flags=re.DOTALL)
if not match:
return [f"{path}:1:1: malformed-frontmatter: document appears to start with malformed frontmatter"]
yaml_content = match.group('content')
try:
yaml.load(yaml_content, Loader=SafeLoader)
except yaml.MarkedYAMLError as ex:
message = ' '.join(filter(None, (ex.context, ex.problem, ex.note))).strip()
return [f"{path}:{ex.problem_mark.line}:{ex.problem_mark.column}: frontmatter-yaml: {message}"]
except yaml.YAMLError as ex:
return [f"{path}:1:1: frontmatter-yaml: {ex}"]
return []
def run_pymarkdown(paths: list[str], config_path: pathlib.Path, base_dir: pathlib.Path, enable_frontmatter: bool) -> list[str]:
"""Run pymarkdown on the given paths and return a list of results."""
if not paths:
return []
extensions: list[str] = []
if enable_frontmatter:
extensions.append('front-matter')
cmd = [
sys.executable,
'-m',
'pymarkdown',
'--config',
pathlib.Path(__file__).parent / 'pymarkdown.config.json',
config_path,
'--strict-config',
'--enable-extensions',
','.join(extensions),
'scan',
] + paths
@@ -36,19 +124,17 @@ def main() -> None:
sys.exit(1)
if not (stdout := process.stdout.strip()):
return
return []
pattern = re.compile(r'^(?P<path>[^:]*):(?P<line>[0-9]+):(?P<column>[0-9]+): (?P<code>[^:]*): (?P<message>.*) \((?P<aliases>.*)\)$')
matches = parse_to_list_of_dict(pattern, stdout)
base_dir = pathlib.Path(__file__).parent.parent.parent.parent
for match in matches:
match['path'] = str(pathlib.Path(match['path']).relative_to(base_dir))
results = [f"{match['path']}:{match['line']}:{match['column']}: {match['aliases'].split(', ')[0]}: {match['message']}" for match in matches]
print('\n'.join(results))
return results
def parse_to_list_of_dict(pattern: re.Pattern, value: str) -> list[dict[str, t.Any]]:
-4
View File
@@ -1,7 +1,3 @@
.claude/skills/azp-logs/SKILL.md pymarkdown!skip # Claude Code skill with YAML frontmatter
.claude/skills/context/SKILL.md pymarkdown!skip # Claude Code skill with YAML frontmatter
.claude/skills/review/SKILL.md pymarkdown!skip # Claude Code skill with YAML frontmatter
.github/ISSUE_TEMPLATE/internal_issue.md pymarkdown!skip
lib/ansible/_internal/_wrapt.py black!skip # vendored code
lib/ansible/config/base.yml no-unwanted-files
lib/ansible/keyword_desc.yml no-unwanted-files