Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions .github/actions/setup-nix/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: Set up Nix
description: >-
Install Nix and point it at the shared `argo-workflows` Cachix cache, so that
a job entering the development shell downloads the toolchain instead of
building it. Every job that runs `nix develop` should use this action rather
than installing Nix itself, so there is one place to change the installer
version and the cache configuration.

Pull-only unless the caller passes `cachix-auth-token`. GitHub does not give
secrets to workflows triggered by pull requests from forks, so those jobs read
the cache and never write to it, whatever the caller asks for.

inputs:
cachix-auth-token:
description: >-
Cachix token with write access to the cache, i.e.
`secrets.CACHIX_AUTH_TOKEN`. Pass it only from jobs whose whole purpose is
to populate the cache; leave it unset everywhere else and the job pulls
without pushing.
default: ""

runs:
using: composite
steps:
# The installer turns on `nix-command` and `flakes`, and passes the job's
# GITHUB_TOKEN to Nix so that flake inputs fetched from GitHub are not
# rate-limited.
- uses: cachix/install-nix-action@630ae543ea3a38a9a4166f03376c02c50f408342 # v31.11.0
- uses: cachix/cachix-action@5f2d7c5294214f71b873db4b969586b980625e71 # v17
with:
name: argo-workflows
authToken: ${{ inputs.cachix-auth-token }}
# Pushing without a token fails the job, and most jobs have no token.
skipPush: ${{ inputs.cachix-auth-token == '' }}
74 changes: 74 additions & 0 deletions .github/workflows/nix.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Keeps the Cachix cache stocked with the development shell, so entering it is a
# download everywhere else: on a contributor's machine, in the dev container and
# in CI. Nothing depends on this workflow succeeding — a cold cache only means
# the next `nix develop` builds the tools itself, slowly.
#
# Pushing needs a CACHIX_AUTH_TOKEN repository secret with write access to the
# `argo-workflows` cache. Without one — on a fork — the jobs still build the
# shell, they only read from the cache.
name: Nix

on:
push:
branches:
- main
paths: # keep in step with the pull_request list below
- flake.nix
- flake.lock
- go.mod # the flake takes the Go version from here
- .github/actions/setup-nix/action.yml
- .github/workflows/nix.yaml
# So that a change to the toolchain is built and reviewed before it is merged,
# rather than breaking everyone's shell afterwards.
pull_request:
paths:
- flake.nix
- flake.lock
- go.mod
- .github/actions/setup-nix/action.yml
- .github/workflows/nix.yaml
# The tools also stop being cached when nothing changes: Cachix evicts, and
# nixpkgs garbage-collects what our closure is built against.
schedule:
- cron: "0 4 * * 1" # Mondays, ahead of the working week
workflow_dispatch:

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

permissions:
contents: read

jobs:
linux:
name: Build development shell (x86_64-linux)
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: ./.github/actions/setup-nix
with:
# Pull requests only read the cache, whoever opened them: a branch
# anyone can push to must not be able to write to a cache everyone
# else trusts.
cachix-auth-token: ${{ github.event_name != 'pull_request' && secrets.CACHIX_AUTH_TOKEN || '' }}
- name: Build the development shell
# Realises every tool the shell puts on PATH. Cachix pushes each one as
# it is built; anything substituted from cache.nixos.org is already
# public and is not copied into our cache.
run: nix develop --profile "$RUNNER_TEMP/devshell" --command true

darwin:
name: Build development shell (aarch64-darwin)
# A macOS runner bills at ten times the Linux rate, so this one sits out
# pull requests and warms the cache once the change is merged. Apple
# silicon only: nobody develops on x86_64-darwin any more.
if: github.event_name != 'pull_request'
runs-on: macos-15
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- uses: ./.github/actions/setup-nix
with:
cachix-auth-token: ${{ secrets.CACHIX_AUTH_TOKEN }}
- name: Build the development shell
run: nix develop --profile "$RUNNER_TEMP/devshell" --command true
15 changes: 15 additions & 0 deletions docs/running-locally.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,21 @@ whatever the shell provides is what `make codegen`, `make lint` and `make test`
If you use [direnv](https://direnv.net), `direnv allow` once and the shell is entered whenever you `cd` into the repo.
Install [nix-direnv](https://github.com/nix-community/nix-direnv) alongside it so that is instant.

#### Binary cache

Most of the shell comes from the public nixpkgs cache, but the pinned tools are built by this project and nobody else,
so they are not in it. CI builds them for `x86_64-linux` and `aarch64-darwin` and pushes them to the
[`argo-workflows`](https://app.cachix.org/cache/argo-workflows) [Cachix](https://cachix.org) cache. Point Nix at it and
entering the shell is a download rather than a compile:

```bash
nix run nixpkgs#cachix -- use argo-workflows
```

That writes the cache and its public key into your Nix configuration; on a multi-user install it will ask for `sudo`,
or tell you to add yourself to `trusted-users` first. It is optional — without it everything still works, it is just
slower the first time and after each tool upgrade.

#### Upgrading a tool

Everything lives in `flake.nix`, in two tiers:
Expand Down