Repository navigation
fix(hive): seed Pi with positional bootstrap prompt #263
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Grants the Discord "employee of the month" role. | ||
|
Check warning on line 1 in .github/workflows/contributor-role.yml
|
||
| # | ||
| # Two ways in: | ||
| # 1. Automatically, when a pull request whose body contains "Discord: handle" | ||
| # is merged. | ||
| # 2. By hand, from the Actions tab or `gh workflow run`, with a list of | ||
| # handles. That is for people who earned it without a pull request, or who | ||
| # gave their handle in a discussion comment instead of a PR body. | ||
| # | ||
| # pull_request_target is required so the job can see repo secrets for PRs opened | ||
| # from forks. It deliberately does NOT check out the PR's code — the only thing | ||
| # read from the pull request is its body text, and that arrives via an env var so | ||
| # it is never interpolated into the shell. The manual input is handled the same | ||
| # way, and every handle is checked against a strict pattern before it is used. | ||
| name: contributor role | ||
| on: | ||
| pull_request_target: | ||
| types: [closed] | ||
| workflow_dispatch: | ||
| inputs: | ||
| handles: | ||
| description: 'Discord usernames, separated by spaces or commas' | ||
| required: true | ||
| type: string | ||
| permissions: | ||
| contents: read | ||
| jobs: | ||
| grant: | ||
| if: github.event_name == 'workflow_dispatch' || github.event.pull_request.merged == true | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: grant "employee of the month" | ||
| env: | ||
| BOT_TOKEN: ${{ secrets.DISCORD_BOT_TOKEN }} | ||
| GUILD_ID: "1539397814352613496" | ||
| ROLE_ID: "1539474540298764308" | ||
| PR_BODY: ${{ github.event.pull_request.body }} | ||
| PR_AUTHOR: ${{ github.event.pull_request.user.login }} | ||
| INPUT_HANDLES: ${{ inputs.handles }} | ||
| EVENT: ${{ github.event_name }} | ||
| run: | | ||
| set -euo pipefail | ||
| API=https://discord.com/api/v10 | ||
| if [ -z "${BOT_TOKEN:-}" ]; then | ||
| echo "DISCORD_BOT_TOKEN is not set — nothing to do."; exit 0 | ||
| fi | ||
| if [ "$EVENT" = "workflow_dispatch" ]; then | ||
| # Commas and spaces both separate. Anything that is not a legal | ||
| # Discord username is dropped before it reaches a command. | ||
| HANDLES=$(printf '%s' "${INPUT_HANDLES:-}" | tr ',' ' ' | tr -s '[:space:]' '\n' \ | ||
| | grep -E '^[A-Za-z0-9._]+$' || true) | ||
| if [ -z "$HANDLES" ]; then | ||
| echo "No usable handle in the input — nothing to do."; exit 1 | ||
| fi | ||
| else | ||
| # "Discord: someone" anywhere in the PR body. Optional by design. | ||
| HANDLES=$(printf '%s' "${PR_BODY:-}" \ | ||
| | grep -iEo 'Discord:[[:space:]]*[A-Za-z0-9._]+' \ | ||
| | head -1 | sed -E 's/.*:[[:space:]]*//' || true) | ||
| if [ -z "$HANDLES" ]; then | ||
| echo "No Discord handle in the PR body from @$PR_AUTHOR — skipping (this is fine)."; exit 0 | ||
| fi | ||
| fi | ||
| failed=0 | ||
| while IFS= read -r HANDLE; do | ||
| [ -n "$HANDLE" ] || continue | ||
| echo "Looking up Discord handle: $HANDLE" | ||
| Q=$(jq -rn --arg q "$HANDLE" '$q|@uri') | ||
| USER_ID=$(curl -sS -H "Authorization: Bot $BOT_TOKEN" \ | ||
| "$API/guilds/$GUILD_ID/members/search?query=$Q&limit=10" \ | ||
| | jq -r --arg h "$HANDLE" \ | ||
| '[.[] | select((.user.username // "" | ascii_downcase) == ($h | ascii_downcase))][0].user.id // empty') | ||
| if [ -z "$USER_ID" ]; then | ||
| echo "'$HANDLE' is not a member of the server yet — skipping." | ||
| echo "They can join at https://discord.gg/SEDzP5ZPk5 and we'll grant it on their next PR." | ||
| continue | ||
| fi | ||
| code=$(curl -sS -o /dev/null -w '%{http_code}' -X PUT \ | ||
| -H "Authorization: Bot $BOT_TOKEN" -H 'Content-Length: 0' \ | ||
| "$API/guilds/$GUILD_ID/members/$USER_ID/roles/$ROLE_ID") | ||
| case "$code" in | ||
| 204) echo "Granted 'employee of the month' to $HANDLE ($USER_ID)." ;; | ||
| *) echo "Discord returned HTTP $code for $HANDLE — role not granted."; failed=1 ;; | ||
| esac | ||
| done <<< "$HANDLES" | ||
| exit "$failed" | ||