pr-gfm-validator

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

PR 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
    gh pr create
    or
    gh 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 BodyGitHub Resolves ToResult
[ADR](/docs/adr/file.md)
/blob/main/docs/adr/file.md
404 (file only on feature branch)
PR描述中的仓库相对链接会解析到基准分支(main),而非功能分支:
PR正文中的链接GitHub解析结果结果
[ADR](/docs/adr/file.md)
/blob/main/docs/adr/file.md
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.md

Workflow

工作流程

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
undefined
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
undefined

Step 2: Identify Links to Convert

步骤2:识别需要转换的链接

Scan PR body for GFM links matching these patterns:
CONVERT these patterns:
  • /path/to/file.md
    - Repo-root relative
  • ./relative/path.md
    - Current-directory relative
  • ../parent/path.md
    - Parent-directory relative
SKIP these patterns:
  • https://...
    - Already absolute URLs
  • http://...
    - Already absolute URLs
  • #anchor
    - In-page anchors
  • mailto:...
    - Email links
扫描PR正文,查找符合以下模式的GFM链接:
需要转换的模式:
  • /path/to/file.md
    - 仓库根目录相对路径
  • ./relative/path.md
    - 当前目录相对路径
  • ../parent/path.md
    - 上级目录相对路径
需要跳过的模式:
  • https://...
    - 已为绝对URL
  • http://...
    - 已为绝对URL
  • #anchor
    - 页面内锚点
  • mailto:...
    - 邮件链接

Step 3: Construct Blob URLs

步骤3:构建Blob URL

For each link to convert:
python
undefined
对每个需要转换的链接:
python
undefined

Pattern

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

Step 4: Apply Conversions

步骤4:执行转换

Replace all identified links in the PR body:
markdown
undefined
替换PR正文中所有识别出的链接:
markdown
undefined

Before

Before

After

After

undefined
undefined

Step 5: Validate Result

步骤5:验证结果

After conversion, verify:
  1. All repo-relative links are now absolute blob URLs
  2. External links remain unchanged
  3. Anchor links remain unchanged

转换完成后,验证以下内容:
  1. 所有仓库相对链接已转换为绝对Blob URL
  2. 外部链接保持不变
  3. 锚点链接保持不变

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
undefined

References

References

References

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:
  1. Regex patterns still match intended link formats
  2. Examples reflect current behavior
  3. Edge cases documented
  4. Workflow steps are executable

修改此技能后:
  1. 正则表达式仍能匹配目标链接格式
  2. 示例反映当前行为
  3. 边缘情况已记录
  4. 工作流步骤可执行

References

参考资料

Troubleshooting

故障排除

IssueCauseSolution
Links still 404 after PRFile not pushed to branch yetPush commits before creating PR
Regex not matching linksEscaped parentheses in contentUse raw string regex pattern
Branch name has slashesURL encoding neededEncode branch name for URL construction
External links convertedPattern too broadCheck link starts with
/
,
./
, or
../
only
gh repo view failsNot in a git repositoryRun from repository root directory
Anchor links brokenIncorrectly included in scanSkip links starting with
#
Wrong repo detectedRemote not set correctlyCheck
git remote -v
output
Conversion duplicatedRunning validator twiceCheck if links already absolute before converting
问题原因解决方案
Links still 404 after PRFile not pushed to branch yetPush commits before creating PR
Regex not matching linksEscaped parentheses in contentUse raw string regex pattern
Branch name has slashesURL encoding neededEncode branch name for URL construction
External links convertedPattern too broadCheck link starts with
/
,
./
, or
../
only
gh repo view failsNot in a git repositoryRun from repository root directory
Anchor links brokenIncorrectly included in scanSkip links starting with
#
Wrong repo detectedRemote not set correctlyCheck
git remote -v
output
Conversion duplicatedRunning validator twiceCheck if links already absolute before converting