From 3ef3b0229569a40f0a5aee67940b8337eaa402d9 Mon Sep 17 00:00:00 2001 From: Jeffrey Hung <17494876+Jeffreyhung@users.noreply.github.com> Date: Fri, 9 May 2025 15:56:25 -0700 Subject: [PATCH 1/5] create new workflow --- .github/workflows/codeowner_assignment.yaml | 84 +++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 .github/workflows/codeowner_assignment.yaml diff --git a/.github/workflows/codeowner_assignment.yaml b/.github/workflows/codeowner_assignment.yaml new file mode 100644 index 0000000000000..176835bd1be18 --- /dev/null +++ b/.github/workflows/codeowner_assignment.yaml @@ -0,0 +1,84 @@ +name: Codeowner assignment + +on: [pull_request] + +jobs: + codeowner_assignment: + name: Codeowner assignment + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + + steps: + - uses: actions/checkout@v4 + + - uses: actions/create-github-app-token@v2 + id: token + with: + app-id: ${{ vars.CODEOWNER_ASSIGNMENT_GITHUB_APP_ID }} + private-key: ${{ secrets.CODEOWNER_ASSIGNMENT_PRI_KEY }} + + - name: Parse CODEOWNERS and assign reviewers + id: assign-reviewers + env: + PR_NUMBER: ${{ github.event.number }} + GH_TOKEN: ${{ steps.token.outputs.token }} + run: | + # Ensure CODEOWNERS file exists + if [[ -f .github/CODEOWNERS ]]; then + codeowner_path=".github/CODEOWNERS" + elif [[ -f CODEOWNERS ]]; then + codeowner_path="CODEOWNERS" + else + echo "CODEOWNERS file not found, skipping." + exit 0 + fi + + # Get changed files in the PR + git fetch origin ${{ github.event.pull_request.base.ref }} \ + ${{ github.event.pull_request.head.ref }} + CHANGED_FILES=$(git diff --name-only origin/${{ github.event.pull_request.base.ref }} \ + origin/${{ github.event.pull_request.head.ref }}) + + echo "----------------------------------------" + echo "Changed files:" + echo "$CHANGED_FILES" | tr ' ' '\n' | sed 's/^/- /' + echo "----------------------------------------" + + # Parse CODEOWNERS and find commented lines + # Add newline to the end of the file if it doesn't have one + sed -i -e '$a\' $codeowner_path + + while read -r LINE; do + # Skip lines that are not commented + if [[ ! "$LINE" =~ ^# ]]; then continue; fi + + # Extract pattern and reviewer from the commented line + PATTERN=$(echo "$LINE" | sed -E 's/^#\s*([^@]+).*$/\1/' | xargs) + # Capture both individual users and team reviewers + REVIEWERS=$(echo "$LINE" | grep -o "@[a-zA-Z0-9_-]\+\(/[a-zA-Z0-9_-]\+\)\?" | tr '\n' ' ' | xargs) + + # Skip if no reviewers found + if [[ -z "$REVIEWERS" ]]; then + continue + fi + + # Convert pattern to a regex for matching + REGEX_PATTERN=$(echo "$PATTERN" | sed -e 's/\./\\./g' -e 's/\*/.*/g' -e 's/\?/./g' -e 's|^/||') + + # Match changed files to the pattern + for FILE in $CHANGED_FILES; do + # Check if the file starts with the pattern (removing leading slash) + if [[ "$FILE" == ${REGEX_PATTERN}* ]]; then + echo "File $FILE matches pattern $PATTERN" + # Assign each reviewer + for REVIEWER in $REVIEWERS; do + # Remove @ symbol from reviewer name + REVIEWER_NAME=${REVIEWER#@} + echo "Assigning $REVIEWER_NAME to review changes in $FILE" + gh pr edit $PR_NUMBER --add-reviewer "$REVIEWER_NAME" + done + fi + done + done < $codeowner_path From 7203589a7319e1774e11c99cb008205762109322 Mon Sep 17 00:00:00 2001 From: Jeffrey Hung <17494876+Jeffreyhung@users.noreply.github.com> Date: Fri, 9 May 2025 16:05:56 -0700 Subject: [PATCH 2/5] update action and limit token scope --- .github/workflows/codeowner_assignment.yaml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/codeowner_assignment.yaml b/.github/workflows/codeowner_assignment.yaml index 176835bd1be18..892cd1097f33e 100644 --- a/.github/workflows/codeowner_assignment.yaml +++ b/.github/workflows/codeowner_assignment.yaml @@ -13,11 +13,14 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: actions/create-github-app-token@v2 + - uses: actions/create-github-app-token@v2.0.6 id: token with: app-id: ${{ vars.CODEOWNER_ASSIGNMENT_GITHUB_APP_ID }} private-key: ${{ secrets.CODEOWNER_ASSIGNMENT_PRI_KEY }} + owner: ${{ github.repository_owner }} + repositories: | + sentry-docs - name: Parse CODEOWNERS and assign reviewers id: assign-reviewers From b2469284d72fcd03a0c73f0731a7e11c7a9b0e70 Mon Sep 17 00:00:00 2001 From: Jeffrey Hung <17494876+Jeffreyhung@users.noreply.github.com> Date: Fri, 9 May 2025 16:08:10 -0700 Subject: [PATCH 3/5] Test the workflow --- .github/CODEOWNERS | 2 +- vercel.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 8a8336b5fc2a3..55482926fa877 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,7 +1,7 @@ # https://docs.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners#codeowners-syntax # Requiring review from security team for Content-Security-Policy changes -**/vercel.json @getsentry/security +# **/vercel.json @getsentry/security # Codeowners listed below are used as a reference for the Sentry team to know who to contact for a given area of the codebase. diff --git a/vercel.json b/vercel.json index 877b7b53d8ae1..fa039f3e27cac 100644 --- a/vercel.json +++ b/vercel.json @@ -31,4 +31,4 @@ } ], "trailingSlash": true -} \ No newline at end of file +} From 47db1ef1bad7b74a8d547c764878a636ad80c11c Mon Sep 17 00:00:00 2001 From: Jeffrey Hung <17494876+Jeffreyhung@users.noreply.github.com> Date: Fri, 9 May 2025 16:10:27 -0700 Subject: [PATCH 4/5] Revert "Test the workflow" This reverts commit b2469284d72fcd03a0c73f0731a7e11c7a9b0e70. --- .github/CODEOWNERS | 2 +- vercel.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 55482926fa877..8a8336b5fc2a3 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,7 +1,7 @@ # https://docs.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners#codeowners-syntax # Requiring review from security team for Content-Security-Policy changes -# **/vercel.json @getsentry/security +**/vercel.json @getsentry/security # Codeowners listed below are used as a reference for the Sentry team to know who to contact for a given area of the codebase. diff --git a/vercel.json b/vercel.json index fa039f3e27cac..877b7b53d8ae1 100644 --- a/vercel.json +++ b/vercel.json @@ -31,4 +31,4 @@ } ], "trailingSlash": true -} +} \ No newline at end of file From 4c97ce3fd58d3739b98e8ecf772f4898c0bcc68e Mon Sep 17 00:00:00 2001 From: Jeffrey Hung <17494876+Jeffreyhung@users.noreply.github.com> Date: Fri, 9 May 2025 16:23:06 -0700 Subject: [PATCH 5/5] handle global wildcards like **/ --- .github/workflows/codeowner_assignment.yaml | 62 ++++++++++++++++----- 1 file changed, 48 insertions(+), 14 deletions(-) diff --git a/.github/workflows/codeowner_assignment.yaml b/.github/workflows/codeowner_assignment.yaml index 892cd1097f33e..6afe3b719b4c3 100644 --- a/.github/workflows/codeowner_assignment.yaml +++ b/.github/workflows/codeowner_assignment.yaml @@ -28,7 +28,7 @@ jobs: PR_NUMBER: ${{ github.event.number }} GH_TOKEN: ${{ steps.token.outputs.token }} run: | - # Ensure CODEOWNERS file exists + # locate CODEOWNERS file exists if [[ -f .github/CODEOWNERS ]]; then codeowner_path=".github/CODEOWNERS" elif [[ -f CODEOWNERS ]]; then @@ -50,16 +50,16 @@ jobs: echo "----------------------------------------" # Parse CODEOWNERS and find commented lines - # Add newline to the end of the file if it doesn't have one + # Add newline to the end of the file if it doesn't have one, otherwise sed will not read the last line sed -i -e '$a\' $codeowner_path while read -r LINE; do - # Skip lines that are not commented + # Skip lines that are not commented, GitHub will take care of un-commented lines if [[ ! "$LINE" =~ ^# ]]; then continue; fi # Extract pattern and reviewer from the commented line PATTERN=$(echo "$LINE" | sed -E 's/^#\s*([^@]+).*$/\1/' | xargs) - # Capture both individual users and team reviewers + # Capture both individual users and GitHub teams reviewers that have "/" in the name REVIEWERS=$(echo "$LINE" | grep -o "@[a-zA-Z0-9_-]\+\(/[a-zA-Z0-9_-]\+\)\?" | tr '\n' ' ' | xargs) # Skip if no reviewers found @@ -72,16 +72,50 @@ jobs: # Match changed files to the pattern for FILE in $CHANGED_FILES; do - # Check if the file starts with the pattern (removing leading slash) - if [[ "$FILE" == ${REGEX_PATTERN}* ]]; then - echo "File $FILE matches pattern $PATTERN" - # Assign each reviewer - for REVIEWER in $REVIEWERS; do - # Remove @ symbol from reviewer name - REVIEWER_NAME=${REVIEWER#@} - echo "Assigning $REVIEWER_NAME to review changes in $FILE" - gh pr edit $PR_NUMBER --add-reviewer "$REVIEWER_NAME" - done + # For glob patterns(e.g. "**/"), use a different matching approach + if [[ "$PATTERN" == *"*"* ]]; then + # Special handling for **/ pattern + if [[ "$PATTERN" == "**/"* ]]; then + # Get the filename part after **/ + FILENAME=${PATTERN#**/} + # Match either the filename directly or with any path prefix + if [[ "$FILE" == "$FILENAME" ]] || [[ "$FILE" == */"$FILENAME" ]]; then + echo "File $FILE matches glob pattern $PATTERN" + # Assign each reviewer + for REVIEWER in $REVIEWERS; do + # Remove @ symbol from reviewer name + REVIEWER_NAME=${REVIEWER#@} + echo " - Assigning $REVIEWER_NAME to review changes in $FILE" + gh pr edit $PR_NUMBER --add-reviewer "$REVIEWER_NAME" + done + fi + else + # Convert other glob patterns to regex for matching + GLOB_PATTERN=$(echo "$PATTERN" | sed -e 's/\./\\./g' -e 's/\*/.*/g' -e 's/\?/./g') + if [[ "$FILE" =~ $GLOB_PATTERN ]]; then + echo "File $FILE matches glob pattern $PATTERN" + # Assign each reviewer + for REVIEWER in $REVIEWERS; do + # Remove @ symbol from reviewer name + REVIEWER_NAME=${REVIEWER#@} + echo " - Assigning $REVIEWER_NAME to review changes in $FILE" + gh pr edit $PR_NUMBER --add-reviewer "$REVIEWER_NAME" + done + fi + fi + else + # Original directory matching logic + if [[ "$FILE" == ${REGEX_PATTERN}* ]]; then + echo "File $FILE matches pattern $PATTERN" + # Assign each reviewer + for REVIEWER in $REVIEWERS; do + # Remove @ symbol from reviewer name + REVIEWER_NAME=${REVIEWER#@} + echo " - Assigning $REVIEWER_NAME to review changes in $FILE" + gh pr edit $PR_NUMBER --add-reviewer "$REVIEWER_NAME" + done + fi fi done done < $codeowner_path +