setup-php 2.12.0 → 2.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +977 -936
  3. package/package.json +66 -56
  4. package/src/config.ts +82 -82
  5. package/src/configs/brew_extensions +30 -0
  6. package/src/configs/os_releases.csv +17 -0
  7. package/src/configs/php-versions.json +6 -5
  8. package/src/configs/{php.json → pm/php.json} +29 -29
  9. package/src/configs/{phpunit.json → pm/phpunit.json} +24 -24
  10. package/src/configs/tools.json +256 -234
  11. package/src/configs/tools_schema.json +114 -103
  12. package/src/coverage.ts +169 -142
  13. package/src/extensions.ts +363 -349
  14. package/src/install.ts +79 -82
  15. package/src/scripts/common.sh +366 -314
  16. package/src/scripts/darwin.sh +257 -248
  17. package/src/scripts/ext/blackfire.ps1 +32 -32
  18. package/src/scripts/ext/blackfire.sh +22 -21
  19. package/src/scripts/ext/couchbase.sh +43 -43
  20. package/src/scripts/ext/cubrid.sh +60 -60
  21. package/src/scripts/ext/extension_map.php +109 -0
  22. package/src/scripts/ext/firebird.ps1 +19 -19
  23. package/src/scripts/ext/firebird.sh +39 -35
  24. package/src/scripts/ext/gearman.sh +22 -22
  25. package/src/scripts/ext/geos.sh +17 -17
  26. package/src/scripts/ext/http.ps1 +54 -54
  27. package/src/scripts/ext/http.sh +120 -120
  28. package/src/scripts/ext/intl.sh +23 -23
  29. package/src/scripts/ext/ioncube.ps1 +33 -32
  30. package/src/scripts/ext/ioncube.sh +21 -19
  31. package/src/scripts/ext/oci.ps1 +60 -60
  32. package/src/scripts/ext/oci.sh +65 -63
  33. package/src/scripts/ext/patches/firebird.sh +11 -11
  34. package/src/scripts/ext/patches/geos.sh +7 -7
  35. package/src/scripts/ext/patches/http.sh +11 -11
  36. package/src/scripts/ext/patches/pdo_oci.sh +6 -6
  37. package/src/scripts/ext/patches/phpize.sh +26 -26
  38. package/src/scripts/ext/patches/protobuf.sh +4 -4
  39. package/src/scripts/ext/phalcon.ps1 +54 -55
  40. package/src/scripts/ext/phalcon.sh +59 -59
  41. package/src/scripts/ext/source.sh +144 -144
  42. package/src/scripts/linux.sh +239 -280
  43. package/src/scripts/tools/add_tools.ps1 +28 -25
  44. package/src/scripts/tools/add_tools.sh +27 -19
  45. package/src/scripts/tools/blackfire.ps1 +19 -21
  46. package/src/scripts/tools/blackfire.sh +40 -35
  47. package/src/scripts/tools/grpc_php_plugin.ps1 +21 -21
  48. package/src/scripts/tools/grpc_php_plugin.sh +58 -61
  49. package/src/scripts/tools/ppa.sh +189 -0
  50. package/src/scripts/tools/protoc.ps1 +38 -38
  51. package/src/scripts/tools/protoc.sh +28 -28
  52. package/src/scripts/win32.ps1 +566 -471
  53. package/src/tools.ts +538 -509
  54. package/src/utils.ts +503 -497
  55. package/.eslintrc.json +0 -16
  56. package/.github/CODE_OF_CONDUCT.md +0 -76
  57. package/.github/CONTRIBUTING.md +0 -70
  58. package/.github/FUNDING.yml +0 -7
  59. package/.github/ISSUE_TEMPLATE/bug_report.md +0 -42
  60. package/.github/ISSUE_TEMPLATE/feature_request.md +0 -26
  61. package/.github/PULL_REQUEST_TEMPLATE.md +0 -37
  62. package/.github/SECURITY.md +0 -29
  63. package/.github/workflows/docs.yml +0 -77
  64. package/.github/workflows/node-workflow.yml +0 -51
  65. package/.github/workflows/workflow.yml +0 -78
  66. package/.idea/workspace.xml +0 -113
  67. package/.prettierrc.json +0 -12
  68. package/__tests__/config.test.ts +0 -52
  69. package/__tests__/coverage.test.ts +0 -110
  70. package/__tests__/extensions.test.ts +0 -261
  71. package/__tests__/install.test.ts +0 -175
  72. package/__tests__/tools.test.ts +0 -490
  73. package/__tests__/utils.test.ts +0 -303
  74. package/action.yml +0 -29
  75. package/dist/index.js +0 -3001
  76. package/examples/bedrock.yml +0 -32
  77. package/examples/blackfire-player.yml +0 -31
  78. package/examples/blackfire.yml +0 -31
  79. package/examples/cakephp-mysql.yml +0 -114
  80. package/examples/cakephp-postgres.yml +0 -112
  81. package/examples/cakephp.yml +0 -92
  82. package/examples/codeigniter.yml +0 -34
  83. package/examples/laravel-mysql.yml +0 -74
  84. package/examples/laravel-postgres.yml +0 -74
  85. package/examples/laravel.yml +0 -42
  86. package/examples/lumen-mysql.yml +0 -74
  87. package/examples/lumen-postgres.yml +0 -74
  88. package/examples/lumen.yml +0 -38
  89. package/examples/phalcon-mysql.yml +0 -74
  90. package/examples/phalcon-postgres.yml +0 -73
  91. package/examples/sage.yml +0 -57
  92. package/examples/slim-framework.yml +0 -34
  93. package/examples/symfony-mysql.yml +0 -57
  94. package/examples/symfony-postgres.yml +0 -55
  95. package/examples/symfony.yml +0 -39
  96. package/examples/yii2-mysql.yml +0 -73
  97. package/examples/yii2-postgres.yml +0 -71
  98. package/examples/zend-framework.yml +0 -36
  99. package/jest.config.js +0 -12
  100. package/lib/config.js +0 -72
  101. package/lib/config.js.map +0 -1
  102. package/lib/coverage.js +0 -88
  103. package/lib/coverage.js.map +0 -1
  104. package/lib/extensions.js +0 -201
  105. package/lib/extensions.js.map +0 -1
  106. package/lib/install.js +0 -82
  107. package/lib/install.js.map +0 -1
  108. package/lib/sapi.js +0 -64
  109. package/lib/tools.js +0 -387
  110. package/lib/tools.js.map +0 -1
  111. package/lib/utils.js +0 -292
  112. package/lib/utils.js.map +0 -1
  113. package/tsconfig.json +0 -18
