Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into hkm/ghc-git
Browse files Browse the repository at this point in the history
# Conflicts:
#	cross-windows.nix
  • Loading branch information
hamishmack committed Oct 18, 2023
2 parents 80ed5ca + 979fc22 commit f104ef9
Show file tree
Hide file tree
Showing 8 changed files with 290 additions and 35 deletions.
50 changes: 50 additions & 0 deletions .github/workflows/lints.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: "Lints"

on:
workflow_dispatch:
pull_request:
branches:
- master

push:
branches:
- master

defaults:
run:
shell: bash

# do we really want nixos-unstable?
env:
NIX_PATH: "nixpkgs=channel:nixos-unstable"
REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# PR_NUMBER: ${{ github.event.number }}

jobs:
deadnix:
runs-on: [self-hosted, linux]
steps:
- uses: actions/checkout@v3
- run: |
nix run github:astro/deadnix -- --edit --no-lambda-pattern-names
TMPFILE=$(mktemp)
git diff >"${TMPFILE}"
git stash -u && git stash drop
nix-shell -p reviewdog --run "reviewdog -f=diff -f.diff.strip=1 -reporter=github-pr-review < \"${TMPFILE}\""
nixprof:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: cachix/install-nix-action@v22
with:
nix_path: nixpkgs=channel:nixos-unstable
- run: |
nix profile install github:Kha/nixprof
nixprof record nix develop .#ghc8107 --accept-flake-config
nixprof report -p
nixprof report -a
nixprof report -s
# FIXME: is that the right way to publish a report on GitHub?
# curl -s -H "Authorization: token $GITHUB_TOKEN" -X POST -d "{\"body\": \"$report\"}" "https://api.github.com/repos/input-output-hk/haskell.nix/issues/$PR_NUMBER/comments"
29 changes: 4 additions & 25 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,30 +18,9 @@ jobs:
name: "Wait for hydra status"
runs-on: ubuntu-latest
steps:
- name: Get specific check run status
run: |
# start with a random sleep to prevent hitting the api too hard.
while true; do
# For GitHub Apps
# conclusion=$(gh api repos/$GITHUB_REPOSITORY/commits/$GITHUB_SHA/status --jq '.check_runs[] | select(.name == "ci/hydra-build:$DEV_SHELL") | .conclusion')
# For GitHub Statuses; we need --paginate because there are so many statuses
echo "Querying: gh api repos/$GITHUB_REPOSITORY/commits/$GITHUB_SHA/status --paginate --jq '.statuses[] | select(.context == \"$HYDRA_JOB\") | .state'"
conclusion=$(gh api "repos/$GITHUB_REPOSITORY/commits/$GITHUB_SHA/status" --paginate --jq ".statuses[] | select(.context == \"$HYDRA_JOB\") | .state")
case "$conclusion" in
success)
echo "$HYDRA_JOB succeeded"
exit 0;;
failure)
echo "$HYDRA_JOB failed"
exit 1;;
*)
echo "conclusion is: '$conclusion'"
gh api "repos/$GITHUB_REPOSITORY/commits/$GITHUB_SHA/status" --paginate --jq '.statuses[] | .state+"\t"+.context'|sort
WAIT=$((30 + RANDOM % 30))
echo "$HYDRA_JOB pending. Waiting ${WAIT}s..."
sleep $WAIT;;
esac
done
- uses: input-output-hk/actions/wait-for-hydra@latest
with:
status: ci/hydra-build:required

upload:
needs: wait-for-hydra-eval
Expand Down Expand Up @@ -108,4 +87,4 @@ jobs:
target-platform: ${{ matrix.target-platform }}
compiler-nix-name: ${{ matrix.compiler-nix-name }}
minimal: ${{ matrix.variant == '-minimal' }}
iog: ${{ matrix.iog == '-iog' }}
iog: ${{ matrix.iog == '-iog' }}
5 changes: 5 additions & 0 deletions cross-windows.nix
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,11 @@ pkgs.pkgsBuildBuild.mkShell ({
(tool "happy")
(tool "alex")
stdenv.cc.cc.lib ])
++ map pkgs.lib.getDev (with pkgs; [
zlib pcre openssl
windows.mcfgthreads
windows.mingw_w64_pthreads
])
++ pkgs.lib.optional (withHLS && (compiler-not-in (
pkgs.lib.optional (builtins.compareVersions compiler.version "9.9" >= 0) compiler-nix-name
++ pkgs.lib.optional (pkgs.stdenv.hostPlatform.isDarwin && pkgs.stdenv.hostPlatform.isAarch64) "ghc902") "Haskell Language Server")) (tool "haskell-language-server")
Expand Down
209 changes: 209 additions & 0 deletions docs/bootstrap.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
#!/usr/bin/env bash
set -euo pipefail

