Skip to content

Commit

Permalink
Merge pull request #4 from improbable-eng/fix-multiples
Browse files Browse the repository at this point in the history
  • Loading branch information
Peter Mounce authored Jun 5, 2020
2 parents 8f8bcc9 + bb69f70 commit d3789e5
Show file tree
Hide file tree
Showing 13 changed files with 172 additions and 50 deletions.
4 changes: 1 addition & 3 deletions .buildkite/local-pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,5 @@ steps:
pre-command: |
echo "pre-command hook"
echo "with two commands"
command.bat: echo "command hook .bat"
post-command: echo "post-command hook"
pre-artifact.cmd: echo "pre-artifact hook .cmd"
pre-exit: echo "pre-exit hook"
pre-exit: echo "pre-exit hook"
55 changes: 55 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Changelog

## 0.4.0

### Fixed

- Allow multiple steps to use metahooks for the same hook but with different content.
- Inject `bash` shebang and Bash Strict Mode (`set -euo pipefail`) so that if metahooks fail with errors the job halts rather than continuing.

Bash Strict Mode is provided by
- `set -o errexit` - halt on error
- `set -o nounset` - halt if variable is unset
- `set -o pipefail` - halt if a command inside a pipe fails

You can override those choices by setting different values (e.g. `set +o nounset`) within your metahook.

### Removed

- **Breaking change** Removed support for `command` metahook.

Buildkite special-cases this which triggers edge-cases that a `command` metahook would need to work around.

If you want to override behaviour here, you will need to modify the automation you're running rather than inject a difference via metahook.

- **Breaking change** Removed Windows Batch (`.bat`, `.cmd`) support.

Sorry if this impacts you.

To transition from a Windows Batch metahook like

