Fix PECL extension minimum stability resolution

This commit is contained in:
Shivam Mathur
2026-11-02 03:40:24 +05:30
parent 73aede52cb
commit 0b3aa3e956
6 changed files with 39 additions and 19 deletions
+2
View File
@@ -174,6 +174,8 @@ PHP extensions can be set up using the `extensions` input. It accepts a `string`
- Extensions with pre-release versions available on `PECL` can be set up by suffixing the extension's name with its state i.e `alpha`, `beta`, `devel` or `snapshot`.
This sets the minimum stability. The newest release with that stability or a more stable state is selected.
```yaml
- name: Setup PHP with pre-release PECL extension
uses: shivammathur/setup-php@v2
+1
View File
@@ -7,6 +7,7 @@ describe('Extension tests', () => {
${'none'} | ${'7.4'} | ${'Disable-AllShared'}
${':intl'} | ${'7.4'} | ${'Disable-Extension intl'}
${'ast-beta'} | ${'7.4'} | ${'Add-Extension ast beta'}
${'ast-stable'} | ${'7.4'} | ${'Add-Extension ast stable'}
${'blackfire'} | ${'7.3'} | ${'Add-Blackfire blackfire'}
${'blackfire-1.31.0'} | ${'7.3'} | ${'Add-Blackfire blackfire-1.31.0'}
${'grpc-1.2.3'} | ${'7.4'} | ${'Add-Extension grpc stable 1.2.3'}
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -180,7 +180,7 @@ export async function addExtensionWindows(
add_script += await utils.joins(
'\nAdd-Extension',
ext_name,
ext_version.replace('stable', '')
ext_version
);
break;
// match extensions for compiling from source
+5 -3
View File
@@ -104,6 +104,7 @@ Function Add-Extension {
[string]
$extension_version = ''
)
$minimum_stability_requested = $PSBoundParameters.ContainsKey('stability') -and $extension_version -eq ''
$extension_backup = ''
$restore_startup_errors = $false
try {
@@ -115,7 +116,7 @@ Function Add-Extension {
$extension_info = Get-PhpExtension -Path $php_dir | Where-Object { $_.Name -eq $extension -or $_.Handle -eq $extension }
}
# Only suppress startup errors while probing a cached DLL or replacing an installed DLL.
if($cached -or ($extension_version -ne '' -and $extension_info.Version -ne $extension_version -and (Test-Path "$ext_dir\php_$extension.dll"))) {
if($cached -or (($minimum_stability_requested -or ($extension_version -ne '' -and $extension_info.Version -ne $extension_version)) -and (Test-Path "$ext_dir\php_$extension.dll"))) {
$startup_errors = Get-PhpIniKey -Key display_startup_errors -Path "$php_dir\php.ini"
if($startup_errors -notmatch '^(0|off|false|no)$') {
$restore_startup_errors = $true
@@ -147,7 +148,7 @@ Function Add-Extension {
Remove-Item "$ext_dir\php_$extension.dll" -Force
$extension_info = $null
}
if ($null -ne $extension_info -and ($extension_version -eq '' -or $extension_info.Version -eq $extension_version)) {
if ($null -ne $extension_info -and ($extension_info.State -eq 'Builtin' -or (-not $minimum_stability_requested -and ($extension_version -eq '' -or $extension_info.Version -eq $extension_version)))) {
switch ($extension_info.State) {
'Builtin' {
Add-Log $tick $extension "Enabled"
@@ -169,8 +170,9 @@ Function Add-Extension {
if ($version -match '8.[1-4]' -and $stability -eq 'stable') {
$minimumStability = 'snapshot'
}
$maximumStability = if ($extension_version -eq '') { 'stable' } else { $stability }
$params = @{ Extension = $extension; MinimumStability = $minimumStability; MaximumStability = $stability; Path = $php_dir; AdditionalFilesPath = $deps_dir; NoDependencies = $true }
$params = @{ Extension = $extension; MinimumStability = $minimumStability; MaximumStability = $maximumStability; Path = $php_dir; AdditionalFilesPath = $deps_dir; NoDependencies = $true }
if ($extension_version -ne '')
{
$params["Version"] = $extension_version
+29 -14
View File
@@ -165,19 +165,27 @@ add_extension() {
# Function to get the PECL version of an extension.
get_pecl_version() {
local extension=$1
states=("stable" "rc" "preview" "beta" "alpha" "snapshot")
stability="$(echo "$2" | grep -m 1 -Eio "($(IFS='|' ; echo "${states[*]}"))")"
IFS=' ' read -r -a states <<< "$(echo "${states[@]}" | grep -Eo "$stability.*")"
local requested=${2:-stable}
local states=("stable" "rc" "preview" "beta" "alpha" "devel" "snapshot")
local stability major_version response pecl_version pattern
response=$(get -s -n "" "https://pecl.php.net/rest/r/$extension/allreleases.xml")
if [[ "$requested" =~ ^[0-9] ]]; then
# Preserve exact pins and PECL's case-sensitive archive directory names.
pecl_version=$(echo "$response" | grep -Fio "<v>$requested</v>" | head -n 1 | cut -d '>' -f 2 | cut -d '<' -f 1)
echo "${pecl_version:-$requested}"
return
fi
requested="$(echo "$requested" | tr '[:upper:]' '[:lower:]')"
[[ " ${states[*]} " = *" $requested "* ]] || return 0
IFS=' ' read -r -a states <<< "$(echo "${states[@]}" | grep -Eo ".*$requested")"
stability="$(IFS='|' ; echo "${states[*]}")"
major_version=${3:-'[0-9]+'}
pecl_rest='https://pecl.php.net/rest/r/'
response=$(get -s -n "" "$pecl_rest$extension"/allreleases.xml)
for state in "${states[@]}"; do
pecl_version=$(echo "$response" | grep -m 1 -Eio "v>($major_version\.[0-9]+(\.[0-9]+)?${state}[0-9]+<)" | cut -d '>' -f 2 | cut -d '<' -f 1)
[ -z "$pecl_version" ] && pecl_version=$(echo "$response" | grep -m 1 -Eio "v>(.*)<\/v>.*$state<" | grep -m 1 -Eo "v>($major_version\.[0-9]+(\.[0-9]+)?.*)<" | cut -d '>' -f 2 | cut -d '<' -f 1)
[ -n "$pecl_version" ] && break;
done
[ -z "$pecl_version" ] && pecl_version=$(echo "$response" | grep -m 1 -Eo "v>($major_version\.[0-9]+(\.[0-9]+)?)<" | cut -d '>' -f 2 | cut -d '<' -f 1)
echo "$pecl_version"
pattern="v>($major_version\.[0-9]+(\.[0-9]+)?)[^<]*</v>[[:space:]]*<s>($stability)<"
if [[ "$requested" = rc || "$requested" = preview ]]; then
pattern="$pattern|v>($major_version\.[0-9]+(\.[0-9]+)?)($stability)[0-9]*<"
fi
# PECL orders releases by version, so select the first acceptable state.
echo "$response" | grep -Eio "$pattern" | head -n 1 | cut -d '>' -f 2 | cut -d '<' -f 1
}
# Function to install PECL extensions and accept default options
@@ -190,7 +198,10 @@ pecl_install() {
# Install using the source interface as it allows for patching.
if [[ $(printf "%s\n%s" "${version:?}" "8.3" | sort -V | head -n1) != "$version" ]]; then
extension_version=${extension##*-};
[ "$extension_version" = "${extension%-*}" ] && extension_version=$(get_pecl_version "$extension" "stable")
if [ "$extension_version" = "${extension%-*}" ]; then
extension_version=$(get_pecl_version "$extension" "stable")
[ -n "$extension_version" ] || return 1
fi
add_extension_from_source "${extension%-*}" https://pecl.php.net "${extension%-*}" "${extension%-*}" "$extension_version" "$prefix" pecl
check_extension "${extension%-*}" && return 0 || return 1;
else
@@ -217,7 +228,7 @@ add_pecl_extension() {
local extension=$1
local pecl_version=$2
local prefix=$3
if [[ $pecl_version =~ .*(alpha|beta|rc|snapshot|preview).* ]]; then
if [[ $pecl_version =~ (alpha|beta|rc|snapshot|preview|devel) ]]; then
pecl_version=$(get_pecl_version "$extension" "$pecl_version")
fi
# Cache versioned extensions using suffixless copies in extension_dir.
@@ -258,6 +269,10 @@ add_unstable_extension() {
local stability=$2
local prefix=$3
pecl_version=$(get_pecl_version "$extension" "$stability")
if [ -z "$pecl_version" ]; then
add_log "${cross:?}" "$extension-$stability" "No release found with minimum stability $stability"
return
fi
add_pecl_extension "$extension" "$pecl_version" "$prefix"
}