Skip to content

Commit cbb321b

Browse files
DeveloperAllyclaude
andcommitted
fix(workflow): repair sync-large-assets — heredoc-in-YAML parse bug
The workflow has never successfully run since it was added. Root cause: bash heredocs (<<EOF, <<MANIFEST) inside a YAML | block put content at column 0, which breaks GitHub Actions' YAML parser. Every run failed at parse time with 0s duration. Fixes: - Replace all heredocs with printf/echo (the actual parse fix) - Lower threshold from 20MB to 1MB (catches all 10 binary files, not just 1) - Add weekly cron schedule (Sunday midnight UTC) - Add paths filter so push trigger only fires on asset changes - Explicit branch list (docs-v2, docs-v2-dev) replaces wildcard + if condition - Move input resolution to a separate step to avoid || '' expression pattern Ref: #849 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent de6026f commit cbb321b

File tree

1 file changed

+89
-70
lines changed

1 file changed

+89
-70
lines changed
Lines changed: 89 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,25 @@
1-
name: Sync Large Assets
1+
name: "Sync Large Assets"
22

33
on:
44
push:
55
branches:
66
- docs-v2
7+
- docs-v2-dev
8+
paths:
9+
- "snippets/assets/**"
10+
- "v2/assets/**"
11+
schedule:
12+
- cron: "0 0 * * 0"
713
workflow_dispatch:
814
inputs:
915
target_branch:
1016
description: "Branch that stores large published assets"
1117
required: false
1218
default: "docs-v2-assets"
1319
threshold_mb:
14-
description: "File size threshold in MB"
20+
description: "File size threshold in MB (default 1)"
1521
required: false
16-
default: "20"
22+
default: "1"
1723

1824
permissions:
1925
contents: write
@@ -22,122 +28,135 @@ jobs:
2228
sync-large-assets:
2329
runs-on: ubuntu-latest
2430
env:
25-
DEFAULT_TARGET_BRANCH: docs-v2-assets
26-
DEFAULT_THRESHOLD_MB: "20"
31+
TARGET_BRANCH: "docs-v2-assets"
32+
THRESHOLD_MB: "1"
2733
steps:
2834
- name: Checkout source branch
2935
uses: actions/checkout@v4
3036
with:
3137
fetch-depth: 0
3238

