<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Ci on Simon Shine</title><link>https://simonshine.dk/tags/ci/</link><description>Recent content in Ci on Simon Shine</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Wed, 04 Nov 2026 00:56:50 +0200</lastBuildDate><atom:link href="https://simonshine.dk/tags/ci/index.xml" rel="self" type="application/rss+xml"/><item><title>GitHub Releases: A poor man's Nix binary cache</title><link>https://simonshine.dk/articles/github-releases-poor-mans-nix-binary-cache/</link><pubDate>Wed, 04 Nov 2026 00:56:50 +0200</pubDate><guid>https://simonshine.dk/articles/github-releases-poor-mans-nix-binary-cache/</guid><description>&lt;h2 id="tldr"&gt;
 tl;dr
 &lt;a class="heading-anchor" href="#tldr" aria-label="Link to this section"&gt;&amp;para;&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;Run or install binaries without compiling them by relying on GitHub Releases as a binary cache:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ nix run github:sshine/walltime-rs#walltime-bin -- --version
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;walltime 0.2.0
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="motivation"&gt;
 Motivation
 &lt;a class="heading-anchor" href="#motivation" aria-label="Link to this section"&gt;&amp;para;&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;The simplest way to export a Rust CLI from a Nix flake is with &lt;code&gt;rustPlatform.buildRustPackage&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Anyone who adds it as an input compiles it. A Rust developer or a Nix fanatic might accept a few
