Skip to content

Commit afe2986

Browse files
authored
ci: Add Github action to add "has:owner-approval" label for approved PRs (#2798)
1 parent ef0ca68 commit afe2986

File tree

4 files changed

+185
-0
lines changed

4 files changed

+185
-0
lines changed

.github/workflows/pr-review.yml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
name: PR review
2+
# 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.
3+
on:
4+
pull_request_review:
5+
types:
6+
- submitted
7+
8+
permissions:
9+
contents: read
10+
11+
jobs:
12+
add-owner-approved-label:
13+
if: github.event.review.state == 'approved'
14+
runs-on: ubuntu-latest
15+
permissions:
16+
contents: read
17+
pull-requests: write
18+
steps:
19+
- name: Checkout
20+
uses: actions/checkout@v4
21+
22+
- name: Run add-labels-to-reviewed-pr.sh
23+
run: |
24+
chmod +x ./.github/workflows/scripts/add-labels-to-reviewed-pr.sh
25+
./.github/workflows/scripts/add-labels-to-reviewed-pr.sh
26+
env:
27+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
28+
REPO: ${{ github.repository }}
29+
PR: ${{ github.event.pull_request.number }}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
#!/usr/bin/env bash
2+
#
3+
# Copyright The OpenTelemetry Authors
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# https://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
#
17+
# Adds a "has:owner-approval" label to a PR if a reviewer who approved it is a component owner.
18+
19+
set -euo pipefail
20+
21+
if [[ -z "${REPO:-}" || -z "${PR:-}" ]]; then
22+
echo "One or more of REPO and PR have not been set. Please ensure each is set."
23+
exit 0
24+
fi
25+
26+
main () {
27+
CUR_DIRECTORY=$(dirname "$0")
28+
29+
# The latestReviews key returns the latest review for each reviewer cutting out any other reviews.
30+
JSON=$(gh pr view "${PR}" --json "files,author,latestReviews" | tr -dc '[:print:]' | sed -E 's/\\[a-z]//g')
31+
FILES=$(echo -n "${JSON}"| jq -r '.files[].path')
32+
LATEST_REVIEWS=$(echo -n "${JSON}" | jq -c '.latestReviews')
33+
34+
# Fetch components
35+
COMPONENTS=$(bash "${CUR_DIRECTORY}/get-components.sh" | tac) # Reversed so we visit subdirectories first
36+
37+
declare -A PROCESSED_COMPONENTS
38+
39+
for COMPONENT in ${COMPONENTS}; do
40+
COMPONENT_OWNERS=$(COMPONENT="${COMPONENT}" bash "${CUR_DIRECTORY}/get-codeowners.sh")
41+
42+
for FILE in ${FILES}; do
43+
MATCH=$(echo -n "${FILE}" | grep -E "^${COMPONENT}" || true)
44+
45+
if [[ -z "${MATCH}" ]]; then
46+
continue
47+
fi
48+
49+
# If we match a file with a component, skip further processing for this file
50+
if [[ -v PROCESSED_COMPONENTS["${COMPONENT}"] ]]; then
51+
continue
52+
fi
53+
PROCESSED_COMPONENTS["${COMPONENT}"]=true
54+
55+
# Check if updated file is owned by one of the reviewers"
56+
echo "${LATEST_REVIEWS}" | jq -c '.[]' | while IFS= read -r REVIEW; do
57+
REVIEW_AUTHOR=$(echo -n "${REVIEW}"| jq -r '.author.login')
58+
REVIEW_STATE=$(echo -n "${REVIEW}"| jq -r '.state')
59+
if [[ "${REVIEW_STATE}" == "APPROVED" ]]; then
60+
# Review is approved. Checking if reviewer is a component owner
61+
for OWNER in ${COMPONENT_OWNERS}; do
62+
if [[ "${REVIEW_AUTHOR}" == "${OWNER}" ]]; then
63+
echo "Reviewer $REVIEW_AUTHOR is a component owner. Adding 'has:owner-approval' label."
64+
gh pr edit "${PR}" --repo "${REPO}" --add-label "has:owner-approval"
65+
exit 0
66+
fi
67+
done
68+
fi
69+
done
70+
done
71+
done
72+
}
73+
74+
# Ensure the script does not block a PR even if it fails
75+
main || echo "Failed to run $0"
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#!/usr/bin/env bash
2+
#
3+
# Copyright The OpenTelemetry Authors
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# https://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
#
17+
# Gets the owners for a given component from the component_owners.yml file.
18+
19+
# Define the file path
20+
YML_FILE=".github/component_owners.yml"
21+
22+
if [[ -z "${COMPONENT:-}" ]]; then
23+
echo "COMPONENT has not been set, please ensure it is set."
24+
exit 1
25+
fi
26+
27+
FOUND=0
28+
29+
# Parse the YAML file and extract owners for the given component
30+
while IFS= read -r line; do
31+
# Check if the line matches the given component
32+
if [[ "$line" =~ ^[[:space:]]*${COMPONENT}:[[:space:]]*$ ]]; then
33+
FOUND=1
34+
continue
35+
fi
36+
37+
# If the component is found, extract owners
38+
if [[ $FOUND -eq 1 ]]; then
39+
# Stop if we encounter another component or an empty line
40+
if [[ "$line" =~ ^[[:space:]]*[^#]+: || -z "$line" ]]; then
41+
break
42+
fi
43+
44+
# Extract the owner (remove leading spaces and '- ')
45+
if [[ "$line" =~ ^[[:space:]]*-[[:space:]]*[^#]+ ]]; then
46+
OWNER=$(echo "$line" | sed -E 's/^[[:space:]]*-[[:space:]]*([^#]+).*/\1/')
47+
echo "$OWNER"
48+
fi
49+
fi
50+
done < "$YML_FILE"
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#!/usr/bin/env bash
2+
#
3+
# Copyright The OpenTelemetry Authors
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# https://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
#
17+
# Gets the components from the component_owners.yml file.
18+
19+
20+
# Define the file path
21+
YML_FILE=".github/component_owners.yml"
22+
23+
# Parse the YAML file and extract components and their owners
24+
while IFS= read -r line; do
25+
# Check if the line contains a component (ends with ':')
26+
if [[ "$line" =~ ^[[:space:]]*[^#]+: ]]; then
27+
# Extract the component name (remove leading spaces and trailing ':')
28+
COMPONENT=$(echo "$line" | sed -E 's/^[[:space:]]*([^:]+):.*/\1/')
29+
echo "$COMPONENT"
30+
fi
31+
done < "$YML_FILE"

0 commit comments

Comments
 (0)