```yaml
- label: my-step
command: echo "hello world"
plugins:
- improbable-eng/metahook#0.3.0:
post-checkout.bat: scripts/windows-setup.bat
post-artifact.bat: |
call some-batch-file.bat
echo "Step finished!"
```
to
```yaml
- label: my-step
command: echo "hello world"
plugins:
- improbable-eng/metahook#0.4.0:
post-checkout: scripts/windows-setup.sh
post-artifact: |
some-bash-script-that-was-the-batch-file.sh
echo "Step finished!"
```
To transition Windows Batch shell scripts to bash shell scripts [here is a porting guide](https://www.tldp.org/LDP/abs/html/dosbatch.html).
50 changes: 46 additions & 4 deletions contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,22 @@
make vendorize local_run
```

On macOS & linux, the output should contain
## Expected output

### On macOS & linux, the output should contain

```txt
~~~ Running plugin metahook environment hook
$ .buildkite/plugins/metahook/hooks/environment
# BUILDKITE_METAHOOK_HOOKS_PATH changed
~~~ Running plugin metahook pre-command hook
$ .buildkite/plugins/metahook/hooks/pre-command
pre-command hook
with two commands
~~~ Running commands
$ trap 'kill -- $$' INT TERM QUIT; echo "Hello World"
Hello World
~~~ Running plugin metahook command hook
$ .buildkite/plugins/metahook/hooks/command
~~~ Running plugin metahook post-command hook
$ .buildkite/plugins/metahook/hooks/post-command
Expand All @@ -24,3 +29,40 @@ post-command hook
$ .buildkite/plugins/metahook/hooks/pre-exit
pre-exit hook
```

### On Windows, the output should contain

```txt
>>> Executing command step Test
~~~ Preparing plugins
> cd C:\Users\Pete\src\improbable\metahook-buildkite-plugin
~~~ Running plugin metahook environment hook
> .buildkite\plugins\metahook\hooks\environment
> cd C:\Users\Pete\src\improbable\metahook-buildkite-plugin\c\Users\Pete\src\improbable\metahook-buildkite-plugin
# BUILDKITE_METAHOOK_HOOKS_PATH changed
~~~ Running plugin metahook pre-command hook
> .buildkite\plugins\metahook\hooks\pre-command
pre-command hook
with two commands
> cd C:\Users\Pete\src\improbable\metahook-buildkite-plugin\c\Users\Pete\src\improbable\metahook-buildkite-plugin
~~~ Running plugin metahook command hook
> .buildkite\plugins\metahook\hooks\command
> cd C:\Users\Pete\src\improbable\metahook-buildkite-plugin\c\Users\Pete\src\improbable\metahook-buildkite-plugin
~~~ Running plugin metahook post-command hook
> .buildkite\plugins\metahook\hooks\post-command
post-command hook
> cd C:\Users\Pete\src\improbable\metahook-buildkite-plugin\c\Users\Pete\src\improbable\metahook-buildkite-plugin
~~~ Running plugin metahook pre-exit hook
> .buildkite\plugins\metahook\hooks\pre-exit
pre-exit hook
> cd C:\Users\Pete\src\improbable\metahook-buildkite-plugin\c\Users\Pete\src\improbable\metahook-buildkite-plugin
>>> Command succeeded in 3.2662428s
>>> Build finished in 3.2672403s
```
3 changes: 3 additions & 0 deletions hooks/checkout
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/usr/bin/env bash
set -euo pipefail
"${BASH_SOURCE%/*}/run-hook.sh" "$(basename "${BASH_SOURCE[0]}")"
53 changes: 11 additions & 42 deletions hooks/environment
Original file line number Diff line number Diff line change
@@ -1,46 +1,15 @@
#!/usr/bin/env bash
set -euo pipefail

# The list of possible hooks to implement.
declare -a hooks=(
# "environment" # not allowed
"pre-checkout"
"checkout"
"post-checkout"
"pre-command"
"command"
"post-command"
"pre-artifact"
"post-artifact"
"pre-exit"
)
BUILDKITE_METAHOOK_HOOKS_PATH="$(mktemp -d)"
export BUILDKITE_METAHOOK_HOOKS_PATH
env | sort | grep "BUILDKITE_PLUGIN_METAHOOK" | uniq >"${BUILDKITE_METAHOOK_HOOKS_PATH}/vars"

# The list of possible file extensions for hooks.
declare -a extensions=(
""
".bat"
".cmd"
)
if grep -E 'BUILDKITE_PLUGIN_METAHOOK_.+(\.BAT|\.CMD)=' "${BUILDKITE_METAHOOK_HOOKS_PATH}/vars"; then
echo "Sorry, we had to remove Windows Batch file support in 0.4.0."
echo "Please refer to https://github.com/improbable-eng/metahook-buildkite-plugin/tree/master/changelog.md#0.4.0"
echo ""
exit 1
fi

hooks_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

vars="$(mktemp)"
cleanup() {
rm -rf "${vars}"
}
trap cleanup EXIT

env | sort | grep "METAHOOK" | uniq >"${vars}"

for hook_name in "${hooks[@]}"; do
for ext in "${extensions[@]}"; do
hook_file="${hooks_dir}/${hook_name}${ext}"
rm -f "${hook_file}"
upperd="$(echo "${hook_name}${ext}" | tr "[:lower:]" "[:upper:]")"
var_name="BUILDKITE_PLUGIN_METAHOOK_${upperd//-/_}"
if grep "${var_name}" <"${vars}"; then
# Note: ! syntax here is dynamic variable expansion. That is
# use the var_name string's variable value.
echo "${!var_name}" >"${hook_file}"
fi
done
done
"${BASH_SOURCE%/*}/run-hook.sh" "$(basename "${BASH_SOURCE[0]}")"
3 changes: 3 additions & 0 deletions hooks/post-artifact
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/usr/bin/env bash
set -euo pipefail
"${BASH_SOURCE%/*}/run-hook.sh" "$(basename "${BASH_SOURCE[0]}")"
3 changes: 3 additions & 0 deletions hooks/post-checkout
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/usr/bin/env bash
set -euo pipefail
"${BASH_SOURCE%/*}/run-hook.sh" "$(basename "${BASH_SOURCE[0]}")"
3 changes: 3 additions & 0 deletions hooks/post-command
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/usr/bin/env bash
set -euo pipefail
"${BASH_SOURCE%/*}/run-hook.sh" "$(basename "${BASH_SOURCE[0]}")"
3 changes: 3 additions & 0 deletions hooks/pre-artifact
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/usr/bin/env bash
set -euo pipefail
"${BASH_SOURCE%/*}/run-hook.sh" "$(basename "${BASH_SOURCE[0]}")"
3 changes: 3 additions & 0 deletions hooks/pre-command
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/usr/bin/env bash
set -euo pipefail
"${BASH_SOURCE%/*}/run-hook.sh" "$(basename "${BASH_SOURCE[0]}")"
9 changes: 9 additions & 0 deletions hooks/pre-exit
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/usr/bin/env bash
set -euo pipefail

cleanup() {
rm -rf "${BUILDKITE_METAHOOK_HOOKS_PATH}"
}
trap cleanup EXIT

"${BASH_SOURCE%/*}/run-hook.sh" "$(basename "${BASH_SOURCE[0]}")"
20 changes: 20 additions & 0 deletions hooks/run-hook.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/usr/bin/env bash
set -euo pipefail
hook_name="${1:?1st arg needs to be hook name}"

upperd="$(echo "${hook_name}" | tr "[:lower:]" "[:upper:]" | sed "s:-:_:")"
var_name="BUILDKITE_PLUGIN_METAHOOK_${upperd}"

if grep -q "${var_name}" <"${BUILDKITE_METAHOOK_HOOKS_PATH}/vars"; then
hook_file="${BUILDKITE_METAHOOK_HOOKS_PATH}/${hook_name}"

echo "#\!/usr/bin/env bash" >"${hook_file}"
echo "set -o errexit" >>"${hook_file}"
echo "set -o nounset" >>"${hook_file}"
echo "set -o pipefail" >>"${hook_file}"
# Exclamation syntax here is dynamic variable expansion.
# That is, use the var_name string to look up the value.
echo "${!var_name}" >>"${hook_file}"
chmod +x "${hook_file}"
exec "${hook_file}"
fi
13 changes: 12 additions & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ common: &common
plugins:
- improbable-eng/metahook:
post-checkout: scripts/setup.sh
post-checkout.bat: scripts/windows-setup.bat
pre-exit: |
scripts/cleanup.sh
echo "Step finished!"
Expand All @@ -25,6 +24,18 @@ steps:
<<: *common
```
Metahooks execute via a `bash` script, searching your `PATH` for `bash`.

Metahooks execute in Bash Strict Mode.

Bash Strict Mode is provided by

- `set -o errexit` - halt on error
- `set -o nounset` - halt if variable is unset
- `set -o pipefail` - halt if a command inside a pipe fails

You can override those choices by setting different values (e.g. `set +o nounset`) within your metahook.

## Contributing

See [contributing](contributing.md)

0 comments on commit d3789e5

Please sign in to comment.