# End-user DevX could also be potentially improved through this script: e.g,
# by helping new users to set up Nix using Determinate Systems new installer,
# or detect that it's used in a GitHub Actions context and advise installing Nix with Cachix's
# install Nix action.

verbosity=1

while getopts "v" opt; do
case $opt in
v) verbosity=$((verbosity + 1));;
*) echo "Invalid option: -$OPTARG" >&2; exit 1;;
esac
done

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
NC='\033[0m'

log() {
local level="$1"
local msg="$2"
local color="$NC"

case "$level" in
DEBUG) color="$BLUE" ;;
INFO) color="$GREEN" ;;
WARN) color="$YELLOW";;
ERROR) color="$RED" ;;
*) echo "Unknown log level: $level" >&2; return 1;;
esac

if [ $verbosity -ge 2 ] || [ "$level" != "DEBUG" ]; then
echo -e "${color}${level}: ${NC}${msg}"
fi
}

log "INFO" "This script will set up nix and direnv, with opinionated default for Haskell development."


log "INFO" "[1/7] Install nix if it's not already installed ..."

if ! which nix >/dev/null 2>&1; then
if [ "$GITHUB_ACTIONS" == "true" ]; then
log "ERROR" "This script requires nix to be installed; you don't appear to have nix available. Since it seems that you're running this inside a GitHub Action, you can set up Nix using https://github.com/cachix/install-nix-action, e.g.:
- name: Install Nix with good defaults
uses: cachix/install-nix-action@v20
with:
extra_nix_config: |
trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ= loony-tools:pr9m4BkM/5/eSTZlkQyRt57Jz7OMBxNSUiMC4FkcNfk=
substituters = https://cache.iog.io/ https://cache.zw3rk.com/ https://cache.nixos.org/
nix_path: nixpkgs=channel:nixos-unstable"
exit 1
else
log "DEBUG" "nix is not installed. Would you like to install it now? (y/n)"
read -r confirm
if [[ "$confirm" == [yY] || "$confirm" == [yY][eE][sS] ]]; then
log "DEBUG" "Installing nix..."
curl -L https://nixos.org/nix/install | sh
. "$HOME/.nix-profile/etc/profile.d/nix.sh"
log "DEBUG" "nix installed successfully."
else
log "ERROR" "nix is required for the setup process. Please install nix and re-run the script."
exit 1
fi
fi
else
log "DEBUG" "nix is already installed."
fi


log "INFO" "[2/7] Tweak nix.conf with good defaults (may need sudo) ..."

if [ -z "${XDG_CONFIG_HOME:-}" ]; then
XDG_CONFIG_HOME="$HOME/.config"
fi

nix_conf_file="$XDG_CONFIG_HOME/nix/nix.conf"
if grep -q "experimental-features" "$nix_conf_file"; then
log "WARN" "The 'experimental-features' option already exists in '$nix_conf_file'. Please check that it's set to 'experimental-features = nix-command flakes'."
echo "Press ENTER to open $nix_conf_file in $EDITOR:"
read -r confirm
$EDITOR "$nix_conf_file"
else
echo "experimental-features = nix-command flakes" >> "$nix_conf_file"
log "DEBUG" "'experimental-features = nix-command flakes' added to nix configuration."
fi
if grep -q "accept-flake-config" "$nix_conf_file"; then
log "WARN" "The 'accept-flake-config' option already exists in '$nix_conf_file'. Please check that it's set to 'accept-flake-config = true'."
echo "Press ENTER to open $nix_conf_file in $EDITOR:"
read -r confirm
$EDITOR "$nix_conf_file"
else
echo "accept-flake-config = true" >> "$nix_conf_file"
log "DEBUG" "'accept-flake-config = true' added to nix configuration."
fi

