Skip to content

Commit ba004c3

Browse files
committed
Add the strict Clay publication gate
1 parent fa1ed5d commit ba004c3

5 files changed

Lines changed: 105 additions & 1 deletion

File tree

.github/workflows/render-and-publish.yml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
on:
2+
pull_request:
3+
branches:
4+
- main
25
push:
36
branches:
47
- main
@@ -49,8 +52,11 @@ jobs:
4952
key: cljdeps-${{ hashFiles('deps.edn') }}
5053
restore-keys: cljdeps-
5154

55+
- name: Test strict Clay failure detection
56+
run: scripts/test-render-clay-strict.sh
57+
5258
- name: Build the content notebooks
53-
run: clojure -M:clay -A:markdown
59+
run: scripts/render-clay-strict.sh
5460

5561
- name: Install lsof and apt prerequisites for Janqua
5662
run: sudo apt-get update && sudo apt-get install -y lsof gnupg lsb-release
@@ -91,6 +97,7 @@ jobs:
9197
path: site/_site
9298

9399
deploy:
100+
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
94101
needs: build
95102
permissions:
96103
pages: write

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,13 @@ Goal: Minimize friction in authoring while ensuring publishable reproducibility.
310310

311311
The site is built and deployed using GitHub Actions with two workflows:
312312

313+
Before opening a pull request, run `scripts/pre-publish-gate.sh` from the
314+
repository root. The same strict Clay renderer is used locally and in the full
315+
GitHub Pages workflow. It requires Java 21, uses the runner's 1 MiB JVM thread
316+
stack, fails when any source prints `Clay FAILED:`, then renders the full site
317+
with Quarto. `scripts/test-render-clay-strict.sh` reproduces the historical
318+
stack-overflow signal and checks that CI rejects it with an error annotation.
319+
313320
- **Full Build and Publish**: Triggered on pushes to `main`.
314321
Rebuilds all notebooks with Clay, renders the entire site with Quarto, and deploys to GitHub Pages.
315322
See [.github/workflows/render-and-publish.yml](.github/workflows/render-and-publish.yml).

scripts/pre-publish-gate.sh

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#!/usr/bin/env bash
2+
3+
set -euo pipefail
4+
5+
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
6+
cd "$repo_root"
7+
8+
scripts/render-clay-strict.sh
9+
quarto render site

scripts/render-clay-strict.sh

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#!/usr/bin/env bash
2+
3+
set -euo pipefail
4+
5+
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
6+
cd "$repo_root"
7+
8+
java_version="$({ java -XshowSettings:properties -version; } 2>&1 \
9+
| awk -F= '/java.specification.version/ {gsub(/[[:space:]]/, "", $2); print $2; exit}')"
10+
if [[ "$java_version" != "21" ]]; then
11+
echo "Expected Java 21 to match GitHub Pages, found Java ${java_version:-unknown}." >&2
12+
exit 1
13+
fi
14+
15+
# GitHub's Ubuntu runner uses a 1 MiB JVM thread stack. macOS commonly uses
16+
# 2 MiB, which can hide recursive parser/regex failures until publication.
17+
export JAVA_TOOL_OPTIONS="${JAVA_TOOL_OPTIONS:+${JAVA_TOOL_OPTIONS} }-Xss1m"
18+
19+
log_file="$(mktemp "${TMPDIR:-/tmp}/clay-render.XXXXXX.log")"
20+
trap 'rm -f "$log_file"' EXIT
21+
22+
set +e
23+
clojure -M:clay -A:markdown "$@" 2>&1 | tee "$log_file"
24+
clay_status="${PIPESTATUS[0]}"
25+
set -e
26+
27+
if [[ "$clay_status" -ne 0 ]]; then
28+
exit "$clay_status"
29+
fi
30+
31+
# Clay reports individual source failures but can still return success.
32+
if grep -q 'Clay FAILED:' "$log_file"; then
33+
echo "Clay reported source failures despite exiting successfully:" >&2
34+
grep 'Clay FAILED:' "$log_file" >&2
35+
if [[ "${GITHUB_ACTIONS:-}" == "true" ]]; then
36+
while IFS= read -r failure; do
37+
echo "::error title=Clay source render failed::${failure}" >&2
38+
done < <(grep 'Clay FAILED:' "$log_file")
39+
fi
40+
exit 1
41+
fi

scripts/test-render-clay-strict.sh

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#!/usr/bin/env bash
2+
3+
set -euo pipefail
4+
5+
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
6+
fixture_bin="$(mktemp -d "${TMPDIR:-/tmp}/clay-strict-fixture.XXXXXX")"
7+
output_file="$(mktemp "${TMPDIR:-/tmp}/clay-strict-output.XXXXXX.log")"
8+
trap 'rm -rf "$fixture_bin"; rm -f "$output_file"' EXIT
9+
10+
cat >"$fixture_bin/java" <<'EOF'
11+
#!/usr/bin/env bash
12+
echo ' java.specification.version = 21' >&2
13+
EOF
14+
15+
cat >"$fixture_bin/clojure" <<'EOF'
16+
#!/usr/bin/env bash
17+
echo 'Clay FAILED: src/language_learning/vocabulary_estimation/beta_binomial_first_pass.clj'
18+
echo 'java.lang.StackOverflowError'
19+
exit 0
20+
EOF
21+
22+
chmod +x "$fixture_bin/java" "$fixture_bin/clojure"
23+
24+
set +e
25+
GITHUB_ACTIONS=true PATH="$fixture_bin:$PATH" \
26+
"$repo_root/scripts/render-clay-strict.sh" >"$output_file" 2>&1
27+
result_status=$?
28+
set -e
29+
30+
if [[ "$result_status" -ne 1 ]]; then
31+
sed -n '1,120p' "$output_file" >&2
32+
echo "Expected the strict Clay renderer to reject the historical failure; got status $result_status." >&2
33+
exit 1
34+
fi
35+
36+
grep -Fq 'java.lang.StackOverflowError' "$output_file"
37+
grep -Fq 'Clay reported source failures despite exiting successfully:' "$output_file"
38+
grep -Fq '::error title=Clay source render failed::Clay FAILED: src/language_learning/vocabulary_estimation/beta_binomial_first_pass.clj' "$output_file"
39+
40+
echo 'Strict Clay regression passed: the historical stack-overflow signal was rejected with a GitHub error annotation.'

0 commit comments

Comments
 (0)