Skip to content

Commit a988b90

Browse files
committed
ci: Transfer symbol graphs (instead of archives), use same docc for all targets
This should hopefully address some annoying issues where the documentation for each target behaved a bit differently due to being compiled with different docc versions. The new approach uploads/downloads symbol graphs instead of built documentation and compiles all of the documentation archives using the latest Xcode version on the same macOS 15 runner.
1 parent afecbb4 commit a988b90

File tree

3 files changed

+222
-139
lines changed

3 files changed

+222
-139
lines changed

.github/actions/compile-docs/action.yml

Lines changed: 65 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,40 @@ inputs:
44
target:
55
description: 'Target to compile documentation for'
66
required: true
7-
upload:
8-
# Assumed false if omitted. We could supply the 'default' field, but it doesn't take
9-
# effect when this composite action is called from a workflow, so it would just be
10-
# misleading.
11-
description: 'Whether to upload the documentation as an artifact or not'
12-
xcodebuild:
13-
# Assumed false if omitted
14-
description: 'Whether to use xcodebuild instead of SwiftPM or not'
15-
xcodebuild-device-type:
16-
# Assumed 'Mac' if omitted
17-
description: 'The device type to compile docs for when using xcodebuild (e.g. iPhone, iPad or TV)'
7+
use-swiftpm:
8+
description: 'If true, use SwiftPM to compile documentation'
9+
symbol-graph-dir:
10+
# If use-swiftpm is false, then you must provide this or use-symbol-graph-artifact
11+
description: 'Directory containing extracted symbol graphs'
12+
use-symbol-graph-artifact:
13+
# If use-swiftpm is false, then you must provide this or symbol-graph-dir
14+
description: 'If true, download symbol graphs from the [target]-symbol-graphs artifact'
15+
docc-catalog:
16+
# If not provided, a dummy catalog is created.
17+
description: 'DocC catalog containing DocC articles etc'
18+
1819
runs:
1920
using: "composite"
2021
steps:
22+
- name: Reject invalid inputs
23+
if: ${{ (inputs.use-swiftpm == 'true' && (inputs.symbol-graph-dir != '' || inputs.use-symbol-graph-artifact == 'true' || inputs.docc-catalog != '')) || ((inputs.symbol-graph-dir != '') == (inputs.use-symbol-graph-artifact == 'true')) }}
24+
run: |
25+
echo "target: $TARGET"
26+
echo "use-swiftpm: $USE_SWIFTPM"
27+
echo "symbol-graph-dir: $SYMBOL_GRAPH_DIR"
28+
echo "use-symbol-graph-artifact: $USE_SYMBOL_GRAPH_ARTIFACT"
29+
echo "docc-catalog: $DOCC_CATALOG"
30+
exit 1
31+
shell: bash
32+
env:
33+
TARGET: ${{ inputs.target }}
34+
USE_SWIFTPM: ${{ inputs.use-swiftpm }}
35+
SYMBOL_GRAPH_DIR: ${{ inputs.symbol-graph-dir }}
36+
USE_SYMBOL_GRAPH_ARTIFACT: ${{ inputs.use-symbol-graph-artifact }}
37+
DOCC_CATALOG: ${{ inputs.docc-catalog }}
38+
2139
- name: Compile documentation (with SwiftPM)
22-
if: ${{ inputs.xcodebuild != 'true' }} # Compare to constant to treat empty input as false
40+
if: ${{ inputs.use-swiftpm == 'true' }} # Compare to constant to treat empty input as false
2341
run: |
2442
set -ex
2543
mkdir "$TARGET.doccarchive" && \
@@ -39,35 +57,42 @@ runs:
3957
env:
4058
TARGET: ${{ inputs.target }}
4159

