├── LICENSE ├── README.md ├── commands ├── config ├── plugin.toml ├── post-deploy ├── receive-app └── trigger /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Nick Stenning 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # dokku-webhooks 2 | 3 | dokku-webhooks is a plugin for [dokku](https://github.com/progrium/dokku) that 4 | triggers external [webhooks](https://en.wikipedia.org/wiki/Webhook) in response 5 | to build/deployment stages. 6 | 7 | ## Installation 8 | 9 | 10 | ```shell 11 | # dokku 0.4.x+ 12 | sudo dokku plugin:install https://github.com/nickstenning/dokku-webhooks.git 13 | 14 | # dokku 0.3 15 | git clone https://github.com/nickstenning/dokku-webhooks.git /var/lib/dokku/plugins/webhooks 16 | git reset --hard c5ade98a8e188ccd9f1f544e3ffc8c1d5d0ea4e0 17 | ``` 18 | 19 | Next, move the `receive-app` hook out of the way: 20 | 21 | ```shell 22 | mv /var/lib/dokku/plugins/git/receive-app /var/lib/dokku/plugins/git/receive-app.bak 23 | ``` 24 | 25 | The second step is necessary because this plugin replaces the default 26 | `receive-app` hook. If you don't use the default git `receive-app` hook then you 27 | will need to modify the last lines of `receive-app` in this plugin accordingly. 28 | 29 | ## Configuration 30 | 31 | Add a webhook: 32 | 33 | dokku webhooks:add https://example.com/my/webhook 34 | 35 | Remove a webhook: 36 | 37 | dokku webhooks:remove https://example.com/my/webhook 38 | 39 | List all installed webhooks: 40 | 41 | dokku webhooks 42 | 43 | ## Hooks 44 | 45 | Each webhook endpoint is sent an HTTP POST request with a standard 46 | `application/x-www-form-urlencoded` POST payload, the contents of which depend 47 | on which stage of deployment has been reached. 48 | 49 | All hook requests contain the following POST params: 50 | 51 | Param | Example value | Description 52 | ---------------- | -------------------- | ------------------------------ 53 | `action` | `receive-app` | The deployment stage. 54 | `hostname` | `dokku.example.com` | The FQDN of the dokku host. 55 | `app` | `mywebapp` | The dokku app being deployed. 56 | 57 | Other hook requests contain additional data, as detailed below. 58 | 59 | ### `receive-app` 60 | 61 | This hook is triggered at the very start of a deployment, when dokku starts 62 | receiving data pushed to git. 63 | 64 | Param | Example value | Description 65 | ---------------- | ------------------------------------------ | ---------------------------------------------------------------------------- 66 | `git_rev` | `ade8218956d4a744ca42f872700384124edf015b` | The git revision being deployed. 67 | `git_rev_before` | `0000000000000000000000000000000000000000` | The git revision currently deployed, or `0{40}` if this is the first deploy. 68 | 69 | ### `post-deploy` 70 | 71 | This hook is triggered at the very end of a successful deployment. 72 | 73 | Param | Example value | Description 74 | ---------------- | ------------------------------------- | ------------------------------------------------ 75 | `internal_ip` | `127.0.0.1` | The internal IP on which the app is listening. 76 | `internal_port` | `49152` | The internal port on which the app is listening. 77 | `url` | `https://mywebapp.dokku.example.com` | The public URL of the deployed app. 78 | 79 | ## License 80 | 81 | This free software is released under the MIT license, a copy of which can be 82 | found in `LICENSE`. 83 | -------------------------------------------------------------------------------- /commands: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x 3 | source "$(dirname $0)/config" 4 | 5 | case "$1" in 6 | webhooks) 7 | cat "$HOOKS_FILE" 2>/dev/null 8 | ;; 9 | 10 | webhooks:add) 11 | [[ -z $2 ]] && echo "Please specify a webhook URL to add" && exit 1 12 | if grep -Fxq "$2" "$HOOKS_FILE" 2>/dev/null; then 13 | echo "URL already registered" 14 | exit 1 15 | fi 16 | echo "$2" >> "$HOOKS_FILE" 17 | echo "URL added" 18 | ;; 19 | 20 | webhooks:remove) 21 | [[ -z $2 ]] && echo "Please specify a webhook URL to remove" && exit 1 22 | grep -Fxv "$2" "$HOOKS_FILE" >"${HOOKS_FILE}.new" 2>/dev/null || : 23 | mv "${HOOKS_FILE}.new" "$HOOKS_FILE" 24 | echo "URL removed (if it was present)" 25 | ;; 26 | 27 | help | webhooks:help) 28 | 29 | help_content_func() { 30 | #shellcheck disable=SC2034 31 | declare desc="return webhooks plugin help content" 32 | 33 | cat< Adds a webhook URL 36 | webhooks:remove Removes a webhook URL 37 | help_content 38 | } 39 | 40 | if [[ $1 = "webhooks:help" ]]; then 41 | echo -e 'Usage: dokku webhooks[:COMMAND]' 42 | echo '' 43 | echo 'Allows triggering external webhooks' 44 | echo '' 45 | echo 'Additional commands:' 46 | help_content_func | sort | column -c2 -t -s, 47 | else 48 | help_content_func 49 | fi 50 | 51 | ;; 52 | 53 | *) 54 | exit $DOKKU_NOT_IMPLEMENTED_EXIT 55 | ;; 56 | 57 | esac 58 | -------------------------------------------------------------------------------- /config: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x 3 | 4 | HOOKS_FILE="$DOKKU_ROOT/WEBHOOKS" 5 | -------------------------------------------------------------------------------- /plugin.toml: -------------------------------------------------------------------------------- 1 | [plugin] 2 | description = "Allows triggering external webhooks" 3 | version = "0.4.0" 4 | [plugin.config] 5 | -------------------------------------------------------------------------------- /post-deploy: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x 3 | 4 | APP=$1; PORT=$2; IP=$3 5 | 6 | "$(dirname $0)"/trigger post-deploy $APP \ 7 | internal_port=$PORT \ 8 | internal_ip=$IP \ 9 | url=$(dokku url $APP) 10 | -------------------------------------------------------------------------------- /receive-app: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x 3 | 4 | # In order to get access to the git revision being pushed, we have to intercept 5 | # it in the only pluginhook which has access to it, receive-app. This is ugly, 6 | # and there may be a better way in the future. 7 | 8 | APP=$1; REV=$2 9 | 10 | # Current git rev is either master or 0{40} if this is the first push. Again, 11 | # ideally we'd get this direct from the prereceive hook, but it's not passed 12 | # through by dokku at the moment. 13 | OLDREV=$(cat $DOKKU_ROOT/$APP/refs/heads/master 2>/dev/null || 14 | echo 0000000000000000000000000000000000000000) 15 | 16 | # If we're called as a result of a ps:rebuild or similar, then REV will be 17 | # empty, in which case we should set it to the OLDREV. 18 | if [[ -z "$REV" ]]; then 19 | NEWREV=$OLDREV 20 | else 21 | NEWREV=$REV 22 | fi 23 | 24 | "$(dirname $0)"/trigger receive-app $APP \ 25 | git_rev=$NEWREV \ 26 | git_rev_before=$OLDREV 27 | 28 | # And then continue the build as normal 29 | dokku git-build $APP $REV 30 | -------------------------------------------------------------------------------- /trigger: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -eo pipefail; [[ $DOKKU_TRACE ]] && set -x 3 | source "$(dirname $0)/../common/functions" 4 | source "$(dirname $0)/config" 5 | 6 | ACTION=$1; APP=$2; shift; shift 7 | 8 | join () { 9 | IFS=$1; shift; echo "$*" 10 | } 11 | 12 | dokku_log_info1 "Running webhooks for $ACTION" 13 | 14 | [[ -f "$HOOKS_FILE" ]] || exit 0 15 | 16 | PAYLOAD=$(join '&' action=$ACTION app=$APP host=$(hostname -f) "$@") 17 | 18 | while read url; do 19 | dokku_log_info2_quiet "$url" 20 | if ! curl -sSL -X POST -d "$PAYLOAD" -o/dev/null "$url"; then 21 | dokku_log_warn "Failed to post webhook to '$url'. Continuing..." 22 | fi 23 | done < "$HOOKS_FILE" 24 | --------------------------------------------------------------------------------