dolibarr/.github/scripts/get_changed_php.sh
Frédéric FRANCE e746e56126
FIX: Exclude deleted files from the PHPStan/Phan changed-files CI script
get_changed_php.sh listed every file the GitHub PR-files API reports,
including ones with status "removed" — deleted files no longer exist
on disk, so passing them to phpstan/phan made the CI job fail trying
to analyse a missing path. Any PR deleting PHP files hits this, not
specific to one branch; exposed here since this PR removes 79 files.
2026-08-12 07:10:32 +02:00

132 lines
4.9 KiB
Bash
Executable file

#!/bin/bash
# Copyright (C) 2025-2026 MDW <mdeweerd@users.noreply.github.com>
# shellcheck disable=2129,2128,2034,2016
set -euo pipefail
# This script retrieves the list of changed PHP files for a pull request
# using the GitHub API and sets two outputs:
# - any_changed: "true" if at least one PHP file changed, "false" otherwise
# - all_changed_files: space-separated list of changed PHP file paths
#
# Required environment variables:
# GITHUB_TOKEN - GitHub token with repo access
# GITHUB_REPOSITORY - "owner/repo"
# GITHUB_EVENT_PATH - Path to the event JSON payload
# Verify required environment variables are set
if [[ -z "${GITHUB_TOKEN:-}" ]]; then
echo "GITHUB_TOKEN is not set" >&2
exit 1
fi
if [[ -z "${GITHUB_REPOSITORY:-}" ]]; then
echo "GITHUB_REPOSITORY is not set" >&2
exit 2
fi
if [[ -z "${GITHUB_EVENT_PATH:-}" ]]; then
echo "GITHUB_EVENT_PATH is not set" >&2
exit 3
fi
# Extract the pull request number from the event payload
pr_number=$(jq --raw-output '.pull_request.number' "$GITHUB_EVENT_PATH")
if [[ "$pr_number" == "null" ]]; then
echo "Not a pull request event"
exit 0
fi
# Split repository into owner and repo name using Bash parameter expansion
owner="${GITHUB_REPOSITORY%%/*}" # Extract text before the first '/'
repo="${GITHUB_REPOSITORY##*/}" # Extract text after the last '/'
page=1
per_page=100
changed_php_files=()
changed_phan_files=()
changed_lang_files=()
# Get phan path configuration
phan_directory_list=$(php -r '$config = require("dev/tools/phan/config.php"); echo "^".implode("|",$config["directory_list"]);')
phan_exclude_directory=$(php -r '$config = require("dev/tools/phan/config.php"); echo "^".implode("|",$config["exclude_analysis_directory_list"]);')
phan_exclude_file_regex=$(php -r '$config = require("dev/tools/phan/config.php"); echo $config["exclude_file_regex"];')
phan_exclude_file_regex=${phan_exclude_file_regex#@}
phan_exclude_file_regex=${phan_exclude_file_regex%@}
# Loop through all pages to gather changed files
while true; do
response=$(curl -s -H "Authorization: token ${GITHUB_TOKEN}" \
"https://api.github.com/repos/${owner}/${repo}/pulls/${pr_number}/files?per_page=${per_page}&page=${page}")
# Filter for files ending with .php and add them to the list
# Deleted files (status "removed") are excluded: they no longer exist on disk, so
# passing them to phpstan/phan would just fail trying to analyse a missing path.
mapfile -t files < <(echo "$response" | jq -r '.[] | select((.filename | test("\\.php$")) and (.filename | test("^dev/") | not) and (.status != "removed")) | .filename')
changed_php_files+=("${files[@]}")
mapfile -t files < <(echo "$response" | jq -r '.[] | select((.filename | test("\\.php$")) and (.filename | test("'"$phan_directory_list"'")) and (.status != "removed")) | .filename' | grep -vP "$phan_exclude_file_regex")
changed_phan_files+=("${files[@]}")
mapfile -t files < <(echo "$response" | jq -r '.[] | select((.filename | test("\\.lang$")) and (.status != "removed")) | .filename')
changed_lang_files+=("${files[@]}")
# Check if we have reached the last page (less than per_page results)
count=$(echo "$response" | jq 'length')
if (( count < per_page )); then
break
fi
((page++))
done
# Build a space-separated string of changed PHP and lang files
# This does not cope with files that have spaces.
# But such files do not exist in the project (at least not for the
# files we are filtering).
all_changed_files=$(IFS=" " ; echo "${changed_php_files[*]}")
all_changed_lang=$(IFS=" " ; echo "${changed_lang_files[*]}")
phan_changed_files=$(IFS=" " ; echo "${changed_phan_files[*]}")
forbidden_files=""
#forbidden_files=$(echo "$all_changed_lang" | grep -E 'htdocs/langs/([^/]+)/.*\.lang$' | grep -v 'htdocs/langs/en_US/')
#if [ -n "$forbidden_files" ]; then
# echo "You tried to modify one or more language files that are not allowed to be modified in Pull requests."
# echo "$forbidden_files"
# echo "To modify translations that are not the source language (en_US), you must modify them from transifex.com"
# exit 10
#fi
# Determine changed files flags
if [ -z "${all_changed_files}" ]; then
any_changed="false"
else
any_changed="true"
fi
if [ -z "${phan_changed_files}" ]; then
phan_changed="false"
else
phan_changed="true"
fi
# Set outputs for GitHub Actions if GITHUB_OUTPUT is available
if [ -n "${GITHUB_OUTPUT:-}" ]; then
echo "any_changed=${any_changed}" >> "$GITHUB_OUTPUT"
echo "phan_changed=${phan_changed}" >> "$GITHUB_OUTPUT"
echo "all_changed_files=${all_changed_files}" >> "$GITHUB_OUTPUT"
echo "phan_changed_files=${phan_changed_files[*]}" >> "$GITHUB_OUTPUT"
echo "forbidden_files=${forbidden_files}" >> "$GITHUB_OUTPUT"
else
# Otherwise, print the outputs
echo "any_changed=${any_changed}"
echo "phan_changed=${phan_changed}"
echo "phan_changed_files=${phan_changed_files[*]}"
echo "all_changed_files=${all_changed_files}"
echo "forbidden_files=${forbidden_files}"
fi