@@ -1,314 +1,366 @@
1
- # Variables
2
- export tick="✓"
3
- export cross="✗"
4
- export curl_opts=(-sL)
5
- export old_versions="5.[3-5]"
6
- export jit_versions="8.[0-9]"
7
- export nightly_versions="8.[1-9]"
8
- export xdebug3_versions="7.[2-4]|8.[0-9]"
9
- export tool_path_dir="/usr/local/bin"
10
- export composer_home="$HOME/.composer"
11
- export composer_bin="$composer_home/vendor/bin"
12
- export composer_json="$composer_home/composer.json"
13
- export composer_lock="$composer_home/composer.lock"
14
- export latest="releases/latest/download"
15
- export github="https://github.com/shivammathur"
16
- export jsdeliver="https://cdn.jsdelivr.net/gh/shivammathur"
17
-
18
- # Function to log start of a operation.
19
- step_log() {
20
- message=$1
21
- printf "\n\033[90;1m==> \033[0m\033[37;1m%s\033[0m\n" "$message"
22
- }
23
-
24
- # Function to log result of a operation.
25
- add_log() {
26
- mark=$1
27
- subject=$2
28
- message=$3
29
- if [ "$mark" = "$tick" ]; then
30
- printf "\033[32;1m%s \033[0m\033[34;1m%s \033[0m\033[90;1m%s\033[0m\n" "$mark" "$subject" "$message"
31
- else
32
- printf "\033[31;1m%s \033[0m\033[34;1m%s \033[0m\033[90;1m%s\033[0m\n" "$mark" "$subject" "$message"
33
- [ "$fail_fast" = "true" ] && exit 1
34
- fi
35
- }
36
-
37
- # Function to log result of installing extension.
38
- add_extension_log() {
39
- (
40
- check_extension "$(echo "$1" | cut -d '-' -f 1)" && add_log "$tick" "$1" "$2"
41
- ) || add_log "$cross" "$1" "Could not install $1 on PHP ${semver:?}"
42
- }
43
-
44
- # Function to read env inputs.
45
- read_env() {
46
- [[ -z "${update}" ]] && update='false' && UPDATE='false' || update="${update}"
47
- [ "$update" = false ] && [[ -n ${UPDATE} ]] && update="${UPDATE}"
48
- [[ -z "${runner}" ]] && runner='github' && RUNNER='github' || runner="${runner}"
49
- [ "$runner" = false ] && [[ -n ${RUNNER} ]] && runner="${RUNNER}"
50
- [[ -z "${fail_fast}" ]] && fail_fast='false' || fail_fast="${fail_fast}"
51
- }
52
-
53
- # Function to download a file using cURL.
54
- # mode: -s pipe to stdout, -v save file and return status code
55
- # execute: -e save file as executable
56
- get() {
57
- mode=$1
58
- execute=$2
59
- file_path=$3
60
- shift 3
61
- links=("$@")
62
- if [ "$mode" = "-s" ]; then
63
- sudo curl "${curl_opts[@]}" "${links[0]}"
64
- else
65
- for link in "${links[@]}"; do
66
- status_code=$(sudo curl -w "%{http_code}" -o "$file_path" "${curl_opts[@]}" "$link")
67
- [ "$status_code" = "200" ] && break
68
- done
69
- [ "$execute" = "-e" ] && sudo chmod a+x "$file_path"
70
- [ "$mode" = "-v" ] && echo "$status_code"
71
- fi
72
- }
73
-
74
- # Function to download and run scripts from GitHub releases with jsdeliver fallback.
75
- run_script() {
76
- repo=$1
77
- shift
78
- args=("$@")
79
- get -q -e /tmp/install.sh "$github/$repo/$latest/install.sh" "$jsdeliver/$1@main/scripts/install.sh"
80
- bash /tmp/install.sh "${args[@]}"
81
- }
82
-
83
- # Function to install required packages on self-hosted runners.
84
- self_hosted_setup() {
85
- if [ "$runner" = "self-hosted" ]; then
86
- if [[ "${version:?}" =~ $old_versions ]]; then
87
- add_log "$cross" "PHP" "PHP $version is not supported on self-hosted runner"
88
- exit 1
89
- else
90
- self_hosted_helper >/dev/null 2>&1
91
- fi
92
- fi
93
- }
94
-
95
- # Function to test if extension is loaded.
96
- check_extension() {
97
- extension=$1
98
- if [ "$extension" != "mysql" ]; then
99
- php -m | grep -i -q -w "$extension"
100
- else
101
- php -m | grep -i -q "$extension"
102
- fi
103
- }
104
-
105
- # Function to enable cached extensions.
106
- enable_cache_extension() {
107
- deps=()
108
- for ext in /tmp/extcache/"$1"/*; do
109
- deps+=("$(basename "$ext")")
110
- done
111
- if [ "x${deps[*]}" = "x" ]; then
112
- sudo rm -rf /tmp/extcache/"$1"
113
- enable_extension "$1" "$2"
114
- else
115
- deps+=("$1")
116
- if php "${deps[@]/#/-d ${2}=}" -m 2>/dev/null | grep -i -q "$1"; then
117
- for ext in "${deps[@]}"; do
118
- sudo rm -rf /tmp/extcache/"$ext"
119
- enable_extension "$ext" "$2"
120
- done
121
- fi
122
- fi
123
- }
124
-
125
- # Function to enable existing extensions.
126
- enable_extension() {
127
- modules_dir="/var/lib/php/modules/$version"
128
- [ -d "$modules_dir" ] && sudo find "$modules_dir" -path "*disabled*$1" -delete
129
- if [ -d /tmp/extcache/"$1" ]; then
130
- enable_cache_extension "$1" "$2"
131
- elif ! check_extension "$1" && [ -e "${ext_dir:?}/$1.so" ]; then
132
- echo "$2=${ext_dir:?}/$1.so" | sudo tee -a "${pecl_file:-${ini_file[@]}}" >/dev/null
133
- fi
134
- }
135
-
136
- # Function to configure PHP
137
- configure_php() {
138
- (
139
- echo -e "date.timezone=UTC\nmemory_limit=-1"
140
- [[ "$version" =~ $jit_versions ]] && echo -e "opcache.enable=1\nopcache.jit_buffer_size=256M\nopcache.jit=1235"
141
- [[ "$version" =~ $xdebug3_versions ]] && echo -e "xdebug.mode=coverage"
142
- ) | sudo tee -a "${pecl_file:-${ini_file[@]}}" >/dev/null
143
- }
144
-
145
- # Function to configure PECL.
146
- configure_pecl() {
147
- if ! [ -e /tmp/pecl_config ]; then
148
- for script in pear pecl; do
149
- sudo "$script" config-set php_ini "${pecl_file:-${ini_file[@]}}"
150
- sudo "$script" channel-update "$script".php.net
151
- done
152
- echo '' | sudo tee /tmp/pecl_config >/dev/null 2>&1
153
- fi
154
- }
155
-
156
- # Function to get the PECL version of an extension.
157
- get_pecl_version() {
158
- extension=$1
159
- stability="$(echo "$2" | grep -m 1 -Eio "(stable|alpha|beta|rc|snapshot|preview)")"
160
- pecl_rest='https://pecl.php.net/rest/r/'
161
- response=$(get -s -n "" "$pecl_rest$extension"/allreleases.xml)
162
- pecl_version=$(echo "$response" | grep -m 1 -Eio "([0-9]+\.[0-9]+\.[0-9]+${stability}[0-9]+)")
163
- if [ ! "$pecl_version" ]; then
164
- pecl_version=$(echo "$response" | grep -m 1 -Eo "([0-9]+\.[0-9]+\.[0-9]+)")
165
- fi
166
- echo "$pecl_version"
167
- }
168
-
169
- # Function to install PECL extensions and accept default options
170
- pecl_install() {
171
- local extension=$1
172
- add_pecl >/dev/null 2>&1
173
- yes '' 2>/dev/null | sudo pecl install -f "$extension" >/dev/null 2>&1
174
- }
175
-
176
- # Function to install a specific version of PECL extension.
177
- add_pecl_extension() {
178
- extension=$1
179
- pecl_version=$2
180
- prefix=$3
181
- enable_extension "$extension" "$prefix"
182
- if [[ $pecl_version =~ .*(alpha|beta|rc|snapshot|preview).* ]]; then
183
- pecl_version=$(get_pecl_version "$extension" "$pecl_version")
184
- fi
185
- ext_version=$(php -r "echo phpversion('$extension');")
186
- if [ "$ext_version" = "$pecl_version" ]; then
187
- add_log "${tick:?}" "$extension" "Enabled"
188
- else
189
- disable_extension "$extension" >/dev/null 2>&1
190
- delete_extension "$extension" >/dev/null 2>&1
191
- pecl_install "$extension-$pecl_version"
192
- add_extension_log "$extension-$pecl_version" "Installed and enabled"
193
- fi
194
- }
195
-
196
- # Function to setup pre-release extensions using PECL.
197
- add_unstable_extension() {
198
- extension=$1
199
- stability=$2
200
- prefix=$3
201
- pecl_version=$(get_pecl_version "$extension" "$stability")
202
- add_pecl_extension "$extension" "$pecl_version" "$prefix"
203
- }
204
-
205
- # Function to extract tool version.
206
- get_tool_version() {
207
- tool=$1
208
- param=$2
209
- alp="[a-zA-Z0-9]"
210
- version_regex="[0-9]+((\.{1}$alp+)+)(\.{0})(-$alp+){0,1}"
211
- if [ "$tool" = "composer" ]; then
212
- if [ "$param" != "snapshot" ]; then
213
- composer_version="$(grep -Ea "const\sVERSION" "$tool_path_dir/composer" | grep -Eo "$version_regex")"
214
- else
215
- composer_version="$(grep -Ea "const\sBRANCH_ALIAS_VERSION" "$tool_path_dir/composer" | grep -Eo "$version_regex")+$(grep -Ea "const\sVERSION" "$tool_path_dir/composer" | grep -Eo "[a-zA-z0-9]+" | tail -n 1)"
216
- fi
217
- echo "$composer_version" | sudo tee /tmp/composer_version
218
- else
219
- $tool "$param" 2>/dev/null | sed -Ee "s/[Cc]omposer(.)?$version_regex//g" | grep -Eo "$version_regex" | head -n 1
220
- fi
221
- }
222
-
223
- # Function to configure composer
224
- configure_composer() {
225
- tool_path=$1
226
- sudo ln -sf "$tool_path" "$tool_path.phar"
227
- php -r "try {\$p=new Phar('$tool_path.phar', 0);exit(0);} catch(Exception \$e) {exit(1);}"
228
- if [ $? -eq 1 ]; then
229
- add_log "$cross" "composer" "Could not download composer"
230
- exit 1
231
- fi
232
- if ! [ -d "$composer_home" ]; then
233
- sudo -u "$(id -un)" -g "$(id -gn)" mkdir -p -m=00755 "$composer_home"
234
- else
235
- sudo chown -R "$(id -un)":"$(id -gn)" "$composer_home"
236
- fi
237
- if ! [ -e "$composer_json" ]; then
238
- echo '{}' | tee "$composer_json" >/dev/null
239
- chmod 644 "$composer_json"
240
- fi
241
- composer -q config -g process-timeout 0
242
- echo "$composer_bin" >>"$GITHUB_PATH"
243
- if [ -n "$COMPOSER_TOKEN" ]; then
244
- composer -q config -g github-oauth.github.com "$COMPOSER_TOKEN"
245
- fi
246
- }
247
-
248
- # Function to setup a remote tool.
249
- add_tool() {
250
- url=$1
251
- tool=$2
252
- ver_param=$3
253
- tool_path="$tool_path_dir/$tool"
254
- if ! [[ "$PATH" =~ $tool_path_dir ]]; then
255
- export PATH=$PATH:"$tool_path_dir"
256
- echo "export PATH=\$PATH:$tool_path_dir" | sudo tee -a "$GITHUB_ENV" >/dev/null
257
- fi
258
- if [ ! -e "$tool_path" ]; then
259
- rm -rf "$tool_path"
260
- fi
261
- IFS="," read -r -a url <<<"$url"
262
- status_code=$(get -v -e "$tool_path" "${url[@]}")
263
- if [ "$status_code" != "200" ] && [[ "${url[0]}" =~ .*github.com.*releases.*latest.* ]]; then
264
- url[0]="${url[0]//releases\/latest\/download/releases/download/$(get -s -n "" "$(echo "${url[0]}" | cut -d '/' -f '1-5')/releases" | grep -Eo -m 1 "([0-9]+\.[0-9]+\.[0-9]+)/$(echo "${url[0]}" | sed -e "s/.*\///")" | cut -d '/' -f 1)}"
265
- status_code=$(get -v -e "$tool_path" "${url[0]}")
266
- fi
267
- if [ "$status_code" = "200" ]; then
268
- add_tools_helper "$tool"
269
- tool_version=$(get_tool_version "$tool" "$ver_param")
270
- add_log "$tick" "$tool" "Added $tool $tool_version"
271
- else
272
- add_log "$cross" "$tool" "Could not setup $tool"
273
- fi
274
- }
275
-
276
- # Function to setup a tool using composer.
277
- add_composertool() {
278
- tool=$1
279
- release=$2
280
- prefix=$3
281
- if [[ "$tool" =~ prestissimo|composer-prefetcher ]]; then
282
- composer_version=$(cat /tmp/composer_version)
283
- if [ "$(echo "$composer_version" | cut -d'.' -f 1)" != "1" ]; then
284
- echo "::warning:: Skipping $tool, as it does not support Composer $composer_version. Specify composer:v1 in tools to use $tool"
285
- add_log "$cross" "$tool" "Skipped"
286
- return
287
- fi
288
- fi
289
- (
290
- sudo rm -f "$composer_lock" >/dev/null 2>&1 || true
291
- composer global require "$prefix$release" 2>&1 | tee /tmp/composer.log >/dev/null 2>&1
292
- log=$(grep "$prefix$tool" /tmp/composer.log) &&
293
- tool_version=$(get_tool_version 'echo' "$log") &&
294
- add_log "$tick" "$tool" "Added $tool $tool_version"
295
- ) || add_log "$cross" "$tool" "Could not setup $tool"
296
- add_tools_helper "$tool"
297
- if [ -e "$composer_bin/composer" ]; then
298
- sudo cp -p "$tool_path_dir/composer" "$composer_bin"
299
- fi
300
- }
301
-
302
- # Function to get PHP version in semver format.
303
- php_semver() {
304
- php -v | grep -Eo -m 1 "[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z]+([0-9]+)?)?" | head -n 1
305
- }
306
-
307
- # Function to get the tag for a php version.
308
- php_src_tag() {
309
- php_src_tag='master'
310
- if ! [[ ${version:?} =~ $nightly_versions ]]; then
311
- php_src_tag="php-$semver"
312
- fi
313
- echo "$php_src_tag"
314
- }
1
+ # Variables
2
+ export tick="✓"
3
+ export cross="✗"
4
+ export curl_opts=(-sL)
5
+ export old_versions="5.[3-5]"
6
+ export jit_versions="8.[0-9]"
7
+ export nightly_versions="8.[1-9]"
8
+ export xdebug3_versions="7.[2-4]|8.[0-9]"
9
+ export tool_path_dir="/usr/local/bin"
10
+ export composer_home="$HOME/.composer"
11
+ export composer_bin="$composer_home/vendor/bin"
12
+ export composer_json="$composer_home/composer.json"
13
+ export composer_lock="$composer_home/composer.lock"
14
+ export latest="releases/latest/download"
15
+ export github="https://github.com/shivammathur"
16
+ export jsdeliver="https://cdn.jsdelivr.net/gh/shivammathur"
17
+
18
+ # Function to log start of a operation.
19
+ step_log() {
20
+ message=$1
21
+ printf "\n\033[90;1m==> \033[0m\033[37;1m%s\033[0m\n" "$message"
22
+ }
23
+
24
+ # Function to log result of a operation.
25
+ add_log() {
26
+ mark=$1
27
+ subject=$2
28
+ message=$3
29
+ if [ "$mark" = "$tick" ]; then
30
+ printf "\033[32;1m%s \033[0m\033[34;1m%s \033[0m\033[90;1m%s\033[0m\n" "$mark" "$subject" "$message"
31
+ else
32
+ printf "\033[31;1m%s \033[0m\033[34;1m%s \033[0m\033[90;1m%s\033[0m\n" "$mark" "$subject" "$message"
33
+ [ "$fail_fast" = "true" ] && exit 1
34
+ fi
35
+ }
36
+
37
+ # Function to log result of installing extension.
38
+ add_extension_log() {
39
+ (
40
+ check_extension "$(echo "$1" | cut -d '-' -f 1)" && add_log "$tick" "$1" "$2"
41
+ ) || add_log "$cross" "$1" "Could not install $1 on PHP ${semver:?}"
42
+ }
43
+
44
+ # Function to read env inputs.
45
+ read_env() {
46
+ [[ -z "${update}" ]] && update='false' && UPDATE='false' || update="${update}"
47
+ [ "$update" = false ] && [[ -n ${UPDATE} ]] && update="${UPDATE}"
48
+ [[ -z "${runner}" ]] && runner='github' && RUNNER='github' || runner="${runner}"
49
+ [ "$runner" = false ] && [[ -n ${RUNNER} ]] && runner="${RUNNER}"
50
+ [[ -z "${fail_fast}" ]] && fail_fast='false' || fail_fast="${fail_fast}"
51
+ }
52
+
53
+ # Function to download a file using cURL.
54
+ # mode: -s pipe to stdout, -v save file and return status code
55
+ # execute: -e save file as executable
56
+ get() {
57
+ mode=$1
58
+ execute=$2
59
+ file_path=$3
60
+ shift 3
61
+ links=("$@")
62
+ if [ "$mode" = "-s" ]; then
63
+ sudo curl "${curl_opts[@]}" "${links[0]}"
64
+ else
65
+ for link in "${links[@]}"; do
66
+ status_code=$(sudo curl -w "%{http_code}" -o "$file_path" "${curl_opts[@]}" "$link")
67
+ [ "$status_code" = "200" ] && break
68
+ done
69
+ [ "$execute" = "-e" ] && sudo chmod a+x "$file_path"
70
+ [ "$mode" = "-v" ] && echo "$status_code"
71
+ fi
72
+ }
73
+
74
+ # Function to download and run scripts from GitHub releases with jsdeliver fallback.
75
+ run_script() {
76
+ repo=$1
77
+ shift
78
+ args=("$@")
79
+ get -q -e /tmp/install.sh "$github/$repo/$latest/install.sh" "$jsdeliver/$1@main/scripts/install.sh"
80
+ bash /tmp/install.sh "${args[@]}"
81
+ }
82
+
83
+ # Function to install required packages on self-hosted runners.
84
+ self_hosted_setup() {
85
+ if [ "$runner" = "self-hosted" ]; then
86
+ if [[ "${version:?}" =~ $old_versions ]]; then
87
+ add_log "$cross" "PHP" "PHP $version is not supported on self-hosted runner"
88
+ exit 1
89
+ else
90
+ self_hosted_helper >/dev/null 2>&1
91
+ fi
92
+ fi
93
+ }
94
+
95
+ # Function to test if extension is loaded.
96
+ check_extension() {
97
+ local extension=$1
98
+ if [ "$extension" != "mysql" ]; then
99
+ php -m | grep -i -q -w "$extension"
100
+ else
101
+ php -m | grep -i -q "$extension"
102
+ fi
103
+ }
104
+
105
+ # Function to check if extension is shared
106
+ shared_extension() {
107
+ [ -e "${ext_dir:?}/$1.so" ]
108
+ }
109
+
110
+ # Function to enable cached extension's dependencies.
111
+ enable_cache_extension_dependencies() {
112
+ if [ -d /tmp/extcache ] && shared_extension "$1"; then
113
+ cache_dir=$(find /tmp/extcache -maxdepth 1 -type d -regex ".*$1[0-9]*")
114
+ if [[ -n "$cache_dir" ]]; then
115
+ IFS=" " read -r -a deps <<<"$(find "$cache_dir" -maxdepth 1 -type f -name "*" -exec basename {} \; | tr '\n' ' ')"
116
+ if [[ -n "${deps[*]}" ]] && php "${deps[@]/#/-d ${2}=}" -d "${2}=$1" -m 2>/dev/null | grep -i -q "$1"; then
117
+ for ext in "${deps[@]}"; do
118
+ sudo rm -rf /tmp/extcache/"$ext"
119
+ enable_extension "$ext" "$2"
120
+ done
121
+ fi
122
+ fi
123
+ fi
124
+ }
125
+
126
+ # Function to enable existing extensions.
127
+ enable_extension() {
128
+ modules_dir="/var/lib/php/modules/$version"
129
+ [ -d "$modules_dir" ] && sudo find "$modules_dir" -path "*disabled*$1" -delete
130
+ enable_extension_dependencies "$1" "$2"
131
+ enable_cache_extension_dependencies "$1" "$2"
132
+ if ! check_extension "$1" && shared_extension "$1"; then
133
+ echo "$2=${ext_dir:?}/$1.so" | sudo tee -a "${pecl_file:-${ini_file[@]}}" >/dev/null
134
+ fi
135
+ }
136
+
137
+ # Function to get a map of extensions and their dependent shared extensions.
138
+ get_extension_map() {
139
+ php -d'error_reporting=0' "${dist:?}"/../src/scripts/ext/extension_map.php
140
+ }
141
+
142
+ # Function to enable extension dependencies which are also extensions.
143
+ enable_extension_dependencies() {
144
+ local extension=$1
145
+ prefix=$2
146
+ if ! [ -e /tmp/map.orig ]; then
147
+ get_extension_map | sudo tee /tmp/map.orig >/dev/null
148
+ fi
149
+ for dependency in $(grep "$extension:" /tmp/map.orig | cut -d ':' -f 2 | tr '\n' ' '); do
150
+ enable_extension "$dependency" "$prefix"
151
+ done
152
+ }
153
+
154
+ # Function to disable dependent extensions.
155
+ disable_extension_dependents() {
156
+ local extension=$1
157
+ for dependent in $(get_extension_map | grep -E ".*:.*\s$extension(\s|$)" | cut -d ':' -f 1 | tr '\n' ' '); do
158
+ disable_extension_helper "$dependent" true
159
+ add_log "${tick:?}" ":$extension" "Disabled $dependent as it depends on $extension"
160
+ done
161
+ }
162
+
163
+ # Function to disable an extension.
164
+ disable_extension() {
165
+ local extension=$1
166
+ if check_extension "$extension"; then
167
+ if shared_extension "$extension"; then
168
+ disable_extension_helper "$extension" true
169
+ (! check_extension "$extension" && add_log "${tick:?}" ":$extension" "Disabled") ||
170
+ add_log "${cross:?}" ":$extension" "Could not disable $extension on PHP ${semver:?}"
171
+ else
172
+ add_log "${cross:?}" ":$extension" "Could not disable $extension on PHP $semver as it not a shared extension"
173
+ fi
174
+ elif shared_extension "$extension"; then
175
+ add_log "${tick:?}" ":$extension" "Disabled"
176
+ else
177
+ add_log "${tick:?}" ":$extension" "Could not find $extension on PHP $semver"
178
+ fi
179
+ }
180
+
181
+ # Function to disable shared extensions.
182
+ disable_all_shared() {
183
+ sudo sed -i.orig -E -e "/^(zend_)?extension\s*=/d" "${ini_file[@]}" "$pecl_file" 2>/dev/null || true
184
+ sudo find "${ini_dir:-$scan_dir}"/.. -name "*.ini" -not -path "*php.ini" -not -path "*mods-available*" -delete >/dev/null 2>&1 || true
185
+ add_log "${tick:?}" "none" "Disabled all shared extensions"
186
+ }
187
+
188
+ # Function to configure PHP
189
+ configure_php() {
190
+ (
191
+ echo -e "date.timezone=UTC\nmemory_limit=-1"
192
+ [[ "$version" =~ $jit_versions ]] && echo -e "opcache.enable=1\nopcache.jit_buffer_size=256M\nopcache.jit=1235"
193
+ [[ "$version" =~ $xdebug3_versions ]] && echo -e "xdebug.mode=coverage"
194
+ ) | sudo tee -a "${pecl_file:-${ini_file[@]}}" >/dev/null
195
+ }
196
+
197
+ # Function to configure PECL.
198
+ configure_pecl() {
199
+ if ! [ -e /tmp/pecl_config ]; then
200
+ for script in pear pecl; do
201
+ sudo "$script" config-set php_ini "${pecl_file:-${ini_file[@]}}"
202
+ sudo "$script" channel-update "$script".php.net
203
+ done
204
+ echo '' | sudo tee /tmp/pecl_config >/dev/null 2>&1
205
+ fi
206
+ }
207
+
208
+ # Function to get the PECL version of an extension.
209
+ get_pecl_version() {
210
+ local extension=$1
211
+ stability="$(echo "$2" | grep -m 1 -Eio "(stable|alpha|beta|rc|snapshot|preview)")"
212
+ pecl_rest='https://pecl.php.net/rest/r/'
213
+ response=$(get -s -n "" "$pecl_rest$extension"/allreleases.xml)
214
+ pecl_version=$(echo "$response" | grep -m 1 -Eio "([0-9]+\.[0-9]+\.[0-9]+${stability}[0-9]+)")
215
+ if [ ! "$pecl_version" ]; then
216
+ pecl_version=$(echo "$response" | grep -m 1 -Eo "([0-9]+\.[0-9]+\.[0-9]+)")
217
+ fi
218
+ echo "$pecl_version"
219
+ }
220
+
221
+ # Function to install PECL extensions and accept default options
222
+ pecl_install() {
223
+ local extension=$1
224
+ add_pecl >/dev/null 2>&1
225
+ yes '' 2>/dev/null | sudo pecl install -f "$extension" >/dev/null 2>&1
226
+ }
227
+
228
+ # Function to install a specific version of PECL extension.
229
+ add_pecl_extension() {
230
+ local extension=$1
231
+ pecl_version=$2
232
+ prefix=$3
233
+ enable_extension "$extension" "$prefix"
234
+ if [[ $pecl_version =~ .*(alpha|beta|rc|snapshot|preview).* ]]; then
235
+ pecl_version=$(get_pecl_version "$extension" "$pecl_version")
236
+ fi
237
+ ext_version=$(php -r "echo phpversion('$extension');")
238
+ if [ "$ext_version" = "$pecl_version" ]; then
239
+ add_log "${tick:?}" "$extension" "Enabled"
240
+ else
241
+ disable_extension_helper "$extension" >/dev/null 2>&1
242
+ pecl_install "$extension-$pecl_version"
243
+ add_extension_log "$extension-$pecl_version" "Installed and enabled"
244
+ fi
245
+ }
246
+
247
+ # Function to setup pre-release extensions using PECL.
248
+ add_unstable_extension() {
249
+ local extension=$1
250
+ stability=$2
251
+ prefix=$3
252
+ pecl_version=$(get_pecl_version "$extension" "$stability")
253
+ add_pecl_extension "$extension" "$pecl_version" "$prefix"
254
+ }
255
+
256
+ # Function to extract tool version.
257
+ get_tool_version() {
258
+ tool=$1
259
+ param=$2
260
+ alp="[a-zA-Z0-9]"
261
+ version_regex="[0-9]+((\.{1}$alp+)+)(\.{0})(-$alp+){0,1}"
262
+ if [ "$tool" = "composer" ]; then
263
+ if [ "$param" != "snapshot" ]; then
264
+ composer_version="$(grep -Ea "const\sVERSION" "$tool_path_dir/composer" | grep -Eo "$version_regex")"
265
+ else
266
+ composer_version="$(grep -Ea "const\sBRANCH_ALIAS_VERSION" "$tool_path_dir/composer" | grep -Eo "$version_regex")+$(grep -Ea "const\sVERSION" "$tool_path_dir/composer" | grep -Eo "[a-zA-z0-9]+" | tail -n 1)"
267
+ fi
268
+ echo "$composer_version" | sudo tee /tmp/composer_version
269
+ else
270
+ $tool "$param" 2>/dev/null | sed -Ee "s/[Cc]omposer(.)?$version_regex//g" | grep -Eo "$version_regex" | head -n 1
271
+ fi
272
+ }
273
+
274
+ # Function to configure composer
275
+ configure_composer() {
276
+ tool_path=$1
277
+ sudo ln -sf "$tool_path" "$tool_path.phar"
278
+ php -r "try {\$p=new Phar('$tool_path.phar', 0);exit(0);} catch(Exception \$e) {exit(1);}"
279
+ if [ $? -eq 1 ]; then
280
+ add_log "$cross" "composer" "Could not download composer"
281
+ exit 1
282
+ fi
283
+ if ! [ -d "$composer_home" ]; then
284
+ sudo -u "$(id -un)" -g "$(id -gn)" mkdir -p -m=00755 "$composer_home"
285
+ else
286
+ sudo chown -R "$(id -un)":"$(id -gn)" "$composer_home"
287
+ fi
288
+ if ! [ -e "$composer_json" ]; then
289
+ echo '{}' | tee "$composer_json" >/dev/null
290
+ chmod 644 "$composer_json"
291
+ fi
292
+ composer -q config -g process-timeout 0
293
+ echo "$composer_bin" >>"$GITHUB_PATH"
294
+ if [ -n "$COMPOSER_TOKEN" ]; then
295
+ composer -q config -g github-oauth.github.com "$COMPOSER_TOKEN"
296
+ fi
297
+ }
298
+
299
+ # Function to setup a remote tool.
300
+ add_tool() {
301
+ url=$1
302
+ tool=$2
303
+ ver_param=$3
304
+ tool_path="$tool_path_dir/$tool"
305
+ if ! [[ "$PATH" =~ $tool_path_dir ]]; then
306
+ export PATH=$PATH:"$tool_path_dir"
307
+ echo "export PATH=\$PATH:$tool_path_dir" | sudo tee -a "$GITHUB_ENV" >/dev/null
308
+ fi
309
+ if [ ! -e "$tool_path" ]; then
310
+ rm -rf "$tool_path"
311
+ fi
312
+ IFS="," read -r -a url <<<"$url"
313
+ status_code=$(get -v -e "$tool_path" "${url[@]}")
314
+ if [ "$status_code" != "200" ] && [[ "${url[0]}" =~ .*github.com.*releases.*latest.* ]]; then
315
+ url[0]="${url[0]//releases\/latest\/download/releases/download/$(get -s -n "" "$(echo "${url[0]}" | cut -d '/' -f '1-5')/releases" | grep -Eo -m 1 "([0-9]+\.[0-9]+\.[0-9]+)/$(echo "${url[0]}" | sed -e "s/.*\///")" | cut -d '/' -f 1)}"
316
+ status_code=$(get -v -e "$tool_path" "${url[0]}")
317
+ fi
318
+ if [ "$status_code" = "200" ]; then
319
+ add_tools_helper "$tool"
320
+ tool_version=$(get_tool_version "$tool" "$ver_param")
321
+ add_log "$tick" "$tool" "Added $tool $tool_version"
322
+ else
323
+ add_log "$cross" "$tool" "Could not setup $tool"
324
+ fi
325
+ }
326
+
327
+ # Function to setup a tool using composer.
328
+ add_composertool() {
329
+ tool=$1
330
+ release=$2
331
+ prefix=$3
332
+ if [[ "$tool" =~ prestissimo|composer-prefetcher ]]; then
333
+ composer_version=$(cat /tmp/composer_version)
334
+ if [ "$(echo "$composer_version" | cut -d'.' -f 1)" != "1" ]; then
335
+ echo "::warning:: Skipping $tool, as it does not support Composer $composer_version. Specify composer:v1 in tools to use $tool"
336
+ add_log "$cross" "$tool" "Skipped"
337
+ return
338
+ fi
339
+ fi
340
+ (
341
+ sudo rm -f "$composer_lock" >/dev/null 2>&1 || true
342
+ composer global require "$prefix$release" 2>&1 | tee /tmp/composer.log >/dev/null 2>&1
343
+ log=$(grep "$prefix$tool" /tmp/composer.log) &&
344
+ tool_version=$(get_tool_version 'echo' "$log") &&
345
+ add_log "$tick" "$tool" "Added $tool $tool_version"
346
+ ) || add_log "$cross" "$tool" "Could not setup $tool"
347
+ add_tools_helper "$tool"
348
+ if [ -e "$composer_bin/composer" ]; then
349
+ sudo cp -p "$tool_path_dir/composer" "$composer_bin"
350
+ fi
351
+ }
352
+
353
+ # Function to get PHP version in semver format.
354
+ php_semver() {
355
+ php -v | grep -Eo -m 1 "[0-9]+\.[0-9]+\.[0-9]+((-?[a-zA-Z]+([0-9]+)?)?){2}" | head -n 1
356
+ }
357
+
358
+ # Function to get the tag for a php version.
359
+ php_src_tag() {
360
+ commit=$(php_extra_version | grep -Eo "[0-9a-zA-Z]+")
361
+ if [[ -n "${commit}" ]]; then
362
+ echo "$commit"
363
+ else
364
+ echo "php-$semver"
365
+ fi
366
+ }