get_changed_php.sh 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. #!/bin/bash
  2. # Copyright (C) 2025 MDW <mdeweerd@users.noreply.github.com>
  3. set -euo pipefail
  4. # This script retrieves the list of changed PHP files for a pull request
  5. # using the GitHub API and sets two outputs:
  6. # - any_changed: "true" if at least one PHP file changed, "false" otherwise
  7. # - all_changed_files: space-separated list of changed PHP file paths
  8. #
  9. # Required environment variables:
  10. # GITHUB_TOKEN - GitHub token with repo access
  11. # GITHUB_REPOSITORY - "owner/repo"
  12. # GITHUB_EVENT_PATH - Path to the event JSON payload
  13. # Verify required environment variables are set
  14. if [[ -z "${GITHUB_TOKEN:-}" ]]; then
  15. echo "GITHUB_TOKEN is not set" >&2
  16. exit 1
  17. fi
  18. if [[ -z "${GITHUB_REPOSITORY:-}" ]]; then
  19. echo "GITHUB_REPOSITORY is not set" >&2
  20. exit 1
  21. fi
  22. if [[ -z "${GITHUB_EVENT_PATH:-}" ]]; then
  23. echo "GITHUB_EVENT_PATH is not set" >&2
  24. exit 1
  25. fi
  26. # Extract the pull request number from the event payload
  27. pr_number=$(jq --raw-output '.pull_request.number' "$GITHUB_EVENT_PATH")
  28. if [[ "$pr_number" == "null" ]]; then
  29. echo "Not a pull request event"
  30. exit 0
  31. fi
  32. # Split repository into owner and repo name
  33. # Split repository into owner and repo name using Bash parameter expansion
  34. owner="${GITHUB_REPOSITORY%%/*}" # Extract text before the first '/'
  35. repo="${GITHUB_REPOSITORY##*/}" # Extract text after the last '/'
  36. page=1
  37. per_page=100
  38. changed_php_files=()
  39. # Loop through all pages to gather changed files
  40. while true; do
  41. response=$(curl -s -H "Authorization: token ${GITHUB_TOKEN}" \
  42. "https://api.github.com/repos/${owner}/${repo}/pulls/${pr_number}/files?per_page=${per_page}&page=${page}")
  43. # Filter for files ending with .php and add them to the list
  44. mapfile -t files < <(echo "$response" | jq -r '.[] | select(.filename | test("\\.php$")) | .filename')
  45. changed_php_files+=("${files[@]}")
  46. # Check if we have reached the last page (less than per_page results)
  47. count=$(echo "$response" | jq 'length')
  48. if (( count < per_page )); then
  49. break
  50. fi
  51. ((page++))
  52. done
  53. # Build a space-separated string of changed PHP files
  54. # This does not cope with files that have spaces.
  55. # But such files do not exist in the project (at least not for the
  56. # files we are filtering).
  57. all_changed_files=$(IFS=" " ; echo "${changed_php_files[*]}")
  58. # Determine changed files flag
  59. if [ -z "$all_changed_files" ]; then
  60. any_changed="false"
  61. else
  62. any_changed="true"
  63. fi
  64. # Set outputs for GitHub Actions if GITHUB_OUTPUT is available
  65. if [ -n "${GITHUB_OUTPUT:-}" ]; then
  66. echo "any_changed=${any_changed}" >> "$GITHUB_OUTPUT"
  67. echo "all_changed_files=${all_changed_files}" >> "$GITHUB_OUTPUT"
  68. else
  69. # Otherwise, print the outputs
  70. echo "any_changed=${any_changed}"
  71. echo "all_changed_files=${all_changed_files}"
  72. fi