42-
- name: Compile documentation (with xcodebuild)
43-
if: ${{ inputs.xcodebuild == 'true' }} # Compare to constant to treat empty input as false
44-
run: |
45-
set -ex
46-
destination=""
47-
if [[ $DEVICE_TYPE == "Mac" ]] || [[ $DEVICE_TYPE == "" ]]; then
48-
destination="platform=OS X"
49-
else
50-
destination="id=$(xcrun simctl list devices $devicetype available | grep -v -- -- | tail -n 1 | grep -oE '[0-9A-F\-]{36}')"
51-
fi
52-
echo "$DEVICE_TYPE"
53-
echo "Building documentation for destination '$destination'"
54-
xcodebuild -skipMacroValidation -scheme "$TARGET" -destination "$destination" -derivedDataPath /tmp/data docbuild | xcbeautify --renderer github-actions
55-
cp -R $(find /tmp/data -name "$TARGET.doccarchive") "$TARGET.doccarchive"
56-
shell: bash
57-
env:
58-
TARGET: ${{ inputs.target }}
59-
DEVICE_TYPE: ${{ inputs.xcodebuild-device-type }}
60+
- name: Download symbol graphs (from artifact)
61+
if: ${{ inputs.use-symbol-graph-artifact == 'true' }}
62+
uses: actions/download-artifact@v4
63+
with:
64+
name: ${{ inputs.target }}-symbol-graphs.tar.gz
6065

61-
- name: Compress DocC archive
66+
- name: Extract symbol graphs artifact
67+
if: ${{ inputs.use-symbol-graph-artifact == 'true' }}
6268
uses: a7ul/tar-action@v1.1.0
6369
with:
64-
command: c
65-
files: ./${{ inputs.target }}.doccarchive
66-
outPath: ${{ inputs.target }}.doccarchive.tar.gz
70+
command: x
71+
files: ./${{ inputs.target }}-symbol-graphs.tar.gz
6772

