|
| 1 | +name: discord-release |
| 2 | + |
| 3 | +on: |
| 4 | + workflow_dispatch: |
| 5 | + |
| 6 | +permissions: |
| 7 | + contents: read |
| 8 | + |
| 9 | +jobs: |
| 10 | + post: |
| 11 | + runs-on: ubuntu-latest |
| 12 | + steps: |
| 13 | + - name: Post shuvcode release notes to Discord |
| 14 | + env: |
| 15 | + DISCORD_TOKEN: ${{ secrets.DISCORD_TOKEN }} |
| 16 | + DISCORD_CHANNEL_ID: "1473184731037433929" |
| 17 | + GH_TOKEN: ${{ github.token }} |
| 18 | + RELEASE_TAG: "v1.2.27" |
| 19 | + run: | |
| 20 | + set -euo pipefail |
| 21 | +
|
| 22 | + api="https://discord.com/api/v10" |
| 23 | + ua='Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36' |
| 24 | +
|
| 25 | + call() { |
| 26 | + local auth="$1" |
| 27 | + local path="$2" |
| 28 | + local method="${3:-GET}" |
| 29 | + local body="${4:-}" |
| 30 | + local bodyf code |
| 31 | + bodyf=$(mktemp) |
| 32 | + if [ -n "$body" ]; then |
| 33 | + code=$(curl -sS --http1.1 -o "$bodyf" -w '%{http_code}' \ |
| 34 | + -X "$method" "$api$path" \ |
| 35 | + -H "Authorization: $auth" \ |
| 36 | + -H 'Accept: application/json' \ |
| 37 | + -H 'Content-Type: application/json' \ |
| 38 | + -H "User-Agent: $ua" \ |
| 39 | + --data "$body") |
| 40 | + else |
| 41 | + code=$(curl -sS --http1.1 -o "$bodyf" -w '%{http_code}' \ |
| 42 | + -X "$method" "$api$path" \ |
| 43 | + -H "Authorization: $auth" \ |
| 44 | + -H 'Accept: application/json' \ |
| 45 | + -H 'Content-Type: application/json' \ |
| 46 | + -H "User-Agent: $ua") |
| 47 | + fi |
| 48 | + printf '%s\n' "$code" |
| 49 | + cat "$bodyf" |
| 50 | + rm -f "$bodyf" |
| 51 | + } |
| 52 | +
|
| 53 | + pick() { |
| 54 | + local body code auth label entry |
| 55 | + local pairs=( |
| 56 | + "user|$DISCORD_TOKEN" |
| 57 | + "bot|Bot $DISCORD_TOKEN" |
| 58 | + "bearer|Bearer $DISCORD_TOKEN" |
| 59 | + ) |
| 60 | + for entry in "${pairs[@]}"; do |
| 61 | + IFS='|' read -r label auth <<< "$entry" |
| 62 | + mapfile -t out < <(call "$auth" /users/@me) |
| 63 | + code="${out[0]}" |
| 64 | + body="$(printf '%s\n' "${out[@]:1}")" |
| 65 | + echo "probe $label: $code" >&2 |
| 66 | + { printf '%s\n' "$body" | head -c 200; echo; } >&2 |
| 67 | + if [ "$code" = "200" ]; then |
| 68 | + echo "selected auth: $label" >&2 |
| 69 | + printf '%s' "$auth" |
| 70 | + return 0 |
| 71 | + fi |
| 72 | + done |
| 73 | + return 1 |
| 74 | + } |
| 75 | +
|
| 76 | + auth="$(pick)" || { echo "could not authenticate to Discord"; exit 1; } |
| 77 | +
|
| 78 | + mapfile -t out < <(call "$auth" "/channels/$DISCORD_CHANNEL_ID") |
| 79 | + code="${out[0]}" |
| 80 | + body="$(printf '%s\n' "${out[@]:1}")" |
| 81 | + echo "channel lookup: $code" |
| 82 | + printf '%s\n' "$body" | head -c 300; echo |
| 83 | + [ "$code" = "200" ] || { echo "could not access target channel"; exit 1; } |
| 84 | +
|
| 85 | + export RELEASE_JSON="$(gh release view "$RELEASE_TAG" --repo Latitudes-Dev/shuvcode --json tagName,body,url)" |
| 86 | + python - <<'PY' > /tmp/discord-payloads.jsonl |
| 87 | +import json, os |
| 88 | + |
| 89 | +data = json.loads(os.environ["RELEASE_JSON"]) |
| 90 | +tag = data["tagName"] |
| 91 | +body = data.get("body") or "" |
| 92 | +url = data["url"] |
| 93 | +npm = f"https://www.npmjs.com/package/shuvcode/v/{tag.removeprefix('v')}" |
| 94 | +parts = [f"**shuvcode {tag}** release notes\n\n[GitHub Release](<{url}>) | [npm](<{npm}>)"] |
| 95 | +buf = "" |
| 96 | +limit = 1900 |
| 97 | +for line in body.splitlines(): |
| 98 | + add = (line or "") + "\n" |
| 99 | + if len(buf) + len(add) > limit: |
| 100 | + if buf.strip(): |
| 101 | + parts.append(buf.rstrip()) |
| 102 | + buf = add |
| 103 | + else: |
| 104 | + buf += add |
| 105 | +if buf.strip(): |
| 106 | + parts.append(buf.rstrip()) |
| 107 | +for part in parts: |
| 108 | + print(json.dumps({"content": part})) |
| 109 | +PY |
| 110 | + |
| 111 | + while IFS= read -r payload; do |
| 112 | + mapfile -t out < <(call "$auth" "/channels/$DISCORD_CHANNEL_ID/messages" POST "$payload") |
| 113 | + code="${out[0]}" |
| 114 | + body="$(printf '%s\n' "${out[@]:1}")" |
| 115 | + echo "post: $code" |
| 116 | + printf '%s\n' "$body" | head -c 300; echo |
| 117 | + [[ "$code" = "200" || "$code" = "201" ]] || { echo "post failed"; exit 1; } |
| 118 | + done < /tmp/discord-payloads.jsonl |
0 commit comments