10000 docs: unify documentation workflows with improved validation by EdwardAngert · Pull Request #17522 · coder/coder · GitHub
[go: up one dir, main page]

Skip to content

docs: unify documentation workflows with improved validation #17522

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 24 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
d0fe1f8
Add simplified docs preview GitHub action
EdwardAngert Apr 9, 2025
3010c77
Merge branch 'main' into simplified-docs-preview
EdwardAngert Apr 9, 2025
afbdde9
\Fix tj-actions/changed-files SHA to match existing usage\n\nUpdate t…
EdwardAngert Apr 9, 2025
1f716c9
\Fix docs preview workflow to ensure PR comments are posted\n\nUpdate…
EdwardAngert Apr 9, 2025
38cfd56
\Update preview URL format and add direct doc links\
EdwardAngert Apr 9, 2025
e072e92
Add shared docs GitHub action
EdwardAngert Apr 9, 2025
07e93b0
test: Add heading to docs README
EdwardAngert Apr 9, 2025
6a7a2bc
Add test workflow
EdwardAngert Apr 9, 2025
4fcb322
Unified documentation workflow
EdwardAngert Apr 23, 2025
777bddc
Enhance documentation workflows with cross-reference checking
EdwardAngert Apr 23, 2025
992c592
Enhance PR comment with informative status overview and collapsible s…
EdwardAngert Apr 23, 2025
6420b3f
Optimize workflow logic and improve Vale style checking
EdwardAngert Apr 23, 2025
0a464f3
enhance: optimize workflow with unified reporting and concurrency
EdwardAngert Apr 23, 2025
3840432
refactor: replace linkspector with lychee for link checking
EdwardAngert Apr 23, 2025
b555621
refactor: combine documentation workflow optimizations
EdwardAngert Apr 23, 2025
00a4fb0
fix: address workflow issues for GitHub Actions compatibility
EdwardAngert Apr 23, 2025
ba403f2
docs: update GitHub Actions documentation
EdwardAngert Apr 23, 2025
168b54b
Merge branch 'main' into feature/unified-docs-workflow-combined
EdwardAngert Apr 23, 2025
6a0c1c1
fix: remove duplicate docs example workflows and fix caching issues
EdwardAngert Apr 23, 2025
8a29450
fix: update lychee-action configuration for v1 compatibility
EdwardAngert Apr 23, 2025
e37cda8
fix readme
EdwardAngert Apr 23, 2025
749d142
fix: correct YAML syntax in docs-link-check.yaml
EdwardAngert Apr 23, 2025
90a9ca8
chore: use caret versioning for tj-actions/changed-files
EdwardAngert Apr 23, 2025
bb9e393
fix: update actions and preview URL handling
EdwardAngert Apr 23, 2025
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
Prev Previous commit
Next Next commit
Enhance documentation workflows with cross-reference checking
- Adds cross-reference validation to detect broken links when files or headings change
- Centralizes file processing for better efficiency
- Creates a reusable docs-setup action to reduce redundancy
- Updates PR comment with cross-reference validation results
- Improves documentation with updated features
- Optimizes code for better maintainability
  • Loading branch information
EdwardAngert committed Apr 23, 2025
commit 777bddc52b30d81ef6a170b43a16d90f481e66eb
12 changes: 7 additions & 5 deletions .github/docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ jobs:
lint-markdown: true
check-format: true
check-links: true
check-cross-references: true
lint-vale: true
generate-preview: true
post-comment: true
Expand All @@ -47,11 +48,12 @@ The `docs-link-check.yaml` workflow runs after merges to main and on a weekly sc
1. **Documentation Preview**: Generates preview links for documentation changes
2. **Vale Style Checking**: Enforces consistent terminology and style
3. **Link Validation**: Checks for broken links in documentation
4. **Markdown Linting**: Ensures proper markdown formatting with markdownlint-cli2
5. **Markdown Table Format Checking**: Checks (but doesn't apply) markdown table formatting
6. **PR Comments**: Creates or updates PR comments with preview links and validation results
7. **Post-Merge Validation**: Ensures documentation quality after merges to main
8. **Issue Creation**: Automatically creates GitHub issues for broken links
4. **Cross-Reference Validation**: Detects broken references when files or headings are changed/removed
5. **Markdown Linting**: Ensures proper markdown formatting with markdownlint-cli2
6. **Markdown Table Format Checking**: Checks (but doesn't apply) markdown table formatting
7. **PR Comments**: Creates or updates PR comments with preview links and validation results
8. **Post-Merge Validation**: Ensures documentation quality after merges to main
9. **Issue Creation**: Automatically creates GitHub issues for broken links

## Formatting Local Workflow

Expand Down
36 changes: 36 additions & 0 deletions .github/docs/actions/docs-setup/action.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: 'Docs Setup'
description: 'Sets up the environment for docs-related workflows'
author: 'Coder'

inputs:
node-version:
description: 'Node.js version'
required: false
default: '20'
fetch-depth:
description: 'Git fetch depth'
required: false
default: '0'

runs:
using: 'composite'
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: ${{ inputs.fetch-depth }}

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }}
cache: 'pnpm'