39+
- name: Resolve inputs
40+
id: config
41+
run: |
42+
if [ -n "${{ inputs.target_branch }}" ]; then
43+
echo "target=${{ inputs.target_branch }}" >> "$GITHUB_OUTPUT"
44+
else
45+
echo "target=${{ env.TARGET_BRANCH }}" >> "$GITHUB_OUTPUT"
46+
fi
47+
if [ -n "${{ inputs.threshold_mb }}" ]; then
48+
echo "threshold=${{ inputs.threshold_mb }}" >> "$GITHUB_OUTPUT"
49+
else
50+
echo "threshold=${{ env.THRESHOLD_MB }}" >> "$GITHUB_OUTPUT"
51+
fi
52+
3353
- name: Sync large assets to target branch
3454
shell: bash
55+
env:
56+
RESOLVED_TARGET: ${{ steps.config.outputs.target }}
57+
RESOLVED_THRESHOLD: ${{ steps.config.outputs.threshold }}
3558
run: |
3659
set -euo pipefail
3760
3861
SOURCE_SHA="${GITHUB_SHA}"
3962
SOURCE_REF="${GITHUB_REF_NAME}"
40-
41-
TARGET_BRANCH="${{ github.event.inputs.target_branch || '' }}"
42-
if [ -z "$TARGET_BRANCH" ]; then
43-
TARGET_BRANCH="$DEFAULT_TARGET_BRANCH"
44-
fi
45-
46-
THRESHOLD_MB="${{ github.event.inputs.threshold_mb || '' }}"
47-
if [ -z "$THRESHOLD_MB" ]; then
48-
THRESHOLD_MB="$DEFAULT_THRESHOLD_MB"
49-
fi
63+
TARGET_BRANCH="${RESOLVED_TARGET}"
64+
THRESHOLD_MB="${RESOLVED_THRESHOLD}"
5065
5166
if ! [[ "$THRESHOLD_MB" =~ ^[0-9]+$ ]]; then
52-
echo "threshold_mb must be an integer"
67+
echo "::error::threshold_mb must be an integer, got: $THRESHOLD_MB"
5368
exit 1
5469
fi
5570
5671
THRESHOLD_BYTES=$((THRESHOLD_MB * 1024 * 1024))
5772
73+
echo "::group::Configuration"
5874
echo "Source branch: $SOURCE_REF"
59-
echo "Source SHA: $SOURCE_SHA"
75+
echo "Source SHA: $SOURCE_SHA"
6076
echo "Target branch: $TARGET_BRANCH"
61-
echo "Threshold: ${THRESHOLD_MB}MB (${THRESHOLD_BYTES} bytes)"
77+
echo "Threshold: ${THRESHOLD_MB} MB (${THRESHOLD_BYTES} bytes)"
78+
echo "::endgroup::"
6279
6380
git config user.name "github-actions[bot]"
6481
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
6582
66-
git fetch origin "$TARGET_BRANCH" || true
83+
git fetch origin "$TARGET_BRANCH" 2>/dev/null || true
6784
6885
WORKTREE_DIR="../_assets-branch"
6986
rm -rf "$WORKTREE_DIR"
7087
7188
if git show-ref --verify --quiet "refs/remotes/origin/$TARGET_BRANCH"; then
7289
git worktree add -B "$TARGET_BRANCH" "$WORKTREE_DIR" "origin/$TARGET_BRANCH"
7390
else
91+
echo "Target branch $TARGET_BRANCH does not exist — creating it."
7492
git worktree add -b "$TARGET_BRANCH" "$WORKTREE_DIR"
75-
(
76-
cd "$WORKTREE_DIR"
77-
: > .nojekyll
78-
mkdir -p .github
79-
cat > .github/README.md <<'EOF'
80-
This branch is auto-managed by .github/workflows/sync-large-assets.yml.
81-
It stores large asset files mirrored from docs-v2 for static hosting.
82-
EOF
83-
git add .nojekyll .github/README.md
84-
git commit -m "Initialize large-assets branch"
85-
git push -u origin "$TARGET_BRANCH"
86-
)
93+
pushd "$WORKTREE_DIR" > /dev/null
94+
printf '' > .nojekyll
95+
mkdir -p .github
96+
echo "Auto-managed by sync-large-assets.yml. Stores large asset files for static hosting." > .github/README.md
97+
git add .nojekyll .github/README.md
98+
git commit -m "chore: initialise large-assets branch"
99+
git push -u origin "$TARGET_BRANCH"
100+
popd > /dev/null
87101
fi
88102
89-
LARGE_LIST_FILE="$(mktemp)"
103+
# Build list of files exceeding threshold
104+
LARGE_LIST="$(mktemp)"
105+
file_count=0
90106
91107
while IFS= read -r file; do
92108
[ -z "$file" ] && continue
93109
size=$(wc -c < "$file")
94110
if [ "$size" -gt "$THRESHOLD_BYTES" ]; then
95-
echo "$file" >> "$LARGE_LIST_FILE"
111+
echo "$file" >> "$LARGE_LIST"
112+
file_count=$((file_count + 1))
96113
fi
97114
done < <(git ls-files 'snippets/assets/**' 'v2/assets/**')
98115
99-
sort -u "$LARGE_LIST_FILE" -o "$LARGE_LIST_FILE"
116+
sort -u "$LARGE_LIST" -o "$LARGE_LIST"
100117
101-
echo "Large assets selected:"
102-
if [ -s "$LARGE_LIST_FILE" ]; then
103-
cat "$LARGE_LIST_FILE"
118+
echo "::group::Large assets selected ($file_count files)"
119+
if [ -s "$LARGE_LIST" ]; then
120+
cat "$LARGE_LIST"
104121
else
105-
echo "(none)"
122+
echo "(none — no files exceed ${THRESHOLD_MB} MB)"
106123
fi
124+
echo "::endgroup::"
107125
108-
(
109-
cd "$WORKTREE_DIR"
126+
# Sync to target branch
127+
pushd "$WORKTREE_DIR" > /dev/null
110128
111-
# Remove previously tracked mirrored assets not present in latest selection.
112-
while IFS= read -r tracked; do
113-
[ -z "$tracked" ] && continue
114-
if ! grep -Fxq "$tracked" "$LARGE_LIST_FILE"; then
115-
rm -f "$tracked"
116-
fi
117-
done < <(git ls-files 'snippets/assets/**' 'v2/assets/**')
129+
# Remove previously tracked assets no longer in the selection
130+
while IFS= read -r tracked; do
131+
[ -z "$tracked" ] && continue
132+
if ! grep -Fxq "$tracked" "$LARGE_LIST"; then
133+
rm -f "$tracked"
134+
fi
135+
done < <(git ls-files 'snippets/assets/**' 'v2/assets/**')
118136
119-
# Copy current large assets from source checkout.
120-
while IFS= read -r file; do
121-
[ -z "$file" ] && continue
122-
mkdir -p "$(dirname "$file")"
123-
cp -f "${GITHUB_WORKSPACE}/$file" "$file"
124-
done < "$LARGE_LIST_FILE"
137+
# Copy selected large assets from source checkout
138+
while IFS= read -r file; do
139+
[ -z "$file" ] && continue
140+
mkdir -p "$(dirname "$file")"
141+
cp -f "${GITHUB_WORKSPACE}/$file" "$file"
142+
done < "$LARGE_LIST"
143+
144+
# Write manifest
145+
mkdir -p .github
146+
printf 'source_branch=%s\nsource_sha=%s\nthreshold_mb=%s\nfile_count=%s\ngenerated_at=%s\n' \
147+
"$SOURCE_REF" "$SOURCE_SHA" "$THRESHOLD_MB" "$file_count" \
148+
"$(date -u +'%Y-%m-%dT%H:%M:%SZ')" \
149+
> .github/assets-manifest.txt
150+
151+
git add -A snippets/assets v2/assets .nojekyll .github/assets-manifest.txt .github/README.md
152+
153+
if git diff --cached --quiet; then
154+
echo "No large-asset changes to commit."
155+
exit 0
156+
fi
125157
126-
mkdir -p .github
127-
cat > .github/assets-manifest.txt <<EOF
128-
source_branch=$SOURCE_REF
129-
source_sha=$SOURCE_SHA
130-
threshold_mb=$THRESHOLD_MB
131-
generated_at=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
132-
EOF
133-
134-
git add -A snippets/assets v2/assets .nojekyll .github/assets-manifest.txt .github/README.md
135-
136-
if git diff --cached --quiet; then
137-
echo "No large-asset changes to commit."
138-
exit 0
139-
fi
158+
git commit -m "chore(assets): sync from ${SOURCE_REF}@${SOURCE_SHA:0:7}"
159+
git push origin "$TARGET_BRANCH"
160+
echo "::notice::Synced $file_count assets to $TARGET_BRANCH"
140161
141-
git commit -m "Sync large assets from ${SOURCE_REF}@${SOURCE_SHA}"
142-
git push origin "$TARGET_BRANCH"
143-
)
162+
popd > /dev/null

0 commit comments

Comments
 (0)