This commit is contained in:
2025-11-24 10:14:23 -05:00
parent 51ee84e692
commit 1f656f31c0
+17 -27
View File
@@ -1,5 +1,5 @@
name: "manual-approval-cross" name: "manual-approval-cross"
description: "Manual approval for Github & Gitea with reminders + Apprise notifications" description: "Manual approval for GitHub & Gitea with reminders + Apprise notifications"
branding: branding:
icon: "check-circle" icon: "check-circle"
color: "green" color: "green"
@@ -14,11 +14,11 @@ inputs:
required: true required: true
approval_keywords: approval_keywords:
description: "Approval keywords" description: "Approval keywords (comma-separated)"
default: "approve,approved,lgtm,yes" default: "approve,approved,lgtm,yes"
denial_keywords: denial_keywords:
description: "Denial keywords" description: "Denial keywords (comma-separated)"
default: "deny,denied,no" default: "deny,denied,no"
poll_interval: poll_interval:
@@ -39,7 +39,6 @@ inputs:
outputs: outputs:
approved: approved:
description: Approval response
value: ${{ steps.wait.outputs.approved }} value: ${{ steps.wait.outputs.approved }}
runs: runs:
@@ -72,9 +71,9 @@ runs:
**Approval keywords:** ${{ inputs.approval_keywords }} **Approval keywords:** ${{ inputs.approval_keywords }}
**Denial keywords:** ${{ inputs.denial_keywords }} **Denial keywords:** ${{ inputs.denial_keywords }}
Please reply with a keyword on this issue. Please reply with a keyword on this issue."
"
# Proper JSON array for assignees
ASSIGNEES_JSON=$(jq -nc --arg csv "$APPROVERS" '$csv | split(",")') ASSIGNEES_JSON=$(jq -nc --arg csv "$APPROVERS" '$csv | split(",")')
json=$(jq -n \ json=$(jq -n \
@@ -90,10 +89,9 @@ runs:
"${{ steps.detect.outputs.api_url }}/repos/${{ github.repository }}/issues") "${{ steps.detect.outputs.api_url }}/repos/${{ github.repository }}/issues")
issue_number=$(echo "$resp" | jq -r '.number // .index') issue_number=$(echo "$resp" | jq -r '.number // .index')
echo "issue=$issue_number" >> $GITHUB_OUTPUT echo "issue=$issue_number" >> $GITHUB_OUTPUT
# Notification helper function # Notification helper
- id: notify - id: notify
shell: bash shell: bash
if: always() if: always()
@@ -102,8 +100,6 @@ runs:
APPRISE_API: ${{ inputs.apprise_api }} APPRISE_API: ${{ inputs.apprise_api }}
run: | run: |
msg="$1" msg="$1"
# Apprise CLI URLs
if [[ -n "$APPRISE_URLS" ]]; then if [[ -n "$APPRISE_URLS" ]]; then
IFS=',' read -r -a urls <<< "$APPRISE_URLS" IFS=',' read -r -a urls <<< "$APPRISE_URLS"
for u in "${urls[@]}"; do for u in "${urls[@]}"; do
@@ -111,16 +107,13 @@ runs:
done done
fi fi
# Apprise-API server
if [[ -n "$APPRISE_API" ]]; then if [[ -n "$APPRISE_API" ]]; then
curl -s -X POST "$APPRISE_API" \ curl -s -X POST "$APPRISE_API" \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
-d "{\"title\": \"Manual Approval\", \"body\": \"$msg\"}" || true -d "{\"title\":\"Manual Approval\",\"body\":\"$msg\"}" || true
fi fi
# note: the script expects $1, so we will call it with "run: echo 'message' | ./.github/actions/.../notify" # Wait for approval with reminders
# Wait for approval with reminder support
- id: wait - id: wait
shell: bash shell: bash
env: env:
@@ -129,23 +122,20 @@ runs:
API_URL: ${{ steps.detect.outputs.api_url }} API_URL: ${{ steps.detect.outputs.api_url }}
ISSUE: ${{ steps.create-issue.outputs.issue }} ISSUE: ${{ steps.create-issue.outputs.issue }}
APPROVERS: ${{ inputs.approvers }} APPROVERS: ${{ inputs.approvers }}
APPROVAL_KEYWORDS: ${{ inputs.approval_keywords }}
DENIAL_KEYWORDS: ${{ inputs.denial_keywords }}
REMINDER_INTERVAL: ${{ inputs.reminder_interval }} REMINDER_INTERVAL: ${{ inputs.reminder_interval }}
POLL_INTERVAL: ${{ inputs.poll_interval }} POLL_INTERVAL: ${{ inputs.poll_interval }}
run: | run: |
# Split comma-separated inputs into Bash arrays
IFS=',' read -r -a approver_list <<< "$APPROVERS" IFS=',' read -r -a approver_list <<< "$APPROVERS"
IFS=',' read -r -a approved_kws <<< "$APPROVAL_KEYWORDS"
approved_kws=(${ { inputs.approval_keywords }//,/ }) IFS=',' read -r -a denied_kws <<< "$DENIAL_KEYWORDS"
denied_kws=(${ { inputs.denial_keywords }//,/ })
last_reminder=$(date +%s) last_reminder=$(date +%s)
ISSUE_URL="${API_URL}/repos/${{ github.repository }}/issues/$ISSUE" ISSUE_URL="${API_URL}/repos/${{ github.repository }}/issues/$ISSUE"
# Send first notification # Function to send notifications
echo "::group::Initial notification"
echo "Issue #$ISSUE created for manual approval"
echo "::endgroup::"
# Run notifications in a reusable function
notify_func() { notify_func() {
msg="$1" msg="$1"
echo "::notice::$msg" echo "::notice::$msg"
@@ -156,8 +146,8 @@ runs:
while true; do while true; do
comments=$(curl -s \ comments=$(curl -s \
-H "Authorization: token $TOKEN" \ -H "Authorization: token $TOKEN" \
"$ISSUE_URL/comments") "$ISSUE_URL/comments")
declare -A state declare -A state
for u in "${approver_list[@]}"; do state[$u]="pending"; done for u in "${approver_list[@]}"; do state[$u]="pending"; done
@@ -196,7 +186,7 @@ runs:
break break
fi fi
# Send reminder # Send reminders
if (( REMINDER_INTERVAL > 0 )); then if (( REMINDER_INTERVAL > 0 )); then
now=$(date +%s) now=$(date +%s)
since=$(( now - last_reminder )) since=$(( now - last_reminder ))