Some Clay notebooks should only be run locally
:clay {:title "Some Clay notebooks should only be run locally"
^{:external-requirements ["my-secret.txt"]
:quarto {:author :daslu
:description "How to create notebooks with secrets, large files, and slow processes."
:image "skip-if-unchanged.jpg"
:type :post
:date "2025-07-25"
:category :clay
:tags [:clay :workflow]
:draft true}}}
ns scicloj.clay.skip-if-unchanged-example) (
Usually, when we wish to create Clojure Civitas posts, we enjoy the fact that Civitas runs our notebooks in the GitHub Actions as it renders the website.
While this is the default behavior, sometimes, we cannot expect our notebooks to be run in GitHub Actions. For example, they may depend on a local file or service.
This notebook, for example, assumes that you have a local secrets file, and it will not work without it!
slurp "temp/my-secret.txt") (
"this is my secret!\n"
If you are the author of such a notebook, the recommended practice is to render the notebook locally using Clay in Quarto .qmd
format, and include that file in your Pull Request.
The .qmd
file is all that Civitas needs to include your notebook in the website. As long as the .qmd
file is already there, Civitas will just rely on it and not even try to generate it in GitHub Actions.
To do that, you will need to make the file locally with a Quarto target.
Here are two ways to do that:
- Use the command line. Note that here, we use the path to the notebook, relative to
src
.
clojure -M:clay -A:markdown scicloj/clay/skip_if_unchanged_example.clj
- … Or do the same in Clojure code.
comment
(require '[scicloj.clay.v2.api :as clay])
(:source-path "scicloj/clay/skip_if_unchanged_example.clj"
(clay/make! {:aliases [:markdown]}))
Now git add
the generated qmd
file.
git add -f site/scicloj/clay/skip_if_unchanged_example.qmd
Also we need to add some metadata to this namespace. Notice in the above namespace form there is:
^{:clay {:external-requirements ["my-secret.txt"] ...}...}
That tells Clay that it should use the .qmd
file instead of executing the notebook. When we commit and push, the site will be built from our .qmd
file instead of .clj
file.
This approach works for credentials, large files, and slow processes which would otherwise cause the build process to be slow or fail.
We hope this enables interesting use cases where providing reproducible code is important, while capturing just one specific execution of the code is valuable… such as an interactive session calling an LLM API which is saved as a static document.