Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 86 additions & 0 deletions .github/workflows/auto-assign.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
name: Auto Assign Reviewers

on:
pull_request:
types: [opened, reopened, synchronize]
pull_request_target:
types: [opened, reopened, synchronize]

permissions:
contents: read
pull-requests: write

jobs:
auto-assign:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Auto assign reviewers
env:
GITHUB_TOKEN: ${{ secrets.AUTO_ASSIGN_PAT != '' && secrets.AUTO_ASSIGN_PAT || secrets.GITHUB_TOKEN }} # Use PAT if non-empty, else GITHUB_TOKEN
PR_NUMBER: ${{ github.event.pull_request.number }}
PR_AUTHOR: ${{ github.event.pull_request.user.login }}
REPO: ${{ github.repository }}
run: |
set -euo pipefail

if [ ! -f "OWNERS" ]; then
echo "OWNERS file not found, skipping auto-assignment"
exit 0
fi

in_auto_assign=false
all_reviewers=""

# Helper: normalize a reviewer (strip @ and whitespace)
normalize_reviewer() {
echo "$1" | sed -E 's/^[[:space:]]*@?//; s/[[:space:]]*$//'
}

# Parse OWNERS
while IFS= read -r line; do
# Skip comments/empty
[[ -z "${line// }" || "$line" =~ ^[[:space:]]*# ]] && continue

# Enter auto-assign section
if [[ "$line" =~ ^auto-assign: ]]; then
in_auto_assign=true
continue
fi

# Exit auto-assign section when a new top-level key is encountered
if $in_auto_assign && [[ "$line" =~ ^[^[:space:]] ]]; then
in_auto_assign=false
fi
$in_auto_assign || continue

# Reviewer entry: collect the user directly
if [[ "$line" =~ ^[[:space:]]*-[[:space:]]*([^:]+)$ ]]; then
reviewer=$(normalize_reviewer "$(echo "$line" | sed -E 's/^[[:space:]]*-[[:space:]]*//')")
echo "Found reviewer: $reviewer"
all_reviewers+="$reviewer"$'\n'
fi
done < OWNERS

# De-dup, drop blanks, exclude PR author
mapfile -t reviewers < <(printf "%s" "$all_reviewers" | sed '/^$/d' | sort -u | grep -v -x "$PR_AUTHOR" || true)

if [ "${#reviewers[@]}" -eq 0 ]; then
echo "No reviewers found for auto-assignment"
exit 0
fi

echo "Assigning reviewers: ${reviewers[*]}"

# JSON array
payload=$(printf '%s\n' "${reviewers[@]}" | jq -R -s -c 'split("\n") | map(select(length>0))')

# Request reviewers
curl -sS -X POST \
-H "Authorization: token $GITHUB_TOKEN" \
-H "Accept: application/vnd.github.v3+json" \
"https://api.github.com/repos/$REPO/pulls/$PR_NUMBER/requested_reviewers" \
-d "{\"reviewers\": $payload}" \
| jq -r '.message? // "ok"'
12 changes: 12 additions & 0 deletions OWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,15 @@ reviewers:
- nirrozenbaum
- shmuelk
- vMaroon

# Auto-assign configuration for global assignment
# Works in addition to GitHub's built-in CODEOWNERS functionality
# Implemented via a custom GitHub Action
auto-assign:
- elevran
- kfirtoledo
- kfswain
- nilig
- nirrozenbaum
- shmuelk
- vMaroon