- name: Install PNPM
uses: pnpm/action-setup@v3
with:
run_install: false

- name: Install dependencies
shell: bash
run: ./scripts/pnpm_install.sh
173 changes: 170 additions & 3 deletions .github/docs/actions/docs-shared/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ inputs:
description: 'Whether to run Vale style checks on documentation'
required: false
default: 'true'
check-cross-references:
description: 'Whether to check for broken cross-references when files or headings change'
required: false
default: 'true'
generate-preview:
description: 'Whether to generate preview links'
required: false
Expand Down Expand Up @@ -84,6 +88,9 @@ outputs:
vale_results:
description: 'Results from Vale style checks'
value: ${{ steps.lint-vale.outputs.result || '' }}
cross_ref_results:
description: 'Results from cross-reference checking'
value: ${{ steps.cross-references.outputs.cross_ref_results || '' }}

runs:
using: 'composite'
Expand All @@ -110,6 +117,31 @@ runs:
${{ inputs.include-md-files == 'true' && '**.md' || '' }}
separator: ','
json: true

- name: Process file lists
id: process-files
shell: bash
run: |
# Set up environment
CHANGED_FILES='${{ steps.changed-files.outputs.all_changed_files_json }}'
DELETED_FILES='${{ steps.changed-files.outputs.deleted_files_json || '[]' }}'

# Process files into different formats once
echo "md_files_comma<<EOF" >> $GITHUB_OUTPUT
echo "${{ steps.changed-files.outputs.all_changed_files }}" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT

echo "md_files_line<<EOF" >> $GITHUB_OUTPUT
echo "$CHANGED_FILES" | jq -r '.[] | select(endswith(".md"))' >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT

echo "docs_files_line<<EOF" >> $GITHUB_OUTPUT
echo "$CHANGED_FILES" | jq -r '.[] | select(endswith(".md")) | select(startswith("${{ inputs.docs-dir }}/"))' >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT

echo "deleted_md_files_line<<EOF" >> $GITHUB_OUTPUT
echo "$DELETED_FILES" | jq -r '.[] | select(endswith(".md"))' >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT

- name: Check if manifest changed
id: manifest-check
Expand Down Expand Up @@ -239,7 +271,7 @@ runs:
id: lint-docs
shell: bash
run: |
lint_output=$(pnpm exec markdownlint-cli2 ${{ steps.changed-files.outputs.all_changed_files }} 2>&1) || true
lint_output=$(pnpm exec markdownlint-cli2 ${{ steps.process-files.outputs.md_files_comma }} 2>&1) || true
echo "result<<EOF" >> $GITHUB_OUTPUT
echo "$lint_output" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
Expand All @@ -256,7 +288,7 @@ runs:
shell: bash
run: |
# markdown-table-formatter requires a space separated list of files
format_output=$(echo ${{ steps.changed-files.outputs.all_changed_files }} | tr ',' '\n' | pnpm exec markdown-table-formatter --check 2>&1) || true
format_output=$(echo "${{ steps.process-files.outputs.md_files_line }}" | pnpm exec markdown-table-formatter --check 2>&1) || true
echo "result<<EOF" >> $GITHUB_OUTPUT
echo "$format_output" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
Expand Down Expand Up @@ -289,7 +321,7 @@ runs:
shell: bash
run: |
# Run Vale on changed files and capture output
vale_output=$(echo ${{ steps.changed-files.outputs.all_changed_files }} | tr ',' '\n' | grep '\.md$' | xargs -r vale --config=.github/docs/vale/.vale.ini --output=line 2>&1) || true
vale_output=$(echo "${{ steps.process-files.outputs.md_files_line }}" | xargs -r vale --config=.github/docs/vale/.vale.ini --output=line 2>&1) || true

echo "result<<EOF" >> $GITHUB_OUTPUT
echo "$vale_output" >> $GITHUB_OUTPUT
Expand All @@ -300,6 +332,137 @@ runs:
echo "$vale_output"
exit 1
fi

