Skip to content

Commit 070ca4a

Browse files
committed
Add on-demand docs preview workflow
Lets a dev trigger a workflow_dispatch run with a PR number or branch and a product (asgardeo / identity-server/next / 7.x), spin up mkdocs serve behind a cloudflared quick tunnel, and post the preview link to the run summary and the PR.
1 parent 9ff24d4 commit 070ca4a

1 file changed

Lines changed: 160 additions & 0 deletions

File tree

.github/workflows/preview-docs.yml

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
name: Preview Docs (on-demand)
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
ref:
7+
description: 'PR number (e.g. 6138) or branch name'
8+
required: true
9+
type: string
10+
product:
11+
description: 'Which docs to build'
12+
required: true
13+
type: choice
14+
options:
15+
- asgardeo
16+
- identity-server/next
17+
- identity-server/7.3.0
18+
- identity-server/7.2.0
19+
- identity-server/7.1.0
20+
- identity-server/7.0.0
21+
duration_minutes:
22+
description: 'Minutes to keep the preview link alive (max 350)'
23+
required: true
24+
default: '120'
25+
type: string
26+
27+
permissions:
28+
contents: read
29+
pull-requests: write
30+
31+
jobs:
32+
preview:
33+
runs-on: ubuntu-latest
34+
timeout-minutes: 355
35+
steps:
36+
- name: Resolve ref
37+
id: resolve
38+
env:
39+
INPUT_REF: ${{ inputs.ref }}
40+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
41+
run: |
42+
set -euo pipefail
43+
if [[ "$INPUT_REF" =~ ^[0-9]+$ ]]; then
44+
head_ref=$(gh pr view "$INPUT_REF" --repo "$GITHUB_REPOSITORY" --json headRefName -q .headRefName)
45+
head_repo=$(gh pr view "$INPUT_REF" --repo "$GITHUB_REPOSITORY" --json headRepositoryOwner,headRepository -q '.headRepositoryOwner.login + "/" + .headRepository.name')
46+
echo "ref=$head_ref" >> "$GITHUB_OUTPUT"
47+
echo "repo=$head_repo" >> "$GITHUB_OUTPUT"
48+
echo "pr=$INPUT_REF" >> "$GITHUB_OUTPUT"
49+
else
50+
echo "ref=$INPUT_REF" >> "$GITHUB_OUTPUT"
51+
echo "repo=$GITHUB_REPOSITORY" >> "$GITHUB_OUTPUT"
52+
echo "pr=" >> "$GITHUB_OUTPUT"
53+
fi
54+
55+
- name: Checkout
56+
uses: actions/checkout@v4
57+
with:
58+
repository: ${{ steps.resolve.outputs.repo }}
59+
ref: ${{ steps.resolve.outputs.ref }}
60+
fetch-depth: 1
61+
62+
- name: Set up Python
63+
uses: actions/setup-python@v5
64+
with:
65+
python-version: '3.12'
66+
67+
- name: Install mkdocs dependencies
68+
run: |
69+
set -euo pipefail
70+
python -m pip install --upgrade pip
71+
pip install -r "en/${{ inputs.product }}/requirements.txt"
72+
73+
- name: Install cloudflared
74+
run: |
75+
set -euo pipefail
76+
curl -fsSL -o cloudflared.deb https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
77+
sudo dpkg -i cloudflared.deb
78+
79+
- name: Serve docs and open tunnel
80+
id: tunnel
81+
env:
82+
PRODUCT: ${{ inputs.product }}
83+
DURATION_MINUTES: ${{ inputs.duration_minutes }}
84+
PR_NUMBER: ${{ steps.resolve.outputs.pr }}
85+
RESOLVED_REF: ${{ steps.resolve.outputs.ref }}
86+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
87+
run: |
88+
set -euo pipefail
89+
90+
cd "en/$PRODUCT"
91+
nohup mkdocs serve -a 127.0.0.1:8000 > "$GITHUB_WORKSPACE/mkdocs.log" 2>&1 &
92+
MKDOCS_PID=$!
93+
cd "$GITHUB_WORKSPACE"
94+
95+
echo "Waiting for mkdocs to come up..."
96+
for i in $(seq 1 120); do
97+
if nc -z 127.0.0.1 8000; then
98+
echo "mkdocs is up."
99+
break
100+
fi
101+
if ! kill -0 "$MKDOCS_PID" 2>/dev/null; then
102+
echo "::error::mkdocs serve exited early. Log:"
103+
cat mkdocs.log
104+
exit 1
105+
fi
106+
sleep 1
107+
done
108+
109+
nohup cloudflared tunnel --no-autoupdate --url http://127.0.0.1:8000 > cloudflared.log 2>&1 &
110+
CF_PID=$!
111+
112+
URL=""
113+
for i in $(seq 1 60); do
114+
URL=$(grep -oE 'https://[a-z0-9-]+\.trycloudflare\.com' cloudflared.log | head -1 || true)
115+
if [ -n "$URL" ]; then break; fi
116+
if ! kill -0 "$CF_PID" 2>/dev/null; then
117+
echo "::error::cloudflared exited early. Log:"
118+
cat cloudflared.log
119+
exit 1
120+
fi
121+
sleep 1
122+
done
123+
124+
if [ -z "$URL" ]; then
125+
echo "::error::Could not find a trycloudflare.com URL in cloudflared output."
126+
cat cloudflared.log
127+
exit 1
128+
fi
129+
130+
echo "Preview URL: $URL"
131+
132+
{
133+
echo "## Docs preview ready"
134+
echo ""
135+
echo "| Field | Value |"
136+
echo "| --- | --- |"
137+
echo "| Product | \`$PRODUCT\` |"
138+
echo "| Ref | \`$RESOLVED_REF\` |"
139+
echo "| URL | $URL |"
140+
echo "| Lifetime | $DURATION_MINUTES min |"
141+
echo ""
142+
echo "The link goes dead when this job ends."
143+
} >> "$GITHUB_STEP_SUMMARY"
144+
145+
if [ -n "$PR_NUMBER" ]; then
146+
BODY=$(printf '**Docs preview:** %s\n\nProduct: `%s` · Ref: `%s` · Live for %s min.\n\n_Triggered by @%s via the Preview Docs workflow._' \
147+
"$URL" "$PRODUCT" "$RESOLVED_REF" "$DURATION_MINUTES" "$GITHUB_ACTOR")
148+
gh pr comment "$PR_NUMBER" --repo "$GITHUB_REPOSITORY" --body "$BODY" || \
149+
echo "::warning::Failed to post PR comment (continuing anyway)."
150+
fi
151+
152+
MAX_MINUTES=350
153+
if [ "$DURATION_MINUTES" -gt "$MAX_MINUTES" ]; then
154+
DURATION_MINUTES=$MAX_MINUTES
155+
fi
156+
echo "Keeping preview alive for $DURATION_MINUTES minutes..."
157+
sleep $(( DURATION_MINUTES * 60 ))
158+
159+
kill "$CF_PID" 2>/dev/null || true
160+
kill "$MKDOCS_PID" 2>/dev/null || true

0 commit comments

Comments
 (0)