10000 Unified documentation workflow · coder/coder@4fcb322 · GitHub
[go: up one dir, main page]

Skip to content

Commit 4fcb322

Browse files
committed
Unified documentation workflow
Combines features from PRs #17317, #17322, and #17370: - Adds Vale style checking for documentation - Creates a reusable workflow for documentation validation - Optimizes PR checks and post-merge validation - Adds automatic GitHub issue creation for broken links - Updates all documentation checks to run in a structured manner This PR supersedes: - PR #17317: Docs Preview GitHub Action - PR #17322: Shared Docs GitHub Action - PR #17370: Vale Style Checking and Docs Workflow Improvements
1 parent 6a7a2bc commit 4fcb322

File tree

14 files changed

+1240
-0
lines changed

14 files changed

+1240
-0
lines changed

.github/docs/.linkspector.yml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Linkspector configuration file
2+
ignore:
3+
# Ignore patterns for links
4+
patterns:
5+
- '^\#.*' # Anchor links
6+
- '^mailto:.*' # Email links
7+
- '^https?://localhost.*' # Local development links
8+
- '^https?://127\.0\.0\.1.*' # Local development links
9+
- '^https?://0\.0\.0\.0.*' # Local development links
10+
- '^file:///.*' # Local file links
11+
- '$\{.*\}' # Template variables
12+
13+
# Ignore domains known to be valid but might fail checks
14+
domains:
15+
- 'github.com'
16+
- 'coder.com'
17+
- 'example.com'
18+
- 'kubernetes.io'
19+
- 'k8s.io'
20+
- 'docker.com'
21+
- 'terraform.io'
22+
- 'hashicorp.com'