nix_conf_file="/etc/nix/nix.conf"
if grep -q "trusted-users" "$nix_conf_file"; then
log "WARN" "The 'trusted-users' option already exists in '$nix_conf_file'. Please ensure that your user is part of 'trusted-users'."
echo "Press ENTER to open $nix_conf_file in $EDITOR:"
read -r confirm
$EDITOR "$nix_conf_file"
else
echo "trusted-users = root $USER" | sudo tee "$nix_conf_file" > /dev/null
log "DEBUG" "'trusted-users = root $USER' added to nix configuration."
fi


log "INFO" "[3/7] Restart nix-daemon (need sudo) ..."

if [[ "$OSTYPE" == "linux-gnu"* ]]; then
if which systemctl >/dev/null 2>&1 && systemctl is-active --quiet systemd; then
log "DEBUG" "Restarting nix-daemon..."
sudo systemctl restart nix-daemon.service
else
log "WARN" "Please restart nix-daemon manually."
echo "Press ENTER to continue ..."
read -r confirm
fi
elif [[ "$OSTYPE" == "darwin"* ]]; then
if which launchctl >/dev/null 2>&1; then
log "DEBUG" "Restarting nix-daemon..."
sudo launchctl kickstart -k system/org.nixos.nix-daemon
else
log "WARN" "Please restart nix-daemon manually."
echo "Press ENTER to continue ..."
read -r confirm
fi
fi


log "INFO" "[4/7] Install direnv if it's not already installed ..."

if ! which direnv >/dev/null 2>&1; then
log "DEBUG" "direnv is not installed. Would you like to install it now? (y/n)"
read -r confirm
if [[ "$confirm" == [yY] || "$confirm" == [yY][eE][sS] ]]; then
log "DEBUG" "Installing direnv..."
nix profile install nixpkgs#direnv
log "DEBUG" "direnv installed successfully."
else
log "ERROR" "direnv is required for the setup process. Please install direnv and re-run the script."
exit 1
fi
else
log "DEBUG" "direnv is already installed."
fi


log "INFO" "[5/7] Hook direnv into the user shell ..."

# shellcheck disable=SC2016
if grep -q 'direnv hook' "$HOME/.bashrc"; then
log "DEBUG" "direnv seems already hooked into '$HOME/.bashrc'."
else
echo 'eval "$(direnv hook bash)"' >> "$HOME/.bashrc"
log "DEBUG" "direnv hook added to '$HOME/.bashrc'."
fi
# shellcheck disable=SC2016
if ! which zsh >/dev/null 2>&1 || grep -q 'direnv hook' "$HOME/.zshrc"; then
log "DEBUG" "zsh isn't in PATH or direnv seems already hooked into '$HOME/.zshrc'."
else
echo 'eval "$(direnv hook zsh)"' >> "$HOME/.zshrc"
log "DEBUG" "direnv hook added to '$HOME/.zshrc'."
fi
# shellcheck disable=SC2016
if ! which fish >/dev/null 2>&1 || grep -q 'direnv hook' "$XDG_CONFIG_HOME/fish/config.fish"; then
log "DEBUG" "fish isn't in PATH or direnv seems already hooked into '$XDG_CONFIG_HOME/fish/config.fish'."
else
echo 'eval "$(direnv hook fish)"' >> "$XDG_CONFIG_HOME/fish/config.fish"
log "DEBUG" "direnv hook added to '$XDG_CONFIG_HOME/fish/config.fish'."
fi


log "INFO" "[6/7] Configure .envrc in the project directory ..."

if [ -f ".envrc" ]; then
log "DEBUG" ".envrc file already exists."
else
echo 'if ! has nix_direnv_version || ! nix_direnv_version 2.3.0; then
source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/2.3.0/direnvrc" "sha256-Dmd+j63L84wuzgyjITIfSxSD57Tx7v51DMxVZOsiUD8="
fi' >> ".envrc"
if [ -f "flake.nix" ]; then
echo "use flake" >> ".envrc"
elif [ -f "shell.nix" ]; then
echo "use nix" >> ".envrc"
else
# FIXME: maybe we could ask interactively what compiler version and shell flavor the user want to use?
echo "use flake \"github:input-output-hk/devx#ghc8107-iog\"" >> ".envrc"
fi
log "DEBUG" "Successfully created and populated .envrc file."
fi


log "INFO" "[7/7] Allow direnv to load the .envrc ..."

