Skip to content
Merged
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
19 changes: 10 additions & 9 deletions .github/workflows/nix-dev-cache.yaml
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
name: Nix development cache

on:
push:
branches:
# Cache trunk, to keep recent builds in the cache for development.
- trunk
tags:
# Cache releases, so they can be pinned in the cache for downstream consumers of Unison.
- 'release/**'
# Allow manual caching of branches. This is particularly useful when upgrading the Nix tooling, as we can test the PR
# and ensure that the cache is populated before merging into trunk.
workflow_dispatch:
# # Build on every pull request (and new PR commit)
# pull_request:
# # Build on new pushes to trunk (E.g. Merge commits)
# # Without the branch filter, each commit on a branch with a PR is triggered twice.
# # See: https://github.community/t/how-to-trigger-an-action-on-push-or-pull-request-but-not-both/16662
# push:
# branches:
# - trunk

jobs:
nix:
Expand All @@ -22,7 +23,7 @@ jobs:
os:
- ubuntu-24.04
- macos-13
# - macos-14
- macos-14
steps:
- uses: actions/checkout@v4
- name: mount Nix store on larger partition
Expand Down
112 changes: 6 additions & 106 deletions development.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ __General:__ `./scripts/test.sh` compiles and builds the Haskell code and runs a

_Disclaimer_ If you have trouble getting started, please get in touch via [Discord](https://unison-lang.org/discord) so we can help. If you have any fixes to the process, please send us a PR!

## Development Dependencies

If you are having trouble with a build, please ensure that your tooling matches the versions we expect. Some build mechanisms will guarantee this to some extent (e.g., the Nix build, or [the Haskell extension for VS Code](https://marketplace.visualstudio.com/items?itemName=haskell.haskell)), but you can see versions listed in [our version file](./nix/versions.nix) (some of which is inherited from [this repo’s VS Code settings](./.vscode/settings.json)).

## Running Unison

To get cracking with Unison:
Expand Down Expand Up @@ -113,113 +117,9 @@ More context at: https://stackoverflow.com/a/59761201/310162

Stack doesn't work deterministically in Windows due to mismatched expectations about how file deletion works. If you get this error, you can just retry the build and it will probably make more progress than the last time.

## Building with Nix

__NB__: It is important that the Unison Nix cache is trusted when building, otherwise you will likely end up building hundreds of packages, including GHC itself.

The recommended way to do this is to add the public key and URL for the cache to your system’s Nix configuration. /etc/nix/nix.conf should have lines similar to
```conf
trusted-public-keys = unison.cachix.org-1:i1DUFkisRPVOyLp/vblDsbsObmyCviq/zs6eRuzth3k=
trusted-substituters = https://unison.cachix.org
```
these lines could be prefixed with `extra-` and they may have additional entries besides the ones for our cache.

This command should work if you don’t want to edit the file manually:
```shell
sudo sh -c 'echo "extra-trusted-public-keys = unison.cachix.org-1:i1DUFkisRPVOyLp/vblDsbsObmyCviq/zs6eRuzth3k=
extra-trusted-substituters = https://unison.cachix.org" >>/etc/nix/nix.conf'
```
After updating /etc/nix/nix.conf, you need to restart the Nix daemon. To do this on
- Ubuntu: `sudo systemctl restart nix-daemon`
- MacOS:
```shell
sudo launchctl unload /Library/LaunchDaemons/org.nixos.nix-daemon.plist
sudo launchctl load /Library/LaunchDaemons/org.nixos.nix-daemon.plist
```

If you use NixOS, you may instead add this via your configuration.nix with
```nix
nix.settings.trusted-public-keys = ["unison.cachix.org-1:i1DUFkisRPVOyLp/vblDsbsObmyCviq/zs6eRuzth3k="];
nix.settings.trusted-substituters = ["https://unison.cachix.org"];
```
and run `sudo nixos-rebuild switch` afterward.

It is _not_ recommended to add your user to `trusted-users`. This _can_ make enabling flake configurations simpler (like the Unison Nix cache here), but [it is equivalent to giving that user root access (without need for sudo)](https://nix.dev/manual/nix/2.23/command-ref/conf-file.html#conf-trusted-users).

## Building package components with nix

### Build the unison executable
```shell
nix build
```

### Build a specific component
This is specified with the normal
`<package>:<component-type>:<component-name>` triple.

Some examples:
```shell
nix build '.#component-unison-cli:lib:unison-cli'
nix build '.#component-unison-syntax:test:syntax-tests'
nix build '.#component-unison-cli:exe:transcripts'
```

### Development environments

#### Get into a development environment for building with stack
This gets you into a development environment with the preferred
versions of the compiler and other development tools. These
include:

- ghc
- stack
- ormolu
- haskell-language-server
## Nix support

```shell
nix develop
```

#### Get into a development environment for building with cabal
This gets you into a development environment with the preferred
versions of the compiler and other development tools. Additionally,
all non-local haskell dependencies (including profiling dependencies)
are provided in the nix shell.

```shell
nix develop '.#cabal-local'
```

#### Get into a development environment for building a specific package
This gets you into a development environment with the preferred
versions of the compiler and other development tools. Additionally,
all haskell dependencies of this package are provided by the nix shell
(including profiling dependencies).

```shell
nix develop '.#cabal-<package-name>'
```

for example:

```shell
nix develop '.#cabal-unison-cli'
```
or
```shell
nix develop '.#cabal-unison-parser-typechecker'
```

This is useful if you wanted to profile a package. For example, if you
want to profile `unison-cli-main:exe:unison` then you could get into one of these
shells, cd into its directory, then run the program with
profiling.

```shell
nix develop '.#cabal-unison-parser-typechecker'
cd unison-cli
cabal run --enable-profiling unison-cli-main:exe:unison -- +RTS -p
```
See the [readme](./nix/README.md).

## Native compilation

Expand Down
11 changes: 1 addition & 10 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,7 @@
"aarch64-darwin"
]
(system: let
## It’s much easier to read from a JSON file than to have JSON import from some other file, so we extract some
## configuration from the VS Code settings to avoid duplication.
vscodeSettings = nixpkgs-release.lib.importJSON ./.vscode/settings.json;
versions =
vscodeSettings."haskell.toolchain"
## There are some things we want to pin that the VS Code Haskell extension doesn’t let us control.
// {
hpack = "0.35.2";
ormolu = "0.7.2.0";
};
versions = import ./nix/versions.nix {inherit (nixpkgs-haskellNix) lib;};
pkgs = import nixpkgs-haskellNix {
inherit system;
inherit (haskellNix) config;
Expand Down
107 changes: 107 additions & 0 deletions nix/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
## Building with Nix

__NB__: It is important that the Unison Nix cache is trusted when building, otherwise you will likely end up building hundreds of packages, including GHC itself.

The recommended way to do this is to add the public key and URL for the cache to your system’s Nix configuration. /etc/nix/nix.conf should have lines similar to
```conf
trusted-public-keys = unison.cachix.org-1:i1DUFkisRPVOyLp/vblDsbsObmyCviq/zs6eRuzth3k=
trusted-substituters = https://unison.cachix.org
```
these lines could be prefixed with `extra-` and they may have additional entries besides the ones for our cache.

This command should work if you don’t want to edit the file manually:
```shell
sudo sh -c 'echo "extra-trusted-public-keys = unison.cachix.org-1:i1DUFkisRPVOyLp/vblDsbsObmyCviq/zs6eRuzth3k=
extra-trusted-substituters = https://unison.cachix.org" >>/etc/nix/nix.conf'
```
After updating /etc/nix/nix.conf, you need to restart the Nix daemon. To do this on
- Ubuntu: `sudo systemctl restart nix-daemon`
- MacOS:
```shell
sudo launchctl unload /Library/LaunchDaemons/org.nixos.nix-daemon.plist
sudo launchctl load /Library/LaunchDaemons/org.nixos.nix-daemon.plist
```

If you use NixOS, you may instead add this via your configuration.nix with
```nix
nix.settings.trusted-public-keys = ["unison.cachix.org-1:i1DUFkisRPVOyLp/vblDsbsObmyCviq/zs6eRuzth3k="];
nix.settings.trusted-substituters = ["https://unison.cachix.org"];
```
and run `sudo nixos-rebuild switch` afterward.

It is _not_ recommended to add your user to `trusted-users`. This _can_ make enabling flake configurations simpler (like the Unison Nix cache here), but [it is equivalent to giving that user root access (without need for sudo)](https://nix.dev/manual/nix/2.23/command-ref/conf-file.html#conf-trusted-users).

## Building package components with nix

### Build the unison executable
```shell
nix build
```

### Build a specific component
This is specified with the normal
`<package>:<component-type>:<component-name>` triple.

Some examples:
```shell
nix build '.#component-unison-cli:lib:unison-cli'
nix build '.#component-unison-syntax:test:syntax-tests'
nix build '.#component-unison-cli:exe:transcripts'
```

### Development environments

#### Get into a development environment for building with stack
This gets you into a development environment with the preferred
versions of the compiler and other development tools. These
include:

- ghc
- stack
- ormolu
- haskell-language-server

```shell
nix develop
```

#### Get into a development environment for building with cabal
This gets you into a development environment with the preferred
versions of the compiler and other development tools. Additionally,
all non-local haskell dependencies (including profiling dependencies)
are provided in the nix shell.

```shell
nix develop '.#cabal-local'
```

#### Get into a development environment for building a specific package
This gets you into a development environment with the preferred
versions of the compiler and other development tools. Additionally,
all haskell dependencies of this package are provided by the nix shell
(including profiling dependencies).

```shell
nix develop '.#cabal-<package-name>'
```

for example:

```shell
nix develop '.#cabal-unison-cli'
```
or
```shell
nix develop '.#cabal-unison-parser-typechecker'
```

This is useful if you wanted to profile a package. For example, if you
want to profile `unison-cli-main:exe:unison` then you could get into one of these
shells, cd into its directory, then run the program with
profiling.

```shell
nix develop '.#cabal-unison-parser-typechecker'
cd unison-cli
cabal run --enable-profiling unison-cli-main:exe:unison -- +RTS -p
```
11 changes: 11 additions & 0 deletions nix/versions.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{lib}: let
## It’s much easier to read from a JSON file than to have JSON import from some other file, so we extract some
## configuration from the VS Code settings to avoid duplication.
vscodeSettings = lib.importJSON ../.vscode/settings.json;
in
vscodeSettings."haskell.toolchain"
## There are some things we want to pin that the VS Code Haskell extension doesn’t let us control.
// {
hpack = "0.35.2";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have seen some hpack 0.37 slipping in, so we may want to bump this too at some point.

-- This file has been generated from package.yaml by hpack version 0.37.0.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, good call. In #5486, I mention that 0.36 is the minimum supported by our pinned stack version, so it’s even inconsistent within the current Nix environment. I should rebase that, now that this is merged, and see if the cache issue is gone.

ormolu = "0.7.2.0";
}
Loading