Skip to content

Commit 3c2c294

Browse files
committed
docs: add a script for automatic documentation deploy
1 parent 54d86f6 commit 3c2c294

2 files changed

Lines changed: 463 additions & 0 deletions

File tree

Lines changed: 245 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,245 @@
1+
# .github/actions/build-docc/action.yml
2+
name: 'Build DocC Documentation'
3+
description: 'Builds Swift DocC documentation for multiple products and platforms'
4+
5+
inputs:
6+
products:
7+
description: 'Comma-separated list of product names (e.g., "ValidatorCore,ValidatorUI")'
8+
required: true
9+
docc-paths:
10+
description: 'Comma-separated list of .docc paths (e.g., "Sources/ValidatorCore/Validator.docc,Sources/ValidatorUI/ValidatorUI.docc")'
11+
required: false
12+
default: ''
13+
bundle-identifier-prefix:
14+
description: 'Bundle identifier prefix (e.g., "dev.validator")'
15+
required: false
16+
default: 'dev.package'
17+
bundle-version:
18+
description: 'Bundle version for documentation'
19+
required: false
20+
default: '1.0.0'
21+
platforms:
22+
description: 'Comma-separated list of platforms to build for (e.g., "iOS,macOS,watchOS,tvOS,visionOS")'
23+
required: false
24+
default: 'iOS,macOS,watchOS,tvOS,visionOS'
25+
output-path:
26+
description: 'Output directory for generated documentation'
27+
required: false
28+
default: './docs'
29+
hosting-base-path:
30+
description: 'Base path for static hosting (leave empty for root)'
31+
required: false
32+
default: ''
33+
34+
runs:
35+
using: 'composite'
36+
steps:
37+
- name: Verify Schemes
38+
shell: bash
39+
run: |
40+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
41+
echo "Verifying available schemes"
42+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
43+
xcodebuild -list
44+
echo ""
45+
46+
IFS=',' read -ra PRODUCTS <<< "${{ inputs.products }}"
47+
for PRODUCT in "${PRODUCTS[@]}"; do
48+
if xcodebuild -list | grep -q "^\s*${PRODUCT}\s*$"; then
49+
echo "✓ Scheme '${PRODUCT}' found"
50+
else
51+
echo "✗ Scheme '${PRODUCT}' NOT FOUND"
52+
echo " Available schemes:"
53+
xcodebuild -list | grep -A 100 "Schemes:" | grep "^\s" | head -20
54+
exit 1
55+
fi
56+
done
57+
58+
- name: Setup Build Directories
59+
shell: bash
60+
run: |
61+
mkdir -p .build/symbol-graphs
62+
mkdir -p ${{ inputs.output-path }}
63+
64+
- name: Build Symbol Graphs
65+
shell: bash
66+
run: |
67+
IFS=',' read -ra PRODUCTS <<< "${{ inputs.products }}"
68+
IFS=',' read -ra PLATFORMS <<< "${{ inputs.platforms }}"
69+
70+
for PRODUCT in "${PRODUCTS[@]}"; do
71+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
72+
echo "Building symbol graphs for ${PRODUCT}"
73+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
74+
75+
for PLATFORM in "${PLATFORMS[@]}"; do
76+
echo "→ Platform: ${PLATFORM}"
77+
SYMBOL_DIR=".build/symbol-graphs/${PRODUCT}/${PLATFORM}"
78+
mkdir -p "${SYMBOL_DIR}"
79+
80+
xcodebuild build \
81+
-scheme "${PRODUCT}" \
82+
-destination "generic/platform=${PLATFORM}" \
83+
-derivedDataPath .deriveddata \
84+
DOCC_EXTRACT_EXTENSION_SYMBOLS=YES \
85+
OTHER_SWIFT_FLAGS="-Xfrontend -emit-symbol-graph -Xfrontend -emit-symbol-graph-dir -Xfrontend ${SYMBOL_DIR} -Xfrontend -emit-extension-block-symbols"
86+
87+
BUILD_STATUS=$?
88+
if [ $BUILD_STATUS -eq 0 ]; then
89+
echo "✓ ${PRODUCT} built successfully for ${PLATFORM}"
90+
echo " Symbol graphs in: ${SYMBOL_DIR}"
91+
ls -la "${SYMBOL_DIR}" || echo " (empty)"
92+
else
93+
echo "✗ ${PRODUCT} build failed for ${PLATFORM} (exit code: ${BUILD_STATUS})"
94+
fi
95+
done
96+
done
97+
98+
- name: Generate Documentation
99+
shell: bash
100+
run: |
101+
IFS=',' read -ra PRODUCTS <<< "${{ inputs.products }}"
102+
IFS=',' read -ra DOCC_PATHS <<< "${{ inputs.docc-paths }}"
103+
104+
for i in "${!PRODUCTS[@]}"; do
105+
PRODUCT="${PRODUCTS[$i]}"
106+
DOCC_PATH=""
107+
108+
if [ ${#DOCC_PATHS[@]} -gt $i ]; then
109+
DOCC_PATH="${DOCC_PATHS[$i]}"
110+
fi
111+
112+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
113+
echo "Generating documentation for ${PRODUCT}"
114+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
115+
116+
BUNDLE_ID="${{ inputs.bundle-identifier-prefix }}.${PRODUCT}"
117+
SYMBOL_GRAPHS_DIR=".build/symbol-graphs/${PRODUCT}"
118+
119+
# Check if symbol graphs exist
120+
if [ -d "${SYMBOL_GRAPHS_DIR}" ]; then
121+
SYMBOL_COUNT=$(find "${SYMBOL_GRAPHS_DIR}" -name "*.symbols.json" | wc -l)
122+
echo "Found ${SYMBOL_COUNT} symbol graph files"
123+
if [ $SYMBOL_COUNT -eq 0 ]; then
124+
echo "⚠ Warning: No symbol graphs found for ${PRODUCT}"
125+
echo " This usually means the build failed or there's no public API"
126+
fi
127+
else
128+
echo "⚠ Warning: Symbol graphs directory not found: ${SYMBOL_GRAPHS_DIR}"
129+
fi
130+
131+
if [ -n "${DOCC_PATH}" ] && [ -d "${DOCC_PATH}" ]; then
132+
echo "Using .docc catalog: ${DOCC_PATH}"
133+
$(xcrun --find docc) convert "${DOCC_PATH}" \
134+
--fallback-display-name "${PRODUCT}" \
135+
--fallback-bundle-identifier "${BUNDLE_ID}" \
136+
--fallback-bundle-version "${{ inputs.bundle-version }}" \
137+
--output-dir "${PRODUCT}.doccarchive" \
138+
--additional-symbol-graph-dir "${SYMBOL_GRAPHS_DIR}"
139+
else
140+
echo "⚠ .docc catalog not found at: ${DOCC_PATH}"
141+
echo "Generating from symbol graphs only"
142+
143+
if [ ! -d "${SYMBOL_GRAPHS_DIR}" ] || [ $(find "${SYMBOL_GRAPHS_DIR}" -name "*.symbols.json" | wc -l) -eq 0 ]; then
144+
echo "✗ Error: Cannot generate documentation without .docc catalog or symbol graphs"
145+
continue
146+
fi
147+
148+
$(xcrun --find docc) convert \
149+
--fallback-display-name "${PRODUCT}" \
150+
--fallback-bundle-identifier "${BUNDLE_ID}" \
151+
--fallback-bundle-version "${{ inputs.bundle-version }}" \
152+
--output-dir "${PRODUCT}.doccarchive" \
153+
--additional-symbol-graph-dir "${SYMBOL_GRAPHS_DIR}"
154+
fi
155+
156+
DOCC_STATUS=$?
157+
if [ $DOCC_STATUS -ne 0 ]; then
158+
echo "✗ Failed to generate documentation for ${PRODUCT}"
159+
continue
160+
fi
161+
162+
# Check if .doccarchive was created
163+
if [ ! -d "${PRODUCT}.doccarchive" ]; then
164+
echo "✗ Error: ${PRODUCT}.doccarchive was not created"
165+
continue
166+
fi
167+
168+
echo "✓ Documentation archive created"
169+
170+
# Transform for static hosting
171+
if [ -n "${{ inputs.hosting-base-path }}" ]; then
172+
BASE_PATH="${{ inputs.hosting-base-path }}/${PRODUCT}"
173+
else
174+
BASE_PATH="${PRODUCT}"
175+
fi
176+
177+
echo "Transforming for static hosting with base path: ${BASE_PATH}"
178+
179+
$(xcrun --find docc) process-archive transform-for-static-hosting \
180+
"${PRODUCT}.doccarchive" \
181+
--output-path "${{ inputs.output-path }}/${PRODUCT}" \
182+
--hosting-base-path "${BASE_PATH}"
183+
184+
TRANSFORM_STATUS=$?
185+
if [ $TRANSFORM_STATUS -eq 0 ]; then
186+
echo "✓ ${PRODUCT} documentation generated successfully"
187+
echo " Output: ${{ inputs.output-path }}/${PRODUCT}"
188+
ls -la "${{ inputs.output-path }}/${PRODUCT}" | head -10
189+
else
190+
echo "✗ Failed to transform ${PRODUCT} for static hosting"
191+
fi
192+
done
193+
194+
- name: Verify Generated Documentation
195+
shell: bash
196+
run: |
197+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
198+
echo "Verifying generated documentation structure"
199+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
200+
201+
IFS=',' read -ra PRODUCTS <<< "${{ inputs.products }}"
202+
203+
for PRODUCT in "${PRODUCTS[@]}"; do
204+
DOCS_DIR="${{ inputs.output-path }}/${PRODUCT}"
205+
206+
if [ ! -d "${DOCS_DIR}" ]; then
207+
echo "✗ Documentation directory not found: ${DOCS_DIR}"
208+
continue
209+
fi
210+
211+
echo "Checking ${PRODUCT}:"
212+
213+
# Check for essential files
214+
if [ -f "${DOCS_DIR}/index.html" ]; then
215+
echo " ✓ index.html exists"
216+
else
217+
echo " ✗ index.html MISSING"
218+
fi
219+
220+
if [ -d "${DOCS_DIR}/documentation" ]; then
221+
echo " ✓ documentation/ directory exists"
222+
DOC_COUNT=$(find "${DOCS_DIR}/documentation" -name "*.html" | wc -l)
223+
echo " Found ${DOC_COUNT} HTML documentation pages"
224+
else
225+
echo " ✗ documentation/ directory MISSING"
226+
fi
227+
228+
if [ -d "${DOCS_DIR}/data" ]; then
229+
echo " ✓ data/ directory exists"
230+
JSON_COUNT=$(find "${DOCS_DIR}/data" -name "*.json" | wc -l)
231+
echo " Found ${JSON_COUNT} JSON data files"
232+
else
233+
echo " ✗ data/ directory MISSING"
234+
fi
235+
236+
echo ""
237+
done
238+
239+
- name: Cleanup Build Artifacts
240+
shell: bash
241+
if: always()
242+
run: |
243+
rm -rf .deriveddata
244+
rm -rf .build
245+
rm -rf *.doccarchive

0 commit comments

Comments
 (0)