|
| 1 | +name: Detect API Changes |
| 2 | + |
| 3 | +on: |
| 4 | + # pull_request_target is used instead of pull_request so that the workflow has write access |
| 5 | + # (to post comments and apply labels) even when triggered by fork PRs. |
| 6 | + # |
| 7 | + # SECURITY: this workflow must never checkout or execute any code from the PR branch. |
| 8 | + # Doing so would allow malicious PRs to exfiltrate secrets. All we use from the PR |
| 9 | + # is github.event.pull_request.number (an integer), which is safe. |
| 10 | + pull_request_target: |
| 11 | + types: [opened, synchronize, reopened, ready_for_review] |
| 12 | + |
| 13 | +permissions: {} |
| 14 | + |
| 15 | +jobs: |
| 16 | + detect-api-changes: |
| 17 | + name: Detect API surface area changes |
| 18 | + runs-on: ubuntu-latest |
| 19 | + steps: |
| 20 | + - uses: actions/create-github-app-token@f8d387b68d61c58ab83c6c016672934102569859 # v3.0.0 |
| 21 | + id: otelbot-token |
| 22 | + with: |
| 23 | + app-id: ${{ vars.OTELBOT_APP_ID }} |
| 24 | + private-key: ${{ secrets.OTELBOT_PRIVATE_KEY }} |
| 25 | + |
| 26 | + - name: Check for API changes and update PR |
| 27 | + env: |
| 28 | + GH_TOKEN: ${{ steps.otelbot-token.outputs.token }} |
| 29 | + PR_NUMBER: ${{ github.event.pull_request.number }} |
| 30 | + REPO: ${{ github.repository }} |
| 31 | + run: | |
| 32 | + MARKER="<!-- api-change-detector -->" |
| 33 | +
|
| 34 | + # Get list of apidiff files changed in this PR |
| 35 | + api_files=$(gh api "repos/${REPO}/pulls/${PR_NUMBER}/files" --paginate \ |
| 36 | + --jq '.[] | select(.filename | startswith("docs/apidiffs/current_vs_latest/")) | .filename') |
| 37 | +
|
| 38 | + # Find existing bot comment (if any) |
| 39 | + comment_id=$(gh api "repos/${REPO}/issues/${PR_NUMBER}/comments" --paginate \ |
| 40 | + --jq ".[] | select(.body | startswith(\"${MARKER}\")) | .id" | head -1) |
| 41 | +
|
| 42 | + if [[ -z "$api_files" ]]; then |
| 43 | + echo "No API diff files changed." |
| 44 | +
|
| 45 | + # Remove label if present (ok to fail if label doesn't exist on PR) |
| 46 | + gh pr edit "$PR_NUMBER" --repo "$REPO" --remove-label "api-change" 2>/dev/null || true |
| 47 | +
|
| 48 | + # Delete existing comment if present |
| 49 | + if [[ -n "$comment_id" ]]; then |
| 50 | + gh api --method DELETE "repos/${REPO}/issues/comments/${comment_id}" |
| 51 | + echo "Removed stale API change comment." |
| 52 | + fi |
| 53 | + exit 0 |
| 54 | + fi |
| 55 | +
|
| 56 | + echo "API diff files changed:" |
| 57 | + echo "$api_files" |
| 58 | +
|
| 59 | + # Add label |
| 60 | + gh pr edit "$PR_NUMBER" --repo "$REPO" --add-label "api-change" |
| 61 | +
|
| 62 | + # Build bulleted module list |
| 63 | + modules=$(echo "$api_files" \ |
| 64 | + | sed 's|docs/apidiffs/current_vs_latest/||' \ |
| 65 | + | sed 's|\.txt$||' \ |
| 66 | + | sort \ |
| 67 | + | sed 's/^/- /') |
| 68 | +
|
| 69 | + BODY=$(cat <<EOF |
| 70 | + ${MARKER} |
| 71 | + ## :warning: API changes detected — additional maintainer review required |
| 72 | +
|
| 73 | + @jack-berg @jkwatson |
| 74 | +
|
| 75 | + This PR modifies the public API surface area of the following module(s): |
| 76 | +
|
| 77 | + ${modules} |
| 78 | +
|
| 79 | + Please review the changes in \`docs/apidiffs/current_vs_latest/\` carefully before approving. |
| 80 | + EOF |
| 81 | + ) |
| 82 | +
|
| 83 | + if [[ -n "$comment_id" ]]; then |
| 84 | + echo "Updating existing comment ${comment_id}" |
| 85 | + gh api --method PATCH "repos/${REPO}/issues/comments/${comment_id}" \ |
| 86 | + --field body="$BODY" |
| 87 | + else |
| 88 | + echo "Creating new comment" |
| 89 | + gh pr comment "$PR_NUMBER" --repo "$REPO" --body "$BODY" |
| 90 | + fi |
0 commit comments