1- name : Build notebooks and publish
1+ name : CI with dynamic parallel matrix
22
33on :
44 workflow_dispatch :
1515 JULIA_CI : ' true'
1616 JULIA_CONDAPKG_BACKEND : ' Null'
1717 JULIA_CONDAPKG_OFFLINE : ' true'
18- # JULIA_CPU_TARGET: 'generic;icelake-server,clone_all;znver3,clone_all'
19- JULIA_NUM_THREADS : ' 2 '
18+ JULIA_CPU_TARGET : ' generic;icelake-server,clone_all;znver3,clone_all'
19+ JULIA_NUM_THREADS : ' auto '
2020 NBCACHE : ' .cache'
21- LITERATE_PROC : ' 6'
2221 PY_VER : ' 3.14'
2322
23+
2424jobs :
25- CI :
26- runs-on : self-hosted
25+ setup :
26+ runs-on : ubuntu-latest
27+ outputs :
28+ matrix : ${{ steps.set-matrix.outputs.matrix }}
29+ hash : ${{ steps.hash.outputs.value }}
30+ ver : ${{ steps.julia-version.outputs.resolved }}
2731 steps :
2832 - name : Checkout repository
2933 uses : actions/checkout@v6
@@ -38,89 +42,145 @@ jobs:
3842 run : uv pip install --system -r requirements.txt
3943 - name : Read Julia version
4044 id : julia-version
41- run : python -c 'import tomllib; from pathlib import Path; print("value =", tomllib.loads(Path("Manifest.toml").read_text())["julia_version"], sep="")' >> "$GITHUB_OUTPUT"
45+ run : python -c 'import tomllib; from pathlib import Path; print("resolved =", tomllib.loads(Path("Manifest.toml").read_text())["julia_version"], sep="")' >> "$GITHUB_OUTPUT"
4246 - name : Get environment hash
4347 id : hash
4448 run : |
4549 echo "value=${{ hashFiles('Project.toml', 'Manifest.toml', 'src/**') }}" >> "$GITHUB_OUTPUT"
46- - name : Cache executed notebooks
50+ echo "ver=${{ runner.os }}-julia-${{ steps.julia-version.outputs.resolved }}" >> "$GITHUB_OUTPUT"
51+ - name : Cache Julia packages
4752 uses : actions/cache@v5
48- id : cache-nb
53+ id : cache-julia
4954 with :
50- path : |
51- ${{ env.NBCACHE }}/**/*.ipynb
52- ${{ env.NBCACHE }}/**/*.sha
53- key : notebook-${{ steps.hash.outputs.value }}-${{ hashFiles('docs/**') }}
55+ path : ~/.julia
56+ key : ${{ runner.os }}-julia-${{ steps.julia-version.outputs.resolved }}-${{ steps.hash.outputs.value }}
5457 restore-keys : |
55- notebook- ${{ steps.hash .outputs.value }}-
58+ ${{ runner.os }}-julia- ${{ steps.julia-version .outputs.resolved }}-
5659 - name : Setup Julia
5760 uses : julia-actions/setup-julia@v2
58- if : ${{ steps.cache-nb .outputs.cache-hit != 'true' }}
61+ if : ${{ steps.cache-julia .outputs.cache-hit != 'true' }}
5962 with :
60- version : ${{ steps.julia-version.outputs.value }}
63+ version : ${{ steps.julia-version.outputs.resolved }}
6164 arch : ${{ runner.arch }}
62- - name : Restore Julia packages
63- uses : actions/cache/restore@v5
64- if : ${{ steps.cache-nb.outputs.cache-hit != 'true' && runner.environment == 'github-hosted'}}
65- id : cache-julia
66- with :
67- path : ~/.julia
68- key : ${{ runner.os }}-julia-${{ steps.julia-version.outputs.value }}-${{ steps.hash.outputs.value }}
69- restore-keys : |
70- ${{ runner.os }}-julia-${{ steps.julia-version.outputs.value }}
7165 - name : Install Julia packages
72- if : ${{ steps.cache-nb.outputs.cache-hit != 'true' && (runner.environment == 'self-hosted' || steps.cache- julia.outputs.cache-hit != 'true') }}
66+ if : ${{ steps.cache-julia.outputs.cache-hit != 'true' }}
7367 shell : julia --color=yes --project=@. {0}
7468 run : |
7569 using Pkg, Dates
7670 Pkg.instantiate()
7771 Pkg.precompile()
78- if ENV["RUNNER_ENVIRONMENT"] == "github-hosted"
79- Pkg.gc(;collect_delay=Day(0))
80- end
81- - name : Save Julia packages
82- uses : actions/cache/save@v5
83- if : ${{ steps.cache-nb.outputs.cache-hit != 'true' && runner.environment == 'github-hosted' && steps.cache-julia.outputs.cache-hit != 'true' }}
84- with :
85- path : ~/.julia
86- key : ${{ steps.cache-julia.outputs.cache-primary-key }}
87- - name : Run notebooks
88- if : ${{ steps.cache-nb.outputs.cache-hit != 'true' }}
89- run : julia --project=@. --color=yes -p ${{ env.LITERATE_PROC }} .github/ci.jl
90- - name : Copy back built notebooks
91- run : |
92- cp --verbose -rf ${{ env.NBCACHE }}/docs/* docs/
93- find docs/ -type f -name "*.jl" -delete
94- - name : Upload notebook
95- uses : actions/upload-artifact@v6
96- with :
97- name : notebooks
98- path : docs/**/*.ipynb
99- - name : Upload figures
100- uses : actions/upload-artifact@v6
101- with :
102- name : figures
103- path : |
104- docs/**/*.png
105- docs/**/*.pdf
106- - name : Setup Quarto
107- if : ${{ runner.environment == 'github-hosted' }}
108- uses : quarto-dev/quarto-actions/setup@v2
109- - name : Render Quarto Project
110- run : quarto render docs/
111- - name : Upload pages artifact
112- uses : actions/upload-pages-artifact@v4
113- if : ${{ github.ref == 'refs/heads/main' }}
114- with :
115- path : docs/_site/
72+ Pkg.gc(;collect_delay=Day(0))
73+ - name : List notebooks as a JSON array
74+ id : set-matrix
75+ run : echo "matrix=$(python -c 'import glob, json; print(json.dumps(glob.glob("**/*.ipynb", root_dir="docs", recursive=True) + glob.glob("**/*.jl", root_dir="docs", recursive=True)))')" >> "$GITHUB_OUTPUT"
76+
77+ execute :
78+ needs : setup
79+ strategy :
80+ max-parallel : 10
81+ fail-fast : false
82+ matrix :
83+ notebook : ${{ fromJSON(needs.setup.outputs.matrix) }}
84+ runs-on : ubuntu-latest
85+ env :
86+ NB : docs/${{ matrix.notebook }}
87+ steps :
88+ - name : Checkout
89+ uses : actions/checkout@v6
90+ - name : Cache notebook
91+ uses : actions/cache@v5
92+ id : nb-cache
93+ with :
94+ path : ${{ env.NBCACHE }}
95+ key : notebook-${{ needs.setup.outputs.hash }}-${{ hashFiles(env.NB) }}
96+ - name : Setup Python
97+ uses : actions/setup-python@v6
98+ if : ${{ steps.nb-cache.outputs.cache-hit != 'true' }}
99+ id : setup-python
100+ with :
101+ python-version : ${{ env.PY_VER }}
102+ - name : Install the latest version of uv
103+ if : ${{ steps.nb-cache.outputs.cache-hit != 'true' }}
104+ uses : astral-sh/setup-uv@v7
105+ - name : Install Python dependencies
106+ if : ${{ steps.nb-cache.outputs.cache-hit != 'true' }}
107+ run : uv pip install --system -r requirements.txt
108+ - name : Setup Julia
109+ uses : julia-actions/setup-julia@v2
110+ if : ${{ steps.nb-cache.outputs.cache-hit != 'true' }}
111+ with :
112+ version : ${{ needs.setup.outputs.ver }}
113+ arch : ${{ runner.arch }}
114+ - name : Restore Julia packages
115+ uses : actions/cache/restore@v5
116+ if : ${{ steps.nb-cache.outputs.cache-hit != 'true' }}
117+ with :
118+ path : ~/.julia
119+ key : ${{ runner.os }}-julia-${{ needs.setup.outputs.ver }}-${{ needs.setup.outputs.hash }}
120+ - name : Execute notebook
121+ if : ${{ steps.nb-cache.outputs.cache-hit != 'true' }}
122+ run : julia --project=@. .github/ci.jl
123+ - name : Convert artifact Name
124+ id : art
125+ run : echo "name=$(echo ${{ env.NB }} | sed 's/\//-/g')" >> "$GITHUB_OUTPUT"
126+ - name : Upload Notebook
127+ uses : actions/upload-artifact@v6
128+ with :
129+ name : notebook-${{ steps.art.outputs.name }}-${{ needs.setup.outputs.hash }}-${{ hashFiles(env.NB) }}
130+ path : ${{ env.NBCACHE }}
131+ include-hidden-files : true
132+ retention-days : 1
133+
134+ render :
135+ needs : execute
136+ runs-on : ubuntu-latest
137+ steps :
138+ - name : Checkout
139+ uses : actions/checkout@v6
140+ - name : Download notebooks
141+ uses : actions/download-artifact@v7
142+ with :
143+ path : ${{ env.NBCACHE }}/
144+ pattern : notebook-*
145+ merge-multiple : true
146+ - name : Copy back built notebooks
147+ run : |
148+ cp --verbose -rf ${{ env.NBCACHE }}/docs/* docs/
149+ find docs/ -type f -name "*.jl" -delete
150+ - name : Setup Quarto
151+ uses : quarto-dev/quarto-actions/setup@v2
152+ - name : Render Quarto Project
153+ run : quarto render docs --to html
154+ - name : Upload artifact for GH pages
155+ uses : actions/upload-pages-artifact@v4
156+ if : ${{ github.ref == 'refs/heads/main' }}
157+ with :
158+ path : docs/_site/
159+
160+ # CI conclusion for GitHub status check
161+ # Adaped from https://brunoscheufler.com/blog/2022-04-09-the-required-github-status-check-that-wasnt
162+ CI :
163+ needs : render
164+ if : always()
165+ runs-on : ubuntu-slim
166+ steps :
167+ - run : |
168+ if [[ ${{ needs.render.result }} == "success" ]]; then
169+ echo "Tests passed"
170+ exit 0
171+ else
172+ echo "Tests failed"
173+ exit 1
174+ fi
116175
176+ # Deployment job
117177 deploy :
118178 name : Deploy to GitHub pages
119- needs : CI
120- if : ${{ github.ref == 'refs/heads/main'}}
179+ needs : render
180+ if : ${{ github.ref == 'refs/heads/main' }}
121181 # Grant GITHUB_TOKEN the permissions required to make a Pages deployment
122182 permissions :
123- pages : write # to deploy to Pages
183+ pages : write # to deploy to Pages
124184 id-token : write # to verify the deployment originates from an appropriate source
125185 environment :
126186 name : github-pages
0 commit comments