Skip to content

Commit fbe24ed

Browse files
authored
Fail the build when documentation content fails to compile (#122)
compile-content.tsx never checked the git clone exit status. A failed clone of documentdb/docs left the copy loop with nothing to copy, and the site would build and deploy successfully with empty /docs and /docs/reference sections - a silent, total documentation outage. - The clone now fails the build with the git stderr on a non-zero exit. - A mapping whose source folder is missing from the cloned repository (layout change upstream) fails with a pointed message. - A mapping that matches zero files fails instead of shipping an empty section. - The deploy workflow gains an independent artifact check before upload: key pages must exist in out/ and at least 100 reference pages must have been exported (the docs repo currently holds ~240 reference entries). Also anchors the api-reference/ and reference/ gitignore patterns to the repo root so they can no longer swallow tracked paths like app/docs/reference/ (verified with git check-ignore before and after).
1 parent 30266dc commit fbe24ed

3 files changed

Lines changed: 55 additions & 5 deletions

File tree

‎.github/workflows/continuous-deployment.yml‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,26 @@ jobs:
8787
env:
8888
JEKYLL_BASE_PATH: /blogs
8989
run: npm run build
90+
- name: Verify exported documentation pages
91+
# A partially failed content compile must never reach production as a
92+
# docs-less site. compile-content fails the build on clone/copy errors;
93+
# this is the independent belt-and-braces check on the final artifact.
94+
run: |
95+
set -euo pipefail
96+
for page in out/index.html out/docs/index.html out/docs/getting-started/index.html out/docs/reference/index.html; do
97+
if [ ! -f "$page" ]; then
98+
echo "Missing expected page: $page"
99+
exit 1
100+
fi
101+
done
102+
reference_count=$(find out/docs/reference -name index.html | wc -l)
103+
echo "Reference pages exported: $reference_count"
104+
# The docs repo currently holds ~240 reference entries; well under
105+
# half of that means the compile silently lost content.
106+
if [ "$reference_count" -lt 100 ]; then
107+
echo "Only $reference_count reference pages exported - documentation content looks incomplete."
108+
exit 1
109+
fi
90110
- name: Download DocumentDB packages from latest release
91111
run: .github/scripts/download_packages.sh
92112
- name: Verify generated package components

‎.gitignore‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@
44
# Temporary content cloning directory
55
_tmp/
66

7-
# Reference files
8-
api-reference/
9-
reference/
7+
# Reference files (compiled into the repo root from documentdb/docs; anchored
8+
# so the patterns cannot swallow tracked paths like app/docs/reference/)
9+
/api-reference/
10+
/reference/
1011

1112
# Documentation articles
1213
articles/*/

‎scripts/compile-content.tsx‎

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,22 +180,45 @@ async function cloneContent(
180180
const repoName = source.repository.split('/').pop() || 'repo';
181181
const cloneDir = path.join(TEMP_DIR, repoName);
182182

183-
// Clone the repository
184-
spawnSync(
183+
// Clone the repository. A failed clone must fail the build: the copy
184+
// loop below finds nothing to copy and the site would otherwise deploy
185+
// with empty documentation and reference sections.
186+
const cloneResult = spawnSync(
185187
'git',
186188
['clone', '--depth', '1', '--branch', source.branch, source.repository, cloneDir],
187189
{ stdio: 'pipe' }
188190
);
189191

192+
if (cloneResult.error) {
193+
throw new Error(
194+
`git clone failed for ${source.repository}: ${cloneResult.error.message}`
195+
);
196+
}
197+
198+
if (cloneResult.status !== 0) {
199+
const stderr = cloneResult.stderr?.toString().trim();
200+
throw new Error(
201+
`git clone failed for ${source.repository} (branch ${source.branch}): ${stderr || `exit code ${cloneResult.status}`}`
202+
);
203+
}
204+
190205
// Process each mapping
191206
for (const mapping of source.mappings) {
192207
const sourceDir = path.join(cloneDir, mapping.source);
193208
const targetDir = path.join(process.cwd(), mapping.target);
194209

210+
if (!fs.existsSync(sourceDir)) {
211+
throw new Error(
212+
`Source folder "${mapping.source}" does not exist in ${source.repository}; the repository layout may have changed.`
213+
);
214+
}
215+
195216
// Clean target directory
196217
cleanDirectory(targetDir);
197218
ensureDirectory(targetDir);
198219

220+
const copiedBefore = tracker.getCopiedFiles().length;
221+
199222
// Copy files with filtering
200223
copyFilesRecursive(
201224
sourceDir,
@@ -205,6 +228,12 @@ async function cloneContent(
205228
tracker,
206229
source.repository
207230
);
231+
232+
if (tracker.getCopiedFiles().length === copiedBefore) {
233+
throw new Error(
234+
`No files matched for mapping "${mapping.source}" -> "${mapping.target}" from ${source.repository}; refusing to build with empty documentation content.`
235+
);
236+
}
208237
}
209238
}
210239

0 commit comments

Comments
 (0)