pr-gfm-validator
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChinesePR GFM Link Validator
PR GFM链接验证器
Validate and auto-convert GFM links in pull request descriptions to prevent 404 errors.
验证并自动转换拉取请求(PR)描述中的GFM链接,以避免404错误。
When to Use This Skill
何时使用此技能
This skill triggers when:
- Creating a pull request from a feature branch
- Discussing PR descriptions or body content
- Mentioning GFM links, PR links, or link validation
- Using or
gh pr creategh pr edit
当以下情况发生时触发此技能:
- 从功能分支创建PR
- 讨论PR描述或正文内容
- 提及GFM链接、PR链接或链接验证
- 使用或
gh pr create命令gh pr edit
The Problem
问题说明
Repository-relative links in PR descriptions resolve to the base branch (main), not the feature branch:
| Link in PR Body | GitHub Resolves To | Result |
|---|---|---|
| | 404 (file only on feature branch) |
PR描述中的仓库相对链接会解析到基准分支(main),而非功能分支:
| PR正文中的链接 | GitHub解析结果 | 结果 |
|---|---|---|
| | 404(文件仅存在于功能分支) |
The Solution
解决方案
Convert repo-relative links to absolute blob URLs with the correct branch:
/docs/adr/file.md
↓
https://github.com/{owner}/{repo}/blob/{branch}/docs/adr/file.md将仓库相对链接转换为带有正确分支的绝对Blob URL:
/docs/adr/file.md
↓
https://github.com/{owner}/{repo}/blob/{branch}/docs/adr/file.mdWorkflow
工作流程
Step 1: Detect Context
步骤1:检测上下文
Before any PR operation, gather repository context:
bash
/usr/bin/env bash << 'PREFLIGHT_EOF'在执行任何PR操作前,收集仓库上下文:
bash
/usr/bin/env bash << 'PREFLIGHT_EOF'Get repo owner and name
Get repo owner and name
gh repo view --json nameWithOwner --jq '.nameWithOwner'
gh repo view --json nameWithOwner --jq '.nameWithOwner'
Get current branch
Get current branch
git rev-parse --abbrev-ref HEAD
git rev-parse --abbrev-ref HEAD
Check if on feature branch (not main/master)
Check if on feature branch (not main/master)
BRANCH=$(git rev-parse --abbrev-ref HEAD)
if [[ "$BRANCH" == "main" || "$BRANCH" == "master" ]]; then
echo "On default branch - no conversion needed"
exit 0
fi
PREFLIGHT_EOF
undefinedBRANCH=$(git rev-parse --abbrev-ref HEAD)
if [[ "$BRANCH" == "main" || "$BRANCH" == "master" ]]; then
echo "On default branch - no conversion needed"
exit 0
fi
PREFLIGHT_EOF
undefinedStep 2: Identify Links to Convert
步骤2:识别需要转换的链接
Scan PR body for GFM links matching these patterns:
CONVERT these patterns:
- - Repo-root relative
/path/to/file.md - - Current-directory relative
./relative/path.md - - Parent-directory relative
../parent/path.md
SKIP these patterns:
- - Already absolute URLs
https://... - - Already absolute URLs
http://... - - In-page anchors
#anchor - - Email links
mailto:...
扫描PR正文,查找符合以下模式的GFM链接:
需要转换的模式:
- - 仓库根目录相对路径
/path/to/file.md - - 当前目录相对路径
./relative/path.md - - 上级目录相对路径
../parent/path.md
需要跳过的模式:
- - 已为绝对URL
https://... - - 已为绝对URL
http://... - - 页面内锚点
#anchor - - 邮件链接
mailto:...
Step 3: Construct Blob URLs
步骤3:构建Blob URL
For each link to convert:
python
undefined对每个需要转换的链接:
python
undefinedPattern
Pattern
Example
Example
owner = "Eon-Labs"
repo = "alpha-forge"
branch = "feat/2025-12-01-eth-block-metrics"
path = "docs/adr/2025-12-01-file.md"
owner = "Eon-Labs"
repo = "alpha-forge"
branch = "feat/2025-12-01-eth-block-metrics"
path = "docs/adr/2025-12-01-file.md"
Result
Result
undefinedStep 4: Apply Conversions
步骤4:执行转换
Replace all identified links in the PR body:
markdown
undefined替换PR正文中所有识别出的链接:
markdown
undefinedBefore
Before
After
After
undefinedundefinedStep 5: Validate Result
步骤5:验证结果
After conversion, verify:
- All repo-relative links are now absolute blob URLs
- External links remain unchanged
- Anchor links remain unchanged
转换完成后,验证以下内容:
- 所有仓库相对链接已转换为绝对Blob URL
- 外部链接保持不变
- 锚点链接保持不变
Integration with gh pr create
与gh pr create集成
When creating a PR, apply this workflow automatically:
bash
/usr/bin/env bash << 'GIT_EOF'创建PR时自动应用此工作流:
bash
/usr/bin/env bash << 'GIT_EOF'1. Get context
1. Get context
REPO_INFO=$(gh repo view --json nameWithOwner --jq '.nameWithOwner')
OWNER=$(echo "$REPO_INFO" | cut -d'/' -f1)
REPO=$(echo "$REPO_INFO" | cut -d'/' -f2)
BRANCH=$(git rev-parse --abbrev-ref HEAD)
REPO_INFO=$(gh repo view --json nameWithOwner --jq '.nameWithOwner')
OWNER=$(echo "$REPO_INFO" | cut -d'/' -f1)
REPO=$(echo "$REPO_INFO" | cut -d'/' -f2)
BRANCH=$(git rev-parse --abbrev-ref HEAD)
2. Process PR body (convert links)
2. Process PR body (convert links)
... link conversion logic ...
... link conversion logic ...
3. Create PR with converted body
3. Create PR with converted body
gh pr create --title "..." --body "$CONVERTED_BODY"
GIT_EOF
---gh pr create --title "..." --body "$CONVERTED_BODY"
GIT_EOF
---Link Detection Regex
链接检测正则表达式
Use this regex pattern to find GFM links:
regex
\[([^\]]+)\]\((/[^)]+|\.\.?/[^)]+)\)Breakdown:
- - Capture link text
\[([^\]]+)\] - - Opening parenthesis
\( - - Capture path starting with
(/[^)]+|\.\.?/[^)]+),/, or./../ - - Closing parenthesis
\)
使用以下正则表达式匹配GFM链接:
regex
\[([^\]]+)\]\((/[^)]+|\.\.?/[^)]+)\)解析:
- - 捕获链接文本
\[([^\]]+)\] - - 左括号
\( - - 捕获以
(/[^)]+|\.\.?/[^)]+)、/或./开头的路径../ - - 右括号
\)
Examples
示例
Example 1: Simple Repo-Relative Link
示例1:简单仓库相对链接
Input:
markdown
See the [ADR](/docs/adr/2025-12-01-eth-block-metrics.md) for details.Context:
- Owner:
Eon-Labs - Repo:
alpha-forge - Branch:
feat/2025-12-01-eth-block-metrics-data-plugin
Output:
markdown
See the [ADR](https://github.com/Eon-Labs/alpha-forge/blob/feat/2025-12-01-eth-block-metrics-data-plugin/docs/adr/2025-12-01-eth-block-metrics.md) for details.输入:
markdown
See the [ADR](/docs/adr/2025-12-01-eth-block-metrics.md) for details.上下文:
- Owner:
Eon-Labs - Repo:
alpha-forge - Branch:
feat/2025-12-01-eth-block-metrics-data-plugin
输出:
markdown
See the [ADR](https://github.com/Eon-Labs/alpha-forge/blob/feat/2025-12-01-eth-block-metrics-data-plugin/docs/adr/2025-12-01-eth-block-metrics.md) for details.Example 2: Multiple Links
示例2:多个链接
Input:
markdown
undefined输入:
markdown
undefinedReferences
References
**Output:**
```markdown
**输出:**
```markdownReferences
References
Note: External link unchanged.
注意:外部链接保持不变。Example 3: Credential File Link
示例3:凭证文件链接
Input:
markdown
**See [`.env.clickhouse`](/.env.clickhouse)** for credentials.Output:
markdown
**See [`.env.clickhouse`](https://github.com/Eon-Labs/alpha-forge/blob/feat/branch/.env.clickhouse)** for credentials.输入:
markdown
**See [`.env.clickhouse`](/.env.clickhouse)** for credentials.输出:
markdown
**See [`.env.clickhouse`](https://github.com/Eon-Labs/alpha-forge/blob/feat/branch/.env.clickhouse)** for credentials.Edge Cases
边缘情况
Already on main/master
当前处于main/master分支
- Skip conversion entirely
- Repo-relative links will work correctly
- 完全跳过转换
- 仓库相对链接可正常工作
Empty PR Body
PR正文为空
- Nothing to convert
- Proceed with PR creation
- 无内容可转换
- 继续创建PR
No GFM Links Found
未找到GFM链接
- Nothing to convert
- Proceed with PR creation
- 无内容可转换
- 继续创建PR
Mixed Link Types
混合链接类型
- Convert only repo-relative links
- Preserve external URLs, anchors, mailto links
- 仅转换仓库相对链接
- 保留外部URL、锚点、邮件链接
Post-Change Checklist
修改后检查清单
After modifying this skill:
- Regex patterns still match intended link formats
- Examples reflect current behavior
- Edge cases documented
- Workflow steps are executable
修改此技能后:
- 正则表达式仍能匹配目标链接格式
- 示例反映当前行为
- 边缘情况已记录
- 工作流步骤可执行
References
参考资料
Troubleshooting
故障排除
| Issue | Cause | Solution |
|---|---|---|
| Links still 404 after PR | File not pushed to branch yet | Push commits before creating PR |
| Regex not matching links | Escaped parentheses in content | Use raw string regex pattern |
| Branch name has slashes | URL encoding needed | Encode branch name for URL construction |
| External links converted | Pattern too broad | Check link starts with |
| gh repo view fails | Not in a git repository | Run from repository root directory |
| Anchor links broken | Incorrectly included in scan | Skip links starting with |
| Wrong repo detected | Remote not set correctly | Check |
| Conversion duplicated | Running validator twice | Check if links already absolute before converting |
| 问题 | 原因 | 解决方案 |
|---|---|---|
| Links still 404 after PR | File not pushed to branch yet | Push commits before creating PR |
| Regex not matching links | Escaped parentheses in content | Use raw string regex pattern |
| Branch name has slashes | URL encoding needed | Encode branch name for URL construction |
| External links converted | Pattern too broad | Check link starts with |
| gh repo view fails | Not in a git repository | Run from repository root directory |
| Anchor links broken | Incorrectly included in scan | Skip links starting with |
| Wrong repo detected | Remote not set correctly | Check |
| Conversion duplicated | Running validator twice | Check if links already absolute before converting |