Skip to content

Instantly share code, notes, and snippets.

@b-
Created May 20, 2025 15:35
Show Gist options
  • Save b-/6a461629bb43bfe7ea6586e880731743 to your computer and use it in GitHub Desktop.
Save b-/6a461629bb43bfe7ea6586e880731743 to your computer and use it in GitHub Desktop.
Script to enroll webhooks with GitHub
#!/usr/bin/env bash
set -euo pipefail
errHookAlreadyExists="Hook already exists on this repository"
WEBHOOK_SECRET_REFERENCE="${WEBHOOK_SECRET_REFERENCE:-"op://komodo secrets/KOMODO_WEBHOOK_SECRET/credential"}"
WEBHOOK_SECRET="${WEBHOOK_SECRET:-$(op read "${WEBHOOK_SECRET_REFERENCE}")}"
get_gh_repo_name() {
gh repo view --json nameWithOwner | jq '.nameWithOwner' -r
}
API_PATH="repos/$(get_gh_repo_name)/hooks"
post_api() {
gh api "${1}" --input - -X POST
}
JSON_TEMPLATE='{"name":"web","active":true,"events":["push","pull_request","release"],"config":{"url":"___WEBHOOK_URL___","secret":"___WEBHOOK_SECRET___","content_type":"json","insecure_ssl":"0"}}'
WEBHOOK_URLS=( ) # empty array
PAYLOADS=( ) # empty array
generate_payload() {
jq --arg url "${1:-"${WEBHOOK_URL:-}"}" --arg secret "${WEBHOOK_SECRET}" '.config.url = $url | .config.secret = $secret' <<<"$JSON_TEMPLATE"
}
generate_payloads() {
for url in "${WEBHOOK_URLS[@]}"; do
PAYLOADS+=("$(generate_payload "$url")")
done
}
setup_webhook() {
set +e # disable exit-on-error for this bit
returnmsg="$(post_api "${API_PATH}" <<< "${PAYLOAD}")"
exitcode=$?
set -e # re-enable exit-on-error
if [[ $exitcode -eq 0 ]]; then
echo "Webhook setup successful."
else
# {
# "message": "Validation Failed",
# "errors": [
# {
# "resource": "Hook",
# "code": "custom",
# "message": "Hook already exists on this repository"
# }
# ],
# "documentation_url": # "https://docs.github.com/rest/repos/webhooks#create-a-repository-webhook",
# "status": "422"
# }
errors0message="$(jq -r '.errors[0].message' <<< "$returnmsg" )"
status="$(jq -r '.status' <<< "$returnmsg" )"
echo "Webhook setup failed. (Status $status)"
if [[ "$errors0message" == "$errHookAlreadyExists" ]]; then
echo "(Hook already exists on this repository.)"
return 0 # override because we don't want to fail the script if the webhook already exists
else
echo "Error message: ${errors0message}"
return "${exitcode}"
fi
fi
}
for arg in "$@"; do
case "$arg" in
--help|-h)
echo "Usage: [WEBHOOK_SECRET=<secret> | WEBHOOK_SECRET_REFERENCE=<reference>] $0 <WEBHOOK_URL> [<WEBHOOK_URL> [<WEBHOOK_URL> ...]]"
echo "Notes:"
echo " - The default secret is read from the secret manager."
echo " - An alternate secret reference can be provided, or a custom secret can be specified."
echo " - Specify a list of webhook URLs as arguments."
exit 250
;;
http://*|https://*)
WEBHOOK_URLS+=("$arg")
;;
*)
echo "Unknown option: $arg"
exit 1
;;
esac
done
if [[ ${#WEBHOOK_URLS[@]} -eq 0 ]]; then
echo "No webhook URLs provided."
exit 250
fi
generate_payloads
for PAYLOAD in "${PAYLOADS[@]}"; do
setup_webhook
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment