Skip to content
Open
29 changes: 29 additions & 0 deletions .github/workflows/pr-review.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: PR review
# This workflow is triggered when a PR review is submitted. It checks if the review is approved and runs a script to add labels to the PR based on the review.
on:
pull_request_review:
types:
- submitted

permissions:
contents: read

jobs:
add-owner-approved-label:
if: github.event.review.state == 'approved'
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Run add-labels-to-reviewed-pr.sh
run: |
chmod +x ./.github/workflows/scripts/add-labels-to-reviewed-pr.sh
./.github/workflows/scripts/add-labels-to-reviewed-pr.sh
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REPO: ${{ github.repository }}
PR: ${{ github.event.number }}
75 changes: 75 additions & 0 deletions .github/workflows/scripts/add-labels-to-reviewed-pr.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#!/usr/bin/env bash
#
# Copyright The OpenTelemetry Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Adds a "has:owner-approval" label to a PR if a reviewer who approved it is a component owner.

set -euo pipefail

if [[ -z "${REPO:-}" || -z "${PR:-}" ]]; then
echo "One or more of REPO and PR have not been set. Please ensure each is set."
exit 0
fi

main () {
CUR_DIRECTORY=$(dirname "$0")

# The latestReviews key returns the latest review for each reviewer cutting out any other reviews.
JSON=$(gh pr view "${PR}" --json "files,author,latestReviews" | tr -dc '[:print:]' | sed -E 's/\\[a-z]//g')
FILES=$(echo -n "${JSON}"| jq -r '.files[].path')
LATEST_REVIEWS=$(echo -n "${JSON}" | jq -c '.latestReviews')

# Fetch components
COMPONENTS=$(bash "${CUR_DIRECTORY}/get-components.sh" | tac) # Reversed so we visit subdirectories first

declare -A PROCESSED_COMPONENTS

for COMPONENT in ${COMPONENTS}; do
COMPONENT_OWNERS=$(COMPONENT="${COMPONENT}" bash "${CUR_DIRECTORY}/get-codeowners.sh")

for FILE in ${FILES}; do
MATCH=$(echo -n "${FILE}" | grep -E "^${COMPONENT}" || true)

if [[ -z "${MATCH}" ]]; then
continue
fi

# If we match a file with a component, skip further processing for this file
if [[ -v PROCESSED_COMPONENTS["${COMPONENT}"] ]]; then
continue
fi
PROCESSED_COMPONENTS["${COMPONENT}"]=true

# Check if updated file is owned by one of the reviewers"
echo "${LATEST_REVIEWS}" | jq -c '.[]' | while IFS= read -r REVIEW; do
REVIEW_AUTHOR=$(echo -n "${REVIEW}"| jq -r '.author.login')
REVIEW_STATE=$(echo -n "${REVIEW}"| jq -r '.state')
if [[ "${REVIEW_STATE}" == "APPROVED" ]]; then
# Review is approved. Checking if reviewer is a component owner
for OWNER in ${COMPONENT_OWNERS}; do
if [[ "${REVIEW_AUTHOR}" == "${OWNER}" ]]; then
echo "Reviewer $REVIEW_AUTHOR is a component owner. Adding 'has:owner-approval' label."
gh pr edit "${PR}" --repo "${REPO}" --add-label "has:owner-approval"
exit 0
fi
done
fi
done
done
done
}

# Ensure the script does not block a PR even if it fails
main || echo "Failed to run $0"
50 changes: 50 additions & 0 deletions .github/workflows/scripts/get-codeowners.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#!/usr/bin/env bash
#
# Copyright The OpenTelemetry Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Gets the owners for a given component from the component_owners.yml file.

# Define the file path
YML_FILE=".github/component_owners.yml"

if [[ -z "${COMPONENT:-}" ]]; then
echo "COMPONENT has not been set, please ensure it is set."
exit 1
fi

FOUND=0

# Parse the YAML file and extract owners for the given component
while IFS= read -r line; do
# Check if the line matches the given component
if [[ "$line" =~ ^[[:space:]]*${COMPONENT}:[[:space:]]*$ ]]; then
FOUND=1
continue
fi

# If the component is found, extract owners
if [[ $FOUND -eq 1 ]]; then
# Stop if we encounter another component or an empty line
if [[ "$line" =~ ^[[:space:]]*[^#]+: || -z "$line" ]]; then
break
fi

# Extract the owner (remove leading spaces and '- ')
if [[ "$line" =~ ^[[:space:]]*-[[:space:]]*[^#]+ ]]; then
OWNER=$(echo "$line" | sed -E 's/^[[:space:]]*-[[:space:]]*([^#]+).*/\1/')
echo "$OWNER"
fi
fi
done < "$YML_FILE"
31 changes: 31 additions & 0 deletions .github/workflows/scripts/get-components.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#!/usr/bin/env bash
#
# Copyright The OpenTelemetry Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Gets the components from the component_owners.yml file.


# Define the file path
YML_FILE=".github/component_owners.yml"

# Parse the YAML file and extract components and their owners
while IFS= read -r line; do
# Check if the line contains a component (ends with ':')
if [[ "$line" =~ ^[[:space:]]*[^#]+: ]]; then
# Extract the component name (remove leading spaces and trailing ':')
COMPONENT=$(echo "$line" | sed -E 's/^[[:space:]]*([^:]+):.*/\1/')
echo "$COMPONENT"
fi
done < "$YML_FILE"
Loading