<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Blog on eirikre</title><link>/blog/</link><description>Recent content in Blog on eirikre</description><generator>Hugo -- gohugo.io</generator><language>en</language><copyright>Copyright (c) 2020-2024 eirikre</copyright><lastBuildDate>Thu, 07 Sep 2023 16:21:44 +0200</lastBuildDate><atom:link href="/blog/rss.xml" rel="self" type="application/rss+xml"/><item><title>Paper publishing workflow</title><link>/blog/2026/02/paper-publishing-workflow/</link><pubDate>Sat, 21 Feb 2026 22:16:35 +0100</pubDate><guid>/blog/2026/02/paper-publishing-workflow/</guid><description>A homage to mise-en-place</description><content:encoded>&lt;blockquote>
&lt;p>&lt;em>A homage to mise-en-place&lt;/em>&lt;/p>
&lt;/blockquote>
&lt;div class="callout callout-tip d-flex flex-row mt-4 mb-4 pt-4 pe-4 pb-2 ps-3">
&lt;svg class="rocket svg-inline callout-icon me-2 mb-3" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentcolor" fill="none" stroke-linecap="round" stroke-linejoin="round">&lt;path stroke="none" d="M0 0h24v24H0z" fill="none"/>&lt;path d="M4 13a8 8 0 017 7 6 6 0 003-5 9 9 0 006-8 3 3 0 00-3-3 9 9 0 00-8 6 6 6 0 00-5 3"/>&lt;path d="M7 14a6 6 0 00-3 6 6 6 0 006-3"/>&lt;path d="M15 9m-1 0a1 1 0 102 0 1 1 0 10-2 0"/>&lt;/svg>
&lt;div class="callout-content">
&lt;div class="callout-title">
&lt;p>TL;DR&lt;/p>
&lt;/div>
&lt;div class="callout-body">
&lt;p>Install a new project from
&lt;a href="https://github.com/engeir/paper-publishing-process">paper-publishing-process&lt;/a> with&lt;/p>
&lt;div class="expressive-code">
&lt;figure class="frame not-content">
&lt;figcaption class="header">
&lt;span class="title">&lt;/span>
&lt;/figcaption>
&lt;div class="highlight" frame="none">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">curl -fsSL https://raw.githubusercontent.com/engeir/paper-publishing-process/main/INSTALL.sh &lt;span class="p">|&lt;/span> sh&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/figure>
&lt;/div>
&lt;ul>
&lt;li>Automatic compilation of &lt;code>main.pdf&lt;/code>, &lt;code>review-&amp;lt;git-tag&amp;gt;.pdf&lt;/code> and &lt;code>diff-&amp;lt;git-tag&amp;gt;.pdf&lt;/code>&lt;/li>
&lt;li>Git Tag-based versioning and changelog generation&lt;/li>
&lt;li>CI/CD pipeline with compilation and new releases&lt;/li>
&lt;/ul>
&lt;video controls preload="auto" width="100%" autoplay loop muted playsinline class="html-video">
&lt;source src="/blog/2026/02/paper-publishing-workflow/compile-all.mp4" type="video/mp4">
&lt;span>Your browser doesn't support embedded videos, but don't worry, you can &lt;a href="/blog/2026/02/paper-publishing-workflow/compile-all.mp4">download it&lt;/a> and watch it with your favorite video player!&lt;/span>
&lt;/video>
&lt;/div>
&lt;/div>
&lt;/div>
&lt;p>A frustration from when I first started writing papers to be submitted to journals and
go through a review cycle was keeping track of which version was submitted at which
point in time. Which version should I respond to, which version should the updated
version be diffed against? This was a very manual process where the work of tracking
what needed to be submitted in the latest revision sometimes felt as large as the
writing itself.&lt;/p>
&lt;p>Fortunately, there are solutions.&lt;/p>
&lt;h2 id="setting-up-tools-and-repo">Setting Up Tools and Repo&lt;/h2>
&lt;p>Everything should be able to live independently of the system you first develop on, so
we create a Git repo where all the files can live. In this guide we will make extensive
use of GitHub&amp;rsquo;s workflow, so we &lt;a href="https://github.com/new/">create the repo there&lt;/a>. I
called mine &lt;code>paper-publishing-process&lt;/code>, so let&amp;rsquo;s clone it down:&lt;/p>
&lt;div class="expressive-code">
&lt;figure class="frame is-terminal not-content">
&lt;figcaption class="header">
&lt;span class="title">&lt;/span>
&lt;/figcaption>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">git clone git@github.com:engeir/paper-publishing-process.git
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">cd&lt;/span> paper-publishing-process&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/figure>
&lt;/div>
&lt;p>Next we need to be able to install all software, and for that we use
&lt;a href="https://mise.jdx.dev/">mise&lt;/a>. First we must install &lt;a href="https://mise.jdx.dev/">mise&lt;/a>;
visit the website, or run the following command:&lt;/p>
&lt;div class="expressive-code">
&lt;figure class="frame is-terminal not-content">
&lt;figcaption class="header">
&lt;span class="title">&lt;/span>
&lt;/figcaption>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">curl https://mise.run &lt;span class="p">|&lt;/span> sh&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/figure>
&lt;/div>
&lt;p>Then we create the file &lt;code>mise.toml&lt;/code> in the project root:&lt;/p>
&lt;div class="expressive-code">
&lt;figure class="frame has-title not-content">
&lt;figcaption class="header">
&lt;span class="title">mise.toml&lt;/span>
&lt;/figcaption>
&lt;div class="highlight" title="mise.toml">&lt;pre tabindex="0" class="chroma">&lt;code class="language-toml" data-lang="toml">&lt;span class="line">&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">tools&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="s2">&amp;#34;github:rstudio/tinytex-releases&amp;#34;&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">asset_pattern&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;TinyTeX-1-*.tar.gz&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">bin_path&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;.TinyTeX/bin/x86_64-linux&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">version&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;latest&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">tools&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">&amp;#34;github:WGUNDERWOOD/tex-fmt&amp;#34;&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;latest&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">&amp;#34;github:orhun/git-cliff&amp;#34;&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;latest&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">hk&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;latest&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">&amp;#34;pipx:bibfish&amp;#34;&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;latest&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">pkl&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;latest&amp;#34;&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/figure>
&lt;/div>
&lt;p>We need to give &lt;a href="https://mise.jdx.dev/">mise&lt;/a> permission to use it, &lt;code>mise trust&lt;/code>, before
installing everything with &lt;code>mise install&lt;/code>.&lt;/p>
&lt;p>In the first commit I added a simple license file (MIT) and a &lt;code>.gitignore&lt;/code> suited for
TeX development.&lt;/p>
&lt;p>&lt;em>→ See commit
&lt;a href="https://github.com/engeir/paper-publishing-process/commit/ce3150c6b25d2bbab7de1bdd98f2be6e64180dd4">ce3150c&lt;/a>.&lt;/em>&lt;/p>
&lt;p>While we&amp;rsquo;re at it, let&amp;rsquo;s add some files that help keep the repo up to a good standard in
terms of formatting:&lt;/p>
&lt;ul>
&lt;li>&lt;code>tex-fmt.toml&lt;/code>: Formatting of &lt;code>.tex&lt;/code> and &lt;code>.bib&lt;/code>&lt;/li>
&lt;li>&lt;code>.taplo.toml&lt;/code>: Formatting of &lt;code>.toml&lt;/code>&lt;/li>
&lt;li>&lt;code>.yamlfmt.yml&lt;/code>: Formatting of &lt;code>.yml&lt;/code>&lt;/li>
&lt;li>&lt;code>hk.pkl&lt;/code>: Formatting and linting&lt;/li>
&lt;/ul>
&lt;p>This change also updates &lt;code>mise.toml&lt;/code> and creates the file &lt;code>tex/main.tex&lt;/code>.&lt;/p>
&lt;p>&lt;em>→ See commit
&lt;a href="https://github.com/engeir/paper-publishing-process/commit/b161e41dc3fe4c10b6abb50f69a71f4d105c143e">b161e41&lt;/a>.&lt;/em>&lt;/p>
&lt;p>We can verify that everything so far is as it should be:&lt;/p>
&lt;div class="expressive-code">
&lt;figure class="frame is-terminal not-content">
&lt;figcaption class="header">
&lt;span class="title">&lt;/span>
&lt;/figcaption>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">$ git --no-pager reflog
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">b161e41 &lt;span class="o">(&lt;/span>HEAD -&amp;gt; main, origin/main, origin/HEAD&lt;span class="o">)&lt;/span> HEAD@&lt;span class="o">{&lt;/span>0&lt;span class="o">}&lt;/span>: commit: feat&lt;span class="o">(&lt;/span>format&lt;span class="o">)&lt;/span>: first working tex file with formatting
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">ce3150c HEAD@&lt;span class="o">{&lt;/span>1&lt;span class="o">}&lt;/span>: commit: build&lt;span class="o">(&lt;/span>mise&lt;span class="o">)&lt;/span>: install basic tools
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">4dd90d7 HEAD@&lt;span class="o">{&lt;/span>2&lt;span class="o">}&lt;/span>: clone: from github.com:engeir/paper-publishing-process.git
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ hk check
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">hk 1.38.0 by @jdx – check &lt;span class="o">[==========================================]&lt;/span> 1/1
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">✔ files - Fetching modified files &lt;span class="o">(&lt;/span>&lt;span class="m">0&lt;/span> files&lt;span class="o">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">✔ bib-filepath
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">bib-filepath stderr:
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">[&lt;/span>check-bib-filepath&lt;span class="o">]&lt;/span> $ &lt;span class="c1">#!/usr/bin/env bash&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ hk fix
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">hk 1.38.0 by @jdx – fix &lt;span class="o">[============================================]&lt;/span> 1/1
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">✔ files - Fetching modified files &lt;span class="o">(&lt;/span>&lt;span class="m">0&lt;/span> files&lt;span class="o">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">✔ bib-filepath
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">bib-filepath stderr:
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">[&lt;/span>fix-bib-filepath&lt;span class="o">]&lt;/span> $ &lt;span class="c1">#!/usr/bin/env bash&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/figure>
&lt;/div>
&lt;h2 id="automatic-compilation-of-tex">Automatic Compilation of TeX&lt;/h2>
&lt;h3 id="local-compilation-with-mise">Local Compilation with mise&lt;/h3>
&lt;p>We are now ready to work on the TeX files! We want to write in &lt;code>tex/main.tex&lt;/code>, and every
time we save, the PDF should update automatically. We turn again to
&lt;a href="https://mise.jdx.dev/">mise&lt;/a> for this functionality.&lt;/p>
&lt;p>&lt;em>→ See commit
&lt;a href="https://github.com/engeir/paper-publishing-process/commit/e7127b4">e7127b4&lt;/a>.&lt;/em>&lt;/p>
&lt;details>
&lt;summary>Motivation for mise tasks&lt;/summary>
In the commit above we add a &lt;a href="https://mise.jdx.dev/">mise&lt;/a> task called
&amp;ldquo;localize-bib-paths&amp;rdquo;. The motivation behind it is that the &amp;ldquo;compile&amp;rdquo; task (introduced a
little later) will run it so that when developing locally all references come from the
global master reference. This is useful in cases where you want to add a new reference
to the TeX document that already exists in the master reference. If you use a modern
editor it will provide completion suggestions, which would not be available in the
generated reference files for &lt;em>new&lt;/em> references.&lt;/details>
&lt;p>We can now run&lt;/p>
&lt;div class="expressive-code">
&lt;figure class="frame is-terminal not-content">
&lt;figcaption class="header">
&lt;span class="title">&lt;/span>
&lt;/figcaption>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">$ mise watch main:compile
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">[&lt;/span>Running: /home/eirikre/.local/bin/mise run main:compile&lt;span class="o">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">[&lt;/span>main:update-refs&lt;span class="o">]&lt;/span> $ bibfish -c &lt;span class="s1">&amp;#39;cite,citet,citep,citeA&amp;#39;&lt;/span> -f main.tex .bib main.bib
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Traceback &lt;span class="o">(&lt;/span>most recent call last&lt;span class="o">)&lt;/span>:
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> File &lt;span class="s2">&amp;#34;/home/eirikre/.local/share/mise/installs/pipx-bibfish/0.3.4/bin/bibfish&amp;#34;&lt;/span>, line 6, in &amp;lt;module&amp;gt;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> sys.exit&lt;span class="o">(&lt;/span>cli&lt;span class="o">())&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> ~~~^^&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/figure>
&lt;/div>
&lt;p>It fails! This is due to the first, slightly special choice we make in this workflow.&lt;/p>
&lt;h3 id="bibfish">Bibfish&lt;/h3>
&lt;p>In order to keep the &lt;code>.bib&lt;/code> files in the repo as minimal as possible, they are all
generated from a local &amp;ldquo;master reference file&amp;rdquo;. This file is what the &lt;code>LOCAL_BIB_PATH&lt;/code>
value we added in &lt;code>mise.toml&lt;/code> points to. This master reference is intended to be a file
that lives only locally, not in the Git repo, and should be able to supply references
not just to this project, but to all your TeX projects! Bibfish will then read it and
generate a reference file based only on the references found in a given TeX file.&lt;/p>
&lt;p>Bibfish supports most common citation formats (e.g. &lt;code>\cite&lt;/code>, &lt;code>\citet&lt;/code>, etc.), but can
easily be extended with custom formats. In &lt;code>mise.toml&lt;/code> we have added &lt;code>citeA&lt;/code>, and also
specify &lt;code>cite&lt;/code>, &lt;code>citet&lt;/code> and &lt;code>citep&lt;/code>
(&lt;code>bibfish -c 'cite,citet,citep,citeA' -f main.tex {{ env.LOCAL_BIB_PATH }}.bib main.bib&lt;/code>).&lt;/p>
&lt;p>Let&amp;rsquo;s fix the error from before by&lt;/p>
&lt;ol>
&lt;li>Adding &lt;code>mise.local.toml&lt;/code> to &lt;code>.gitignore&lt;/code>&lt;/li>
&lt;li>Specifying a local bib file in &lt;code>mise.local.toml&lt;/code>&lt;/li>
&lt;/ol>
&lt;div class="callout callout-caution d-flex flex-row mt-4 mb-4 pt-4 pe-4 pb-2 ps-3">
&lt;svg class="alert-triangle svg-inline callout-icon me-2 mb-3" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentcolor" fill="none" stroke-linecap="round" stroke-linejoin="round">&lt;path stroke="none" d="M0 0h24v24H0z" fill="none"/>&lt;path d="M12 9v4"/>&lt;path d="M10.363 3.591 2.257 17.125a1.914 1.914.0 001.636 2.871h16.214a1.914 1.914.0 001.636-2.87L13.637 3.59a1.914 1.914.0 00-3.274.0z"/>&lt;path d="M12 16h.01"/>&lt;/svg>
&lt;div class="callout-content">
&lt;div class="callout-title">
&lt;p>Local bib file&lt;/p>
&lt;/div>
&lt;div class="callout-body">
&lt;p>Note that the local file&amp;rsquo;s location must either be &amp;ldquo;absolute&amp;rdquo; (&lt;code>/home/user/the-file&lt;/code>),
or &amp;ldquo;relative&amp;rdquo; from the &lt;code>tex&lt;/code> folder, and that it is specified without &lt;code>.bib&lt;/code>.&lt;/p>
&lt;/div>
&lt;/div>
&lt;/div>
&lt;p>I also added the local master reference here to illustrate with a minimal example, but
normally I would place it outside the repo. Also add&lt;/p>
&lt;div class="expressive-code">
&lt;figure class="frame has-title not-content">
&lt;figcaption class="header">
&lt;span class="title">mise.local.toml&lt;/span>
&lt;/figcaption>
&lt;div class="highlight" title="mise.local.toml">&lt;pre tabindex="0" class="chroma">&lt;code class="language-toml" data-lang="toml">&lt;span class="line">&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">env&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">LOCAL_BIB_PATH&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;../main-ref&amp;#34;&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/figure>
&lt;/div>
&lt;div class="expressive-code">
&lt;figure class="frame has-title not-content">
&lt;figcaption class="header">
&lt;span class="title">main-ref.bib&lt;/span>
&lt;/figcaption>
&lt;div class="highlight" title="main-ref.bib">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bib" data-lang="bib">&lt;span class="line">&lt;span class="cl">&lt;span class="nc">@article&lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="nl">enger2025:paper1&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="na">author&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s">{Enger, Eirik Rolland and Graversen, Rune and Theodorsen, Audun}&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="na">title&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s">{{Saturation in Forcing Efficiency and Temperature Response of Large Volcanic Eruptions}}&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="na">journal&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s">{Journal of Geophysical Research: Atmospheres}&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="na">volume&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s">{130}&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="na">number&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s">{9}&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="na">pages&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s">{e2024JD041098}&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="na">keywords&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s">{super-eruption, AOD, ERF, temperature response}&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="na">doi&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s">{10.1029/2024JD041098}&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="na">url&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s">{https://agupubs.onlinelibrary.wiley.com/doi/abs/10.1029/2024JD041098}&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="na">eprint&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s">{https://agupubs.onlinelibrary.wiley.com/doi/pdf/10.1029/2024JD041098}&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="na">note&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s">{e2024JD041098 2024JD041098}&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="na">abstract&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s">{Abstract Volcanic eruptions cause climate cooling due to the reflection of solar radiation by emitted and subsequently produced aerosols. The climate effect of an eruption may last for about a decade and is nonlinearly tied to the amount of injected SO2 \${\text{SO}}\_{2}\$ from the eruption. We investigate the climatic effects of volcanic eruptions, ranging from Mt. Pinatubo-sized events to supereruptions. The study is based on ensemble simulations in the Community Earth System Model Version 2 (CESM2) climate model applying the Whole Atmosphere Community Climate Model Version 6 (WACCM6) atmosphere model, using a coupled ocean and fixed sea surface temperature setting. Our analysis focuses on the impact of different levels of SO2 \${\text{SO}}\_{2}\$ injections on stratospheric aerosol optical depth (SAOD), effective radiative forcing (ERF), and global mean surface temperature (GMST) anomalies. We uncover a notable time-dependent decrease in aerosol forcing efficiency (ERF normalized by SAOD) for all eruption SO2 \${\text{SO}}\_{2}\$ levels during the first posteruption year. In addition, it is revealed that the largest eruptions investigated in this study, including several previous supereruption simulations, provide peak ERF anomalies bounded at −65Wm−2 \${-}65\,\mathrm{W}\,{\mathrm{m}}^{-2}\$. Further, a close linear relationship between peak GMST and ERF effectively bounds the GMST anomaly to, at most, approximately −10K \${-}10\,\mathrm{K}\$. This is consistent across several previous studies using different climate models.}&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="na">year&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s">{2025}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nc">@article&lt;/span>&lt;span class="p">{&lt;/span>&lt;span class="nl">enger2025:paper2&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="na">author&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s">{Enger, Eirik Rolland and Graversen, Rune and Theodorsen, Audun}&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="na">title&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s">{{Nonparametric Estimation of Temperature Response to Volcanic Forcing}}&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="na">journal&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s">{Journal of Geophysical Research: Atmospheres}&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="na">volume&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s">{130}&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="na">number&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s">{10}&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="na">pages&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s">{e2024JD042519}&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="na">keywords&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s">{temperature response, super-eruption, radiative forcing, aerosol, AOD, ERF}&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="na">doi&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s">{10.1029/2024JD042519}&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="na">url&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s">{https://agupubs.onlinelibrary.wiley.com/doi/abs/10.1029/2024JD042519}&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="na">eprint&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s">{https://agupubs.onlinelibrary.wiley.com/doi/pdf/10.1029/2024JD042519}&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="na">note&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s">{e2024JD042519 2024JD042519}&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="na">abstract&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s">{Abstract Large volcanic eruptions strongly influence the internal variability of the climate system. Reliable estimates of the volcanic eruption response as simulated by climate models are needed to reconstruct past climate variability. Yet, the ability of models to represent the response to both single-eruption events and a combination of eruptions remains uncertain. We use the Community Earth System Model version 2 along with the Whole Atmosphere Community Climate Model version 6, known as CESM2(WACCM6), to study the global-mean surface temperature (GMST) response to idealized single volcano eruptions at the equator, ranging in size from Mt. Pinatubo-type events to supereruptions. Additionally, we simulate the GMST response to double-eruption events with eruption separations of a few years. For large idealized eruptions, we demonstrate that double-eruption events separated by 4 years combine linearly in terms of GMST response. In addition, the temporal development is similar across all single volcanic eruptions injecting at least 400 Tg \$\left({\mathrm{S}\mathrm{O}}\_{2}\right)\$ into the atmosphere. Because only a few eruptions in the past millennium occurred within 4 years of a previous eruption, we assume that the historical record can be represented as a superposition of single-eruption events. Hence, we employ a deconvolution method to estimate a nonparametric historical GMST response pulse function for volcanic eruptions, based on climate simulation data from 850 to 1850 taken from a previous study. By applying the estimated GMST response pulse function, we can reconstruct most of the underlying historical GMST signal. Furthermore, the GMST response is significantly perturbed for at least 7 years following eruptions.}&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="na">year&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s">{2025}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/figure>
&lt;/div>
&lt;p>&lt;em>→ See commit
&lt;a href="https://github.com/engeir/paper-publishing-process/commit/a149cdf">a149cdf&lt;/a>.&lt;/em>&lt;/p>
&lt;p>When we now try to compile, no error!&lt;/p>
&lt;div class="expressive-code">
&lt;figure class="frame is-terminal not-content">
&lt;figcaption class="header">
&lt;span class="title">&lt;/span>
&lt;/figcaption>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">$ mise watch main:compile
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">[&lt;/span>Running: /home/eirikre/.local/bin/mise run main:compile&lt;span class="o">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">[&lt;/span>main:update-refs&lt;span class="o">]&lt;/span> $ bibfish -c &lt;span class="s1">&amp;#39;cite,citet,citep,citeA&amp;#39;&lt;/span> -f main.tex ../main-ref.bib main.bib
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">[&lt;/span>main:compile&lt;span class="o">]&lt;/span> $ latexmk -pdf -g -f -silent -recorder- main.tex
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Rc files read:
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> NONE
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Latexmk: Run number &lt;span class="m">1&lt;/span> of rule &lt;span class="s1">&amp;#39;pdflatex&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">This is pdfTeX, Version 3.141592653-2.6-1.40.29 &lt;span class="o">(&lt;/span>TeX Live 2026&lt;span class="o">)&lt;/span> &lt;span class="o">(&lt;/span>preloaded &lt;span class="nv">format&lt;/span>&lt;span class="o">=&lt;/span>pdflatex&lt;span class="o">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> restricted &lt;span class="se">\w&lt;/span>rite18 enabled.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">entering extended mode
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Latexmk: Getting log file &lt;span class="s1">&amp;#39;main.log&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Latexmk: Using bibtex to make bibliography file&lt;span class="o">(&lt;/span>s&lt;span class="o">)&lt;/span>.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">mise WARN task main:compile did not generate expected output: main.bbl
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Finished in 906.8ms
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">[&lt;/span>Command was successful&lt;span class="o">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">^C%
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ ls tex
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">main.aux main.bib main.fdb_latexmk main.log main.pdf main.tex&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/figure>
&lt;/div>
&lt;h3 id="bbl-files-and-references-in-git">BBL Files and References in Git&lt;/h3>
&lt;p>Let&amp;rsquo;s add some references.&lt;/p>
&lt;div class="expressive-code">
&lt;figure class="frame has-title not-content">
&lt;figcaption class="header">
&lt;span class="title">tex/main.tex&lt;/span>
&lt;/figcaption>
&lt;div class="highlight" title="tex/main.tex">&lt;pre tabindex="0" class="chroma">&lt;code class="language-tex" data-lang="tex">&lt;span class="line">&lt;span class="ln"> 1&lt;/span>&lt;span class="cl">&lt;span class="k">\documentclass&lt;/span>&lt;span class="nb">{&lt;/span>article&lt;span class="nb">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl">&lt;span class="k">\author&lt;/span>&lt;span class="nb">{&lt;/span>Eirik Rolland Enger&lt;span class="nb">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl">&lt;span class="k">\title&lt;/span>&lt;span class="nb">{&lt;/span>A dead simple paper publishing workflow&lt;span class="nb">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl">&lt;span class="k">\begin&lt;/span>&lt;span class="nb">{&lt;/span>document&lt;span class="nb">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl">&lt;span class="k">\maketitle&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl">Hello, World!
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">11&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line hl">&lt;span class="ln">12&lt;/span>&lt;span class="cl">&lt;span class="k">\section&lt;/span>&lt;span class="nb">{&lt;/span>Adding references&lt;span class="nb">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line hl">&lt;span class="ln">13&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line hl">&lt;span class="ln">14&lt;/span>&lt;span class="cl">See &lt;span class="k">\cite&lt;/span>&lt;span class="nb">{&lt;/span>enger2025:paper1&lt;span class="nb">}&lt;/span>.
&lt;/span>&lt;/span>&lt;span class="line hl">&lt;span class="ln">15&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line hl">&lt;span class="ln">16&lt;/span>&lt;span class="cl">&lt;span class="k">\bibliographystyle&lt;/span>&lt;span class="nb">{&lt;/span>plain&lt;span class="nb">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line hl">&lt;span class="ln">17&lt;/span>&lt;span class="cl">&lt;span class="k">\bibliography&lt;/span>&lt;span class="nb">{&lt;/span>../main-ref&lt;span class="nb">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">18&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">19&lt;/span>&lt;span class="cl">&lt;span class="k">\end&lt;/span>&lt;span class="nb">{&lt;/span>document&lt;span class="nb">}&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/figure>
&lt;/div>
&lt;p>We also create a general &lt;code>compile&lt;/code> task in &lt;a href="https://mise.jdx.dev/">mise&lt;/a>:&lt;/p>
&lt;div class="expressive-code">
&lt;figure class="frame has-title not-content">
&lt;figcaption class="header">
&lt;span class="title">mise.toml&lt;/span>
&lt;/figcaption>
&lt;div class="highlight" title="mise.toml">&lt;pre tabindex="0" class="chroma">&lt;code class="language-toml" data-lang="toml">&lt;span class="line">&lt;span class="ln">13&lt;/span>&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">env&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">14&lt;/span>&lt;span class="cl">&lt;span class="nx">LOCAL_BIB_PATH&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;&amp;#34;&lt;/span> &lt;span class="c"># override in mise.local.toml with your personal global bib path&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">15&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">16&lt;/span>&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">tasks&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">compile&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">17&lt;/span>&lt;span class="cl">&lt;span class="nx">description&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;Compile all documents for local development.&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">18&lt;/span>&lt;span class="cl">&lt;span class="nx">dir&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;{{ config_root }}/tex/&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">19&lt;/span>&lt;span class="cl">&lt;span class="nx">run&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="p">[{&lt;/span> &lt;span class="nx">task&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;localize-bib-paths&amp;#34;&lt;/span> &lt;span class="p">},&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="nx">task&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;*:compile&amp;#34;&lt;/span> &lt;span class="p">}]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">20&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">21&lt;/span>&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">tasks&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="s2">&amp;#34;main:compile&amp;#34;&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">22&lt;/span>&lt;span class="cl">&lt;span class="nx">depends&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="s2">&amp;#34;main:*&amp;#34;&lt;/span>&lt;span class="p">]&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/figure>
&lt;/div>
&lt;p>When we now run &lt;code>mise watch compile&lt;/code> a new file will be generated: &lt;code>tex/main.bbl&lt;/code>. This
is normally ignored, but we will need it in the future, so we remove it from
&lt;code>.gitignore&lt;/code>.&lt;/p>
&lt;p>It contains a new &lt;code>.bbl&lt;/code> file, and the &lt;code>.bib&lt;/code> file has been updated with exactly one
reference — the one we added in &lt;code>tex/main.tex&lt;/code>!&lt;/p>
&lt;p>&lt;em>→ See commit
&lt;a href="https://github.com/engeir/paper-publishing-process/commit/1a523ea">1a523ea&lt;/a>.&lt;/em>&lt;/p>
&lt;h3 id="managing-tex-packages-with-tlmgr">Managing TeX Packages with tlmgr&lt;/h3>
&lt;p>We use &lt;a href="https://yihui.org/tinytex/">tinytex&lt;/a> as the TeX distribution in this project. As
the name suggests it is much smaller than the more common TeX-live/TeX-live-full. This
also means we will more often find that packages are unavailable, but in return we get
more control. Let&amp;rsquo;s use a handful of packages not found in TinyTeX.&lt;/p>
&lt;p>&lt;em>→ See commit
&lt;a href="https://github.com/engeir/paper-publishing-process/commit/fe28c24">fe28c24&lt;/a> for updated
&lt;code>tex/main.tex&lt;/code> and &lt;code>mise.toml&lt;/code>.&lt;/em>&lt;/p>
&lt;p>If you first update &lt;code>tex/main.tex&lt;/code> with the contents from the commit above and have
&lt;code>mise watch compile&lt;/code> running it should fail, complaining that &lt;code>underscore&lt;/code> is not
available. Then add the &lt;code>postinstall&lt;/code> hook in &lt;code>mise.toml&lt;/code> and run &lt;code>mise install&lt;/code>.&lt;/p>
&lt;p>This will ensure that various packages are installed via &lt;code>tlmgr&lt;/code>. The advantage of this
setup is that many journals are very particular about which packages they accept. If you
have written a long manuscript that uses many packages and compiles fine locally because
you used TeX-live-full, it can quickly become difficult to figure out what needs to go
if compilation on the journal&amp;rsquo;s server crashes.&lt;/p>
&lt;h3 id="local-development-workflow">Local Development Workflow&lt;/h3>
&lt;p>We have now completed the workflow for local TeX files! Run &lt;code>mise watch compile&lt;/code>, write
down all your good ideas, and every time &lt;code>tex/main.tex&lt;/code> is saved the compilation will
run. Notice how &lt;code>tex/main.bib&lt;/code> updates in the terminal window at the top right when I
add and remove references.&lt;/p>
&lt;video controls preload="auto" width="100%" autoplay loop muted playsinline class="html-video">
&lt;source src="/blog/2026/02/paper-publishing-workflow/compile.mp4" type="video/mp4">
&lt;span>Your browser doesn't support embedded videos, but don't worry, you can &lt;a href="/blog/2026/02/paper-publishing-workflow/compile.mp4">download it&lt;/a> and watch it with your favorite video player!&lt;/span>
&lt;/video>
&lt;p>Next steps: automatic compilation on GitHub, support for versioning via Git, and
routines for responding to feedback from journals.&lt;/p>
&lt;h2 id="cicd-pipeline-on-github">CI/CD Pipeline on GitHub&lt;/h2>
&lt;h3 id="git-commit-hooks">Git Commit Hooks&lt;/h3>
&lt;p>Since we have tools for formatting the code as well as a working
&lt;a href="https://hk.jdx.dev/">hk&lt;/a> setup, we can easily set up Git commit hooks:&lt;/p>
&lt;div class="expressive-code">
&lt;figure class="frame is-terminal not-content">
&lt;figcaption class="header">
&lt;span class="title">&lt;/span>
&lt;/figcaption>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">hk install&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/figure>
&lt;/div>
&lt;div class="callout callout-danger d-flex flex-row mt-4 mb-4 pt-4 pe-4 pb-2 ps-3">
&lt;svg class="alert-octagon svg-inline callout-icon me-2 mb-3" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentcolor" fill="none" stroke-linecap="round" stroke-linejoin="round">&lt;path stroke="none" d="M0 0h24v24H0z" fill="none"/>&lt;path d="M12.802 2.165l5.575 2.389c.48.206.863.589 1.07 1.07l2.388 5.574c.22.512.22 1.092.0 1.604l-2.389 5.575c-.206.48-.589.863-1.07 1.07l-5.574 2.388c-.512.22-1.092.22-1.604.0l-5.575-2.389a2.036 2.036.0 01-1.07-1.07l-2.388-5.574a2.036 2.036.0 010-1.604l2.389-5.575c.206-.48.589-.863 1.07-1.07l5.574-2.388a2.036 2.036.0 011.604.0z"/>&lt;path d="M12 8v4"/>&lt;path d="M12 16h.01"/>&lt;/svg>
&lt;div class="callout-content">
&lt;div class="callout-title">
&lt;p>Pre-commit vs. mise run compile&lt;/p>
&lt;/div>
&lt;div class="callout-body">
&lt;p>Since &lt;code>mise run|watch compile&lt;/code> converts all &lt;code>\bibliography{...}&lt;/code> to use the local master
reference, while the pre-commit hook via &lt;code>hk&lt;/code> converts them to use the generated bib
files, a conflict will arise between them.&lt;/p>
&lt;p>Each time you create a commit it is therefore wise to stop &lt;code>mise watch compile&lt;/code>, so that
it does not overwrite before you have finished the commit.&lt;/p>
&lt;/div>
&lt;/div>
&lt;/div>
&lt;h3 id="automatic-building-and-release">Automatic Building and Release&lt;/h3>
&lt;p>To set up CI/CD we create the file &lt;code>mise.ci.toml&lt;/code>, as well as three files in
&lt;code>.github/workflows&lt;/code> and &lt;code>.mise/tasks&lt;/code>:&lt;/p>
&lt;ul>
&lt;li>
&lt;p>&lt;code>.github/workflows/build.yml&lt;/code>&lt;/p>
&lt;p>Compiles all PDFs for every push to the main branch on GitHub.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;code>.github/workflows/fix-bib-filepath.yml&lt;/code>&lt;/p>
&lt;p>An extra check ensuring the correct bib file is used to compile the PDFs.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;code>.mise/tasks/package&lt;/code>&lt;/p>
&lt;p>Puts all files a journal needs into an archive, for easy uploading when submitting.&lt;/p>
&lt;/li>
&lt;/ul>
&lt;p>&lt;em>→ See commit
&lt;a href="https://github.com/engeir/paper-publishing-process/commit/93c8487">93c8487&lt;/a> for the
contents of the files.&lt;/em>&lt;/p>
&lt;p>That commit actually failed in CI on GitHub. I had forgotten that all files in
&lt;code>.mise/tasks&lt;/code> must be executable (executable bit), meaning I needed to&lt;/p>
&lt;div class="expressive-code">
&lt;figure class="frame is-terminal not-content">
&lt;figcaption class="header">
&lt;span class="title">&lt;/span>
&lt;/figcaption>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">chmod +x .mise/tasks/package&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/figure>
&lt;/div>
&lt;p>&lt;em>→ See commit
&lt;a href="https://github.com/engeir/paper-publishing-process/commit/06262fd">06262fd&lt;/a>.&lt;/em>&lt;/p>
&lt;p>Below we see that CI/CD ran without errors and gave us a &lt;code>paper-assets&lt;/code> artifact.&lt;/p>
&lt;figure>
&lt;img
srcset="/blog/2026/02/paper-publishing-workflow/first-ci_hufedf44b0247f3e19129998df0b1f7236_81025_480x0_resize_q85_h2_lanczos_3.webp 480w,/blog/2026/02/paper-publishing-workflow/first-ci_hufedf44b0247f3e19129998df0b1f7236_81025_576x0_resize_q85_h2_lanczos_3.webp 576w,/blog/2026/02/paper-publishing-workflow/first-ci_hufedf44b0247f3e19129998df0b1f7236_81025_768x0_resize_q85_h2_lanczos_3.webp 768w,/blog/2026/02/paper-publishing-workflow/first-ci_hufedf44b0247f3e19129998df0b1f7236_81025_1025x0_resize_q85_h2_lanczos_3.webp 1025w,/blog/2026/02/paper-publishing-workflow/first-ci_hufedf44b0247f3e19129998df0b1f7236_81025_1200x0_resize_q85_h2_lanczos_3.webp 1200w,/blog/2026/02/paper-publishing-workflow/first-ci_hufedf44b0247f3e19129998df0b1f7236_81025_1440x0_resize_q85_h2_lanczos_3.webp 1440w,/blog/2026/02/paper-publishing-workflow/first-ci_hufedf44b0247f3e19129998df0b1f7236_81025_1619x0_resize_q85_h2_lanczos_3.webp 1619w"
src="/blog/2026/02/paper-publishing-workflow/first-ci_hufedf44b0247f3e19129998df0b1f7236_81025_480x0_resize_q85_bgffffff_lanczos_3.jpg"
width="1619"
height="912"
decoding="async"
fetchpriority="auto"
loading="lazy"
alt="First CI/CD run"
class="lazyload blur-up"
>&lt;figcaption>First CI/CD run&lt;/figcaption>
&lt;/figure>
&lt;h2 id="versioning-and-replying-to-the-journal">Versioning and Replying to the Journal&lt;/h2>
&lt;p>We are now almost ready to submit the manuscript to a journal, but first we will set up
versioning in Git that generates new releases with a changelog.
&lt;a href="https://git-cliff.org/">Git-Cliff&lt;/a> is a very flexible and powerful tool for exactly
this, and we configure it with &lt;code>cliff.toml&lt;/code>. This file is completely general, with the
exception of the last two lines, shown below. They indicate the owner of the repo and
the name of the repo.&lt;/p>
&lt;div class="expressive-code">
&lt;figure class="frame has-title not-content">
&lt;figcaption class="header">
&lt;span class="title">cliff.toml&lt;/span>
&lt;/figcaption>
&lt;div class="highlight" title="cliff.toml">&lt;pre tabindex="0" class="chroma">&lt;code class="language-toml" data-lang="toml">&lt;span class="line">&lt;span class="ln">107&lt;/span>&lt;span class="cl">&lt;span class="c"># limit_commits = 42&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">108&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">109&lt;/span>&lt;span class="cl">&lt;span class="p">[&lt;/span>&lt;span class="nx">remote&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">github&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">110&lt;/span>&lt;span class="cl">&lt;span class="nx">owner&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;engeir&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">111&lt;/span>&lt;span class="cl">&lt;span class="nx">repo&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s2">&amp;#34;paper-publishing-process&amp;#34;&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/figure>
&lt;/div>
&lt;p>We can now set a Git Tag on the latest commit to create our first version of the
manuscript!&lt;/p>
&lt;p>&lt;em>→ See commit
&lt;a href="https://github.com/engeir/paper-publishing-process/commit/bfe67c6">bfe67c6&lt;/a>.&lt;/em>&lt;/p>
&lt;div class="expressive-code">
&lt;figure class="frame is-terminal not-content">
&lt;figcaption class="header">
&lt;span class="title">&lt;/span>
&lt;/figcaption>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">$ git tag -a v1.0.0 -m &lt;span class="s2">&amp;#34;**Release v1.0.0**&amp;#34;&lt;/span> -m &lt;span class="s1">&amp;#39;First release!&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ git push --tags
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">hk 1.38.0 by @jdx – pre-push – check &lt;span class="o">[=======================================================]&lt;/span> 1/1
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">✔ files - Fetching files between refs/remotes/origin/main and HEAD &lt;span class="o">(&lt;/span>&lt;span class="m">0&lt;/span> files&lt;span class="o">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">✔ bib-filepath
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">bib-filepath stderr:
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">[&lt;/span>check-bib-filepath&lt;span class="o">]&lt;/span> $ &lt;span class="c1">#!/usr/bin/env bash&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Enumerating objects: 1, &lt;span class="k">done&lt;/span>.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Counting objects: 100% &lt;span class="o">(&lt;/span>1/1&lt;span class="o">)&lt;/span>, &lt;span class="k">done&lt;/span>.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Writing objects: 100% &lt;span class="o">(&lt;/span>1/1&lt;span class="o">)&lt;/span>, &lt;span class="m">189&lt;/span> bytes &lt;span class="p">|&lt;/span> 189.00 KiB/s, &lt;span class="k">done&lt;/span>.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Total &lt;span class="m">1&lt;/span> &lt;span class="o">(&lt;/span>delta 0&lt;span class="o">)&lt;/span>, reused &lt;span class="m">0&lt;/span> &lt;span class="o">(&lt;/span>delta 0&lt;span class="o">)&lt;/span>, pack-reused &lt;span class="m">0&lt;/span> &lt;span class="o">(&lt;/span>from 0&lt;span class="o">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">To github.com:engeir/paper-publishing-process.git
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> * &lt;span class="o">[&lt;/span>new tag&lt;span class="o">]&lt;/span> v1.0.0 -&amp;gt; v1.0.0&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/figure>
&lt;/div>
&lt;p>And there we have it, our
&lt;a href="https://github.com/engeir/paper-publishing-process/releases/tag/v1.0.0">first release&lt;/a>!
It got its name from what we tagged in the Git Tag (&lt;code>v1.0.0&lt;/code>), a tag that is completely
arbitrary, but in this case follows the SemVer standard. We could just as well have used
CalVer (e.g. &lt;code>vYYYY.MM.P&lt;/code>) &lt;code>v2026.03.0&lt;/code>, or something completely custom like &lt;code>rel1&lt;/code>. We
can even switch standards; the next version can perfectly follow CalVer even if we used
SemVer in the first release. As long as you stick to a consistent standard, use whatever
feels most natural.&lt;/p>
&lt;figure>
&lt;img
srcset="/blog/2026/02/paper-publishing-workflow/first-release_hu9d41787f39a30b6ebc2ab3b330a6fbb0_234793_480x0_resize_q85_h2_lanczos_3.webp 480w,/blog/2026/02/paper-publishing-workflow/first-release_hu9d41787f39a30b6ebc2ab3b330a6fbb0_234793_576x0_resize_q85_h2_lanczos_3.webp 576w,/blog/2026/02/paper-publishing-workflow/first-release_hu9d41787f39a30b6ebc2ab3b330a6fbb0_234793_768x0_resize_q85_h2_lanczos_3.webp 768w,/blog/2026/02/paper-publishing-workflow/first-release_hu9d41787f39a30b6ebc2ab3b330a6fbb0_234793_1025x0_resize_q85_h2_lanczos_3.webp 1025w,/blog/2026/02/paper-publishing-workflow/first-release_hu9d41787f39a30b6ebc2ab3b330a6fbb0_234793_1200x0_resize_q85_h2_lanczos_3.webp 1200w,/blog/2026/02/paper-publishing-workflow/first-release_hu9d41787f39a30b6ebc2ab3b330a6fbb0_234793_1396x0_resize_q85_h2_lanczos_3.webp 1396w"
src="/blog/2026/02/paper-publishing-workflow/first-release_hu9d41787f39a30b6ebc2ab3b330a6fbb0_234793_480x0_resize_q85_bgffffff_lanczos_3.jpg"
width="1396"
height="1440"
decoding="async"
fetchpriority="auto"
loading="lazy"
alt="First release"
class="lazyload blur-up"
>&lt;figcaption>First release&lt;/figcaption>
&lt;/figure>
&lt;p>As an attachment (artifact) to the release we have both &lt;code>paper.zip&lt;/code> and &lt;code>main.pdf&lt;/code>. The
archive &lt;code>paper.zip&lt;/code> contains all files specified in &lt;code>.mise/tasks/package&lt;/code>, and more
specifically in the Bash array &lt;code>files&lt;/code>. It is useful to add all the files needed to
&lt;em>generate&lt;/em> the PDF here, so that when uploading to the journal you can easily pick out
all the files from the archive and upload them, instead of hunting through the repo for
every file you need.&lt;/p>
&lt;details>
&lt;summary>About Git Tag contents&lt;/summary>
In the &lt;code>git tag&lt;/code> command we specified the &lt;code>-a&lt;/code> flag (annotation) and two &lt;code>-m&lt;/code> flags.
They stand for message, but do not become part of the release text we see in the image
above, since that is generated by Git-Cliff. It will however be visible in Git Tags, see
&lt;a href="https://github.com/engeir/paper-publishing-process/tags">Tags&lt;/a>.&lt;/details>
&lt;h2 id="review-cycle-and-revision">Review Cycle and Revision&lt;/h2>
&lt;h3 id="receiving-and-setting-up-a-revision">Receiving and Setting Up a Revision&lt;/h3>
&lt;p>Even if we were perfectly happy with the manuscript we will likely get a review back
with requests to improve certain passages. This is where the good work we put into Git
and versioning really shines.&lt;/p>
&lt;p>We create one final &lt;a href="https://mise.jdx.dev/">mise&lt;/a> task: &lt;code>.mise/tasks/setup-revision&lt;/code>. &lt;em>→
See commit &lt;a href="https://github.com/engeir/paper-publishing-process/commit/b490542">b490542&lt;/a>
(also adds &lt;code>diff*.tex&lt;/code> files to &lt;code>.github/workflows/build.yml&lt;/code>).&lt;/em>&lt;/p>
&lt;p>Let&amp;rsquo;s test it:&lt;/p>
&lt;div class="expressive-code">
&lt;figure class="frame is-terminal not-content">
&lt;figcaption class="header">
&lt;span class="title">&lt;/span>
&lt;/figcaption>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">$ mise run setup-revision
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">[&lt;/span>setup-revision&lt;span class="o">]&lt;/span> $ ~/projects/paper-publishing-process/.mise/tasks/setup-revision
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Setting up revision against v1.0.0...
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Working on main.tex
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Checking out old dir into: /tmp/01jqEMnfHT/latexdiff-vc-v1.0.0 &lt;span class="o">(&lt;/span>rev: v1.0.0&lt;span class="o">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Running: latexdiff &lt;span class="s1">&amp;#39;--flatten&amp;#39;&lt;/span> &lt;span class="s2">&amp;#34;/tmp/01jqEMnfHT/latexdiff-vc-v1.0.0/main.tex&amp;#34;&lt;/span> &lt;span class="s2">&amp;#34;main.tex&amp;#34;&lt;/span> &amp;gt; &lt;span class="s2">&amp;#34;main-diffv1.0.0.tex&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Generated difference file main-diffv1.0.0.tex
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Created:
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> tex/diff-v1.0.0.tex &lt;span class="o">(&lt;/span>latexdiff vs v1.0.0&lt;span class="o">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> tex/review-v1.0.0.tex &lt;span class="o">(&lt;/span>review response skeleton using reviewresponse class&lt;span class="o">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> .mise/tasks/review-v1.0.0/update-refs
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> .mise/tasks/review-v1.0.0/compile
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> .mise/tasks/diff-v1.0.0/create
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> .mise/tasks/diff-v1.0.0/compile
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Next: edit review-v1.0.0.tex, &lt;span class="k">then&lt;/span> mise run compile&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/figure>
&lt;/div>
&lt;p>A full six new files were generated! This includes two TeX files to serve as the
response to reviewers and the diff between the previous Git Tag and the new manuscript,
as well as four mise task files to compile the two TeX files. These depend on some TeX
code we also add:&lt;/p>
&lt;ul>
&lt;li>&lt;code>tex/reviewresponse.cls&lt;/code>: the class used by the review documents&lt;/li>
&lt;li>&lt;code>tex/reviewresponse-extra.sty&lt;/code>: extra TeX code that sets up formatting in the review
documents&lt;/li>
&lt;/ul>
&lt;div class="callout callout-note d-flex flex-row mt-4 mb-4 pt-4 pe-4 pb-2 ps-3">
&lt;svg class="bulb svg-inline callout-icon me-2 mb-3" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentcolor" fill="none" stroke-linecap="round" stroke-linejoin="round">&lt;path stroke="none" d="M0 0h24v24H0z" fill="none"/>&lt;path d="M3 12h1m8-9v1m8 8h1M5.6 5.6l.7.7m12.1-.7-.7.7"/>&lt;path d="M9 16a5 5 0 116 0 3.5 3.5.0 00-1 3 2 2 0 01-4 0 3.5 3.5.0 00-1-3"/>&lt;path d="M9.7 17h4.6"/>&lt;/svg>
&lt;div class="callout-content">
&lt;div class="callout-title">
&lt;p>Wrong Git Tag&lt;/p>
&lt;/div>
&lt;div class="callout-body">
&lt;p>If at some point you think you are ready to submit the manuscript and create a Git Tag
against the latest commit, but then later realize you need to make further changes, you
can easily move or delete Git Tags. If you do not move a misplaced Git Tag the
&lt;code>setup-revision&lt;/code> task will not work as expected, since it would then compare the current
&lt;code>main.tex&lt;/code> against a Git Tag pointing to files that were never submitted to the journal.&lt;/p>
&lt;p>Git Tags can be deleted with &lt;code>git tag --delete &amp;lt;git-tag&amp;gt;&lt;/code>, and attached to a specific
commit with &lt;code>git tag -a &amp;lt;git-tag&amp;gt; &amp;lt;commit-hash&amp;gt; -m &amp;quot;Message&amp;quot;&lt;/code>.&lt;/p>
&lt;/div>
&lt;/div>
&lt;/div>
&lt;p>Let&amp;rsquo;s now run &lt;code>mise watch compile&lt;/code>!&lt;/p>
&lt;video controls preload="auto" width="100%" autoplay loop muted playsinline class="html-video">
&lt;source src="/blog/2026/02/paper-publishing-workflow/compile-all.mp4" type="video/mp4">
&lt;span>Your browser doesn't support embedded videos, but don't worry, you can &lt;a href="/blog/2026/02/paper-publishing-workflow/compile-all.mp4">download it&lt;/a> and watch it with your favorite video player!&lt;/span>
&lt;/video>
&lt;p>So what is actually happening in the video? The video starts right after I ran
&lt;code>mise run setup-revision&lt;/code> which generated the six files for &amp;ldquo;diff&amp;rdquo; and &amp;ldquo;review&amp;rdquo;. First
in the video &lt;code>mise watch compile&lt;/code> is run, which then runs in the background for the
entire video. This single command compiles &lt;code>main.pdf&lt;/code>, &lt;code>review-v1.0.0.pdf&lt;/code> and
&lt;code>diff-v1.0.0.pdf&lt;/code>, and also watches for changes. We then open &lt;code>diff-v1.0.0.pdf&lt;/code> and
&lt;code>review-v1.0.0.pdf&lt;/code>, before making a change to &lt;code>main.tex&lt;/code>. The change becomes
immediately visible in &lt;code>main.pdf&lt;/code> and &lt;code>diff-v1.0.0.pdf&lt;/code>. Finally we make a change in
&lt;code>review-v1.0.0.tex&lt;/code>, which is equally immediately visible in &lt;code>review-v1.0.0.pdf&lt;/code>.&lt;/p>
&lt;p>The diff between the new &lt;code>main.tex&lt;/code>/&lt;code>main.pdf&lt;/code> and the one we submitted in version
&lt;code>v1.0.0&lt;/code> can be generated without the file existing locally. Since we have a Git Tag we
simply refer to it, and compare against the file at that point in Git history. This is
the step where we depend on the &lt;code>.bbl&lt;/code> files, which contain the compiled (exact)
bibliography that was used to generate the PDFs. This is done in the generated &lt;code>create&lt;/code>
tasks with the command&lt;/p>
&lt;div class="expressive-code">
&lt;figure class="frame is-terminal not-content">
&lt;figcaption class="header">
&lt;span class="title">&lt;/span>
&lt;/figcaption>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">latexdiff-vc --force --git --flatten -r &amp;lt;git-tag&amp;gt; main.tex&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/figure>
&lt;/div>
&lt;p>&lt;em>→ See commit
&lt;a href="https://github.com/engeir/paper-publishing-process/commit/68d913f">68d913f&lt;/a> for the new
files.&lt;/em>&lt;/p>
&lt;h3 id="submitting-the-revised-manuscript">Submitting the Revised Manuscript&lt;/h3>
&lt;p>Let&amp;rsquo;s say we are now happy with our latest changes and are ready to submit again to the
journal. We again set a Git Tag on the latest commit, push it and wait for the latest
version to be prepared for us in a neat format.&lt;/p>
&lt;p>Since I personally like CalVer in this context I switch to it now:&lt;/p>
&lt;div class="expressive-code">
&lt;figure class="frame is-terminal not-content">
&lt;figcaption class="header">
&lt;span class="title">&lt;/span>
&lt;/figcaption>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">$ git tag -a v2026.3.0 -m &lt;span class="s2">&amp;#34;**Release v2026.03.0**&amp;#34;&lt;/span> -m &lt;span class="s1">&amp;#39;Answer.&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ git push --tags
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">hk 1.38.0 by @jdx – pre-push – check &lt;span class="o">[=======================================================]&lt;/span> 1/1
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">✔ files - Fetching files between refs/remotes/origin/main and HEAD &lt;span class="o">(&lt;/span>&lt;span class="m">0&lt;/span> files&lt;span class="o">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">✔ bib-filepath
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">bib-filepath stderr:
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">[&lt;/span>check-bib-filepath&lt;span class="o">]&lt;/span> $ &lt;span class="c1">#!/usr/bin/env bash&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Enumerating objects: 1, &lt;span class="k">done&lt;/span>.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Counting objects: 100% &lt;span class="o">(&lt;/span>1/1&lt;span class="o">)&lt;/span>, &lt;span class="k">done&lt;/span>.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Writing objects: 100% &lt;span class="o">(&lt;/span>1/1&lt;span class="o">)&lt;/span>, &lt;span class="m">189&lt;/span> bytes &lt;span class="p">|&lt;/span> 189.00 KiB/s, &lt;span class="k">done&lt;/span>.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Total &lt;span class="m">1&lt;/span> &lt;span class="o">(&lt;/span>delta 0&lt;span class="o">)&lt;/span>, reused &lt;span class="m">0&lt;/span> &lt;span class="o">(&lt;/span>delta 0&lt;span class="o">)&lt;/span>, pack-reused &lt;span class="m">0&lt;/span> &lt;span class="o">(&lt;/span>from 0&lt;span class="o">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">To github.com:engeir/paper-publishing-process.git
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> * &lt;span class="o">[&lt;/span>new tag&lt;span class="o">]&lt;/span> v2026.3.0 -&amp;gt; v2026.3.0&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/figure>
&lt;/div>
&lt;figure>
&lt;img
srcset="/blog/2026/02/paper-publishing-workflow/second-release_hucd9a52a6beacf3c4476cdbbd954326ba_150231_480x0_resize_q85_h2_lanczos_3.webp 480w,/blog/2026/02/paper-publishing-workflow/second-release_hucd9a52a6beacf3c4476cdbbd954326ba_150231_576x0_resize_q85_h2_lanczos_3.webp 576w,/blog/2026/02/paper-publishing-workflow/second-release_hucd9a52a6beacf3c4476cdbbd954326ba_150231_768x0_resize_q85_h2_lanczos_3.webp 768w,/blog/2026/02/paper-publishing-workflow/second-release_hucd9a52a6beacf3c4476cdbbd954326ba_150231_1025x0_resize_q85_h2_lanczos_3.webp 1025w,/blog/2026/02/paper-publishing-workflow/second-release_hucd9a52a6beacf3c4476cdbbd954326ba_150231_1200x0_resize_q85_h2_lanczos_3.webp 1200w,/blog/2026/02/paper-publishing-workflow/second-release_hucd9a52a6beacf3c4476cdbbd954326ba_150231_1396x0_resize_q85_h2_lanczos_3.webp 1396w"
src="/blog/2026/02/paper-publishing-workflow/second-release_hucd9a52a6beacf3c4476cdbbd954326ba_150231_480x0_resize_q85_bgffffff_lanczos_3.jpg"
width="1396"
height="954"
decoding="async"
fetchpriority="auto"
loading="lazy"
alt="Second release, with archive (paper.zip) and the three PDFs"
class="lazyload blur-up"
>&lt;figcaption>Second release, with archive (paper.zip) and the three PDFs&lt;/figcaption>
&lt;/figure>
&lt;p>If we now get further rounds of changes from the reviewers, we simply repeat the same
process:&lt;/p>
&lt;ol>
&lt;li>&lt;code>mise run setup-revision&lt;/code>&lt;/li>
&lt;li>&lt;code>mise watch compile&lt;/code>: Make all changes to &lt;code>main.tex&lt;/code> and &lt;code>review-&amp;lt;git-tag&amp;gt;.tex&lt;/code> as we
see fit&lt;/li>
&lt;li>&lt;code>git commit ...&lt;/code>&lt;/li>
&lt;li>&lt;code>git tag -a '...' -m '...'&lt;/code>&lt;/li>
&lt;li>&lt;code>git push --tags&lt;/code>&lt;/li>
&lt;/ol>
&lt;details>
&lt;summary>Once more&lt;/summary>
&lt;p>Here for example is the output from &lt;code>mise run setup-revision&lt;/code> now after I have created
&lt;code>v2026.03.0&lt;/code>:&lt;/p>
&lt;div class="expressive-code">
&lt;figure class="frame is-terminal not-content">
&lt;figcaption class="header">
&lt;span class="title">&lt;/span>
&lt;/figcaption>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">$ mise run setup-revision
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">[&lt;/span>setup-revision&lt;span class="o">]&lt;/span> $ ~/projects/paper-publishing-process/.mise/tasks/setup-revision
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Setting up revision against v2026.3.0...
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Working on main.tex
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Checking out old dir into: /tmp/UxG9Yg13w5/latexdiff-vc-v2026.3.0 &lt;span class="o">(&lt;/span>rev: v2026.3.0&lt;span class="o">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Running: latexdiff &lt;span class="s1">&amp;#39;--flatten&amp;#39;&lt;/span> &lt;span class="s2">&amp;#34;/tmp/UxG9Yg13w5/latexdiff-vc-v2026.3.0/main.tex&amp;#34;&lt;/span> &lt;span class="s2">&amp;#34;main.tex&amp;#34;&lt;/span> &amp;gt; &lt;span class="s2">&amp;#34;main-diffv2026.3.0.tex&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Generated difference file main-diffv2026.3.0.tex
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Created:
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> tex/diff-v2026.3.0.tex &lt;span class="o">(&lt;/span>latexdiff vs v2026.3.0&lt;span class="o">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> tex/review-v2026.3.0.tex &lt;span class="o">(&lt;/span>review response skeleton using reviewresponse class&lt;span class="o">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> .mise/tasks/review-v2026.3.0/update-refs
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> .mise/tasks/review-v2026.3.0/compile
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> .mise/tasks/diff-v2026.3.0/create
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> .mise/tasks/diff-v2026.3.0/compile
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Next: edit review-v2026.3.0.tex, &lt;span class="k">then&lt;/span> mise run compile&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/figure>
&lt;/div>
&lt;p>And then &lt;code>mise run compile&lt;/code>. Notice &lt;code>review-v1.0.0: skipping, newer revision exists&lt;/code>,
and the corresponding for &amp;ldquo;diff&amp;rdquo;. Nothing is compiled unless it is truly necessary!&lt;/p>
&lt;div class="expressive-code">
&lt;figure class="frame is-terminal not-content">
&lt;figcaption class="header">
&lt;span class="title">&lt;/span>
&lt;/figcaption>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">$ mise run compile
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">[&lt;/span>localize-bib-paths&lt;span class="o">]&lt;/span> $ &lt;span class="c1">#!/usr/bin/env bash&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">[&lt;/span>main:update-refs&lt;span class="o">]&lt;/span> $ bibfish -c &lt;span class="s1">&amp;#39;cite,citet,citep,citeA&amp;#39;&lt;/span> -f main.tex ../main-ref.bib main.bib
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">[&lt;/span>review-v1.0.0:update-refs&lt;span class="o">]&lt;/span> $ ~/projects/paper-publishing-process/.mise/tasks/review-v1.0.0/update…
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">[&lt;/span>review-v2026.3.0:update-refs&lt;span class="o">]&lt;/span> $ ~/projects/paper-publishing-process/.mise/tasks/review-v2026.3.0/…
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">[&lt;/span>diff-v1.0.0:create&lt;span class="o">]&lt;/span> $ ~/projects/paper-publishing-process/.mise/tasks/diff-v1.0.0/create
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">review-v1.0.0: skipping, newer revision exists
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">[&lt;/span>diff-v2026.3.0:create&lt;span class="o">]&lt;/span> $ ~/projects/paper-publishing-process/.mise/tasks/diff-v2026.3.0/create
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">diff-v1.0.0: skipping, newer revision exists
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">[&lt;/span>review-v1.0.0:compile&lt;span class="o">]&lt;/span> $ ~/projects/paper-publishing-process/.mise/tasks/review-v1.0.0/compile
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">[&lt;/span>diff-v1.0.0:compile&lt;span class="o">]&lt;/span> $ ~/projects/paper-publishing-process/.mise/tasks/diff-v1.0.0/compile
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">review-v1.0.0: skipping, newer revision exists
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">diff-v1.0.0: skipping, newer revision exists
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Working on main.tex
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Checking out old dir into: /tmp/jXriCzZY0z/latexdiff-vc-v2026.3.0 &lt;span class="o">(&lt;/span>rev: v2026.3.0&lt;span class="o">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Running: latexdiff &lt;span class="s1">&amp;#39;--flatten&amp;#39;&lt;/span> &lt;span class="s2">&amp;#34;/tmp/jXriCzZY0z/latexdiff-vc-v2026.3.0/main.tex&amp;#34;&lt;/span> &lt;span class="s2">&amp;#34;main.tex&amp;#34;&lt;/span> &amp;gt; &lt;span class="s2">&amp;#34;main-diffv2026.3.0.tex&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Generated difference file main-diffv2026.3.0.tex
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">[&lt;/span>main:compile&lt;span class="o">]&lt;/span> $ latexmk -pdf -g -f -silent -recorder- main.tex
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">[&lt;/span>review-v2026.3.0:compile&lt;span class="o">]&lt;/span> $ ~/projects/paper-publishing-process/.mise/tasks/review-v2026.3.0/comp…
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="o">[&lt;/span>diff-v2026.3.0:compile&lt;span class="o">]&lt;/span> $ ~/projects/paper-publishing-process/.mise/tasks/diff-v2026.3.0/compile
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Rc files read:
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> NONE
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Latexmk: Run number &lt;span class="m">1&lt;/span> of rule &lt;span class="s1">&amp;#39;bibtex main&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Rc files read:
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> NONE
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Latexmk: Run number &lt;span class="m">1&lt;/span> of rule &lt;span class="s1">&amp;#39;pdflatex&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Rc files read:
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> NONE
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Latexmk: Run number &lt;span class="m">1&lt;/span> of rule &lt;span class="s1">&amp;#39;pdflatex&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">This is pdfTeX, Version 3.141592653-2.6-1.40.29 &lt;span class="o">(&lt;/span>TeX Live 2026&lt;span class="o">)&lt;/span> &lt;span class="o">(&lt;/span>preloaded &lt;span class="nv">format&lt;/span>&lt;span class="o">=&lt;/span>pdflatex&lt;span class="o">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> restricted &lt;span class="se">\w&lt;/span>rite18 enabled.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Latexmk: Run number &lt;span class="m">1&lt;/span> of rule &lt;span class="s1">&amp;#39;pdflatex&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">This is pdfTeX, Version 3.141592653-2.6-1.40.29 &lt;span class="o">(&lt;/span>TeX Live 2026&lt;span class="o">)&lt;/span> &lt;span class="o">(&lt;/span>preloaded &lt;span class="nv">format&lt;/span>&lt;span class="o">=&lt;/span>pdflatex&lt;span class="o">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> restricted &lt;span class="se">\w&lt;/span>rite18 enabled.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">This is pdfTeX, Version 3.141592653-2.6-1.40.29 &lt;span class="o">(&lt;/span>TeX Live 2026&lt;span class="o">)&lt;/span> &lt;span class="o">(&lt;/span>preloaded &lt;span class="nv">format&lt;/span>&lt;span class="o">=&lt;/span>pdflatex&lt;span class="o">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> restricted &lt;span class="se">\w&lt;/span>rite18 enabled.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">entering extended mode
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">entering extended mode
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">entering extended mode
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Latexmk: Getting log file &lt;span class="s1">&amp;#39;main.log&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Latexmk: Using bibtex to make bibliography file&lt;span class="o">(&lt;/span>s&lt;span class="o">)&lt;/span>.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">===&lt;/span>Source file &lt;span class="s1">&amp;#39;main.bbl&amp;#39;&lt;/span> &lt;span class="k">for&lt;/span> &lt;span class="s1">&amp;#39;pdflatex&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Latexmk: Getting log file &lt;span class="s1">&amp;#39;diff-v2026.3.0.log&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Latexmk: Using bibtex to make bibliography file&lt;span class="o">(&lt;/span>s&lt;span class="o">)&lt;/span>.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Latexmk: Run number &lt;span class="m">2&lt;/span> of rule &lt;span class="s1">&amp;#39;pdflatex&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">This is pdfTeX, Version 3.141592653-2.6-1.40.29 &lt;span class="o">(&lt;/span>TeX Live 2026&lt;span class="o">)&lt;/span> &lt;span class="o">(&lt;/span>preloaded &lt;span class="nv">format&lt;/span>&lt;span class="o">=&lt;/span>pdflatex&lt;span class="o">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> restricted &lt;span class="se">\w&lt;/span>rite18 enabled.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">entering extended mode
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Latexmk: Getting log file &lt;span class="s1">&amp;#39;diff-v2026.3.0.log&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Latexmk: Using bibtex to make bibliography file&lt;span class="o">(&lt;/span>s&lt;span class="o">)&lt;/span>.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Latexmk: Getting log file &lt;span class="s1">&amp;#39;review-v2026.3.0.log&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Latexmk: Missing bbl file &lt;span class="s1">&amp;#39;review-v2026.3.0.bbl&amp;#39;&lt;/span> in following:
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> No file review-v2026.3.0.bbl.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Latexmk: Using bibtex to make bibliography file&lt;span class="o">(&lt;/span>s&lt;span class="o">)&lt;/span>.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">===&lt;/span>Source file &lt;span class="s1">&amp;#39;review-v2026.3.0.bbl&amp;#39;&lt;/span> &lt;span class="k">for&lt;/span> &lt;span class="s1">&amp;#39;pdflatex&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Create bibtex review-v2026.3.0
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Latexmk: Run number &lt;span class="m">1&lt;/span> of rule &lt;span class="s1">&amp;#39;bibtex review-v2026.3.0&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Latexmk: Run number &lt;span class="m">2&lt;/span> of rule &lt;span class="s1">&amp;#39;pdflatex&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">This is pdfTeX, Version 3.141592653-2.6-1.40.29 &lt;span class="o">(&lt;/span>TeX Live 2026&lt;span class="o">)&lt;/span> &lt;span class="o">(&lt;/span>preloaded &lt;span class="nv">format&lt;/span>&lt;span class="o">=&lt;/span>pdflatex&lt;span class="o">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> restricted &lt;span class="se">\w&lt;/span>rite18 enabled.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">entering extended mode
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Latexmk: Getting log file &lt;span class="s1">&amp;#39;review-v2026.3.0.log&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Latexmk: Using bibtex to make bibliography file&lt;span class="o">(&lt;/span>s&lt;span class="o">)&lt;/span>.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">===&lt;/span>Source file &lt;span class="s1">&amp;#39;review-v2026.3.0.bbl&amp;#39;&lt;/span> &lt;span class="k">for&lt;/span> &lt;span class="s1">&amp;#39;pdflatex&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Latexmk: Run number &lt;span class="m">2&lt;/span> of rule &lt;span class="s1">&amp;#39;bibtex review-v2026.3.0&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Latexmk: Run number &lt;span class="m">3&lt;/span> of rule &lt;span class="s1">&amp;#39;pdflatex&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">This is pdfTeX, Version 3.141592653-2.6-1.40.29 &lt;span class="o">(&lt;/span>TeX Live 2026&lt;span class="o">)&lt;/span> &lt;span class="o">(&lt;/span>preloaded &lt;span class="nv">format&lt;/span>&lt;span class="o">=&lt;/span>pdflatex&lt;span class="o">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> restricted &lt;span class="se">\w&lt;/span>rite18 enabled.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">entering extended mode
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Latexmk: Getting log file &lt;span class="s1">&amp;#39;review-v2026.3.0.log&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Latexmk: Using bibtex to make bibliography file&lt;span class="o">(&lt;/span>s&lt;span class="o">)&lt;/span>.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">===&lt;/span>Source file &lt;span class="s1">&amp;#39;review-v2026.3.0.bbl&amp;#39;&lt;/span> &lt;span class="k">for&lt;/span> &lt;span class="s1">&amp;#39;pdflatex&amp;#39;&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/figure>
&lt;/div>
&lt;p>And this is what the
&lt;a href="https://github.com/engeir/paper-publishing-process/releases/tag/v2026.3.1">latest release&lt;/a>
looks like after the final necessary changes were made, ready to be published!&lt;/p>
&lt;/details>
&lt;h2 id="finalizing-and-readme">Finalizing and README&lt;/h2>
&lt;p>The repo now works fully to both easily prepare a manuscript for submission, and to
create a response and diff/change document for any reviewers.&lt;/p>
&lt;p>But to make the repo itself a little more inviting it is good practice to also create a
README file. With all the releases we have created and their artifacts it is easy to
link to files at different stages of the process.&lt;/p>
&lt;div class="expressive-code">
&lt;figure class="frame not-content">
&lt;figcaption class="header">
&lt;span class="title">&lt;/span>
&lt;/figcaption>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-markdown" data-lang="markdown">&lt;span class="line">&lt;span class="cl">&lt;span class="gh"># Paper publishing process
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="gh">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Please see the
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">[&lt;span class="nt">release page&lt;/span>](&lt;span class="na">https://github.com/engeir/paper-publishing-process/releases&lt;/span>) for the
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">latest version of the manuscript and the generated PDF.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">&amp;gt; &lt;/span>&lt;span class="ge">[!TIP]
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="ge">&lt;/span>&lt;span class="k">&amp;gt;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">&lt;/span>&lt;span class="ge">&amp;gt; Download the latest release of the manuscript
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="ge">&lt;/span>&lt;span class="k">&amp;gt; &lt;/span>&lt;span class="ge">[here](https://github.com/engeir/paper-publishing-process/releases/latest/download/main.pdf).
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="ge">&lt;/span>&lt;span class="k">&amp;gt;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">&lt;/span>&lt;span class="ge">&amp;gt; If you want to see the manuscript at the latest commit, download the artefact of the
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="ge">&lt;/span>&lt;span class="k">&amp;gt; &lt;/span>&lt;span class="ge">last
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="ge">&lt;/span>&lt;span class="k">&amp;gt; &lt;/span>&lt;span class="ge">[workflow action](https://github.com/engeir/paper-publishing-process/actions/workflows/release.yml).
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="ge">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="gu">## More
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="gu">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="gu">### Review 1
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="gu">&lt;/span>&lt;span class="k">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">&amp;gt; &lt;/span>&lt;span class="ge">All relevant files used for the reply in review 1 can be found in the
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="ge">&lt;/span>&lt;span class="k">&amp;gt; &lt;/span>&lt;span class="ge">[artefacts of v2026.3.0](https://github.com/engeir/paper-publishing-process/releases/tag/v2026.3.0).
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="ge">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">-&lt;/span> The paper as it was sent in before review 1 is provided as
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> [&lt;span class="nt">main.pdf&lt;/span>](&lt;span class="na">https://github.com/engeir/paper-publishing-process/releases/download/v1.0.0/main.pdf&lt;/span>)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> in v1.0.0, while the current manuscript is available as
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> [&lt;span class="nt">main.pdf&lt;/span>](&lt;span class="na">https://github.com/engeir/paper-publishing-process/releases/download/v2026.3.0/main.pdf&lt;/span>).
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">-&lt;/span> The reply to review 1 is provided as
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> [&lt;span class="nt">review-v1.0.0.pdf&lt;/span>](&lt;span class="na">https://github.com/engeir/paper-publishing-process/releases/download/v2026.3.0/review-v1.0.0.pdf&lt;/span>),
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> and as part of the
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> [&lt;span class="nt">latest artefact&lt;/span>](&lt;span class="na">https://github.com/engeir/paper-publishing-process/actions/workflows/release.yml?query=branch%3Amain&lt;/span>).
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">-&lt;/span> The difference file for review 1 is provided as
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> [&lt;span class="nt">diff-v1.0.0.pdf&lt;/span>](&lt;span class="na">https://github.com/engeir/paper-publishing-process/releases/download/v2026.3.0/diff-v1.0.0.pdf&lt;/span>),
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> and as part of the
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> [&lt;span class="nt">latest artefact&lt;/span>](&lt;span class="na">https://github.com/engeir/paper-publishing-process/actions/workflows/release.yml?query=branch%3Amain&lt;/span>).
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="gu">### Review 2
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="gu">&lt;/span>&lt;span class="k">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">&amp;gt; &lt;/span>&lt;span class="ge">All relevant files used for the reply in review 1 can be found in the
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="ge">&lt;/span>&lt;span class="k">&amp;gt; &lt;/span>&lt;span class="ge">[artefacts of v2026.3.1](https://github.com/engeir/paper-publishing-process/releases/tag/v2026.3.1).
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="ge">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">-&lt;/span> The paper as it was sent in before review 2 is provided as
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> [&lt;span class="nt">main.pdf&lt;/span>](&lt;span class="na">https://github.com/engeir/paper-publishing-process/releases/download/v2026.3.0/main.pdf&lt;/span>)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> in v2026.3.0, while the current manuscript is available as
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> [&lt;span class="nt">main.pdf&lt;/span>](&lt;span class="na">https://github.com/engeir/paper-publishing-process/releases/download/v2026.3.1/main.pdf&lt;/span>).
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">-&lt;/span> The reply to review 2 is provided as
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> [&lt;span class="nt">review-v2026.3.0.pdf&lt;/span>](&lt;span class="na">https://github.com/engeir/paper-publishing-process/releases/download/v2026.3.1/review-v2026.3.0.pdf&lt;/span>),
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> and as part of the
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> [&lt;span class="nt">latest artefact&lt;/span>](&lt;span class="na">https://github.com/engeir/paper-publishing-process/actions/workflows/release.yml?query=branch%3Amain&lt;/span>).
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">-&lt;/span> The difference file for review 2 is provided as
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> [&lt;span class="nt">diff-v2026.3.0.pdf&lt;/span>](&lt;span class="na">https://github.com/engeir/paper-publishing-process/releases/download/v2026.3.1/diff-v2026.3.0.pdf&lt;/span>),
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> or as part of the
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> [&lt;span class="nt">latest artefact&lt;/span>](&lt;span class="na">https://github.com/engeir/paper-publishing-process/actions/workflows/release.yml?query=branch%3Amain&lt;/span>).&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/figure>
&lt;/div>
&lt;p>&lt;em>→ See commit
&lt;a href="https://github.com/engeir/paper-publishing-process/commit/b3cbc9d">b3cbc9d&lt;/a> for the
changes made to &lt;code>README.md&lt;/code>.&lt;/em>&lt;/p>
&lt;h2 id="further-extensions">Further Extensions&lt;/h2>
&lt;h3 id="changelog">Changelog&lt;/h3>
&lt;p>We have already set up quite a lot of automation, but we can of course continue even
further. Git-Cliff can be configured to write to a file, typically called
&lt;code>CHANGELOG.md&lt;/code>, so that in addition to having changes between versions in each release,
the entire changelog lives in that file.&lt;/p>
&lt;h3 id="pr-based-versioning">PR-Based Versioning&lt;/h3>
&lt;p>You can also set up PR-based (pull request) versioning that uses
&lt;a href="https://www.conventionalcommits.org/en/v1.0.0/">Conventional commits&lt;/a> to automatically
generate new release proposals. This requires a slightly larger change to the
configuration in GitHub CI/CD.&lt;/p>
&lt;h3 id="pinning-github-actions-versions">Pinning GitHub Actions Versions&lt;/h3>
&lt;p>As you may have noticed, all actions used in the GitHub workflow are specified with a
long hash, followed by a comment describing which version it points to. This is good
practice because, as briefly mentioned earlier, Git Tags are &amp;ldquo;mutable&amp;rdquo;; they can be
changed and moved. This makes them a potential attack surface, and it is therefore safer
to specify the commit hash, since it is &amp;ldquo;immutable&amp;rdquo;, unchangeable.&lt;/p>
&lt;p>To easily stay up to date with the latest versions you can use
&lt;a href="https://github.com/suzuki-shunsuke/pinact-action">pinact-action&lt;/a>, but this will need a
TOKEN with permissions to write to the &lt;code>.github/workflows&lt;/code> files.&lt;/p>
&lt;h3 id="even-more-mise-magic">Even More mise Magic&lt;/h3>
&lt;p>We have already established that mise-en-place is excellent software, and it can do a
little more. Three commands that are useful for having a repo that is both easy to set
up and has a well-documented flow:&lt;/p>
&lt;div class="expressive-code">
&lt;figure class="frame is-terminal not-content">
&lt;figcaption class="header">
&lt;span class="title">&lt;/span>
&lt;/figcaption>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">mise lock
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">mise generate bootstrap &amp;gt;MISE_BOOTSTRAP.sh
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">mise generate task-docs &amp;gt;TASKS.md&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/figure>
&lt;/div>
&lt;p>The first command writes a file with locked versions adapted for installation on all
common platforms. The second command generates a shell script that installs the same
version of mise-en-place currently in use, while the last command generates
documentation for all tasks defined with mise-en-place.&lt;/p>
&lt;p>&lt;em>→ See commit
&lt;a href="https://github.com/engeir/paper-publishing-process/commit/9c1fb30">9c1fb30&lt;/a> for files
adding functionality for &lt;a href="#pinning-github-actions-versions">pinning actions versions&lt;/a>
and &lt;a href="#even-more-mise-magic">mise bootstrapping&lt;/a>.&lt;/em>&lt;/p></content:encoded></item><item><title>Self-hosting Whoogle using docker</title><link>/blog/2023/08/self-hosting-whoogle-using-docker/</link><pubDate>Sat, 19 Aug 2023 22:35:06 +0200</pubDate><guid>/blog/2023/08/self-hosting-whoogle-using-docker/</guid><description>Setting up my own Whoogle search enigne on an Nginx server</description><content:encoded>&lt;p>For some time I have been hosting my own website and a few subdomains on a server I rent
via &lt;a href="https://www.vultr.com/">Vultr&lt;/a>, but all of it have been placed directly in
directories on the server itself. It&amp;rsquo;s all just been built sites lying there, with
access to the internet via the domain I own.&lt;/p>
&lt;p>But that ends today, as I am now running my own version of the
&lt;a href="https://github.com/benbusby/whoogle-search">Whoogle&lt;/a> search engine on my server via
docker, that I can access from anywhere as the subdomain
&lt;a href="https://whoogle.eirik.re">whoogle.eirik.re&lt;/a>.&lt;/p>
&lt;h2 id="whoogle">Whoogle&lt;/h2>
&lt;p>Whoogle is a nice open source project that is &amp;ldquo;a self-hosted, ad-free,
privacy-respecting metasearch engine&amp;rdquo;. It can be installed in a number of ways: from
source, via &lt;a href="https://pypi.org">PyPI&lt;/a> or via docker, to name a few.&lt;/p>
&lt;p>Running it on my computers via docker and accessing it on
&lt;a href="http://localhost:5000">&lt;code>http://localhost:5000&lt;/code>&lt;/a> has been my go-to way for a long time,
but that leaves my phone out of the fun, so this is the attempt to have a complete
set-up for all my devices at once.&lt;/p>
&lt;h3 id="dockerize-env">Dockerize env&lt;/h3>
&lt;p>Before setting up the docker image, let us first figure out how we can easily configure
this via environment variables. &lt;a href="https://github.com/benbusby/whoogle-search#environment-variables">Whoogle support many of
them&lt;/a>, so it&amp;rsquo;s good to
know how to deal with that right away.&lt;/p>
&lt;p>One issue is when setting the colour theme, which spans many lines, since &lt;a href="https://github.com/moby/moby/issues/12997">docker cannot
pass newlines from variables in &lt;code>--env-file&lt;/code>
files&lt;/a>. We solve this with a handy little
script called &lt;a href="https://gist.github.com/hudon/149466af21dfc52fdc70">dockerize-env&lt;/a>. It&amp;rsquo;s
described how to use it in the script, but in short, you define all variables in &lt;code>.env&lt;/code>:&lt;/p>
&lt;div class="expressive-code">
&lt;figure class="frame has-title not-content">
&lt;figcaption class="header">
&lt;span class="title">.env&lt;/span>
&lt;/figcaption>
&lt;div class="highlight" title=".env">&lt;pre tabindex="0" class="chroma">&lt;code class="language-env" data-lang="env">&lt;span class="line">&lt;span class="cl">&lt;span class="nv">WHOOGLE_CONFIG_LANGUAGE&lt;/span>&lt;span class="o">=&lt;/span>lang_no
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">WHOOGLE_CONFIG_COUNTRY&lt;/span>&lt;span class="o">=&lt;/span>NO
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">WHOOGLE_CONFIG_BLOCK&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;w3schools.com,w3schools.blog,w3schools.in,w3schools.io,w3schools.me&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">WHOOGLE_CONFIG_DARK&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="m">1&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">WHOOGLE_CONFIG_GET_ONLY&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="m">1&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/figure>
&lt;/div>
&lt;p>Then you run&lt;/p>
&lt;div class="expressive-code">
&lt;figure class="frame is-terminal has-title not-content">
&lt;figcaption class="header">
&lt;span class="title">Creating variables for a dummy container named &amp;#39;my_container&amp;#39;&lt;/span>
&lt;/figcaption>
&lt;div class="highlight" title="Creating variables for a dummy container named 'my_container'">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">dockerize-env .env
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">source&lt;/span> .env.exported &lt;span class="o">&amp;amp;&amp;amp;&lt;/span> docker run --env-file .env.vars &amp;lt;my_container&amp;gt;&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/figure>
&lt;/div>
&lt;h3 id="docker">Docker&lt;/h3>
&lt;p>So what is the container we are running? The image is called &lt;code>benbusby/whoogle-search&lt;/code>,
so we first pull it down with&lt;/p>
&lt;div class="expressive-code">
&lt;figure class="frame is-terminal has-title not-content">
&lt;figcaption class="header">
&lt;span class="title">Pull down the docker image&lt;/span>
&lt;/figcaption>
&lt;div class="highlight" title="Pull down the docker image">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">docker pull benbusby/whoogle-search&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/figure>
&lt;/div>
&lt;p>before we fix our environment variables and start the container:&lt;/p>
&lt;div class="expressive-code">
&lt;figure class="frame is-terminal has-title not-content">
&lt;figcaption class="header">
&lt;span class="title">Create variables and run the whoogle container&lt;/span>
&lt;/figcaption>
&lt;div class="highlight" title="Create variables and run the whoogle container">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">dockerize-env .env
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">source&lt;/span> .env.exported &lt;span class="o">&amp;amp;&amp;amp;&lt;/span> docker run --publish 5000:5000 --detach --env-file .env.vars --name whoogle-search benbusby/whoogle-search:latest&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/figure>
&lt;/div>
&lt;p>At this point, a whoogle search should be available at
&lt;a href="http://localhost:5000">&lt;code>http://localhost:5000&lt;/code>&lt;/a>!&lt;/p>
&lt;h2 id="self-hosting">Self-hosting&lt;/h2>
&lt;p>The tricky part for me was to understand how I would take this to my server where I am
running &lt;a href="https://nginx.org/en/">Nginx&lt;/a> as a reverse proxy server with https
using &lt;a href="https://certbot.eff.org/">certbot&lt;/a>, when I am not just pointing to local files,
but are running software in a container. Suddenly you have to deal with the IP address
of the container and different ports that the image expects.&lt;/p>
&lt;h3 id="nginx-and-setting-up-a-website">Nginx and setting up a website&lt;/h3>
&lt;p>I first got started with my website by following along the guide at
&lt;a href="https://landchad.net">landchad.net&lt;/a>, which is why I&amp;rsquo;m using Vultr and Nginx (and
&lt;a href="https://www.epik.com/">Epik&lt;/a>) in the first place. This also means that my static site
at &lt;a href="https://eirik.re">eirik.re&lt;/a> is configured via a file in &lt;code>/etc/nginx/sites-available/&lt;/code> as&lt;/p>
&lt;div class="expressive-code">
&lt;figure class="frame has-title not-content">
&lt;figcaption class="header">
&lt;span class="title">/etc/nginx/sites-available/eirikre&lt;/span>
&lt;/figcaption>
&lt;div class="highlight" title="/etc/nginx/sites-available/eirikre">&lt;pre tabindex="0" class="chroma">&lt;code class="language-nginx" data-lang="nginx">&lt;span class="line">&lt;span class="cl">&lt;span class="k">server&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">listen&lt;/span> &lt;span class="mi">80&lt;/span> &lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">listen&lt;/span> &lt;span class="s">[::]:80&lt;/span> &lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">server_name&lt;/span> &lt;span class="s">eirik.re&lt;/span> &lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">root&lt;/span> &lt;span class="s">/var/www/eirikre&lt;/span> &lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">index&lt;/span> &lt;span class="s">index.html&lt;/span> &lt;span class="s">index.htm&lt;/span> &lt;span class="s">index.nginx-debian.html&lt;/span> &lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">location&lt;/span> &lt;span class="s">/&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">try_files&lt;/span> &lt;span class="nv">$uri&lt;/span> &lt;span class="nv">$uri/&lt;/span> &lt;span class="p">=&lt;/span>&lt;span class="mi">404&lt;/span> &lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/figure>
&lt;/div>
&lt;p>So, what do we need to adjust in this to have a new file for our whoogle subdomain?&lt;/p>
&lt;h3 id="putting-it-all-together">Putting it all together&lt;/h3>
&lt;p>From the domain registrars point of view, I didn&amp;rsquo;t need to do anything. Following the
&lt;a href="https://landchad.net">landchad.net&lt;/a> guide will make us redirect all subdomains to
nginx, and if they are not configured, show us the default error message:&lt;/p>
&lt;figure>
&lt;img
srcset="/blog/2023/08/self-hosting-whoogle-using-docker/welcome-to-nginx_huc11f795d8371262b1451d89c8b85d50e_180980_480x0_resize_q85_h2_lanczos.webp 480w,/blog/2023/08/self-hosting-whoogle-using-docker/welcome-to-nginx_huc11f795d8371262b1451d89c8b85d50e_180980_576x0_resize_q85_h2_lanczos.webp 576w,/blog/2023/08/self-hosting-whoogle-using-docker/welcome-to-nginx_huc11f795d8371262b1451d89c8b85d50e_180980_768x0_resize_q85_h2_lanczos.webp 768w,/blog/2023/08/self-hosting-whoogle-using-docker/welcome-to-nginx_huc11f795d8371262b1451d89c8b85d50e_180980_1025x0_resize_q85_h2_lanczos.webp 1025w,/blog/2023/08/self-hosting-whoogle-using-docker/welcome-to-nginx_huc11f795d8371262b1451d89c8b85d50e_180980_1200x0_resize_q85_h2_lanczos.webp 1200w,/blog/2023/08/self-hosting-whoogle-using-docker/welcome-to-nginx_huc11f795d8371262b1451d89c8b85d50e_180980_1440x0_resize_q85_h2_lanczos.webp 1440w,/blog/2023/08/self-hosting-whoogle-using-docker/welcome-to-nginx_huc11f795d8371262b1451d89c8b85d50e_180980_3320x0_resize_q85_h2_lanczos.webp 3320w"
src="/blog/2023/08/self-hosting-whoogle-using-docker/welcome-to-nginx_huc11f795d8371262b1451d89c8b85d50e_180980_480x0_resize_q85_lanczos.jpg"
width="3320"
height="838"
decoding="async"
fetchpriority="auto"
loading="lazy"
alt=""
class="lazyload blur-up"
>&lt;figcaption>Page shown when visiting whoogle.eirik.re before updating the nginx settings&lt;/figcaption>
&lt;/figure>
&lt;blockquote>
&lt;p>You can see a live example by visiting any subdomain that is not yet configured, for
example &lt;a href="http://no-subdomain-here.eirik.re">no-subdomain-here.eirik.re&lt;/a>.&lt;/p>
&lt;/blockquote>
&lt;p>Therefore, after running the commands from before, but this time on my server&lt;/p>
&lt;div class="expressive-code">
&lt;figure class="frame is-terminal not-content">
&lt;figcaption class="header">
&lt;span class="title">&lt;/span>
&lt;/figcaption>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">dockerize-env .env
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">source&lt;/span> .env.exported &lt;span class="o">&amp;amp;&amp;amp;&lt;/span> docker run --publish 5000:5000 --detach --env-file .env.vars --name whoogle-search benbusby/whoogle-search:latest&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/figure>
&lt;/div>
&lt;p>I checked which IP address the docker container was using:&lt;/p>
&lt;div class="expressive-code">
&lt;figure class="frame not-content">
&lt;figcaption class="header">
&lt;span class="title">&lt;/span>
&lt;/figcaption>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-console" data-lang="console">&lt;span class="line">&lt;span class="cl">&lt;span class="gp">$&lt;/span> ip a
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="go">...
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="go">3: docker0: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 qdisc noqueue state UP group default
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="go"> link/ether 02:42:55:9c:07:3c brd ff:ff:ff:ff:ff:ff
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="go"> inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="go"> valid_lft forever preferred_lft forever
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="go"> inet6 fe80::42:55ff:fe9c:73c/64 scope link
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="go"> valid_lft forever preferred_lft forever
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="go">...
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/figure>
&lt;/div>
&lt;p>The &lt;code>ip a&lt;/code> command gives a lot of output, but you can find docker listed there, and
after &lt;code>inet&lt;/code> on the second line of the docker block, we find the IP address as
&lt;code>172.17.0.1&lt;/code>! From the Whoogle README we actually do get an &lt;a href="https://github.com/benbusby/whoogle-search#nginx">Nginx configuration
file&lt;/a> that &amp;ldquo;works&amp;rdquo;, but having the
actual IP address was crucial to get &lt;code>certbot&lt;/code> to accept it. So we make a tiny change to
the config file, so that it now reads&lt;/p>
&lt;div class="expressive-code">
&lt;figure class="frame has-title not-content">
&lt;figcaption class="header">
&lt;span class="title">/etc/nginx/sites-available/whoogle&lt;/span>
&lt;/figcaption>
&lt;div class="highlight" title="/etc/nginx/sites-available/whoogle">&lt;pre tabindex="0" class="chroma">&lt;code class="language-nginx" data-lang="nginx">&lt;span class="line">&lt;span class="cl">&lt;span class="k">server&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">server_name&lt;/span> &lt;span class="s">whoogle.eirik.re&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">access_log&lt;/span> &lt;span class="s">/dev/null&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">error_log&lt;/span> &lt;span class="s">/dev/null&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">location&lt;/span> &lt;span class="s">/&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">proxy_set_header&lt;/span> &lt;span class="s">X-Real-IP&lt;/span> &lt;span class="nv">$remote_addr&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">proxy_set_header&lt;/span> &lt;span class="s">X-Forwarded-For&lt;/span> &lt;span class="nv">$proxy_add_x_forwarded_for&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">proxy_set_header&lt;/span> &lt;span class="s">X-Forwarded-Proto&lt;/span> &lt;span class="nv">$scheme&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">proxy_set_header&lt;/span> &lt;span class="s">Host&lt;/span> &lt;span class="nv">$host&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">proxy_set_header&lt;/span> &lt;span class="s">X-NginX-Proxy&lt;/span> &lt;span class="s">true&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># proxy_pass http://localhost:5000;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="kn">proxy_pass&lt;/span> &lt;span class="s">http://172.17.0.1:5000&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/figure>
&lt;/div>
&lt;p>The important change here is that instead of using &lt;code>localhost&lt;/code>, we use the IP of our
docker container. (I also tried to use both &lt;code>proxy_pass&lt;/code> variables, but that doesn&amp;rsquo;t
work. You can only have one &lt;code>proxy_pass&lt;/code> variable.) We then save this to
&lt;code>/etc/nginx/sites-available/whoogle&lt;/code> and symlink it to &lt;code>sites-enabled&lt;/code> with&lt;/p>
&lt;div class="expressive-code">
&lt;figure class="frame is-terminal has-title not-content">
&lt;figcaption class="header">
&lt;span class="title">Link the site to enablabed sites&lt;/span>
&lt;/figcaption>
&lt;div class="highlight" title="Link the site to enablabed sites">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">ln -s /etc/nginx/sites-available/whoogle /etc/nginx/sites-enabled/&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/figure>
&lt;/div>
&lt;p>Let us now restart Nginx so that it is aware of our new site&lt;/p>
&lt;div class="expressive-code">
&lt;figure class="frame is-terminal has-title not-content">
&lt;figcaption class="header">
&lt;span class="title">Reload nginx&lt;/span>
&lt;/figcaption>
&lt;div class="highlight" title="Reload nginx">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">systemctl reload nginx&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/figure>
&lt;/div>
&lt;p>and then run &lt;code>certbot&lt;/code> to get our certificates and make the site use https&lt;/p>
&lt;div class="expressive-code">
&lt;figure class="frame is-terminal has-title not-content">
&lt;figcaption class="header">
&lt;span class="title">Create certificates for whoogle.eirik.re&lt;/span>
&lt;/figcaption>
&lt;div class="highlight" title="Create certificates for whoogle.eirik.re">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">certbot --nginx&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;/figure>
&lt;/div>
&lt;p>Let us spectate the greate success!&lt;/p>
&lt;figure>
&lt;img
srcset="/blog/2023/08/self-hosting-whoogle-using-docker/whoogle-desktop_huc11f795d8371262b1451d89c8b85d50e_221261_480x0_resize_q85_h2_lanczos.webp 480w,/blog/2023/08/self-hosting-whoogle-using-docker/whoogle-desktop_huc11f795d8371262b1451d89c8b85d50e_221261_576x0_resize_q85_h2_lanczos.webp 576w,/blog/2023/08/self-hosting-whoogle-using-docker/whoogle-desktop_huc11f795d8371262b1451d89c8b85d50e_221261_768x0_resize_q85_h2_lanczos.webp 768w,/blog/2023/08/self-hosting-whoogle-using-docker/whoogle-desktop_huc11f795d8371262b1451d89c8b85d50e_221261_1025x0_resize_q85_h2_lanczos.webp 1025w,/blog/2023/08/self-hosting-whoogle-using-docker/whoogle-desktop_huc11f795d8371262b1451d89c8b85d50e_221261_1200x0_resize_q85_h2_lanczos.webp 1200w,/blog/2023/08/self-hosting-whoogle-using-docker/whoogle-desktop_huc11f795d8371262b1451d89c8b85d50e_221261_1440x0_resize_q85_h2_lanczos.webp 1440w,/blog/2023/08/self-hosting-whoogle-using-docker/whoogle-desktop_huc11f795d8371262b1451d89c8b85d50e_221261_3344x0_resize_q85_h2_lanczos.webp 3344w"
src="/blog/2023/08/self-hosting-whoogle-using-docker/whoogle-desktop_huc11f795d8371262b1451d89c8b85d50e_221261_480x0_resize_q85_lanczos.jpg"
width="3344"
height="2084"
decoding="async"
fetchpriority="auto"
loading="lazy"
alt="Whoogle on desktop!"
class="lazyload blur-up"
>&lt;figcaption>Whoogle on desktop!&lt;/figcaption>
&lt;/figure>
&lt;figure>
&lt;img
srcset="/blog/2023/08/self-hosting-whoogle-using-docker/whoogle-mobile_hu2bcdd1eeafd01e4d246f14f3adc04eaa_168830_480x0_resize_q85_h2_lanczos.webp 480w,/blog/2023/08/self-hosting-whoogle-using-docker/whoogle-mobile_hu2bcdd1eeafd01e4d246f14f3adc04eaa_168830_576x0_resize_q85_h2_lanczos.webp 576w,/blog/2023/08/self-hosting-whoogle-using-docker/whoogle-mobile_hu2bcdd1eeafd01e4d246f14f3adc04eaa_168830_768x0_resize_q85_h2_lanczos.webp 768w,/blog/2023/08/self-hosting-whoogle-using-docker/whoogle-mobile_hu2bcdd1eeafd01e4d246f14f3adc04eaa_168830_1025x0_resize_q85_h2_lanczos.webp 1025w,/blog/2023/08/self-hosting-whoogle-using-docker/whoogle-mobile_hu2bcdd1eeafd01e4d246f14f3adc04eaa_168830_1080x0_resize_q85_h2_lanczos.webp 1080w"
src="/blog/2023/08/self-hosting-whoogle-using-docker/whoogle-mobile_hu2bcdd1eeafd01e4d246f14f3adc04eaa_168830_480x0_resize_q85_lanczos.jpg"
width="1080"
height="2400"
decoding="async"
fetchpriority="auto"
loading="lazy"
alt="Whoogle on mobile!"
class="lazyload blur-up"
>&lt;figcaption>Whoogle on mobile!&lt;/figcaption>
&lt;/figure>
&lt;h2 id="resources">Resources&lt;/h2>
&lt;p>To get it all working, some guides were particularly useful, other than what I have
linked to throughout the post so far. This guide on the &lt;a href="https://www.techaddressed.com/tutorials/basic-nginx-reverse-proxy/">nginx reverse
proxy&lt;/a> is super
useful to understand what should go in the Nginx configuration file, and then the same
site has a guide on how to &lt;a href="https://www.techaddressed.com/tutorials/setup-whoogle-search-docker/">set up whoogle search with
docker&lt;/a>. Still,
the maybe most useful to me was to watch &lt;a href="https://www.youtube.com/watch?v=aq3mZrDbbYQ">this guy do this exact
thing&lt;/a>, but using GUIs instead of the
command line.&lt;/p></content:encoded></item></channel></rss>