-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathaction.yml
183 lines (167 loc) · 7.57 KB
/
action.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
name: "use-nix-shell-action"
branding:
icon: 'cloud-snow'
color: 'blue'
description: "Apply a nix shell to a GitHub Actions job."
inputs:
exportEnv:
description: >
Boolean indicating whether to export the specified shell's environment
into your GitHub Actions job's environment.
required: false
default: true
type: boolean
preserveDefaultPath:
description: >
Boolean controlling whether the shell's environment *overrides* `$PATH` in
the job (`false`) or appends to it (`true`). Note that things added to
`$GITHUB_PATH` (i.e. by other actions) will be preserved regardless.
required: false
default: true
type: boolean
# Shell specification options; set 0 or 1 of these:
packages:
description: 'Comma-separated list of packages to install in the shell.'
required: false
flakes:
description: >
Comma-separated list of flake references to install in the shell.
required: false
devShell:
description: 'Flake path to a devShell.'
required: false
# These is the default but we can't mark it as such here because we don't
# have an easy way to differentiate between defaults and user-provided
# inputs from within composite (bash) github action implementations.
#
# We want to be able to tell the difference between the user actually
# specifying multiple inputs and the user specifying another shell input +
# the default for `devShell` coming through.
file:
description: 'Path to a file (i.e. shell.nix) describing the shell.'
required: false
# Script options:
script:
description: 'A script to run under the shell specified.'
required: false
interpreter:
description: 'The interpreter under which to run `script`.'
required: false
default: "bash"
clearEnvForScript:
description: >
Boolean specifying whether to preserve existing env vars when running the
provided script.
Note that this does not influence the environment that's exported and
cannot be used to provide a "pure" shell for future steps in your action.
required: false
default: true
type: boolean
extraNixOptions:
description: >
Extra options to pass to the nix invocation used to construct the shell.
required: false
default: ""
runs:
using: "composite"
steps:
# `type compgen` is used to check for bash-interactive which `action.bash`
# needs (it uses `compgen`).
#
# Note: we need `continue-on-error` otherwise subsequent commands won't run
# and we need `steps.... == 'failure'` gates on these commands so they don't
# run when the previous test _didn't_ fail. Unfortunate but what to do.
- id: try-bash
continue-on-error: true
shell: bash
run: |
command -v bash || exit 1
type compgen &>/dev/null || exit 2
echo "bash=$(command -v bash)" >> $GITHUB_OUTPUT
- id: try-hardcoded-bash
continue-on-error: true
if: steps.try-bash.outcome == 'failure'
shell: '/usr/bin/bash {0}'
run: |
/usr/bin/bash -c "type compgen &>/dev/null" || exit 2
echo '::notice::bash not on $PATH, using /usr/bin/bash...'
echo "bash=/usr/bin/bash" >> $GITHUB_OUTPUT
- id: try-nix-shell-bash
continue-on-error: true
if: steps.try-hardcoded-bash.outcome == 'failure'
shell: 'nix-shell {0}'
run: |
{ nixpkgs ? import <nixpkgs> {} }: with nixpkgs; mkShell {
shellHook = ''
echo '::notice::using bash from `nixpkgs`...'
echo "bash=${lib.getExe bashInteractive}" >> $GITHUB_OUTPUT
'';
}
- name: "error: no bash found"
if: steps.try-nix-shell-bash.outcome == 'failure'
# Note: *not* continue on error; this is the end of the chain.
shell: sh
run: echo "::error::no suitable bash found!" && exit 4
- id: bash-path
shell: "${{ (steps.try-bash.outcome == 'success' && steps.try-bash.outputs.bash) || (steps.try-hardcoded-bash.outcome == 'success' && steps.try-hardcoded-bash.outputs.bash) || (steps.try-nix-shell-bash.outcome == 'success' && steps.try-nix-shell-bash.outputs.bash) || 'unreachable' }} {0}"
run: |
BASH_PATH="${{ (steps.try-bash.outcome == 'success' && steps.try-bash.outputs.bash) || (steps.try-hardcoded-bash.outcome == 'success' && steps.try-hardcoded-bash.outputs.bash) || (steps.try-nix-shell-bash.outcome == 'success' && steps.try-nix-shell-bash.outputs.bash) || 'unreachable' }}"
echo "bash=${BASH_PATH} --noprofile --norc -e -o pipefail {0}" >> $GITHUB_OUTPUT
echo "bash-binary-path=${BASH_PATH}" >> $GITHUB_OUTPUT
- id: check-for-nix
shell: ${{ steps.bash-path.outputs.bash }}
run: |
if ! command -v nix; then
echo "nix-missing=true" >> $GITHUB_OUTPUT
echo '::warning::`nix` not found; installing using `cachix/install-nix-action@v18`'
{
echo '## ℹ️ **Note**'
echo '`nix` was not found so it was installed using [`cachix/install-nix-action`](https://github.com/cachix/install-nix-action)'
echo ''
echo 'Consider adding this action to your workflow directly so that you have more control over the nix version/channels/configuration options:'
echo '```yaml'
echo ' - uses: cachix/install-nix-action@v18'
echo ' with:'
echo ' nix_path: nixpkgs=channel:nixos-unstable'
echo '```'
} >> $GITHUB_STEP_SUMMARY
else
echo "nix-missing=false" >> $GITHUB_OUTPUT
echo '::debug::using already present `nix`..'
fi
- if: ${{ steps.check-for-nix.outputs.nix-missing == 'true' }}
uses: cachix/install-nix-action@v18
with:
nix_path: nixpkgs=channel:nixos-unstable
# Point to the vendored `nix-direnv`'s script.
#
# We would grab this from `cache.nixos.org` (by store path, for
# reproducibility) but doing so presents several challenges:
# - `nix-direnv` depends on `nix`, etc so it has a large-ish closure size
# even though we only really want one function from it
# - the derivations technically are system specific (since some of the
# deps are) so we'd want to maintain a matrix of store paths here for
# the different runner platforms ((linux, macos) x (arch)) so that we
# pick the store path that will result in the fewest extra things being
# downloaded to the store (it technically doesn't matter if we pull the
# "wrong" `nix-direnv` for a platform since we're not actually executing
# it; it's just annoying because we'd be pulling in a bunch of binaries
# and deps too)
#
# So, to keep things fast and simple we just vendored the `nix-direnv`
# envrc script.
- run: ${{steps.bash-path.outputs.bash-binary-path }} ${{ github.action_path }}/action.bash ${{ github.env }} ${{ github.path }}
shell: ${{ steps.bash-path.outputs.bash }}
env:
NIX_DIRENV_PATH: ${{ github.action_path }}/vendored/nix-direnv.envrc
BASH_BINARY_PATH: ${{ steps.bash-path.outputs.bash-binary-path }}
INPUT_EXPORT_ENV: ${{ inputs.exportEnv }}
INPUT_PRESERVE_DEFAULT_PATH: ${{ inputs.preserveDefaultPath }}
INPUT_PACKAGES: ${{ inputs.packages }}
INPUT_FLAKES: ${{ inputs.flakes }}
INPUT_DEVSHELL: ${{ inputs.devShell }}
INPUT_FILE: ${{ inputs.file }}
INPUT_SCRIPT: ${{ inputs.script }}
INPUT_INTERPRETER: ${{ inputs.interpreter }}
INPUT_CLEAR_ENV_FOR_SCRIPT: ${{ inputs.clearEnvForScript }}
INPUT_EXTRA_NIX_OPTIONS: ${{ inputs.extraNixOptions }}