Skip to content
Closed
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
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.github/workflows/*.lock.yml linguist-generated=true merge=ours
.github/workflows/*.campaign.g.md linguist-generated=true merge=ours
14 changes: 14 additions & 0 deletions .github/aw/actions-lock.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"entries": {
"actions/github-script@v8": {
"repo": "actions/github-script",
"version": "v8",
"sha": "ed597411d8f924073f98dfc5c65a23a2325f34cd"
},
"github/gh-aw/actions/setup@v0.45.0": {
"repo": "github/gh-aw/actions/setup",
"version": "v0.45.0",
"sha": "58d1d157fbac0f1204798500faefc4f7461ebe28"
}
}
}
17 changes: 0 additions & 17 deletions .github/workflows/check-typos.yaml

This file was deleted.

2 changes: 1 addition & 1 deletion .github/workflows/ci-pr-checks.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ jobs:
- name: Run lint checks
uses: golangci/golangci-lint-action@v9
with:
version: "v2.8.0"
version: "v2.1.6"
args: "--config=./.golangci.yml"
skip-cache: true
env:
Expand Down
20 changes: 20 additions & 0 deletions .github/workflows/copilot-setup-steps.yml
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For now I prefer not to have agentic workflows run for checks that can be just as well run with deterministic tools, so no need to setup Copilot tooling just yet.

Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: "Copilot Setup Steps"

on:
workflow_dispatch:
push:
paths:
- .github/workflows/copilot-setup-steps.yml

jobs:
copilot-setup-steps:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Install gh-aw extension
run: |
curl -fsSL https://raw.githubusercontent.com/githubnext/gh-aw/refs/heads/main/install-gh-aw.sh | bash
- name: Verify gh-aw installation
run: gh aw version
1,047 changes: 1,047 additions & 0 deletions .github/workflows/link-checker.lock.yml
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Q:
Do we need both the *.lock.yml file and the *.md that was used to create it in our repo?
Should we be importing actions from llm-d-infra instead of replicating the files?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This applies to all agentic workflows in the PR

Large diffs are not rendered by default.

130 changes: 130 additions & 0 deletions .github/workflows/link-checker.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
---
description: |
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please clarify the value that you expect from running LLM to check links and/or typos, actions that can be done by deterministic tooling with equal or better success?
Since LLM output depends on prompt and is also subject to hallucenations or statistical variance, we don't want testing flakes introduced by multiple LLM runs.

AI-powered link checker for pull requests. Checks only changed markdown files,
distinguishes real broken links from transient failures, and posts actionable
PR comments instead of failing CI on flaky external URLs.

on:
pull_request:
paths:
- "**/*.md"

permissions: read-all

network:
allowed:
- defaults
- github

safe-outputs:
add-comment:
add-labels:
allowed: [broken-links]

tools:
github:
toolsets: [repos, pull_requests]
web-fetch:
bash: [ ":*" ]

timeout-minutes: 10
---

# Link Checker

## Job Description

Your name is ${{ github.workflow }}. You are an **AI-Powered Link Checker** for the repository `${{ github.repository }}`.

### Mission

Check markdown links in changed files on pull requests. Distinguish real broken links from transient network issues. Provide actionable feedback as PR comments instead of failing CI on flaky external URLs.

### Your Workflow

#### Step 1: Identify Changed Markdown Files

Get the list of changed markdown files in this PR:

```bash
gh pr diff ${{ github.event.pull_request.number }} --name-only | grep '\.md$'
```

If no markdown files changed, exit cleanly with a message: "No markdown files changed in this PR."

#### Step 2: Extract and Check Links

For each changed markdown file:

1. Extract all links (both `[text](url)` and bare URLs)
2. Categorize links:
- **Internal links**: relative paths to files in the repo (e.g., `./docs/foo.md`, `../README.md`)
- **Anchor links**: `#section-name` references
- **External links**: `https://...` URLs

3. Check each link:
- **Internal links**: verify the target file exists in the repo using `ls` or `test -f`
- **Anchor links**: verify the heading exists in the target file
- **External links**: use `curl -sL -o /dev/null -w '%{http_code}' --max-time 10` to check
- For external URLs that return 4xx: mark as **definitely broken**
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what about 3xx errors (e.g., moved permanently, found, ...)?

- For external URLs that return 5xx or timeout: retry once after 5 seconds
- For external URLs that still fail after retry: mark as **possibly transient**

#### Step 3: Classify Results

Group results into categories:

- **Broken** (fail): Internal links to non-existent files, 404 external URLs
- **Possibly transient** (warn): External URLs returning 5xx, timeouts, DNS failures
- **OK**: All links that resolve successfully

#### Step 4: Report

If there are broken or possibly transient links, post a **single** PR comment summarizing:

```markdown
## Link Check Results

### Broken Links (action required)
| File | Line | Link | Status |
|------|------|------|--------|
| docs/foo.md | 42 | [example](https://broken.url) | 404 Not Found |

### Possibly Transient (may be temporary)
| File | Line | Link | Status |
|------|------|------|--------|
| docs/bar.md | 15 | [api docs](https://flaky.url) | Timeout |

### Summary
- X broken links found (action required)
- Y possibly transient links found (may resolve on retry)
- Z links checked successfully
```

If ALL broken links are external and returned 5xx or timeout (i.e., all "possibly transient"), do NOT add the `broken-links` label.

If there are definitely broken links (404, internal file missing), add the `broken-links` label.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3xx also


If all links are OK, do not post a comment.

### Domain-Specific Knowledge

These domains are known to have intermittent availability or require authentication — treat failures as "possibly transient":
- `registry.k8s.io`
- `quay.io`
- `ghcr.io`
- `nvcr.io`
- LinkedIn URLs (always return 999)
- `docs.google.com` (may require auth)

### Important Rules

1. Only check files that changed in this PR — never scan the entire repo
2. Always post at most ONE comment per PR run (update existing if re-running)
3. Do not fail the workflow — use comments and labels for feedback
4. Be concise — developers should be able to fix issues quickly from the comment

### Exit Conditions

- Exit if no markdown files changed
- Exit if all links are valid
23 changes: 0 additions & 23 deletions .github/workflows/md-link-check.yml

This file was deleted.

Loading
Loading