- name: Check for broken cross-references
if: inputs.check-cross-references == 'true' && steps.docs-analysis.outputs.has_changes == 'true'
id: cross-references
shell: bash
run: |
# Get the base branch (usually main)
BASE_SHA=$(git merge-base HEAD origin/main)

echo "Checking for broken cross-references..."

# Initialize results
BROKEN_REFS=""

# Process deleted files
if [ -n "${{ steps.process-files.outputs.deleted_md_files_line }}" ]; then
echo "Processing deleted files"

# Loop through deleted markdown files
while IFS= read -r file; do
[ -z "$file" ] && continue

echo "File $file was deleted, checking for references..."

# Convert file path to potential link formats (removing .md extension)
OLD_PATH=$(echo "$file" | sed 's/\.md$//')

# Search in docs directory
DOC_REFS=$(grep -r --include="*.md" -l -E "\[$OLD_PATH\]|\($OLD_PATH\)" ${{ inputs.docs-dir }} || echo "")

# Search in codebase (excluding specific directories)
CODE_REFS=$(grep -r --include="*.{go,ts,js,py,java,cs,php}" -l "$OLD_PATH" . --exclude-dir={node_modules,.git,build,dist} || echo "")

if [ -n "$DOC_REFS" ] || [ -n "$CODE_REFS" ]; then
BROKEN_REFS="${BROKEN_REFS}## References to deleted file: $file\n\n"

if [ -n "$DOC_REFS" ]; then
BROKEN_REFS="${BROKEN_REFS}### In documentation:\n"
BROKEN_REFS="${BROKEN_REFS}$(echo "$DOC_REFS" | sed 's/^/- /')\n\n"
fi

if [ -n "$CODE_REFS" ]; then
BROKEN_REFS="${BROKEN_REFS}### In codebase:\n"
BROKEN_REFS="${BROKEN_REFS}$(echo "$CODE_REFS" | sed 's/^/- /')\n\n"
fi
fi
done <<< "${{ steps.process-files.outputs.deleted_md_files_line }}"
fi

# Process modified files for heading changes
while IFS= read -r file; do
[ -z "$file" ] && continue

if [ -f "$file" ]; then
echo "Checking for changed headings in $file..."

# Extract headings before the change
OLD_HEADINGS=$(git show "$BASE_SHA:$file" 2>/dev/null | grep -E "^#{1,6} " | sed 's/^#\{1,6\} \(.*\)$/\1/' || echo "")

# Extract current headings
NEW_HEADINGS=$(cat "$file" | grep -E "^#{1,6} " | sed 's/^#\{1,6\} \(.*\)$/\1/')

# Find removed headings
REMOVED_HEADINGS=$(comm -23 <(echo "$OLD_HEADINGS" | sort) <(echo "$NEW_HEADINGS" | sort))

if [ -n "$REMOVED_HEADINGS" ]; then
while IFS= read -r heading; do
[ -z "$heading" ] && continue

# Convert heading to anchor format (lowercase, spaces to hyphens)
ANCHOR=$(echo "$heading" | tr '[:upper:]' '[:lower:]' | tr -cd '[:alnum:] -' | tr ' ' '-')

# Search for references to this anchor in documentation
HEAD_REFS=$(grep -r --include="*.md" -l "#$ANCHOR" ${{ inputs.docs-dir }} || echo "")

if [ -n "$HEAD_REFS" ]; then
BROKEN_REFS="${BROKEN_REFS}## References to removed heading: '$heading' in $file\n\n"
BROKEN_REFS="${BROKEN_REFS}$(echo "$HEAD_REFS" | sed 's/^/- /')\n\n"
fi
done <<< "$REMOVED_HEADINGS"
fi
fi
done <<< "${{ steps.process-files.outputs.docs_files_line }}"

# Check for renamed files by comparing paths
while IFS= read -r file; do
[ -z "$file" ] && continue

# Use git to check if this is a renamed file
PREV_PATH=$(git diff --name-status "$BASE_SHA" | grep "^R" | grep "$file$" | cut -f2)

if [ -n "$PREV_PATH" ] && [ "$PREV_PATH" != "$file" ]; then
echo "File renamed from $PREV_PATH to $file, checking for references..."

# Convert old file path to potential link formats
OLD_PATH=$(echo "$PREV_PATH" | sed 's/\.md$//')

# Search in docs directory
DOC_REFS=$(grep -r --include="*.md" -l -E "\[$OLD_PATH\]|\($OLD_PATH\)" ${{ inputs.docs-dir }} || echo "")

