Skip to content

Commit d0fe1f8

Browse files
EdwardAngertclaude
andcommitted
Add simplified docs preview GitHub action
Creates a simplified docs preview action that comments on PRs with Vercel preview links. The action shows changed files and highlights newly added documentation from manifest.json. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 109e73b commit d0fe1f8

File tree

2 files changed

+244
-0
lines changed

2 files changed

+244
-0
lines changed
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
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: 'Vercel deployment domain'
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: Analyze docs changes
60+
id: docs-analysis
61+
shell: bash
62+
run: |
63+
# Parse changed files from input and write to temp file with strict permissions
64+
echo '${{ inputs.changed-files }}' > changed_files.json
65+
66+
# Count total changed doc files
67+
DOC_FILES_COUNT=$(jq -r '.[] | select(startswith("${{ inputs.docs-dir }}/"))' changed_files.json | wc -l)
68+
echo "doc_files_count=$DOC_FILES_COUNT" >> $GITHUB_OUTPUT
69+
70+
# Format changed files for comment
71+
FORMATTED_FILES=$(jq -r '.[] | select(startswith("${{ inputs.docs-dir }}/")) | "- `" + . + "`"' changed_files.json)
72+
echo "changed_files<<EOF" >> $GITHUB_OUTPUT
73+
echo "$FORMATTED_FILES" >> $GITHUB_OUTPUT
74+
echo "EOF" >> $GITHUB_OUTPUT
75+
76+
# Determine if docs have changed
77+
if [ "$DOC_FILES_COUNT" -gt 0 ]; then
78+
echo "has_changes=true" >> $GITHUB_OUTPUT
79+
else
80+
echo "has_changes=false" >> $GITHUB_OUTPUT
81+
fi
82+
83+
# Clean up sensitive file
84+
rm -f changed_files.json
85+
86+
- name: Generate Vercel preview URL
87+
id: vercel-preview
88+
if: steps.docs-analysis.outputs.has_changes == 'true'
89+
shell: bash
90+
run: |
91+
# Get PR number for Vercel preview URL using GitHub event file
92+
PR_NUMBER=$(jq --raw-output .pull_request.number "$GITHUB_EVENT_PATH")
93+
94+
# Input validation - ensure PR number is a number
95+
if ! [[ "$PR_NUMBER" =~ ^[0-9]+$ ]]; then
96+
echo "::error::Invalid PR number: $PR_NUMBER"
97+
exit 1
98+
fi
99+
100+
# Generate and output Vercel preview URL with sanitized inputs
101+
VERCEL_DOMAIN="${{ inputs.vercel-domain }}"
102+
# Remove any dangerous characters from domain
103+
VERCEL_DOMAIN=$(echo "$VERCEL_DOMAIN" | tr -cd 'a-zA-Z0-9-.')
104+
105+
VERCEL_PREVIEW_URL="https://${VERCEL_DOMAIN}-${PR_NUMBER}.vercel.app"
106+
echo "url=$VERCEL_PREVIEW_URL" >> $GITHUB_OUTPUT
107+
108+
- name: Analyze manifest changes
109+
id: manifest-analysis
110+
if: inputs.manifest-changed == 'true'
111+
shell: bash
112+
run: |
113+
# Get PR number for links
114+
PR_NUMBER=$(jq --raw-output .pull_request.number "$GITHUB_EVENT_PATH")
115+
116+
# Get the base SHA for diff
117+
BASE_SHA=$(git merge-base HEAD origin/main)
118+
119+
# Extract new docs from manifest.json diff with safe patterns
120+
NEW_DOCS=$(git diff "$BASE_SHA"..HEAD -- "${{ inputs.docs-dir }}/manifest.json" | grep -E '^\+.*"path":' | sed -E 's/.*"path": *"(.*)".*/\1/g')
121+
122+
if [ -n "$NEW_DOCS" ]; then
123+
echo "has_new_docs=true" >> $GITHUB_OUTPUT
124+
125+
# Format new docs for comment
126+
FORMATTED_NEW_DOCS=$(echo "$NEW_DOCS" | sort | uniq | grep -v "^$" | sed 's/^/- `/g' | sed 's/$/`/g')
127+
echo "new_docs<<EOF" >> $GITHUB_OUTPUT
128+
echo "$FORMATTED_NEW_DOCS" >> $GITHUB_OUTPUT
129+
echo "EOF" >> $GITHUB_OUTPUT
130+
131+
# Generate preview links for new docs
132+
PREVIEW_LINKS=""
133+
while IFS= read -r doc_path; do
134+
# Skip empty lines
135+
[ -z "$doc_path" ] && continue
136+
137+
# Clean the path and sanitize
138+
clean_path=${doc_path#./}
139+
clean_path=$(echo "$clean_path" | tr -cd 'a-zA-Z0-9_./-')
140+
141+
# Generate preview URL
142+
url_path=$(echo "$clean_path" | sed 's/\.md$//')
143+
VERCEL_DOMAIN="${{ inputs.vercel-domain }}"
144+
VERCEL_DOMAIN=$(echo "$VERCEL_DOMAIN" | tr -cd 'a-zA-Z0-9-.')
145+
preview_url="https://${VERCEL_DOMAIN}-${PR_NUMBER}.vercel.app/${url_path}"
146+
147+
# Extract doc title or use filename safely
148+
if [ -f "$doc_path" ]; then
149+
title=$(grep -m 1 "^# " "$doc_path" | sed 's/^# //')
150+
title=$(echo "$title" | tr -cd 'a-zA-Z0-9 _.,-')
151+
[ -z "$title" ] && title=$(basename "$doc_path" .md | tr -cd 'a-zA-Z0-9_.-')
152+
else
153+
title=$(basename "$doc_path" .md | tr -cd 'a-zA-Z0-9_.-')
154+
fi
155+
156+
PREVIEW_LINKS="${PREVIEW_LINKS}- [$title]($preview_url)\n"
157+
done <<< "$NEW_DOCS"
158+
159+
echo "preview_links<<EOF" >> $GITHUB_OUTPUT
160+
echo -e "$PREVIEW_LINKS" >> $GITHUB_OUTPUT
161+
echo "EOF" >> $GITHUB_OUTPUT
162+
else
163+
echo "has_new_docs=false" >> $GITHUB_OUTPUT
164+
fi

.github/workflows/docs-preview.yaml

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
name: Docs Preview
2+
on:
3+
pull_request:
4+
types: [opened, synchronize, reopened]
5+
paths:
6+
- 'docs/**'
7+
8+
permissions:
9+
contents: read
10+
pull-requests: write
11+
12+
jobs:
13+
preview:
14+
name: Generate docs preview
15+
runs-on: ubuntu-latest
16+
steps:
17+
- name: Harden Runner
18+
uses: step-security/harden-runner@4d991eb9b905ef189e4c376166672c3f2f230481 # v2.11.0
19+
with:
20+
egress-policy: audit
21+
22+
- name: Checkout
23+
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
24+
with:
25+
fetch-depth: 0
26+
27+
- name: Get changed files
28+
id: changed-files
29+
uses: tj-actions/changed-files@2a398787e7b39c6ca11ce0843e5956d0b4165c80 # v43.0.0
30+
with:
31+
files: |
32+
docs/**
33+
34+
- name: Check if manifest changed
35+
id: manifest-check
36+
run: |
37+
echo "changed=${{ contains(steps.changed-files.outputs.all_changed_files, 'docs/manifest.json') }}" >> $GITHUB_OUTPUT
38+
39+
- name: Generate docs preview
40+
id: docs-preview
41+
uses: ./.github/actions/docs-preview
42+
with:
43+
github-token: ${{ secrets.GITHUB_TOKEN }}
44+
changed-files: ${{ steps.changed-files.outputs.all_changed_files_json }}
45+
manifest-changed: ${{ steps.manifest-check.outputs.changed }}
46+
47+
- name: Find existing comment
48+
if: steps.docs-preview.outputs.has_changes == 'true'
49+
uses: peter-evans/find-comment@3eae4d37986fb5a8592848f6a574fdf654e61f9e # v3.1.0
50+
id: find-comment
51+
with:
52+
issue-number: ${{ github.event.pull_request.number }}
53+
comment-author: 'github-actions[bot]'
54+
body-includes: '## 📚 Docs Preview'
55+
56+
- name: Create or update preview comment
57+
if: steps.docs-preview.outputs.has_changes == 'true'
58+
uses: peter-evans/create-or-update-comment@71345be0265236311c031f5c7866368bd1eff043 # v4.0.0
59+
with:
60+
comment-id: ${{ steps.find-comment.outputs.comment-id }}
61+
issue-number: ${{ github.event.pull_request.number }}
62+
body: |
63+
## 📚 Docs Preview
64+
65+
Your documentation changes are available for preview at:
66+
**🔗 [Vercel Preview](${{ steps.docs-preview.outputs.url }})**
67+
68+
### Changed Documentation Files
69+
${{ steps.docs-preview.outputs.changed_files }}
70+
71+
${{ steps.docs-preview.outputs.has_new_docs == 'true' && '### Newly Added Documentation' || '' }}
72+
${{ steps.docs-preview.outputs.has_new_docs == 'true' && steps.docs-preview.outputs.new_docs || '' }}
73+
74+
${{ steps.docs-preview.outputs.has_new_docs == 'true' && '### Preview Links for New Docs' || '' }}
75+
${{ steps.docs-preview.outputs.has_new_docs == 'true' && steps.docs-preview.outputs.preview_links || '' }}
76+
77+
---
78+
<sub>🤖 This comment is automatically generated and updated when documentation changes.</sub>
79+
edit-mode: replace
80+
reactions: eyes

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy