1+ name : Incremental Render and Publish
2+
13on :
24 push :
35 branches :
46 - main
5-
6- name : Render and Publish
7+ workflow_dispatch :
8+ inputs :
9+ publish :
10+ description : " Deploy to Pages (manual runs only)"
11+ type : boolean
12+ default : false
713
814permissions :
915 contents : read
16+ actions : read
1017
1118jobs :
1219 build :
@@ -15,27 +22,79 @@ jobs:
1522 steps :
1623 - name : Check out repository
1724 uses : actions/checkout@v4
25+ with :
26+ fetch-depth : 0
27+
28+ - name : Normalize QMD mtimes to last commit
29+ run : |
30+ set -euo pipefail
31+ git ls-files -z -- '*.qmd' \
32+ | xargs -0 -I{} sh -c '
33+ ts=$(git log -1 --format=%ct -- "{}" || true)
34+ if [ -n "$ts" ]; then
35+ touch -d "@$ts" "{}"
36+ fi
37+ '
38+
39+ - name : Download previous site artifact
40+ if : github.event_name == 'push'
41+ id : artifact_restore
42+ env :
43+ GH_TOKEN : ${{ github.token }}
44+ REPO : ${{ github.repository }}
45+ run : |
46+ set -euo pipefail
47+
48+ run_id=$(gh api \
49+ "/repos/$REPO/actions/workflows/${{ github.workflow_ref }}" \
50+ --jq '.id' || true)
51+
52+ latest_run=$(gh api \
53+ "/repos/$REPO/actions/workflows/$run_id/runs?branch=main&status=success&per_page=1" \
54+ --jq '.workflow_runs[0].id' || true)
55+
56+ if [ -z "${latest_run:-}" ]; then
57+ echo "No previous successful run."
58+ exit 0
59+ fi
60+
61+ artifact_id=$(gh api \
62+ "/repos/$REPO/actions/runs/$latest_run/artifacts" \
63+ --jq '.artifacts[] | select(.name=="site-build") | .id' \
64+ | head -n1 || true)
65+
66+ if [ -z "${artifact_id:-}" ]; then
67+ echo "No site-build artifact found."
68+ exit 0
69+ fi
70+
71+ gh api "/repos/$REPO/actions/artifacts/$artifact_id/zip" > /tmp/site.zip
72+ unzip -qn /tmp/site.zip -d site
73+
74+ if [ -d site/_site ]; then
75+ echo "site_ok=true" >> "$GITHUB_OUTPUT"
76+ fi
1877
1978 - name : Set up Python
2079 uses : actions/setup-python@v5
2180 with :
2281 python-version : ' 3.10'
23- - name : Install dependencies
24- run : |
25- pip install plotly kaleido
82+
83+ - name : Install Python deps
84+ run : pip install plotly kaleido
2685
2786 - name : Set up Java
2887 uses : actions/setup-java@v4
2988 with :
30- distribution : ' temurin'
89+ distribution : temurin
3190 java-version : ' 21'
3291
3392 - name : Set up Clojure
3493 uses : DeLaGuardo/setup-clojure@main
3594 with :
36- cli : ' latest'
95+ cli : latest
3796
38- - name : Cache clojure dependencies
97+ - name : Cache Clojure deps
3998 uses : actions/cache@v3
4099 with :
41100 path : |
@@ -44,8 +103,47 @@ jobs:
44103 ~/.deps.clj
45104 key : cljdeps-${{ runner.os }}
46105
47- - name : Build notebooks (changed set or full when none)
48- run : clojure -M:clay -A:markdown ${{ steps.changed_clj.outputs.files }}
106+ - name : Detect changed Clojure sources
107+ if : github.event_name == 'push' && steps.artifact_restore.outputs.site_ok == 'true'
108+ id : changed_clj
109+ run : |
110+ set -euo pipefail
111+
112+ if [ ! -f site/.artifact_commit ]; then
113+ echo "No artifact commit metadata; full rebuild."
114+ exit 0
115+ fi
116+
117+ base_commit=$(cat site/.artifact_commit)
118+
119+ if [ "$base_commit" = "$GITHUB_SHA" ]; then
120+ echo "Artifact already from this commit."
121+ exit 0
122+ fi
123+
124+ git fetch --quiet origin
125+
126+ changed=$(git diff --name-only --diff-filter=ACMR \
127+ "$base_commit" HEAD -- 'src/**/*.clj' | tr '\n' ' ')
128+
129+ if [ -z "$changed" ]; then
130+ echo "No changed Clojure sources."
131+ exit 0
132+ fi
133+
134+ echo "files=$changed" >> "$GITHUB_OUTPUT"
135+
136+ - name : Build notebooks (incremental or full)
137+ run : |
138+ set -euo pipefail
139+ if [ -n "${{ steps.changed_clj.outputs.files }}" ]; then
140+ echo "Incremental Civitas build:"
141+ echo "${{ steps.changed_clj.outputs.files }}"
142+ clojure -M:clay -A:markdown ${{ steps.changed_clj.outputs.files }}
143+ else
144+ echo "Full Civitas build."
145+ clojure -M:clay -A:markdown
146+ fi
49147
50148 - name : Set up Quarto
51149 uses : quarto-dev/quarto-actions/setup@v2
@@ -57,13 +155,28 @@ jobs:
57155 with :
58156 path : site
59157
60- - name : Upload artifact
158+ - name : Record artifact commit
159+ run : |
160+ mkdir -p site
161+ echo "$GITHUB_SHA" > site/.artifact_commit
162+
163+ - name : Upload Pages artifact
61164 uses : actions/upload-pages-artifact@v3
62165 with :
63166 path : site/_site
64167
168+ - name : Upload site artifact
169+ uses : actions/upload-artifact@v4
170+ with :
171+ name : site-build
172+ path : site/
173+ retention-days : 90
174+
65175 deploy :
66176 needs : build
177+ if : github.event_name == 'workflow_dispatch' &&
178+ github.event.inputs.publish == 'true' &&
179+ github.ref == 'refs/heads/main'
67180 permissions :
68181 pages : write
69182 id-token : write
0 commit comments