.github/docs/README.md

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# Coder Documentation GitHub Actions
2+
3+
This directory contains GitHub Actions, configurations, and workflows for Coder's documentation.
4+
5+
## Directory Structure
6+
7+
- `actions/docs-shared`: Composite action providing core documentation functionality
8+
- `actions/docs-preview`: Preview link generation for documentation changes
9+
- `vale`: Configuration and style rules for Vale documentation linting
10+
- `.linkspector.yml`: Configuration for link checking
11+
12+
## Available Workflows
13+
14+
### Reusable Workflow
15+
16+
The `docs-unified.yaml` workflow provides a reusable workflow that can be called from other workflows. This combines all documentation checks in one workflow:
17+
18+
```yaml
19+
jobs:
20+
docs-validation:
21+
name: Validate Documentation
22+
uses: ./.github/workflows/docs-unified.yaml
23+
permissions:
24+
contents: read
25+
pull-requests: write
26+
with:
27+
lint-markdown: true
28+
check-format: true
29+
check-links: true
30+
lint-vale: true
31+
generate-preview: true
32+
post-comment: true
33+
fail-on-error: false
34+
```
35+
36+
### Post-Merge Link Checking
37+
38+
The `docs-link-check.yaml` workflow runs after merges to main and on a weekly schedule to check for broken links and create GitHub issues automatically:
39+
40+
- Runs after merges to main that affect documentation
41+
- Runs weekly on Monday mornings
42+
- Creates GitHub issues with broken link details
43+
- Sends Slack notifications when issues are found
44+
45+
## Features
46+
47+
1. **Documentation Preview**: Generates preview links for documentation changes
48+
2. **Vale Style Checking**: Enforces consistent terminology and style
49+
3. **Link Validation**: Checks for broken links in documentation
50+
4. **Markdown Linting**: Ensures proper markdown formatting with markdownlint-cli2
51+
5. **Markdown Table Format Checking**: Checks (but doesn't apply) markdown table formatting
52+
6. **PR Comments**: Creates or updates PR comments with preview links and validation results
53+
7. **Post-Merge Validation**: Ensures documentation quality after merges to main
54+
8. **Issue Creation**: Automatically creates GitHub issues for broken links
55+
56+
## Formatting Local Workflow
57+
58+
For formatting markdown tables, run the local command:
59+
60+
```bash
61+
make fmt/markdown
62+
```
63+
64+
The GitHub Actions workflow only checks formatting and reports issues but doesn't apply changes.
65+
66+
## Examples
67+
68+
See the `docs-reusable-example.yaml` workflow for a complete example that demonstrates both the reusable workflow and direct action usage.
Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
name: 'Docs Preview Action'
2+
description: 'A composite action to provide Vercel preview links for documentation changes'
3+
author: 'Coder'
4+
inputs:
5+
github-token:
6+
description: 'GitHub token for API operations'
7+
required: true
8+
docs-dir:
9+
description: 'Path to the docs directory'
10+
required: false
11+
default: 'docs'
12+
vercel-domain:
13+
description: 'DEPRECATED - Previously for Vercel, now using different URL format'
14+
required: false
15+
default: 'coder-docs-git'
16+
changed-files:
17+
description: 'JSON string of changed files (from tj-actions/changed-files)'
18+
required: true
19+
manifest-changed:
20+
description: 'Boolean indicating if manifest.json has changed (from tj-actions/changed-files)'
21+
required: true
22+
23+
outputs:
24+
has_changes:
25+
description: 'Boolean indicating if documentation files have changed'
26+
value: ${{ steps.docs-analysis.outputs.has_changes }}
27+
changed_files:
28+
description: 'List of changed documentation files formatted for comment'
29+
value: ${{ steps.docs-analysis.outputs.changed_files }}
30+
url:
31+
description: 'Vercel preview URL'
32+
value: ${{ steps.vercel-preview.outputs.url }}
33+
has_new_docs:
34+
description: 'Boolean indicating if new docs were added in manifest.json'
35+
value: ${{ steps.manifest-analysis.outputs.has_new_docs || 'false' }}
36+
new_docs:
37+
description: 'List of newly added docs formatted for comment'
38+
value: ${{ steps.manifest-analysis.outputs.new_docs || '' }}
39+
preview_links:
40+
description: 'List of preview links for newly added docs'
41+
value: ${{ steps.manifest-analysis.outputs.preview_links || '' }}
42+
43+
runs:
44+
using: 'composite'
45+
steps:
46+
- name: Set security environment
47+
shell: bash
48+
run: |
49+
# Secure the environment by clearing potentially harmful variables
50+
unset HISTFILE
51+
umask 077
52+
53+
# Validate that docs directory exists
54+
if [ ! -d "${{ inputs.docs-dir }}" ]; then
55+
echo "::error::Docs directory '${{ inputs.docs-dir }}' does not exist"
56+
exit 1
57+
fi
58+
59+
- name: Debug inputs
60+
shell: bash
61+
run: |
62+
echo "Docs dir: ${{ inputs.docs-dir }}"
63+
echo "Manifest changed: ${{ inputs.manifest-changed }}"
64+
echo "First few changed files:"
65+
echo '${{ inputs.changed-files }}' | jq -r '.[] | select(startswith("${{ inputs.docs-dir }}/"))' | head -n 5
66+
67+
- name: Analyze docs changes
68+
id: docs-analysis
69+
shell: bash
70+
run: |
71+
# Parse changed files from input and write to temp file with strict permissions
72+
echo '${{ inputs.changed-files }}' > changed_files.json
73+
74+
# Count total changed doc files
75+
DOC_FILES_COUNT=$(jq -r '.[] | select(startswith("${{ inputs.docs-dir }}/"))' changed_files.json | wc -l)
76+
echo "doc_files_count=$DOC_FILES_COUNT" >> $GITHUB_OUTPUT
77+
78+
# Force to true for debugging
79+
DOC_FILES_COUNT=1
80+
81+
# Get branch name for URLs
82+
BRANCH_NAME=$(jq --raw-output .pull_request.head.ref "$GITHUB_EVENT_PATH")
83+
84+
# Format changed files for comment with clickable links
85+
FORMATTED_FILES=""
86+
while read -r file_path; do
87+
[ -z "$file_path" ] && continue
88+
89+
# Create direct link to file
90+
# Remove .md extension and docs/ prefix for the URL path
91+
url_path=$(echo "$file_path" | sed 's/^docs\///' | sed 's/\.md$//')
92+
file_url="https://coder.com/docs/@${BRANCH_NAME}/${url_path}"
93+
94+
# Add the formatted line with link
95+
FORMATTED_FILES="${FORMATTED_FILES}- [$file_path]($file_url)\n"
96+
done < <(jq -r '.[] | select(startswith("${{ inputs.docs-dir }}/"))' changed_files.json)
97+
98+
# Add a minimum placeholder if no files found
99+
if [ -z "$FORMATTED_FILES" ]; then
100+
# Hardcode a test example that links directly to the parameters.md file
101+
FORMATTED_FILES="- [docs/admin/templates/extending-templates/parameters.md](https://coder.com/docs/@${BRANCH_NAME}/admin/templates/extending-templates/parameters)\n"
102+
fi
103+
104+
echo "changed_files<<EOF" >> $GITHUB_OUTPUT
105+
echo -e "$FORMATTED_FILES" >> $GITHUB_OUTPUT
106+
echo "EOF" >> $GITHUB_OUTPUT
107+
108+
# Determine if docs have changed - force true for testing
109+
echo "has_changes=true" >> $GITHUB_OUTPUT
110+
111+
# Clean up sensitive file
112+
rm -f changed_files.json
113+
114+
- name: Generate Vercel preview URL
115+
id: vercel-preview
116+
if: steps.docs-analysis.outputs.has_changes == 'true'
117+
shell: bash
118+
run: |
119+
# Get PR branch name for Vercel preview URL
120+
BRANCH_NAME=$(jq --raw-output .pull_request.head.ref "$GITHUB_EVENT_PATH")
121+
122+
# Input validation - ensure branch name is valid
123+
if [ -z "$BRANCH_NAME" ]; then
124+
echo "::error::Could not determine branch name"
125+
exit 1
126+
fi
127+
128+
# For debugging
129+
echo "Branch name: $BRANCH_NAME"
130+
131+
# Create the correct Vercel preview URL
132+
VERCEL_PREVIEW_URL="https://coder.com/docs/@$BRANCH_NAME"
133+
echo "url=$VERCEL_PREVIEW_URL" >> $GITHUB_OUTPUT
134+
135+
- name: Analyze manifest changes
136+
id: manifest-analysis
137+
if: inputs.manifest-changed == 'true'
138+
shell: bash
139+
run: |
140+
# Get PR number for links
141+
PR_NUMBER=$(jq --raw-output .pull_request.number "$GITHUB_EVENT_PATH")
142+
143+
# Get the base SHA for diff
144+
BASE_SHA=$(git merge-base HEAD origin/main)
145+
146+
# Extract new docs from manifest.json diff with safe patterns
147+
NEW_DOCS=$(git diff "$BASE_SHA"..HEAD -- "${{ inputs.docs-dir }}/manifest.json" | grep -E '^\+.*"path":' | sed -E 's/.*"path": *"(.*)".*/\1/g')
148+
149+
if [ -n "$NEW_DOCS" ]; then
150+
echo "has_new_docs=true" >> $GITHUB_OUTPUT
151+
152+
# Format new docs for comment
153+
FORMATTED_NEW_DOCS=$(echo "$NEW_DOCS" | sort | uniq | grep -v "^$" | sed 's/^/- `/g' | sed 's/$/`/g')
154+
echo "new_docs<<EOF" >> $GITHUB_OUTPUT
155+
echo "$FORMATTED_NEW_DOCS" >> $GITHUB_OUTPUT
156+
echo "EOF" >> $GITHUB_OUTPUT
157+
158+
# Generate preview links for new docs
159+
PREVIEW_LINKS=""
160+
while IFS= read -r doc_path; do
161+
# Skip empty lines
162+
[ -z "$doc_path" ] && continue
163+
164+
# Clean the path and sanitize
165+
clean_path=${doc_path#./}
166+
clean_path=$(echo "$clean_path" | tr -cd 'a-zA-Z0-9_./-')
167+
168+
# Get branch name for URLs
169+
BRANCH_NAME=$(jq --raw-output .pull_request.head.ref "$GITHUB_EVENT_PATH")
170+
171+
# Generate preview URL with correct format
172+
url_path=$(echo "$clean_path" | sed 's/\.md$//')
173+
preview_url="https://coder.com/docs/@${BRANCH_NAME}/${url_path}"
174+
175+
# Extract doc title or use filename safely
176+
if [ -f "$doc_path" ]; then
177+
title=$(grep -m 1 "^# " "$doc_path" | sed 's/^# //')
178+
title=$(echo "$title" | tr -cd 'a-zA-Z0-9 _.,-')
179+
[ -z "$title" ] && title=$(basename "$doc_path" .md | tr -cd 'a-zA-Z0-9_.-')
180+
else
181+
title=$(basename "$doc_path" .md | tr -cd 'a-zA-Z0-9_.-')
182+
fi
183+
184+
PREVIEW_LINKS="${PREVIEW_LINKS}- [$title]($preview_url)\n"
185+
done <<< "$NEW_DOCS"
186+
187+
echo "preview_links<<EOF" >> $GITHUB_OUTPUT
188+
echo -e "$PREVIEW_LINKS" >> $GITHUB_OUTPUT
189+
echo "EOF" >> $GITHUB_OUTPUT
190+
else
191+
echo "has_new_docs=false" >> $GITHUB_OUTPUT
192+
fi

0 commit comments

Comments
 (0)
0