direnv allow
log "DEBUG" ".envrc configuration allowed."

log "INFO" "Setup process is complete! 🎉"

# FIXME: maybe directly install VSCode extension with `code --install-extension pinage404.nix-extension-pack; code --install-extension haskell.haskell` if `code` is in PATH?!
log "INFO" "For proper editor integration, you need to install the direnv extension for your specific editor. E.g., if you use VSCode, search for \"direnv\" in the extensions marketplace and install the plugin. Reload your editor and you're all set!"
5 changes: 4 additions & 1 deletion docs/direnv.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ To install `nix`, follow the steps provided on the [Nix installer page](https://

If you're not listed, you need to add the line `trusted-users = $USER` in your configuration file. Additionally, two more lines should be added: `experimental-features = nix-command flakes` and `accept-flake-config = true` for the convenince of having flake features enabled globaly.

You can add these lines in either of the two configuration files, `$XDG_CONFIG_HOME/nix/nix.conf` or `/etc/nix/nix.conf`. After making these edits, remember to restart the `nix-daemon`. If your system is based on `systemd`, you can do so by running `sudo systemctl restart nix-daemon`.
You should add the `trusted-users` line in `/etc/nix/nix.conf`, others options could be added there or in `$XDG_CONFIG_HOME/nix/nix.conf` if you only want to change the configuration of your current user. After making these edits, remember to restart the `nix-daemon`. If you use a Linux distribution based on `systemd`, you can do so by running `sudo systemctl restart nix-daemon`, if you're running macOS, it's `launchctl kickstart -k system/org.nixos.nix-daemon`.

## Install and configure `direnv`

Expand Down Expand Up @@ -152,3 +152,6 @@ After installing and reloading Vim, when you open a Haskell file in your project
---

Remember that this tutorial provides a very basic setup. You can further customize your environment and editor to better fit your workflow. Happy coding!

> **Note**
> You can run the whole tutorial (except the IDE configuration part) in one command `curl https://input-output-hk.github.io/devx | sh` (handy if you have several machines to configure) :)
1 change: 1 addition & 0 deletions docs/index.html
11 changes: 5 additions & 6 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 12 additions & 3 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

inputs.haskellNix.url = "github:input-output-hk/haskell.nix";
inputs.nixpkgs.follows = "haskellNix/nixpkgs-unstable";
inputs.flake-utils.url = "github:hamishmack/flake-utils/hkm/nested-hydraJobs";
inputs.flake-utils.url = "github:numtide/flake-utils";
inputs.iohk-nix.url = "github:input-output-hk/iohk-nix";

outputs = { self, nixpkgs, flake-utils, haskellNix, iohk-nix }:
Expand Down Expand Up @@ -47,7 +47,7 @@
"aarch64-linux"
"aarch64-darwin"
];
in flake-utils.lib.eachSystem supportedSystems (system:
in let flake-outputs = flake-utils.lib.eachSystem supportedSystems (system:
let
pkgs = import nixpkgs {
overlays = [haskellNix.overlay] ++ builtins.attrValues overlays;
Expand Down Expand Up @@ -167,7 +167,7 @@
inherit devShells;
hydraJobs = devShells // {
# *-dev sentinel job. Singals all -env have been built.
required = pkgs.runCommand "test-dependencies" {
required = pkgs.runCommand "required dependencies (${system})" {
_hydraAggregate = true;
constituents = map (name: "${system}.${name}-env") (builtins.attrNames devShellsWithEvalOnLinux);
} "touch $out";
Expand Down Expand Up @@ -213,6 +213,15 @@
packages.cabalProjectLocal.cross-js = (import ./quirks.nix { pkgs = js-pkgs; }).template;
packages.cabalProjectLocal.cross-windows = (import ./quirks.nix { pkgs = windows-pkgs; }).template;
});
# we use flake-outputs here to inject a required job that aggregates all required jobs.
in flake-outputs // {
hydraJobs = flake-outputs.hydraJobs // {
required = (import nixpkgs { system = "x86_64-linux"; }).runCommand "required dependencies" {
_hydraAggregate = true;
constituents = map (s: "${s}.required") supportedSystems;
} "touch $out";
};
};

# --- Flake Local Nix Configuration ----------------------------
nixConfig = {
Expand Down

0 comments on commit f104ef9

Please sign in to comment.