gigabytes of build dependencies and a few more of build artifacts, plus several minutes of
downloading, for a 4 MiB static binary.&lt;/p&gt;</description></item><item><title>Evaluating the Kubernetes-native Forgejo CI runners</title><link>https://simonshine.dk/articles/evaluating-the-kubernetes-native-forgejo-ci-runners/</link><pubDate>Sun, 25 Oct 2026 13:19:41 +0100</pubDate><guid>https://simonshine.dk/articles/evaluating-the-kubernetes-native-forgejo-ci-runners/</guid><description>&lt;p&gt;Until 9 October, CI for my &lt;a href="https://forgejo.org"&gt;Forgejo&lt;/a&gt; ran in docker-in-docker: &lt;a href="https://code.forgejo.org/forgejo/runner"&gt;forgejo-runner&lt;/a&gt; 6.3.1
with a privileged &lt;code&gt;docker:29.3.1-dind&lt;/code&gt; sidecar, three replicas. Since then every job runs as a
Kubernetes Job, through the execution-backend protocol that &lt;a href="https://code.forgejo.org/forgejo/runner/releases/tag/v13.1.0"&gt;forgejo-runner v13.1.0&lt;/a&gt; added on
31 August.&lt;/p&gt;
&lt;p&gt;A few people have asked what that is like to run for real. Two weeks and 54 tasks in, this is
what I know. The Forgejo side of the same cluster is in &lt;a href="https://simonshine.dk/articles/running-forgejo-on-a-hetzner-kubernetes-cluster"&gt;Running Forgejo on a Hetzner Kubernetes
cluster&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Four ways to install Nix in GitHub Actions</title><link>https://simonshine.dk/articles/github-nix-actions-eval/</link><pubDate>Wed, 21 Oct 2026 13:19:47 +0200</pubDate><guid>https://simonshine.dk/articles/github-nix-actions-eval/</guid><description>&lt;p&gt;To run Nix in GitHub Actions, the default CI runner needs Nix installed first.&lt;/p&gt;
&lt;p&gt;Here are some popular alternatives for pre-made CI actions that do this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;- &lt;span style="color:#f92672"&gt;uses&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;cachix/install-nix-action@v31&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;- &lt;span style="color:#f92672"&gt;uses&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;NixOS/nix-installer-action@v1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;- &lt;span style="color:#f92672"&gt;uses&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;nixbuild/nix-quick-install-action@v35&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;- &lt;span style="color:#f92672"&gt;uses&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;DeterminateSystems/nix-installer-action@v23&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;All of these work, and do more or less the same thing. Are they all equally fast?&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve benchmarked each of them by first running the installer, and then running &lt;code&gt;nixpkgs#hello&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# .github/workflows/install-nix-action.yml&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;on&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;workflow_dispatch&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;jobs&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;bench&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;runs-on&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;ubuntu-latest&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;steps&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;Install Nix&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;uses&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;cachix/install-nix-action@v31&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;First build hello from pinned nixpkgs&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;run&lt;/span&gt;: |&lt;span style="color:#e6db74"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; nix-build --no-out-link -E &amp;#39;with import (fetchTarball
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; &amp;#34;https://github.com/NixOS/nixpkgs/archive/ac62194c3917d5f474c1a844b6fd6da2db95077d.tar.gz&amp;#34;) {}; hello&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I didn&amp;rsquo;t specify any input parameters on them, and I didn&amp;rsquo;t add any explicit cache or &lt;code&gt;permissions&lt;/code&gt; block.&lt;/p&gt;</description></item><item><title>A poor man's Nix CI cache</title><link>https://simonshine.dk/articles/poor-mans-nix-ci-cache/</link><pubDate>Wed, 21 Oct 2026 11:20:00 +0200</pubDate><guid>https://simonshine.dk/articles/poor-mans-nix-ci-cache/</guid><description>&lt;p&gt;A thing I often come back to is &lt;a href="https://simonshine.dk/articles/speeding-up-ci-with-nix/"&gt;speeding&lt;/a&gt; &lt;a href="998e526196c894e1726ba35f36c92ab7abe8762b"&gt;up&lt;/a&gt; CI. For almost 20 years I&amp;rsquo;ve
been pushing compilation-heavy code to GitHub. Their free tier always provided enough CI minutes. So
optimizing was never a resource problem, but rather a principle.&lt;/p&gt;
&lt;p&gt;For GitHub Actions, my go-to strategy is &lt;code&gt;nixbuild/nix-quick-install-action&lt;/code&gt; and
&lt;code&gt;nix-community/cache-nix-action&lt;/code&gt; that piggyback on the GitHub CI cache:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;jobs&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;build&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;runs-on&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;ubuntu-latest&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;steps&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;Checkout&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;uses&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803&lt;/span&gt; &lt;span style="color:#75715e"&gt;# v6.1.0, 2026-07-16&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;uses&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;nixbuild/nix-quick-install-action@9f63be77f412a248c9d9a65a4c82cf066cdf8f0c&lt;/span&gt; &lt;span style="color:#75715e"&gt;# v35, 2026-06-17&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - &lt;span style="color:#f92672"&gt;name&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;Restore and save Nix store&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;uses&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;nix-community/cache-nix-action@7df957e333c1e5da7721f60227dbba6d06080569&lt;/span&gt; &lt;span style="color:#75715e"&gt;# v7.0.2, 2026-01-30&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;with&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;primary-key&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;nix-${{ runner.os }}-${{ hashFiles(&amp;#39;**/*.nix&amp;#39;, &amp;#39;**/flake.lock&amp;#39;) }}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;restore-prefixes-first-match&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;nix-${{ runner.os }}-&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;gc-max-store-size-linux&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;2G&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;purge&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;purge-prefixes&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;nix-${{ runner.os }}-&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;purge-created&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;purge-last-accessed&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;P1DT12H&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;purge-primary-key&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;never&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;However, I also run a Forgejo instance with a &lt;a href="https://git.shine.town/infra/runners"&gt;NixOS-like CI runner&lt;/a&gt; that cannot benefit
from these community actions.&lt;/p&gt;</description></item><item><title>Hashpinning</title><link>https://simonshine.dk/articles/hashpinning/</link><pubDate>Sat, 08 Aug 2026 01:59:35 +0200</pubDate><guid>https://simonshine.dk/articles/hashpinning/</guid><description>&lt;p&gt;GitHub Actions workflows usually start like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;- &lt;span style="color:#f92672"&gt;uses&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;actions/checkout@v6&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;v6&lt;/code&gt; is a git tag that points to some commit for the release of this version of an action. There is
also a &lt;code&gt;v6.0.1&lt;/code&gt; tag. Every time a minor or patch version is released, e.g. &lt;code&gt;v6.0.2&lt;/code&gt; or &lt;code&gt;v6.1.0&lt;/code&gt;, the
&lt;code&gt;v6&lt;/code&gt; tag is moved to that. Being unspecific means you always get the latest version that begins with
&lt;code&gt;v6&lt;/code&gt;. This is a feature.&lt;/p&gt;</description></item><item><title>NixOS runners on Forgejo Actions</title><link>https://simonshine.dk/articles/forgejo-actions-nixos-runners/</link><pubDate>Thu, 23 Apr 2026 22:06:40 +0200</pubDate><guid>https://simonshine.dk/articles/forgejo-actions-nixos-runners/</guid><description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; You can see the project in action here: &lt;a href="https://git.shine.town/infra/runners"&gt;https://git.shine.town/infra/runners&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I decided to bootstrap a Kubernetes cluster with &lt;a href="https://www.talos.dev/"&gt;Talos&lt;/a&gt; and
&lt;a href="https://kubenix.org/"&gt;kubenix&lt;/a&gt; during my vacation.&lt;/p&gt;
&lt;p&gt;A lot of experience came out of that, and I&amp;rsquo;m trying to unpack it gradually.&lt;/p&gt;
&lt;p&gt;One of the things I host on this cluster is &lt;a href="https://forgejo.org/"&gt;Forgejo&lt;/a&gt;, which is
&lt;a href="https://codeberg.org/"&gt;Codeberg&lt;/a&gt;&amp;rsquo;s fork of Gitea. Forgejo has &lt;a href="https://forgejo.org/docs/next/user/actions/reference/"&gt;Forgejo
Actions&lt;/a&gt; which is a CI system that mimicks
GitHub Actions, and it has a &lt;a href="https://forgejo.org/docs/next/user/packages/container/"&gt;Container Registry&lt;/a&gt;
much like GHCR, or DockerHub.&lt;/p&gt;</description></item><item><title>Speeding up CI more with Nix</title><link>https://simonshine.dk/articles/speeding-up-ci-more-with-nix/</link><pubDate>Mon, 02 Feb 2026 00:44:38 +0100</pubDate><guid>https://simonshine.dk/articles/speeding-up-ci-more-with-nix/</guid><description>&lt;p&gt;Recently I wrote &lt;a href="https://simonshine.dk/articles/speeding-up-ci-with-nix/"&gt;Speeding up CI with Nix&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I improved a 2m30s build to 1m30s after it had recently deteriorated to 10m30s.&lt;/p&gt;
&lt;p&gt;I have another repository that would benefit from Nix.&lt;/p&gt;
&lt;p&gt;Not because of speedups, but because it fails to install Chinese fonts properly.&lt;/p&gt;
&lt;p&gt;My Typst résumé&amp;rsquo;s CI failed to render Chinese fonts for the longest time; for that reason, I never
actually made use of the PDFs that I released. It is the &lt;code&gt;fontist/setup-fontist&lt;/code&gt; and &lt;code&gt;fontist install --formula noto_serif_cjk&lt;/code&gt; parts below (using 3m2s out of 3m20s):&lt;/p&gt;</description></item><item><title>Speeding up CI with Nix</title><link>https://simonshine.dk/articles/speeding-up-ci-with-nix/</link><pubDate>Sun, 25 Jan 2026 12:28:38 +0100</pubDate><guid>https://simonshine.dk/articles/speeding-up-ci-with-nix/</guid><description>&lt;p&gt;In the article &lt;a href="https://simonshine.dk/articles/maintaining-libraries-with-claude"&gt;Maintaining libraries with Claude&lt;/a&gt; I
update the CI pipeline to release the package automatically on Hackage and GitHub when pushing a
version tag.&lt;/p&gt;
&lt;p&gt;I added a git hook, &lt;a href="https://github.com/sshine/evm-opcodes/blob/main/.github/hooks/check-cabal-sync.sh"&gt;check-cabal-sync.sh&lt;/a&gt;, that checks the version in package.yaml against the
version in evm-opcodes.cabal, as well as the version in the git tag, to ensure I ran &lt;code&gt;hpack&lt;/code&gt; before
releasing; otherwise Hackage upload will fail.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Total CI running time: 2m30s before&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Of which &lt;code&gt;haskell-actions/setup&lt;/code&gt; takes: 2m5s.&lt;/p&gt;</description></item></channel></rss>