68-
- name: Upload DocC archive
69-
uses: actions/upload-artifact@v4
70-
if: ${{ inputs.upload == 'true' }} # Compare to constant to treat empty input as false
71-
with:
72-
name: ${{ inputs.target }}.doccarchive.tar.gz
73-
path: ${{ inputs.target }}.doccarchive.tar.gz
73+
- name: Compile documentation (with DocC)
74+
if: ${{ inputs.use-swiftpm != 'true' }}
75+
shell: bash
76+
run: |
77+
set -eux
78+
catalog="$DOCC_CATALOG"
79+
if [[ catalog == "" ]]; then
80+
catalog="$TARGET.docc"
81+
mkdir "$catalog"
82+
fi
83+
symbol_graph_dir="$SYMBOL_GRAPH_DIR"
84+
if [[ symbol_graphs_dir == "" ]]; then
85+
symbol_graph_dir="$TARGET-symbol-graphs"
86+
fi
87+
xcrun docc convert "$catalog" \
88+
--additional-symbol-graph-dir $symbol_graph_dir \
89+
--transform-for-static-hosting \
90+
--hosting-base-path swift-cross-ui \
91+
--output-path "$TARGET.doccarchive" \
92+
--source-service github \
93+
--source-service-base-url https://github.com/stackotter/swift-cross-ui/blob/main \
94+
--checkout-path .
95+
env:
96+
TARGET: ${{ inputs.target }}
97+
DOCC_CATALOG: ${{ inputs.docc-catalog }}
98+
SYMBOL_GRAPH_DIR: ${{ inputs.symbol-graph-dir }}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
name: Extract symbol graphs
2+
description: 'A reusable fragment that extract Swift symbol graphs and optionally uploads them as artifacts'
3+
inputs:
4+
target:
5+
description: 'Target to compile documentation for'
6+
required: true
7+
upload:
8+
# Assumed false if omitted. We could supply the 'default' field, but it doesn't take
9+
# effect when this composite action is called from a workflow, so it would just be
10+
# misleading.
11+
description: 'Whether to upload the documentation as an artifact or not'
12+
xcodebuild:
13+
# Assumed false if omitted
14+
description: 'Whether to use xcodebuild instead of SwiftPM or not'
15+
xcodebuild-device-type:
16+
# Assumed 'Mac' if omitted
17+
description: 'The device type to compile docs for when using xcodebuild (e.g. iPhone, iPad or TV)'
18+
working-directory:
19+
description: 'Root directory of package to extract symbol graphs from'
20+
21+
runs:
22+
using: "composite"
23+
steps:
24+
- name: Extract symbol graphs (with SwiftPM)
25+
if: ${{ inputs.xcodebuild != 'true' }} # Compare to constant to treat empty input as false
26+
run: |
27+
set -eux
28+
mkdir symbol-graphs
29+
swift build --target "$TARGET" \
30+
-Xswiftc -emit-symbol-graph \
31+
-Xswiftc -emit-symbol-graph-dir -Xswiftc symbol-graphs
32+
33+
# Locate relevant symbol graphs and copy them to the target-specific
34+
# output directory
35+
mkdir "$TARGET-symbol-graphs"
36+
find symbol-graphs -name "$TARGET*.symbols.json" -exec cp {} $TARGET-symbol-graphs ';'
37+
shell: bash
38+
working-directory: ${{ inputs.working-directory }}
39+
env:
40+
TARGET: ${{ inputs.target }}
41+
42+
- name: Extract symbol graphs (with xcodebuild)
43+
if: ${{ inputs.xcodebuild == 'true' }} # Compare to constant to treat empty input as false
44+
run: |
45+
set -ex
46+
destination=""
47+
if [[ $DEVICE_TYPE == "Mac" ]] || [[ $DEVICE_TYPE == "" ]]; then
48+
destination="platform=OS X"
49+
else
50+
destination="id=$(xcrun simctl list devices $devicetype available | grep -v -- -- | tail -n 1 | grep -oE '[0-9A-F\-]{36}')"
51+
fi
52+
53+
# I've found that the most reliable way to produce symbol graphs with
54+
# xcodebuild is to just ask it to do a documentation build. This takes
55+
# longer than just emitting symbol graphs while building cause it compiles
56+
# the documentation as well, but I haven't figured out how to get it to do
57+
# so.
58+
xcodebuild -skipMacroValidation -scheme "$TARGET" -destination "$destination" \
59+
-derivedDataPath /tmp/data docbuild \
60+
"OTHER_DOCC_FLAGS=--transform-for-static-hosting --hosting-base-path swift-cross-ui --source-service github --source-service-base-url https://github.com/stackotter/swift-cross-ui/blob/main --checkout-path ." \
61+
| xcbeautify --renderer github-actions
62+
63+
# Locate relevant symbol graphs and copy them to the target-specific
64+
# output directory
65+
mkdir "$TARGET-symbol-graphs"
66+
find /tmp/data -name "$TARGET*.symbols.json" -exec cp {} $TARGET-symbol-graphs ';'
67+
shell: bash
68+
working-directory: ${{ inputs.working-directory }}
69+
env:
70+
TARGET: ${{ inputs.target }}
71+
DEVICE_TYPE: ${{ inputs.xcodebuild-device-type }}
72+
73+
- name: Compress symbol graphs
74+
uses: a7ul/tar-action@v1.1.0
75+
with:
76+
command: c
77+
files: ./${{ inputs.working-directory }}/${{ inputs.target }}-symbol-graphs
78+
outPath: ${{ inputs.target }}-symbol-graphs.tar.gz
79+
80+
- name: Upload symbol graphs
81+
uses: actions/upload-artifact@v4
82+
if: ${{ inputs.upload == 'true' }} # Compare to constant to treat empty input as false
83+
with:
84+
name: ${{ inputs.target }}-symbol-graphs.tar.gz
85+
path: ${{ inputs.target }}-symbol-graphs.tar.gz

0 commit comments

Comments
 (0)