Skip to content

Merge pull request #30 from harriiinnii/test/duplicate-pr-new #5

Merge pull request #30 from harriiinnii/test/duplicate-pr-new

Merge pull request #30 from harriiinnii/test/duplicate-pr-new #5

name: Security Advisory Discord Notification

Check failure on line 1 in .github/workflows/advisory-discord-notify.yml

View workflow run for this annotation

GitHub Actions / .github/workflows/advisory-discord-notify.yml

Invalid workflow file

(Line: 9, Col: 3): Unexpected value 'repository_advisory'
on:
push:
branches:
- '**'
issues:
types: [opened, reopened]
repository_advisory:
types: [reported, created, published, submitted, reopened]
permissions:
contents: read
jobs:
notify-owners:
runs-on: ubuntu-latest
steps:
- name: Ensure Discord webhook is configured
id: check_secret
env:
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
run: |
if [ -z "$DISCORD_WEBHOOK" ]; then
echo "::warning::Missing required secret: DISCORD_WEBHOOK. Skipping advisory notification. Add a Discord webhook URL as the DISCORD_WEBHOOK secret in your repository or organization settings."
echo "skip=true" >> "$GITHUB_OUTPUT"
else
echo "skip=false" >> "$GITHUB_OUTPUT"
fi
- name: Send Discord notification
if: steps.check_secret.outputs.skip == 'false'
env:
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
REPO: ${{ github.repository }}
ACTOR: ${{ github.actor }}
EVENT_NAME: ${{ github.event_name }}
EVENT_PATH: ${{ github.event_path }}
run: |
if [ "$EVENT_NAME" = "repository_advisory" ]; then
ADVISORY_TITLE=$(jq -r '.repository_advisory.summary // "Security advisory"' "$EVENT_PATH")
ADVISORY_SEVERITY=$(jq -r '.repository_advisory.severity // "unknown"' "$EVENT_PATH")
ADVISORY_STATE=$(jq -r '.repository_advisory.state // "unknown"' "$EVENT_PATH")
ADVISORY_CVE=$(jq -r '.repository_advisory.cve_id // empty' "$EVENT_PATH")
ADVISORY_URL=$(jq -r '.repository_advisory.html_url // "https://github.com/'"$REPO"'"' "$EVENT_PATH")
ADVISORY_DESCRIPTION=$(jq -r '.repository_advisory.description // "No description provided."' "$EVENT_PATH")
ADVISORY_ACTION=$(jq -r '.action // "updated"' "$EVENT_PATH")
case "${ADVISORY_SEVERITY,,}" in
critical) COLOR=9831467 ;; # #960B0B dark red
high) COLOR=15548997 ;; # #ED4245 red
medium) COLOR=15105570 ;; # #E67E22 orange
low) COLOR=16776960 ;; # #FFFF00 yellow
*) COLOR=8421504 ;; # #808080 grey
esac
DESCRIPTION="${ADVISORY_DESCRIPTION:0:1024}"
PAYLOAD=$(jq -n \
--arg title "馃敀 Security Advisory ${ADVISORY_ACTION^} in \`${REPO}\`" \
--arg footer_text "GitHub Advisory 路 ${REPO}" \
--arg url "$ADVISORY_URL" \
--arg adv_title "$ADVISORY_TITLE" \
--arg severity "${ADVISORY_SEVERITY^}" \
--arg state "${ADVISORY_STATE^}" \
--arg actor "$ACTOR" \
--arg description "$DESCRIPTION" \
--arg cve "$ADVISORY_CVE" \
--argjson color "$COLOR" \
'{
embeds: [{
title: $title,
url: $url,
color: $color,
fields: (
[
{name: "Title", value: $adv_title, inline: false},
{name: "Severity", value: $severity, inline: true},
{name: "State", value: $state, inline: true},
{name: "Reported by", value: $actor, inline: true}
] +
(if $cve != "" then [{name: "CVE ID", value: $cve, inline: true}] else [] end) +
[{name: "Description", value: $description, inline: false}]
),
footer: {text: $footer_text}
}]
}')
elif [ "$EVENT_NAME" = "push" ]; then
COMMIT_MESSAGE=$(jq -r '.head_commit.message // "No commit message provided."' "$EVENT_PATH")
COMMIT_URL=$(jq -r '.head_commit.url // .compare // "https://github.com/'"$REPO"'"' "$EVENT_PATH")
COMMIT_SHA=$(jq -r '.head_commit.id // .after // ""' "$EVENT_PATH" | cut -c1-7)
BRANCH_NAME=$(jq -r '.ref // ""' "$EVENT_PATH" | sed 's|refs/heads/||')
PUSHER_NAME=$(jq -r '.pusher.name // "unknown"' "$EVENT_PATH")
PAYLOAD=$(jq -n \
--arg title "馃摝 New Commit in \`${REPO}\`" \
--arg footer_text "GitHub Push 路 ${REPO}" \
--arg url "$COMMIT_URL" \
--arg commit "${COMMIT_MESSAGE:0:1024}" \
--arg sha "$COMMIT_SHA" \
--arg branch "$BRANCH_NAME" \
--arg pusher "$PUSHER_NAME" \
'{
embeds: [{
title: $title,
url: $url,
color: 3447003,
fields: [
{name: "Commit", value: $commit, inline: false},
{name: "SHA", value: $sha, inline: true},
{name: "Branch", value: $branch, inline: true},
{name: "Pushed by", value: $pusher, inline: true}
],
footer: {text: $footer_text}
}]
}')
elif [ "$EVENT_NAME" = "issues" ]; then
ISSUE_TITLE=$(jq -r '.issue.title // "Untitled issue"' "$EVENT_PATH")
ISSUE_URL=$(jq -r '.issue.html_url // "https://github.com/'"$REPO"'/issues"' "$EVENT_PATH")
ISSUE_NUMBER=$(jq -r '.issue.number // ""' "$EVENT_PATH")
ISSUE_BODY=$(jq -r '.issue.body // "No description provided."' "$EVENT_PATH")
ISSUE_STATE=$(jq -r '.issue.state // "open"' "$EVENT_PATH")
ISSUE_ACTION=$(jq -r '.action // "opened"' "$EVENT_PATH")
PAYLOAD=$(jq -n \
--arg title "馃悰 Issue ${ISSUE_ACTION^} in \`${REPO}\`" \
--arg footer_text "GitHub Issues 路 ${REPO}" \
--arg url "$ISSUE_URL" \
--arg issue_title "$ISSUE_TITLE" \
--arg issue_number "$ISSUE_NUMBER" \
--arg issue_state "${ISSUE_STATE^}" \
--arg reporter "$ACTOR" \
--arg description "${ISSUE_BODY:0:1024}" \
'{
embeds: [{
title: $title,
url: $url,
color: 15844367,
fields: [
{name: "Issue", value: "#" + $issue_number + " 路 " + $issue_title, inline: false},
{name: "State", value: $issue_state, inline: true},
{name: "Raised by", value: $reporter, inline: true},
{name: "Description", value: $description, inline: false}
],
footer: {text: $footer_text}
}]
}')
else
echo "Skipping unsupported event: $EVENT_NAME"
exit 0
fi
RESPONSE=$(curl -sS -o /tmp/discord_response.txt -w "%{http_code}" \
-X POST "$DISCORD_WEBHOOK" \
-H "Content-Type: application/json" \
-d "$PAYLOAD")
if [ "$RESPONSE" -lt 200 ] || [ "$RESPONSE" -ge 300 ]; then
echo "::error::Discord webhook failed (HTTP $RESPONSE): $(cat /tmp/discord_response.txt)"
exit 1
fi