Search

PythonReactSEOPDF
GitHub Skill

pr-gfm-validator

Validate and auto-fix GitHub Flavored Markdown links in PR descriptions. Use when creating pull requests, mentioning PR links, gh pr create, GFM validation, or fixing broken PR links. Converts repo-relative paths to branch-specific blob URLs.

terrylica☆ 9 Repository stars1 Repository forks

Installation

Follow the repository instructions for this skill and your agent. Review the files and dependencies before adding it to your workflow.

View source ↗Guides

Skill instructions

PR GFM Link Validator

Validate and auto-convert GFM links in pull request descriptions to prevent 404 errors.

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

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
[ADR](/docs/adr/file.md) /blob/main/docs/adr/file.md 404 (file only on feature branch)

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

Workflow

Step 1: Detect Context

Before any PR operation, gather repository context:

/usr/bin/env bash << 'PREFLIGHT_EOF'
# Get repo owner and name
gh repo view --json nameWithOwner --jq '.nameWithOwner'

# Get current branch
git rev-parse --abbrev-ref HEAD

# 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
Step 2: Identify Links to Convert

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
Step 3: Construct Blob URLs

For each link to convert:

# Pattern
f"https://github.com/{owner}/{repo}/blob/{branch}/{path}"

# Example
owner = "Eon-Labs"
repo = "alpha-forge"
branch = "feat/2025-12-01-eth-block-metrics"
path = "docs/adr/2025-12-01-file.md"

# Result
"https://github.com/Eon-Labs/alpha-forge/blob/feat/2025-12-01-eth-block-metrics/docs/adr/2025-12-01-file.md"
Step 4: Apply Conversions

Replace all identified links in the PR body:

# Before

[Plugin Design](/docs/adr/2025-12-01-slug.md)

# After

[Plugin Design](https://github.com/Eon-Labs/alpha-forge/blob/feat/branch/docs/adr/2025-12-01-slug.md)
Step 5: Validate Result

After conversion, verify:

  1. All repo-relative links are now absolute blob URLs
  2. External links remain unchanged
  3. Anchor links remain unchanged

Integration with gh pr create

When creating a PR, apply this workflow automatically:

/usr/bin/env bash << 'GIT_EOF'
# 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)

# 2. Process PR body (convert links)
# ... link conversion logic ...

# 3. Create PR with converted body
gh pr create --title "..." --body "$CONVERTED_BODY"
GIT_EOF

Link Detection Regex

Use this regex pattern to find GFM links:

\[([^\]]+)\]\((/[^)]+|\.\.?/[^)]+)\)

Breakdown:

  • \[([^\]]+)\] - Capture link text
  • \( - Opening parenthesis
  • (/[^)]+|\.\.?/[^)]+) - Capture path starting with /, ./, or ../
  • \) - Closing parenthesis

Examples

Example 1: Simple Repo-Relative Link

Input:

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:

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

Input:

## References

- [Plugin Design](/docs/adr/2025-12-01-slug.md)
- [Probe Integration](/docs/adr/2025-12-02-slug.md)
- [External Guide](https://example.com/guide)

Output:

## References

- [Plugin Design](https://github.com/Eon-Labs/alpha-forge/blob/feat/branch/docs/adr/2025-12-01-slug.md)
- [Probe Integration](https://github.com/Eon-Labs/alpha-forge/blob/feat/branch/docs/adr/2025-12-02-slug.md)
- [External Guide](https://example.com/guide)

Note: External link unchanged.

Example 3: Credential File Link

Input:

**See [`.env.clickhouse`](/.env.clickhouse)** for credentials.

Output:

**See [`.env.clickhouse`](https://github.com/Eon-Labs/alpha-forge/blob/feat/branch/.env.clickhouse)** for credentials.

Edge Cases

Already on main/master
  • Skip conversion entirely
  • Repo-relative links will work correctly
Empty PR Body
  • Nothing to convert
  • Proceed with PR creation
No GFM Links Found
  • Nothing to convert
  • Proceed with PR creation
Mixed Link Types
  • Convert only repo-relative links
  • Preserve external URLs, anchors, mailto links

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

References

Examples

Read the usage examples in the source repository.

View source ↗

Source history

Indexed on
2026-01-20
Index updated
2026-02-02
Branch
main

Index and sync dates describe this directory. View the source repository for code history.

GitHub ↗

chat Comments (0)

chat_bubble_outline

No comments yet. Be the first to share your thoughts!