#!/bin/bash # Called by action.yml. Everything user-written (release name, notes) comes in # through the event JSON file and is only ever handled by jq -- never spliced # into a command line or a JSON string by the shell. set -euo pipefail category_path=$(jq -r --arg r "$REPO" '.[$r] // empty' "$MAP") if [ -z "$category_path" ]; then echo "::error::$REPO is not in discourse-release/release-map.json" exit 1 fi tag=$(jq -r '.release.tag_name' "$EVENT_PATH") # The category id, looked up anonymously (the category is public); the # release-bot key is scoped to creating posts and nothing else. category_id=$(curl -fsS "$FORUM/c/$category_path/find_by_slug.json" | jq -r '.category.id') # One topic per repo+tag, ever: Discourse enforces external_id uniqueness. external_id="rel-$(printf '%s@%s' "$REPO" "$tag" | sha1sum | cut -c1-40)" payload=$(jq -n --arg repo "$REPO" --argjson category "$category_id" --arg ext "$external_id" \ --slurpfile ev "$EVENT_PATH" ' ($ev[0].release) as $r | ($repo | split("/") | last) as $name | ($r.name // "" | if . == "" then $r.tag_name else . end) as $title | { title: "\($name) \($title) released", category: $category, external_id: $ext, raw: ( "**\($name) \($r.tag_name)** is out.\n\n" + (if ($r.body // "") == "" then "" else "\($r.body)\n\n" end) + "---\n[Release on Gitea](\($r.html_url))" ) }') status=$(curl -sS -o /tmp/discourse-release.out -w '%{http_code}' -X POST "$FORUM/posts.json" \ -H "Api-Key: $API_KEY" -H "Api-Username: release-bot" \ -H "Content-Type: application/json" --data-binary "$payload") body=$(cat /tmp/discourse-release.out) case "$status" in 200) url="$FORUM/t/$(jq -r '.topic_slug' <<<"$body")/$(jq -r '.topic_id' <<<"$body")" echo "announced: $url" ;; 422) if jq -e '.errors | tostring | test("External ID"; "i")' <<<"$body" >/dev/null; then echo "already announced (external_id $external_id); nothing to do" exit 0 fi echo "::error::forum refused the post: $body"; exit 1 ;; *) echo "::error::forum returned HTTP $status: $body"; exit 1 ;; esac if [ -n "${DISCORD_WEBHOOK:-}" ]; then jq -n --arg u "$url" --slurpfile ev "$EVENT_PATH" --arg repo "$REPO" ' ($ev[0].release) as $r | {content: ("**\($repo | split("/") | last) \($r.tag_name)** released\n\($u)")[0:1900]}' | curl -fsS -X POST "$DISCORD_WEBHOOK" -H "Content-Type: application/json" --data-binary @- >/dev/null \ && echo "posted to Discord" \ || echo "::warning::Discord webhook failed; the forum post stands" fi