From 6134660644b87be8fa2dd416f91c76e52ad18b4b Mon Sep 17 00:00:00 2001 From: Matthieu Bernardin Date: Tue, 30 Jul 2024 14:51:46 +0200 Subject: [PATCH] feat(task): Add capability to the slack task to dump file content and submodule git log --- task/slack-webhook-notification/0.1/README.md | 3 +- .../0.1/slack-webhook-notification.yaml | 157 +++++++++++++++++- 2 files changed, 157 insertions(+), 3 deletions(-) diff --git a/task/slack-webhook-notification/0.1/README.md b/task/slack-webhook-notification/0.1/README.md index 0aefc20ce9..83ab889a66 100644 --- a/task/slack-webhook-notification/0.1/README.md +++ b/task/slack-webhook-notification/0.1/README.md @@ -8,4 +8,5 @@ Sends message to slack using incoming webhook |message|Message to be sent||true| |secret-name|Secret with least one key where value is webhook URL for slack. eg. oc create secret generic my-secret --from-literal team1=https://hooks.slack.com/services/XXX/XXXXXX --from-literal team2=https://hooks.slack.com/services/YYY/YYYYYY |slack-webhook-notification-secret|false| |key-name|Key in the key in secret which contains webhook URL for slack.||true| - +|files|List of file to dump. The content will be added to the message.|[]|false| +|submodules|List of submodules name to dump. Git log since previous submodule commit will be added to the message. ["*"] for all|[]|false| diff --git a/task/slack-webhook-notification/0.1/slack-webhook-notification.yaml b/task/slack-webhook-notification/0.1/slack-webhook-notification.yaml index 7abe41bc55..32c5b0a238 100644 --- a/task/slack-webhook-notification/0.1/slack-webhook-notification.yaml +++ b/task/slack-webhook-notification/0.1/slack-webhook-notification.yaml @@ -20,6 +20,14 @@ spec: default: slack-webhook-notification-secret - name: key-name description: Key in the key in secret which contains webhook URL for slack. + - name: submodules + type: array + description: List of submodules name to dump. Git log since previous submodule commit will be added to the message. + default: [] + - name: files + type: array + description: List of file to dump. The content will be added to the message. + default: [] volumes: - name: webhook-secret secret: @@ -27,7 +35,7 @@ spec: optional: true steps: - name: send-message - image: registry.access.redhat.com/ubi9/ubi-minimal:9.4-1194@sha256:73f7dcacb460dad137a58f24668470a5a2e47378838a0190eef0ab532c6e8998 + image: quay.io/konflux-ci/appstudio-utils:ab6b0b8e40e440158e7288c73aff1cf83a2cc8a9@sha256:24179f0efd06c65d16868c2d7eb82573cce8e43533de6cea14fec3b7446e0b14 # per https://kubernetes.io/docs/concepts/containers/images/#imagepullpolicy-defaulting # the cluster will set imagePullPolicy to IfNotPresent volumeMounts: @@ -41,12 +49,157 @@ spec: value: $(params.key-name) - name: MESSAGE value: $(params.message) + args: + - --files + - $(params.files[*]) + - --submodules + - $(params.submodules[*]) script: | #!/usr/bin/env bash + + # --------- + # HELPERS + # --------- + + function concat { + cat << EOM + $1 + $2 + EOM + } + + # --------- + # DUMPERS + # --------- + + function dumpSeparator { + echo "-----------------------------------------" + } + + function dumpFile { + filePath=$1 + + cat << EOM + *${filePath}:* + \`\`\` + $(cat "${filePath}") + \`\`\` + EOM + } + + # dumpSubmodule will dump the git log history as follow + # $commitShortSHA $authorName $subject + # with some padding to align the lines (author name is truncated after 27 char). + # A link to the previous commits is available (tested on github & gitlab). + function dumpSubmodule { + name=$1 + + path=$(git config -f .gitmodules --get submodule."${name}".path) + url=$(git config -f .gitmodules --get submodule."${name}".url) + + current_commit=$(git -C "${path}" rev-parse HEAD) + previous_commit=$(git diff HEAD~1 "${path}" | grep commit | head -n 1 | awk '{print $3;}') + if [ "${previous_commit}" = "" ]; then + previous_commit=${current_commit} + fi + + commits=None + if [ "${previous_commit}" != "${current_commit}" ]; then + commits=$(git -C "${path}" log --pretty=format:'%h %<(27,trunc)%an %s' --abbrev-commit "${previous_commit}".."${current_commit}") + fi + + cat << EOM + *Submodule ${name} (<${url}/commits/${current_commit}|commits>):* + \`\`\` + ${commits} + \`\`\` + EOM + } + + # -------------- + # ARGS PARSING + # -------------- + + echo "Parsing $*" + + FILES=() + SUBMODULES=() + + process_all_submodules="false" + + while [[ $# -gt 0 ]]; do + case $1 in + --files) + shift + while [[ $# -gt 0 ]] && ! [[ "$1" =~ --.* ]]; do + FILES+=("$1") + shift + done + ;; + --submodules) + shift + while [[ $# -gt 0 ]] && ! [[ "$1" =~ --.* ]]; do + SUBMODULES+=("$1") + + if [ "$1" == "*" ]; then + process_all_submodules="true" + fi + + shift + done + ;; + esac + done + + # If the user specified "*", add all submodules + if [ ${process_all_submodules} == "true" ]; then + SUBMODULES=() + + for submodule in $(git submodule status | awk '{print $2;}'); do + SUBMODULES+=("${submodule}") + done + fi + + # ------------------- + # PARAMS VALIDATION + # ------------------- + if [ -f "/etc/secrets/$KEY_NAME" ]; then WEBHOOK_URL=$(cat "/etc/secrets/$KEY_NAME") else echo "Secret not defined properly" exit 1 fi - curl -X POST -H 'Content-type: application/json' --data "{\"text\":\"$MESSAGE\"}" $WEBHOOK_URL + + # ------ + # DUMP + # ------ + + slack_message=${MESSAGE} + + if [ ${#FILES[@]} -ne 0 ]; then + slack_message=$(concat "${slack_message}" "$(dumpSeparator)") + fi + + for file in "${FILES[@]}"; do + content=$(dumpFile "${file}") + slack_message=$(concat "${slack_message}" "${content}") + done + + if [ ${#SUBMODULES[@]} -ne 0 ]; then + slack_message=$(concat "${slack_message}" "$(dumpSeparator)") + fi + + for submodule in "${SUBMODULES[@]}"; do + content=$(dumpSubmodule "${submodule}") + slack_message=$(concat "${slack_message}" "${content}") + done + + data=$(jq --compact-output --null-input --arg message "$slack_message" '{text: $message}') + + curl -X POST -H 'Content-type: application/json' --data "${data}" "$WEBHOOK_URL" + workingDir: $(workspaces.source.path)/source + workspaces: + - name: source + description: Workspace containing the source code to build. + optional: true