nix-develop/nix-develop-gha.sh
Nick Novitski 2cd3e161f5 fix: Fail if build fails!
The pipefail option does not catch usage from subshells like this:

```
echo <<<"$(echo foo; exit 1)"
```

Since that's how `nix develop` is called in the script, when the action
could not build an environment, it would still be treated as having run
successfully, and the job would continue.

It's still hypothetically possible for this to happen if `env` or `bash
-c 'echo $PATH'` fail.  Seems unlikely!  But maybe there's something to
be done there.
2023-10-19 10:15:04 -07:00

59 lines
1.9 KiB
Bash
Executable file

#!/usr/bin/env bash
set -euo pipefail
# Read the arguments into an array, so they can be added correctly as flags
IFS=" " read -r -a arguments <<<"${@:-}"
with_nix_develop() {
nix develop --ignore-environment "${arguments[@]}" --command "$@"
}
with_nix_develop true # Exit immediately if build fails
contains() {
grep "$1" --silent <<<"$2"
}
# Add all environment variables except for PATH to GITHUB_ENV.
while IFS='=' read -r -d '' n v; do
if [ "$n" == "PATH" ]; then
continue
fi
# Skip if the variable is already in the environment with the same
# value (treating unset and the empty string as identical states)
if [ "${!n:-}" == "$v" ]; then
continue
fi
if (("$(wc -l <<<"$v")" > 1)); then
delimiter=$(openssl rand -base64 18)
if contains "$delimiter" "$v"; then
echo "Environment variable $n contains randomly generated string $delimiter, file an issue and buy a lottery ticket."
exit 1
fi
printf "%s<<%s\n%s%s\n" "$n" "$delimiter" "$v" "$delimiter" >>"${GITHUB_ENV:-/dev/stderr}"
continue
fi
printf "%s=%s\n" "$n" "$v" >>"${GITHUB_ENV:-/dev/stderr}"
done < <(with_nix_develop env -0)
# Read the nix environment's $PATH into an array
IFS=":" read -r -a nix_path_array <<<"$(with_nix_develop bash -c "echo \$PATH")"
# Iterate over the PATH array in reverse
#
# Why in reverse? Appending a directory to $GITHUB_PATH causes that directory
# to be _prepended_ to $PATH in subsequent steps, so if we append in
# first-to-last order, the result will be in last-to-first order. Order in
# PATH elements is significant, since it determines lookup order, thus we
# preserve their order by reversing them before they are reversed again.
for ((i = ${#nix_path_array[@]} - 1; i >= 0; i--)); do
nix_path_entry="${nix_path_array[$i]}"
if contains "$nix_path_entry" "$PATH"; then
continue
fi
if ! [ -d "$nix_path_entry" ]; then
continue
fi
echo "$nix_path_entry" >>"${GITHUB_PATH:-/dev/stderr}"
done