# Search in codebase (excluding specific directories)
CODE_REFS=$(grep -r --include="*.{go,ts,js,py,java,cs,php}" -l "$OLD_PATH" . --exclude-dir={node_modules,.git,build,dist} || echo "")

if [ -n "$DOC_REFS" ] || [ -n "$CODE_REFS" ]; then
BROKEN_REFS="${BROKEN_REFS}## References to renamed file: $PREV_PATH → $file\n\n"

if [ -n "$DOC_REFS" ]; then
BROKEN_REFS="${BROKEN_REFS}### In documentation:\n"
BROKEN_REFS="${BROKEN_REFS}$(echo "$DOC_REFS" | sed 's/^/- /')\n\n"
fi

if [ -n "$CODE_REFS" ]; then
BROKEN_REFS="${BROKEN_REFS}### In codebase:\n"
BROKEN_REFS="${BROKEN_REFS}$(echo "$CODE_REFS" | sed 's/^/- /')\n\n"
fi
fi
fi
done <<< "${{ steps.process-files.outputs.md_files_line }}"

if [ -n "$BROKEN_REFS" ]; then
echo "cross_ref_results<<EOF" >> $GITHUB_OUTPUT
echo -e "$BROKEN_REFS" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT

if [ "${{ inputs.fail-on-error }}" == "true" ]; then
echo "::error::Broken cross-references found. See output for details."
exit 1
fi
else
echo "No broken cross-references found"
fi

- name: Generate Preview URL
if: inputs.generate-preview == 'true' && steps.docs-analysis.outputs.has_changes == 'true'
Expand Down Expand Up @@ -368,6 +531,10 @@ runs:
${{ steps.lint-vale.outputs.result != '' && steps.lint-vale.outputs.result || '' }}
${{ steps.lint-vale.outputs.result != '' && '```' || '' }}

${{ steps.cross-references.outputs.cross_ref_results != '' && '### Broken Cross-References' || '' }}
${{ steps.cross-references.outputs.cross_ref_results != '' && 'The following cross-references may be broken due to file or heading changes:' || '' }}
${{ steps.cross-references.outputs.cross_ref_results != '' && steps.cross-references.outputs.cross_ref_results || '' }}

---
<sub>🤖 This comment is automatically generated and updated when documentation changes.</sub>
edit-mode: replace
Expand Down
6 changes: 6 additions & 0 deletions .github/workflows/docs-reusable-example.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ jobs:
lint-markdown: true
check-format: true
check-links: true
check-cross-references: true
lint-vale: true
generate-preview: true
post-comment: true
Expand Down Expand Up @@ -77,6 +78,7 @@ jobs:
check-links: "true"
lint-markdown: "true"
check-format: "true"
check-cross-references: "true"
lint-vale: "true"
generate-preview: "true"
post-comment: "true"
Expand All @@ -92,4 +94,8 @@ jobs:

if [ "${{ steps.docs-shared.outputs.format_results }}" != "" ]; then
echo "Formatting issues found, please run 'make fmt/markdown' locally"
fi

if [ "${{ steps.docs-shared.outputs.cross_ref_results }}" != "" ]; then
echo "Broken cross-references found"
fi
30 changes: 12 additions & 18 deletions .github/workflows/docs-unified.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ on:
required: false
type: boolean
default: true
check-cross-references:
description: 'Whether to check for broken cross-references when files or headings change'
required: false
type: boolean
default: true
lint-vale:
description: 'Whether to run Vale style checks on documentation'
required: false
Expand Down Expand Up @@ -51,24 +56,8 @@ jobs:
with:
egress-policy: audit

- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20
cache: 'pnpm'

- name: Install pnpm
uses: pnpm/action-setup@v3
with:
run_install: false

- name: Install dependencies
run: ./scripts/pnpm_install.sh
- name: Setup Environment
uses: ./.github/docs/actions/docs-setup

- name: Get PR info
id: pr_info
Expand All @@ -90,6 +79,7 @@ jobs:
check-links: ${{ inputs.check-links }}
lint-markdown: ${{ inputs.lint-markdown }}
check-format: ${{ inputs.check-format }}
check-cross-references: ${{ inputs.check-cross-references }}
lint-vale: ${{ inputs.lint-vale }}
generate-preview: ${{ inputs.generate-preview }}
post-comment: ${{ inputs.post-comment }}
Expand All @@ -115,4 +105,8 @@ jobs:

if [ "${{ steps.docs-shared.outputs.vale_results }}" != "" ]; then
echo "Vale style issues found"
fi

if [ "${{ steps.docs-shared.outputs.cross_ref_results }}" != "" ]; then
echo "Broken cross-references found"
fi
0