Files
tf-pr-commenter/tf-pr-comment.sh
T
2025-11-07 20:13:04 -05:00

165 lines
4.6 KiB
Bash

#!/usr/bin/env bash
set -e
# Add OpenTofu binary to PATH
export PATH="${PATH}:/home/runner/.opentofu/bin"
# Read inputs
COMMAND=$1
INPUT=$2
EXIT_CODE=$3
WORKING_DIR=$4
# Determine repo root (where .git exists)
REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || echo "$PWD")
# Change to working directory if provided, relative to repo root
if [[ -n "$WORKING_DIR" ]]; then
TARGET_DIR="$REPO_ROOT/$WORKING_DIR"
echo "Switching to working directory: $TARGET_DIR"
cd "$TARGET_DIR" || { echo "Directory $TARGET_DIR not found"; exit 1; }
else
cd "$REPO_ROOT" || { echo "Cannot determine repo root"; exit 1; }
fi
# Strip ANSI codes from input
# INPUT=$(echo "$INPUT" | sed 's/\x1b\[[0-9;]*m//g')
##################
# CI Detection
##################
if [[ -n "$GITHUB_ACTIONS" ]]; then
CI_PLATFORM="github"
elif [[ -n "$GITEA_ACTION" ]]; then
CI_PLATFORM="gitea"
else
CI_PLATFORM="local"
fi
echo "Detected CI platform: $CI_PLATFORM"
##################
# PR Variables
##################
if [[ "$CI_PLATFORM" == "github" ]]; then
: "${PR_NUMBER:?PR_NUMBER not set}"
: "${PR_COMMENTS_URL:?PR_COMMENTS_URL not set}"
: "${PR_COMMENT_URI:?PR_COMMENT_URI not set}"
AUTH_HEADER="Authorization: token $GITHUB_TOKEN"
elif [[ "$CI_PLATFORM" == "gitea" ]]; then
: "${PR_NUMBER:?PR_NUMBER not set}"
: "${PR_COMMENTS_URL:?PR_COMMENTS_URL not set}"
: "${PR_COMMENT_URI:?PR_COMMENT_URI not set}"
: "${GITEA_TOKEN:?GITEA_TOKEN not set}"
AUTH_HEADER="Authorization: token $GITEA_TOKEN"
else
echo "Local mode: PR variables must be set manually."
exit 1
fi
ACCEPT_HEADER="Accept: application/vnd.github.v3+json"
CONTENT_HEADER="Content-Type: application/json"
##################
# Shared Settings
##################
DETAILS_STATE=" open"
COLOURISE=${HIGHLIGHT_CHANGES:-true}
##################
# Helper Functions
##################
handle_pr_comment() {
local type="$1"
local body="$2"
PR_COMMENT_ID=$(curl -sS -H "$AUTH_HEADER" -H "$ACCEPT_HEADER" -L "$PR_COMMENTS_URL" \
| jq ".[] | select(.body|test(\"### tofu \\\`$type\\\`\")) | .id")
if [[ "$PR_COMMENT_ID" ]]; then
echo "Updating existing $type PR comment: $PR_COMMENT_ID"
PR_COMMENT_URL="$PR_COMMENT_URI/$PR_COMMENT_ID"
PR_PAYLOAD=$(jq -n --arg body "$body" '{body: $body}')
curl -sS -X PATCH -H "$AUTH_HEADER" -H "$ACCEPT_HEADER" -H "$CONTENT_HEADER" \
-d "$PR_PAYLOAD" -L "$PR_COMMENT_URL" > /dev/null
else
echo "Creating new $type PR comment"
PR_PAYLOAD=$(jq -n --arg body "$body" '{body: $body}')
curl -sS -X POST -H "$AUTH_HEADER" -H "$ACCEPT_HEADER" -H "$CONTENT_HEADER" \
-d "$PR_PAYLOAD" -L "$PR_COMMENTS_URL" > /dev/null
fi
}
format_diff_block() {
local content="$1"
local codeblock=""
if [[ $CI_PLATFORM == "github" && $COLOURISE == "true" ]]; then
content=$(echo "$content" | sed -r 's/^~/!/g')
codeblock="diff"
fi
echo "```$codeblock
$content
```"
}
##################
# Command Handlers
##################
case "$COMMAND" in
fmt)
STATUS="Succeeded"
[[ "$COMMENTER_EXITCODE" -ne 0 ]] && STATUS="Failed"
ALL_DIFFS=""
# COMMENTER_INPUT is expected to be a newline-separated file list
while IFS= read -r file; do
if [[ -n "$file" && -f "$file" ]]; then
FILE_DIFF=$(tofu fmt -no-color -write=false -diff "$file" 2>/dev/null || true)
DIFF_BLOCK=$(format_diff_block "$FILE_DIFF")
ALL_DIFFS="$ALL_DIFFS
<details$DETAILS_STATE><summary><code>$file</code></summary>
$DIFF_BLOCK
</details>"
fi
done <<< "$COMMENTER_INPUT"
# Fallback if no valid files found
[[ -z "$ALL_DIFFS" ]] && ALL_DIFFS=$(format_diff_block "$COMMENTER_INPUT")
PR_COMMENT="### tofu \`fmt\` $STATUS for Workspace: \`$WORKSPACE\`
$ALL_DIFFS"
handle_pr_comment "$COMMAND" "$PR_COMMENT"
;;
plan)
STATUS="Succeeded"
[[ "$COMMENTER_EXITCODE" -ne 0 ]] && STATUS="Failed"
PR_OUTPUT=$(format_diff_block "$COMMENTER_INPUT")
PR_COMMENT="### tofu \`plan\` $STATUS for Workspace: \`$WORKSPACE\`
<details$DETAILS_STATE><summary>Show Output</summary>
$PR_OUTPUT
</details>"
handle_pr_comment "$COMMAND" "$PR_COMMENT"
;;
init|validate)
STATUS="Succeeded"
[[ "$COMMENTER_EXITCODE" -ne 0 ]] && STATUS="Failed"
PR_COMMENT="### tofu \`$COMMAND\` $STATUS for Workspace: \`$WORKSPACE\`
<details$DETAILS_STATE><summary>Show Output</summary>
\`\`\`
$COMMENTER_INPUT
\`\`\`
</details>"
handle_pr_comment "$COMMAND" "$PR_COMMENT"
;;
*)
echo "Unsupported command: $COMMAND"
exit 1
;;
esac