ReviewOS

also looking at this

pantry-pm/pantry

chore(deps): update dependency softprops/action-gh-release to v2.3.3

#159
Closed chrisbbreuer wants to merge buddy-bot/update-major-update---softprops/action-gh-release-1756037509289 into main
1 file +638 -860
.github/workflows/precompile-php.ymlmodified+638-860
Changes to .github/workflows/precompile-php.yml
@@ -2,28 +2,35 @@ name: Precompile PHP
22
33on:
44 push:
5 branches: [main, develop]
6 paths:
7 - .github/workflows/precompile-php.yml
8 - build-configs/**
9 - scripts/get-php-versions.ts
10 - scripts/check-php-updates.ts
5 branches: [main]
116 schedule:
127 # Check for updates daily at 2 AM UTC
138 - cron: '0 2 * * *'
149 workflow_dispatch:
1510 inputs:
11 php_version:
12 description: PHP version to build (leave empty for auto-detection)
13 required: false
14 type: string
15 php_config:
16 description: PHP build configuration
17 required: true
18 default: laravel-mysql
19 type: choice
20 options:
21 - laravel-mysql
22 - laravel-postgres
23 - laravel-sqlite
24 - api-only
25 - enterprise
26 - wordpress
27 - full-stack
1628 force_rebuild:
17 description: Force rebuild even if no new versions
29 description: Force rebuild even if no updates
1830 required: false
1931 default: false
2032 type: boolean
2133
22env:
23 REGISTRY_URL: ghcr.io
24 REGISTRY_USERNAME: ${{ github.actor }}
25 REGISTRY_PASSWORD: ${{ secrets.GITHUB_TOKEN }}
26
2734jobs:
2835 # First job: Check if we need to rebuild based on new PHP versions
2936 check-for-updates:
@@ -68,7 +75,7 @@ jobs:
6875 get-php-versions:
6976 needs: check-for-updates
7077 runs-on: ubuntu-latest
71 if: needs.check-for-updates.outputs.rebuild_needed == 'true' || github.event.inputs.force_rebuild == 'true'
78 if: needs.check-for-updates.outputs.rebuild_needed == 'true' || github.event.inputs.force_rebuild == 'true' || github.event.inputs.php_version != ''
7279 outputs:
7380 php_versions: ${{ steps.get-versions.outputs.php_versions }}
7481 steps:
@@ -83,937 +90,640 @@ jobs:
8390 - name: Get PHP versions from ts-pkgx
8491 id: get-versions
8592 run: |
86 # Get dynamic PHP versions using our custom script
87 PHP_VERSIONS=$(bun scripts/get-php-versions.ts | grep "JSON output for GitHub Actions:" -A 1 | tail -1)
93 if [ -n "$" ]; then
94 # Use specific version if provided
95 PHP_VERSIONS='["$"]'
96 else
97 # Get dynamic PHP versions using our custom script
98 PHP_VERSIONS=$(bun scripts/get-php-versions.ts | grep "JSON output for GitHub Actions:" -A 1 | tail -1)
99 fi
88100 echo "php_versions=$PHP_VERSIONS" >> $GITHUB_OUTPUT
89101 echo "🔍 Dynamic PHP versions: $PHP_VERSIONS"
90102
91 # Job to provide feedback when no rebuild is needed
92 no-rebuild-needed:
93 needs: check-for-updates
94 runs-on: ubuntu-latest
95 if: needs.check-for-updates.outputs.rebuild_needed == 'false' && github.event.inputs.force_rebuild != 'true'
96 steps:
97 - name: Checkout repository
98 uses: actions/checkout@v4
99
100 - name: No rebuild needed
101 run: |
102 echo "✅ No rebuild needed"
103 echo "Reason: $"
104 echo "Current versions: $"
105 echo "Latest versions: $"
106 echo ""
107 echo "The workflow will skip building since no new PHP versions are available."
108 echo "To force a rebuild, use the 'force_rebuild' input parameter."
109
110 # Matrix strategy for building across different platforms and configurations
111 build-matrix:
103 build:
112104 needs: [check-for-updates, get-php-versions]
113 runs-on: ${{ matrix.os }}
114 if: needs.check-for-updates.outputs.rebuild_needed == 'true' || github.event.inputs.force_rebuild == 'true'
105 if: needs.check-for-updates.outputs.rebuild_needed == 'true' || github.event.inputs.force_rebuild == 'true' || github.event.inputs.php_version != ''
115106 strategy:
116107 fail-fast: false
117108 matrix:
118 os: [ubuntu-latest, macos-latest, macos-13] # Include Intel Mac
119 php_version: ${{ fromJSON(needs.get-php-versions.outputs.php_versions) }}
120 config: [laravel-mysql, laravel-postgres, laravel-sqlite, api-only, enterprise, wordpress, full-stack]
109 php_version: ${{ fromJson(needs.get-php-versions.outputs.php_versions) }}
110 config:
111 - laravel-mysql
112 - laravel-postgres
113 - laravel-sqlite
114 - api-only
115 - enterprise
116 - wordpress
117 - full-stack
118 os:
119 - ubuntu-latest
120 - macos-14
121 - macos-15
122 - macos-15-intel
123 - windows-latest
121124 include:
122 # Add Windows later if needed
123125 - os: ubuntu-latest
124126 platform: linux
125127 arch: x86_64
126 - os: macos-latest
128 - os: macos-14
129 platform: darwin
130 arch: x86_64
131 - os: macos-15
127132 platform: darwin
128133 arch: arm64
129 - os: macos-13
134 - os: macos-15-intel
130135 platform: darwin
131136 arch: x86_64
132 exclude:
133 # Skip some combinations to reduce build time
134 - os: macos-13
135 config: api-only
136 # WordPress mainly used on Linux
137 - os: macos-13
138 config: wordpress
137 - os: windows-latest
138 platform: win32
139 arch: x86_64
140
141 runs-on: ${{ matrix.os }}
139142
140143 steps:
141 - name: Checkout repository
144 - name: Checkout code
142145 uses: actions/checkout@v4
143146
144 - name: Set up build environment
145 run: |
146 echo "Building PHP $ for $-$"
147 echo "Configuration: $"
148 echo "BINARY_NAME=php-$-$-$-$" >> $GITHUB_ENV
149 echo "BUILD_DIR=$/build" >> $GITHUB_ENV
150 echo "OUTPUT_DIR=$/binaries" >> $GITHUB_ENV
151
152 - name: Install Bun
147 - name: Setup Bun
153148 uses: oven-sh/setup-bun@v2
154
155 - name: Use cached node_modules
156 uses: actions/cache@v4
157149 with:
158 path: node_modules
159 key: node-modules-${{ hashFiles('**/bun.lock') }}
160 restore-keys: |
161 node-modules-
162
163 - name: Install Dependencies
164 run: bun install
150 bun-version: latest
165151
166 - name: Install build dependencies (Ubuntu)
152 - name: Install build dependencies (Linux)
167153 if: matrix.platform == 'linux'
168154 run: |
169 # Install PHP dependencies via apt-get (alternative to launchpad)
170 echo "🔧 Installing PHP dependencies via apt-get..."
171 echo "🔍 Debug info:"
172 echo " - Platform: linux"
173 echo " - Architecture: $(uname -m)"
174
175155 sudo apt-get update
176156 sudo apt-get install -y \
177 build-essential \
178 autoconf \
179 automake \
180 libtool \
181 pkg-config \
182 bison \
183 re2c \
184 libxml2-dev \
185 libssl-dev \
186 libcurl4-openssl-dev \
187 libpng-dev \
188 libjpeg-dev \
189 libfreetype6-dev \
190 libonig-dev \
191 libzip-dev \
192 libsqlite3-dev \
193 libpq-dev \
194 libreadline-dev \
195 libbz2-dev \
196 libgmp-dev \
197 libldap2-dev \
198 libsasl2-dev \
199 libxslt1-dev \
200 libicu-dev \
201 libsodium-dev \
202 zlib1g-dev
157 build-essential autoconf automake libtool pkg-config bison re2c \
158 libxml2-dev libssl-dev libcurl4-openssl-dev libpng-dev libjpeg-dev \
159 libfreetype6-dev libonig-dev libzip-dev libpq-dev libreadline-dev \
160 libbz2-dev libgmp-dev libldap2-dev libxslt1-dev libicu-dev \
161 libsodium-dev zlib1g-dev libsqlite3-dev libenchant-2-dev \
162 libtidy-dev libsnmp-dev libgd-dev libwebp-dev libc-client-dev \
163 libkrb5-dev libedit-dev libargon2-dev libffi-dev \
164 libmcrypt-dev libmhash-dev libpcre3-dev libexpat1-dev \
165 libc-ares-dev libnghttp2-dev libpsl-dev libidn2-dev \
166 librtmp-dev libssh2-1-dev libgssapi-krb5-2 libkrb5-dev \
167 gettext libgettext-ocaml-dev
203168
204169 - name: Install build dependencies (macOS)
205170 if: matrix.platform == 'darwin'
206171 run: |
207 # Install PHP dependencies via Homebrew (alternative to launchpad)
208 echo "� Installing PHP dependencies via Homebrew..."
209 echo "� Debug info:"
210 echo " - Platform: darwin"
211 echo " - Architecture: $(uname -m)"
212
213 # Install dependencies with quiet output to reduce warnings
214 brew install --quiet \
215 autoconf \
216 automake \
217 libtool \
218 pkg-config \
219 bison \
220 re2c \
221 libxml2 \
222 openssl@3 \
223 curl \
224 libpng \
225 jpeg \
226 freetype \
227 oniguruma \
228 libzip \
229 postgresql@17 \
230 libpq \
231 readline \
232 bzip2 \
233 gmp \
234 openldap \
235 libxslt \
236 icu4c \
237 libsodium \
238 zlib \
239 libiconv \
240 gettext
241
242 # Verify readline installation
243 echo "Checking readline installation:"
244 ls -la $(brew --prefix readline)/include/readline/readline.h || echo "readline.h not found in expected location"
245 ls -la $(brew --prefix readline)/lib/libreadline.* || echo "libreadline not found in expected location"
246
247 # Verify PostgreSQL installation
248 echo "Checking PostgreSQL installation:"
249 ls -la $(brew --prefix libpq)/include/libpq-fe.h || echo "libpq-fe.h not found in expected location (libpq)"
250 ls -la $(brew --prefix libpq)/lib/libpq.* || echo "libpq not found in expected location (libpq)"
251 which pg_config || echo "pg_config not found in PATH"
252
253 # Verify bzip2 installation
254 echo "Checking bzip2 installation:"
255 ls -la $(brew --prefix bzip2)/include/bzlib.h || echo "bzlib.h not found in expected location"
256 ls -la $(brew --prefix bzip2)/lib/libbz2.* || echo "libbz2 not found in expected location"
257
258 # Verify gettext installation
259 echo "Checking gettext installation:"
260 ls -la $(brew --prefix gettext)/include/libintl.h || echo "libintl.h not found in expected location"
261 ls -la $(brew --prefix gettext)/lib/libintl.* || echo "libintl not found in expected location"
262
263 # Verify OpenLDAP installation
264 echo "Checking OpenLDAP installation:"
265 ls -la $(brew --prefix openldap)/include/ldap.h || echo "ldap.h not found in expected location"
266 ls -la $(brew --prefix openldap)/lib/libldap.* || echo "libldap not found in expected location"
267 ls -la $(brew --prefix openldap)/lib/liblber.* || echo "liblber not found in expected location"
268 echo "OpenLDAP include directory contents:"
269 ls -la $(brew --prefix openldap)/include/ | head -10
270 echo "OpenLDAP lib directory contents:"
271 ls -la $(brew --prefix openldap)/lib/ | head -10
272
273 # Create symlinks to help PHP find readline, bzip2, gettext, and openldap
274 echo "Creating symlinks for readline, bzip2, gettext, and openldap:"
275 sudo mkdir -p /usr/local/include/readline /usr/local/lib
276 sudo ln -sf $(brew --prefix readline)/include/readline/readline.h /usr/local/include/readline/readline.h
277 sudo ln -sf $(brew --prefix readline)/include/readline/history.h /usr/local/include/readline/history.h
278 sudo ln -sf $(brew --prefix readline)/lib/libreadline.* /usr/local/lib/
279 sudo ln -sf $(brew --prefix bzip2)/include/bzlib.h /usr/local/include/bzlib.h
280 sudo ln -sf $(brew --prefix bzip2)/lib/libbz2.* /usr/local/lib/
281 sudo ln -sf $(brew --prefix gettext)/include/libintl.h /usr/local/include/libintl.h
282 sudo ln -sf $(brew --prefix gettext)/lib/libintl.* /usr/local/lib/
283 sudo ln -sf $(brew --prefix openldap)/include/ldap.h /usr/local/include/ldap.h
284 sudo ln -sf $(brew --prefix openldap)/lib/libldap.* /usr/local/lib/
285 sudo ln -sf $(brew --prefix openldap)/lib/liblber.* /usr/local/lib/
286
287 - name: Create build configuration
288 run: |
289 mkdir -p ${{ env.BUILD_DIR }} ${{ env.OUTPUT_DIR }}
290
291 # Determine libpq prefix only on macOS (avoid brew on Linux)
292 PG_PREFIX=""
293 if [[ "$" == "darwin" ]]; then
294 PG_PREFIX="$(brew --prefix libpq)"
172 # macOS: Let Launchpad handle all dependencies
173 echo "� macOS build will use Launchpad for all dependencies"
174 echo "� Installing PHP dependencies via Launchpad first..."
175
176 # Pre-install dependencies to ensure they're available
177 echo "🔧 Pre-installing dependencies via Launchpad..."
178 bun run launchpad install php --deps-only
179
180 # Wait for dependencies to be fully installed
181 echo "⏳ Waiting for dependency installation to complete..."
182 sleep 10
183
184 # Debug: Check what was actually installed
185 echo "🔍 Checking installed dependencies..."
186 echo "📁 .local directory structure (first level):"
187 find "$HOME/.local" -maxdepth 2 -type d | sort | head -20
188
189 echo "🔍 Looking for pkg-config specifically..."
190 find "$HOME/.local" -name "*pkg*" -type f 2>/dev/null | head -10 || echo "No pkg-related files found"
191
192 echo "🔍 Looking for freedesktop.org directory..."
193 find "$HOME/.local" -path "*freedesktop*" -type d 2>/dev/null | head -5 || echo "No freedesktop.org directories found"
194
195 # Debug: Check if pkg-config is available
196 echo "🔍 Checking for pkg-config..."
197 if command -v pkg-config >/dev/null 2>&1; then
198 echo "✅ pkg-config found: $(which pkg-config)"
199 echo "📋 pkg-config version: $(pkg-config --version)"
200 else
201 echo "❌ pkg-config not found in PATH"
202 echo "🔍 Searching for pkg-config in .local..."
203 find "$HOME/.local" -name "pkg-config" -type f 2>/dev/null || echo "No pkg-config found in .local"
295204 fi
296205
297 # Create configuration based on matrix config
298 case "$" in
299 "laravel-mysql")
300 # For PHP 8.1, disable intl extension to avoid ICU4C C++17 issues
301 if [[ "$" == 8.1* ]]; then
302 EXTENSIONS="--enable-cli --enable-fpm --enable-mbstring --enable-opcache --enable-exif --enable-bcmath --with-pdo-mysql --with-mysqli --with-curl --with-openssl --enable-gd --with-zip --with-readline --with-libxml --with-zlib"
303 else
304 EXTENSIONS="--enable-cli --enable-fpm --enable-mbstring --enable-opcache --enable-intl --enable-exif --enable-bcmath --with-pdo-mysql --with-mysqli --with-curl --with-openssl --enable-gd --with-zip --with-readline --with-libxml --with-zlib"
305 fi
306 ;;
307 "laravel-postgres")
308 # For PHP 8.1, disable intl extension to avoid ICU4C C++17 issues
309 if [[ "$" == 8.1* ]]; then
310 EXTENSIONS="--enable-cli --enable-fpm --enable-mbstring --enable-opcache --enable-exif --enable-bcmath --with-pdo-pgsql${PG_PREFIX:+=$PG_PREFIX} --with-pgsql${PG_PREFIX:+=$PG_PREFIX} --with-curl --with-openssl --enable-gd --with-zip --with-readline --with-libxml --with-zlib"
311 else
312 EXTENSIONS="--enable-cli --enable-fpm --enable-mbstring --enable-opcache --enable-intl --enable-exif --enable-bcmath --with-pdo-pgsql${PG_PREFIX:+=$PG_PREFIX} --with-pgsql${PG_PREFIX:+=$PG_PREFIX} --with-curl --with-openssl --enable-gd --with-zip --with-readline --with-libxml --with-zlib"
313 fi
314 ;;
315 "laravel-sqlite")
316 # For PHP 8.1, disable intl extension to avoid ICU4C C++17 issues
317 if [[ "$" == 8.1* ]]; then
318 EXTENSIONS="--enable-cli --enable-fpm --enable-mbstring --enable-opcache --enable-exif --enable-bcmath --with-pdo-sqlite --with-sqlite3 --with-curl --with-openssl --enable-gd --with-zip --with-readline --with-libxml --with-zlib"
319 else
320 EXTENSIONS="--enable-cli --enable-fpm --enable-mbstring --enable-opcache --enable-intl --enable-exif --enable-bcmath --with-pdo-sqlite --with-sqlite3 --with-curl --with-openssl --enable-gd --with-zip --with-readline --with-libxml --with-zlib"
321 fi
322 ;;
323 "api-only")
324 EXTENSIONS="--enable-cli --enable-fpm --enable-mbstring --enable-opcache --enable-bcmath --with-pdo-mysql --with-mysqli --with-curl --with-openssl --with-zip --with-libxml --with-zlib"
325 ;;
326 "enterprise")
327 # For PHP 8.1, disable intl extension to avoid ICU4C C++17 issues
328 if [[ "$" == 8.1* ]]; then
329 EXTENSIONS="--enable-cli --enable-fpm --enable-mbstring --enable-opcache --enable-exif --enable-bcmath --with-pdo-mysql --with-pdo-pgsql${PG_PREFIX:+=$PG_PREFIX} --with-pdo-sqlite --with-mysqli --with-pgsql${PG_PREFIX:+=$PG_PREFIX} --with-sqlite3 --with-curl --with-openssl --enable-gd --enable-soap --enable-sockets --with-zip --with-bz2 --with-readline --with-libxml --with-zlib --enable-pcntl --enable-posix --with-gettext --with-gmp --with-ldap --with-xsl --with-sodium"
330 else
331 EXTENSIONS="--enable-cli --enable-fpm --enable-mbstring --enable-opcache --enable-intl --enable-exif --enable-bcmath --with-pdo-mysql --with-pdo-pgsql${PG_PREFIX:+=$PG_PREFIX} --with-pdo-sqlite --with-mysqli --with-pgsql${PG_PREFIX:+=$PG_PREFIX} --with-sqlite3 --with-curl --with-openssl --enable-gd --enable-soap --enable-sockets --with-zip --with-bz2 --with-readline --with-libxml --with-zlib --enable-pcntl --enable-posix --with-gettext --with-gmp --with-ldap --with-xsl --with-sodium"
332 fi
333 ;;
334 "wordpress")
335 EXTENSIONS="--enable-cli --enable-fpm --enable-mbstring --enable-opcache --enable-exif --with-pdo-mysql --with-mysqli --with-curl --with-openssl --enable-gd --with-zip --with-libxml --with-zlib"
336 ;;
337 "full-stack")
338 # Comprehensive configuration with all major database drivers and extensions for local testing
339 # For PHP 8.1, disable intl extension to avoid ICU4C C++17 issues
340 if [[ "$" == 8.1* ]]; then
341 EXTENSIONS="--enable-cli --enable-fpm --enable-mbstring --enable-opcache --enable-exif --enable-bcmath --enable-calendar --enable-ftp --enable-sysvmsg --enable-sysvsem --enable-sysvshm --enable-wddx --with-pdo-mysql --with-pdo-pgsql${PG_PREFIX:+=$PG_PREFIX} --with-pdo-sqlite --with-mysqli --with-pgsql${PG_PREFIX:+=$PG_PREFIX} --with-sqlite3 --with-curl --with-openssl --enable-gd --enable-soap --enable-sockets --with-zip --with-bz2 --with-readline --with-libxml --with-zlib --enable-pcntl --enable-posix --with-gettext --with-gmp --with-ldap --with-xsl --with-sodium --with-iconv --enable-fileinfo --enable-json --enable-phar --enable-filter --enable-hash --enable-session --enable-tokenizer --enable-ctype --enable-dom --enable-simplexml --enable-xml --enable-xmlreader --enable-xmlwriter --enable-shmop"
342 else
343 EXTENSIONS="--enable-cli --enable-fpm --enable-mbstring --enable-opcache --enable-intl --enable-exif --enable-bcmath --enable-calendar --enable-ftp --enable-sysvmsg --enable-sysvsem --enable-sysvshm --enable-wddx --with-pdo-mysql --with-pdo-pgsql${PG_PREFIX:+=$PG_PREFIX} --with-pdo-sqlite --with-mysqli --with-pgsql${PG_PREFIX:+=$PG_PREFIX} --with-sqlite3 --with-curl --with-openssl --enable-gd --enable-soap --enable-sockets --with-zip --with-bz2 --with-readline --with-libxml --with-zlib --enable-pcntl --enable-posix --with-gettext --with-gmp --with-ldap --with-xsl --with-sodium --with-iconv --enable-fileinfo --enable-json --enable-phar --enable-filter --enable-hash --enable-session --enable-tokenizer --enable-ctype --enable-dom --enable-simplexml --enable-xml --enable-xmlreader --enable-xmlwriter --enable-shmop"
344 fi
345 ;;
346 esac
206 # Debug: Check if ICU libraries are available
207 echo "🔍 Checking for ICU libraries..."
208 if [ -d "$HOME/.local/unicode.org" ]; then
209 echo "✅ ICU libraries found at: $HOME/.local/unicode.org"
210 ls -la "$HOME/.local/unicode.org/"
211 if [ -f "$HOME/.local/unicode.org"/*/lib/pkgconfig/icu-uc.pc ]; then
212 echo "✅ ICU pkgconfig files found"
213 find "$HOME/.local/unicode.org" -name "*.pc" -type f | head -5
214 else
215 echo "❌ ICU pkgconfig files not found"
216 fi
217 else
218 echo "❌ ICU libraries not found"
219 fi
347220
348 echo "CONFIGURE_EXTENSIONS=$EXTENSIONS" >> $GITHUB_ENV
221 # Debug: Check libxml2 libraries
222 echo "🔍 Checking for libxml2 libraries..."
223 if [ -d "$HOME/.local/gnome.org/libxml2" ]; then
224 echo "✅ libxml2 libraries found at: $HOME/.local/gnome.org/libxml2"
225 ls -la "$HOME/.local/gnome.org/libxml2/"
226 if [ -f "$HOME/.local/gnome.org/libxml2"/*/lib/pkgconfig/libxml-2.0.pc ]; then
227 echo "✅ libxml2 pkgconfig files found"
228 find "$HOME/.local/gnome.org/libxml2" -name "libxml-2.0.pc" -type f
229 else
230 echo "❌ libxml2 pkgconfig files not found"
231 fi
232 else
233 echo "❌ libxml2 libraries not found"
234 fi
349235
350 - name: Set macOS specific paths
351 if: matrix.platform == 'darwin'
352 run: |
353 # Set paths for Homebrew dependencies including keg-only packages
354 # Use a more organized approach to avoid duplicates
355 PKG_CONFIG_PATHS=(
356 "$(brew --prefix)/lib/pkgconfig"
357 "$(brew --prefix openssl@3)/lib/pkgconfig"
358 "$(brew --prefix libxml2)/lib/pkgconfig"
359 "$(brew --prefix icu4c)/lib/pkgconfig"
360 "$(brew --prefix zlib)/lib/pkgconfig"
361 "$(brew --prefix postgresql@17)/lib/pkgconfig"
362 "$(brew --prefix libpq)/lib/pkgconfig"
363 "$(brew --prefix bzip2)/lib/pkgconfig"
364 "$(brew --prefix gettext)/lib/pkgconfig"
365 "$(brew --prefix openldap)/lib/pkgconfig"
366 )
367 PKG_CONFIG_PATH_JOINED=$(IFS=:; echo "${PKG_CONFIG_PATHS[*]}")
368 echo "PKG_CONFIG_PATH=$PKG_CONFIG_PATH_JOINED" >> $GITHUB_ENV
369 export PKG_CONFIG_PATH="$PKG_CONFIG_PATH_JOINED"
370
371 PATH_PATHS=(
372 "$(brew --prefix bison)/bin"
373 "$(brew --prefix)/bin"
374 "$(brew --prefix libpq)/bin"
375 "$(brew --prefix postgresql@17)/bin"
376 "$(brew --prefix gettext)/bin"
377 )
378 PATH_JOINED=$(IFS=:; echo "${PATH_PATHS[*]}")
379 echo "PATH=$PATH_JOINED:$PATH" >> $GITHUB_ENV
380 export PATH="$PATH_JOINED:$PATH"
381
382 LDFLAGS_PATHS=(
383 "-L$(brew --prefix)/lib"
384 "-L$(brew --prefix openssl@3)/lib"
385 "-L$(brew --prefix zlib)/lib"
386 "-L$(brew --prefix libiconv)/lib"
387 "-L$(brew --prefix libpq)/lib"
388 "-L$(brew --prefix bzip2)/lib"
389 "-L$(brew --prefix gettext)/lib"
390 "-L$(brew --prefix openldap)/lib"
391 )
392 LDFLAGS_JOINED=$(IFS=' '; echo "${LDFLAGS_PATHS[*]}")
393 echo "LDFLAGS=$LDFLAGS_JOINED" >> $GITHUB_ENV
394 export LDFLAGS="$LDFLAGS_JOINED"
395
396 CPPFLAGS_PATHS=(
397 "-I$(brew --prefix)/include"
398 "-I$(brew --prefix openssl@3)/include"
399 "-I$(brew --prefix zlib)/include"
400 "-I$(brew --prefix libiconv)/include"
401 "-I$(brew --prefix libpq)/include"
402 "-I$(brew --prefix bzip2)/include"
403 "-I$(brew --prefix gettext)/include"
404 "-I$(brew --prefix openldap)/include"
405 )
406 CPPFLAGS_JOINED=$(IFS=' '; echo "${CPPFLAGS_PATHS[*]}")
407 echo "CPPFLAGS=$CPPFLAGS_JOINED" >> $GITHUB_ENV
408 export CPPFLAGS="$CPPFLAGS_JOINED"
409 echo "CXXFLAGS=-std=c++17 -stdlib=libc++" >> $GITHUB_ENV
410 export CXXFLAGS="-std=c++17 -stdlib=libc++"
411
412 # Set readline-specific paths
413 echo "READLINE_CFLAGS=-I$(brew --prefix readline)/include" >> $GITHUB_ENV
414 echo "READLINE_LIBS=-L$(brew --prefix readline)/lib -lreadline" >> $GITHUB_ENV
415 export READLINE_CFLAGS="-I$(brew --prefix readline)/include"
416 export READLINE_LIBS="-L$(brew --prefix readline)/lib -lreadline"
417
418 # Ensure libpq is linked for pg_config availability (keg-only)
419 brew link libpq --force || true
420
421 # Check if PostgreSQL is available and working
422 echo "Debug: Checking PostgreSQL availability:"
423 echo " PATH: $PATH"
424 echo " Checking pg_config:"
425 which pg_config || echo " pg_config not found in PATH"
426 pg_config --version 2>/dev/null || echo " pg_config version check failed"
427 echo " Checking libpq-fe.h:"
428 ls -la $(brew --prefix libpq)/include/libpq-fe.h 2>/dev/null || echo " libpq-fe.h not found"
429 echo " Checking libpq installation:"
430 ls -la $(brew --prefix libpq)/include/ 2>/dev/null | head -5 || echo " libpq include directory not found"
431 ls -la $(brew --prefix libpq)/lib/ 2>/dev/null | head -5 || echo " libpq lib directory not found"
432
433 if which pg_config >/dev/null 2>&1 && [[ -f "$(brew --prefix libpq)/include/libpq-fe.h" ]]; then
434 echo "PostgreSQL found and working"
435 echo "POSTGRESQL_AVAILABLE=true" >> $GITHUB_ENV
236 # Debug: Check PATH and PKG_CONFIG_PATH
237 echo "🔍 Environment check:"
238 echo "PATH includes unicode.org: $(echo $PATH | grep -o unicode.org || echo 'NO')"
239 echo "PATH includes freedesktop.org: $(echo $PATH | grep -o freedesktop.org || echo 'NO')"
240 echo "PKG_CONFIG_PATH: ${PKG_CONFIG_PATH:-'NOT SET'}"
241
242 # Debug: Check if Launchpad environment script exists
243 echo "🔍 Checking for Launchpad environment..."
244 if [ -f "$HOME/.local/launchpad.sh" ]; then
245 echo " Launchpad environment script found"
246 echo "📋 Sourcing environment to check paths..."
247 source "$HOME/.local/launchpad.sh"
248 echo "PATH after sourcing: ${PATH:0:200}..."
249 echo "PKG_CONFIG_PATH after sourcing: ${PKG_CONFIG_PATH:-'NOT SET'}"
436250 else
437 echo "PostgreSQL not found or not working, will disable PostgreSQL support"
438 echo "POSTGRESQL_AVAILABLE=false" >> $GITHUB_ENV
251 echo " Launchpad environment script not found"
439252 fi
440253
441 - name: Download and extract PHP source
254 - name: Install build dependencies (Windows)
255 if: matrix.platform == 'win32'
442256 run: |
443 cd ${{ env.BUILD_DIR }}
444 # Temporarily modify PATH to prioritize system binaries over launchpad binaries
445 # This prevents conflicts with launchpad-installed binaries that may have library dependencies
446 export PATH="/usr/bin:/usr/local/bin:/bin:$PATH"
447 # Use system curl instead of launchpad curl to avoid library conflicts
448 curl -fsSL "https://www.php.net/distributions/php-$.tar.gz" -o php.tar.gz
449 tar -xzf php.tar.gz
450 cd php-${{ matrix.php_version }}
451 echo "PHP_SOURCE_DIR=$/php-$" >> $GITHUB_ENV
452
453 - name: Configure PHP build
257 # Windows: Install Visual Studio Build Tools and dependencies for PHP compilation
258 choco install visualstudio2022buildtools --package-parameters "--add Microsoft.VisualStudio.Workload.VCTools --includeRecommended --includeOptional --passive"
259 choco install cmake --installargs 'ADD_CMAKE_TO_PATH=System'
260 choco install git
261 # Install additional dependencies needed for PHP extensions
262 echo "Windows build dependencies installed for PHP compilation"
263
264 - name: Setup Launchpad Environment (macOS)
265 if: matrix.platform == 'darwin'
266 shell: bash
454267 run: |
455 cd ${{ env.PHP_SOURCE_DIR }}
456
457 # Create installation directory
458 INSTALL_PREFIX="$/$"
459 mkdir -p "$INSTALL_PREFIX"
460
461 # Configure with platform-specific options
462 if [[ "$" == "darwin" ]]; then
463 # On macOS, use Homebrew-installed libraries
464 # Set environment variables for readline detection
465 export CPPFLAGS="$CPPFLAGS -I$(brew --prefix readline)/include"
466 export LDFLAGS="$LDFLAGS -L$(brew --prefix readline)/lib"
467 export LIBS="$LIBS -lreadline"
468
469 # Set PostgreSQL environment variables and PATH
470 export PGSQL_CFLAGS="-I$(brew --prefix libpq)/include"
471 export PGSQL_LIBS="-L$(brew --prefix libpq)/lib -lpq"
472 export PATH="$(brew --prefix libpq)/bin:$(brew --prefix postgresql@17)/bin:$PATH"
473
474 # Set bzip2 environment variables
475 export BZIP2_CFLAGS="-I$(brew --prefix bzip2)/include"
476 export BZIP2_LIBS="-L$(brew --prefix bzip2)/lib -lbz2"
477
478 # Set gettext environment variables
479 export GETTEXT_CFLAGS="-I$(brew --prefix gettext)/include"
480 export GETTEXT_LIBS="-L$(brew --prefix gettext)/lib -lintl"
481
482 # Check if both LDAP libraries are available
483 echo "Debug: Checking for lber library:"
484 ls -la $(brew --prefix openldap)/lib/liblber.* 2>/dev/null || echo " lber library not found"
485 echo "Debug: Checking for ldap library:"
486 ls -la $(brew --prefix openldap)/lib/libldap.* 2>/dev/null || echo " ldap library not found"
487
488 if [[ -f "$(brew --prefix openldap)/lib/liblber.dylib" ]] && [[ -f "$(brew --prefix openldap)/lib/libldap.dylib" ]]; then
489 echo "Both LDAP libraries found, enabling LDAP support"
490 LDAP_AVAILABLE=true
268 # Find and setup Launchpad environment variables
269 echo "🔧 Setting up Launchpad environment for macOS build..."
270
271 # Store original PATH to preserve system tools
272 echo "ORIGINAL_PATH=$PATH" >> $GITHUB_ENV
273
274 # Find all Launchpad binary directories that should be added to PATH
275 LAUNCHPAD_PATHS=""
276
277 # Find pkg-config binary - search broadly first
278 echo "🔍 Searching for pkg-config binary..."
279 PKG_CONFIG_BINARY=$(find "$HOME/.local" -name "pkg-config" -type f 2>/dev/null | head -1)
280 if [ -n "$PKG_CONFIG_BINARY" ]; then
281 PKG_CONFIG_DIR=$(dirname "$PKG_CONFIG_BINARY")
282 echo "✅ Found pkg-config at: $PKG_CONFIG_DIR"
283 LAUNCHPAD_PATHS="$PKG_CONFIG_DIR"
284 else
285 echo "❌ pkg-config binary not found in .local"
286 echo "🔍 Checking if pkg-config exists in system PATH..."
287 if command -v pkg-config >/dev/null 2>&1; then
288 echo "✅ pkg-config found in system PATH: $(which pkg-config)"
491289 else
492 echo "LDAP libraries not found, disabling LDAP support"
493 LDAP_AVAILABLE=false
494 # Remove LDAP from CONFIGURE_EXTENSIONS
495 export CONFIGURE_EXTENSIONS=$(echo "$CONFIGURE_EXTENSIONS" | sed 's/--with-ldap//g' | sed 's/ */ /g')
496 echo "Updated CONFIGURE_EXTENSIONS: $CONFIGURE_EXTENSIONS"
290 echo " pkg-config not found anywhere"
497291 fi
292 fi
498293
499 # Set OpenLDAP environment variables (only if libraries are available)
500 if [[ "$LDAP_AVAILABLE" == "true" ]]; then
501 export LDAP_CFLAGS="-I$(brew --prefix openldap)/include"
502 export LDAP_LIBS="-L$(brew --prefix openldap)/lib -lldap -llber"
503 echo "Debug: LDAP_CFLAGS=$LDAP_CFLAGS"
504 echo "Debug: LDAP_LIBS=$LDAP_LIBS"
505 else
506 # Clear LDAP environment variables if not available
507 unset LDAP_CFLAGS
508 unset LDAP_LIBS
509 echo "Debug: LDAP environment variables cleared"
294 # Find other essential Launchpad tools that might override system tools
295 # We'll be more selective to avoid overriding system tools
296 SED_BINARY=$(find "$HOME/.local" -path "*/gnu.org/sed/*/bin/sed" -type f 2>/dev/null | head -1)
297 if [ -n "$SED_BINARY" ]; then
298 SED_DIR=$(dirname "$SED_BINARY")
299 echo "✅ Found sed at: $SED_DIR"
300 # Only add sed if we have other tools too, to avoid conflicts
301 if [ -n "$LAUNCHPAD_PATHS" ]; then
302 LAUNCHPAD_PATHS="$LAUNCHPAD_PATHS:$SED_DIR"
510303 fi
304 fi
305
306 # Set the combined Launchpad paths (these will be prepended to PATH later)
307 if [ -n "$LAUNCHPAD_PATHS" ]; then
308 echo "LAUNCHPAD_BINARY_PATHS=$LAUNCHPAD_PATHS" >> $GITHUB_ENV
309 echo "✅ Launchpad binary paths: $LAUNCHPAD_PATHS"
310 else
311 echo "LAUNCHPAD_BINARY_PATHS=" >> $GITHUB_ENV
312 echo "❌ No Launchpad binary paths found - PATH will not be modified"
313 fi
511314
512 # Set C++ standard based on PHP version
513 # PHP 8.4+ requires C++17, earlier versions may work with C++14
514 PHP_MAJOR_VERSION=$(echo "$" | cut -d. -f1)
515 PHP_MINOR_VERSION=$(echo "$" | cut -d. -f2)
516
517 if [[ "$PHP_MAJOR_VERSION" -eq 8 && "$PHP_MINOR_VERSION" -ge 2 ]]; then
518 # PHP 8.2+ requires C++17
519 export CXXFLAGS="-std=c++17 -stdlib=libc++"
520 echo "Using C++17 for PHP $"
521 elif [[ "$PHP_MAJOR_VERSION" -eq 8 && "$PHP_MINOR_VERSION" -eq 1 ]]; then
522 # PHP 8.1 configure step requires C++14, but build step will need C++17 for ICU4C
523 export CXXFLAGS="-std=c++14 -stdlib=libc++"
524 echo "Using C++14 for PHP $ (configure step only)"
315 # Setup comprehensive PKG_CONFIG_PATH
316 PKG_PATHS=$(find "$HOME/.local" -name "pkgconfig" -type d 2>/dev/null | tr '\n' ':')
317 if [ -n "$PKG_PATHS" ]; then
318 echo "LAUNCHPAD_PKG_CONFIG_PATH=$PKG_PATHS" >> $GITHUB_ENV
319 echo "✅ PKG_CONFIG_PATH setup with $(echo "$PKG_PATHS" | tr ':' '\n' | wc -l) directories"
320 fi
321
322 - name: Build PHP
323 shell: bash
324 env:
325 PHP_VERSION: ${{ matrix.php_version }}
326 PHP_CONFIG: ${{ matrix.config }}
327 TARGET_PLATFORM: ${{ matrix.platform }}
328 TARGET_ARCH: ${{ matrix.arch }}
329 BUILD_DIR: ${{ github.workspace }}/build
330 OUTPUT_DIR: ${{ github.workspace }}/binaries
331 # Environment for all platforms - will handle PATH logic in shell script
332 PKG_CONFIG_PATH: ${{ matrix.platform == 'darwin' && env.LAUNCHPAD_PKG_CONFIG_PATH || env.PKG_CONFIG_PATH }}
333 run: |
334 # Setup PATH for macOS with Launchpad tools
335 if [ "$" = "darwin" ]; then
336 echo "🔧 Setting up macOS environment..."
337
338 # Preserve original PATH
339 ORIGINAL_PATH="$PATH"
340 echo "✅ Original PATH: ${ORIGINAL_PATH:0:100}..."
341
342 # Add Launchpad binary paths to PATH if they exist
343 if [ -n "${LAUNCHPAD_BINARY_PATHS:-}" ] && [ "${LAUNCHPAD_BINARY_PATHS}" != "NOT SET" ]; then
344 export PATH="$LAUNCHPAD_BINARY_PATHS:$ORIGINAL_PATH"
345 echo "✅ Updated PATH with Launchpad binaries: ${LAUNCHPAD_BINARY_PATHS}"
525346 else
526 # Earlier PHP versions can use C++14
527 export CXXFLAGS="-std=c++14 -stdlib=libc++"
528 echo "Using C++14 for PHP $"
347 echo "❌ No Launchpad binary paths found - using original PATH"
529348 fi
530349
531 # Keep CFLAGS clean for C compiler
532 export CFLAGS=""
533 export CPPFLAGS="$CPPFLAGS"
534 echo "Set C++ flags for configure step"
535 echo "CXXFLAGS: $CXXFLAGS"
536 echo "CFLAGS: $CFLAGS"
537 echo "CPPFLAGS: $CPPFLAGS"
538
539 # Ensure we're using clang++ on macOS
540 if command -v clang++ >/dev/null 2>&1; then
541 export CC=clang
542 export CXX=clang++
543 echo "Using clang/clang++ compilers"
544 echo "CC: $CC"
545 echo "CXX: $CXX"
546 fi
350 echo "✅ Final PATH: ${PATH:0:100}..."
351 echo "✅ PKG_CONFIG_PATH: ${PKG_CONFIG_PATH:-'NOT SET'}"
547352
548 # Verify C++ support based on PHP version
549 if [[ "$PHP_MAJOR_VERSION" -eq 8 && "$PHP_MINOR_VERSION" -ge 4 ]]; then
550 echo "Testing C++17 support before configure:"
551 echo '#include <type_traits>' > test_cpp.cpp
552 echo 'int main() { std::enable_if_t<true, int> x = 0; return x; }' >> test_cpp.cpp
553 if clang++ -std=c++17 -stdlib=libc++ test_cpp.cpp -o test_cpp 2>/dev/null; then
554 echo "C++17 support confirmed before configure"
555 rm -f test_cpp.cpp test_cpp
353 # Verify essential system tools are available
354 echo "🔧 Checking essential system tools..."
355 for tool in curl tar gzip grep tr find wc head; do
356 if command -v $tool >/dev/null 2>&1; then
357 echo "✅ $tool: $(which $tool)"
556358 else
557 echo "C++17 support test failed before configure"
558 rm -f test_cpp.cpp test_cpp
359 echo " $tool: NOT FOUND"
559360 fi
560 elif [[ "$PHP_MAJOR_VERSION" -eq 8 && "$PHP_MINOR_VERSION" -eq 1 ]]; then
561 echo "Testing C++14 support before configure (PHP 8.1 configure step):"
562 echo '#include <type_traits>' > test_cpp.cpp
563 echo 'int main() { typename std::enable_if<true, int>::type x = 0; return x; }' >> test_cpp.cpp
564 if clang++ -std=c++14 -stdlib=libc++ test_cpp.cpp -o test_cpp 2>/dev/null; then
565 echo "C++14 support confirmed before configure"
566 rm -f test_cpp.cpp test_cpp
361 done
362
363 # Verify pkg-config is accessible
364 echo "🔧 Checking pkg-config..."
365 if command -v pkg-config >/dev/null 2>&1; then
366 echo "✅ pkg-config is accessible: $(which pkg-config)"
367 echo "✅ pkg-config version: $(pkg-config --version)"
368
369 # Test libxml-2.0 specifically
370 if pkg-config --exists libxml-2.0; then
371 echo "✅ libxml-2.0 package found via pkg-config"
372 echo "📋 libxml-2.0 cflags: $(pkg-config --cflags libxml-2.0)"
567373 else
568 echo "C++14 support test failed before configure"
569 rm -f test_cpp.cpp test_cpp
374 echo " libxml-2.0 package not found via pkg-config"
375 echo "🔍 Available packages: $(pkg-config --list-all | head -10)"
570376 fi
571377 else
572 echo "Testing C++14 support before configure:"
573 echo '#include <type_traits>' > test_cpp.cpp
574 echo 'int main() { typename std::enable_if<true, int>::type x = 0; return x; }' >> test_cpp.cpp
575 if clang++ -std=c++14 -stdlib=libc++ test_cpp.cpp -o test_cpp 2>/dev/null; then
576 echo "C++14 support confirmed before configure"
577 rm -f test_cpp.cpp test_cpp
578 else
579 echo "C++14 support test failed before configure"
580 rm -f test_cpp.cpp test_cpp
581 fi
378 echo " pkg-config not accessible"
379 echo "🔍 Searching for pkg-config in .local..."
380 find "$HOME/.local" -name "pkg-config" -type f 2>/dev/null | head -3 || echo "No pkg-config binaries found"
582381 fi
583
584 # Try to find readline.h and set the path explicitly
585 READLINE_PATH=$(brew --prefix readline)
586 if [[ -f "$READLINE_PATH/include/readline/readline.h" ]]; then
587 echo "Found readline.h at $READLINE_PATH/include/readline/readline.h"
588 EXTRA_CONFIG="--with-iconv=$(brew --prefix libiconv) --with-readline=$READLINE_PATH"
589 else
590 echo "readline.h not found, disabling readline support"
591 EXTRA_CONFIG="--with-iconv=$(brew --prefix libiconv) --disable-readline"
592 fi
593
594 # Check if PostgreSQL is available and working
595 echo "Debug: POSTGRESQL_AVAILABLE=$POSTGRESQL_AVAILABLE"
596 if [[ "$POSTGRESQL_AVAILABLE" == "true" ]]; then
597 echo "PostgreSQL found and working"
598 else
599 if [[ "$" == "laravel-postgres" ]]; then
600 echo "❌ PostgreSQL not available; cannot build laravel-postgres binary on this runner"
601 exit 1
602 fi
603 echo "PostgreSQL not found or not working, will disable PostgreSQL support for non-postgres configs"
604 # Remove PostgreSQL extensions from CONFIGURE_EXTENSIONS
605 export CONFIGURE_EXTENSIONS=$(echo "$CONFIGURE_EXTENSIONS" | sed 's/--with-pdo-pgsql//g' | sed 's/--with-pgsql//g' | sed 's/ */ /g')
606 echo "Updated CONFIGURE_EXTENSIONS: $CONFIGURE_EXTENSIONS"
607 # Also disable PostgreSQL in the configuration
608 EXTRA_CONFIG="$EXTRA_CONFIG --disable-pgsql --disable-pdo-pgsql"
609 fi
610 else
611 # On Linux, use system-installed libraries
612 # System libraries should be available via apt-get installation
613 echo "Using system libraries installed via apt-get"
614 EXTRA_CONFIG=""
615382 fi
616383
617 echo "Configuring PHP with:"
618 echo " Extensions: $"
619 echo " Prefix: $INSTALL_PREFIX"
620 echo " Extra config: $EXTRA_CONFIG"
621
622 # Debug: Check readline installation on macOS
623 if [[ "$" == "darwin" ]]; then
624 echo "Debug: Checking readline installation on macOS:"
625 echo " READLINE_CFLAGS: $READLINE_CFLAGS"
626 echo " READLINE_LIBS: $READLINE_LIBS"
627 echo " CPPFLAGS: $CPPFLAGS"
628 echo " LDFLAGS: $LDFLAGS"
629 echo " Checking if readline.h exists:"
630 find $(brew --prefix) -name "readline.h" 2>/dev/null || echo " No readline.h found"
631
632 echo "Debug: Checking PostgreSQL installation on macOS:"
633 echo " PGSQL_CFLAGS: $PGSQL_CFLAGS"
634 echo " PGSQL_LIBS: $PGSQL_LIBS"
635 echo " PATH: $PATH"
636 echo " Checking if pg_config is available:"
637 which pg_config || echo " pg_config not found in PATH"
638 pg_config --version 2>/dev/null || echo " pg_config version check failed"
639 echo " Checking if libpq-fe.h exists:"
640 find $(brew --prefix) -name "libpq-fe.h" 2>/dev/null || echo " No libpq-fe.h found"
641 fi
384 # Run the build script with properly configured environment
385 bun run scripts/build-php.ts
642386
643 # Check if libcurl is found via pkg-config
644 if pkg-config --exists libcurl; then
645 echo "libcurl found via pkg-config"
646 CURL_CONFIG=""
647 else
648 echo "libcurl not found via pkg-config, using system curl"
649 CURL_CONFIG=""
387 - name: Create tarball (Unix)
388 if: matrix.platform != 'win32'
389 run: |
390 # Ensure binaries directory exists and check for builds
391 if [ ! -d "binaries" ]; then
392 echo " Binaries directory not found"
393 ls -la
394 exit 1
650395 fi
651396
652 # Build the final configure extensions based on availability
653 FINAL_EXTENSIONS="$"
397 cd binaries
398 BINARY_NAME="php-$-$-$-$"
654399
655 # If PostgreSQL is not available, remove PostgreSQL extensions
656 if [[ "$" == "darwin" ]] && [[ "$POSTGRESQL_AVAILABLE" != "true" ]]; then
657 echo "Removing PostgreSQL extensions from configure command"
658 FINAL_EXTENSIONS=$(echo "$FINAL_EXTENSIONS" | sed 's/--with-pdo-pgsql//g' | sed 's/--with-pgsql//g' | sed 's/ */ /g')
659 echo "Final extensions: $FINAL_EXTENSIONS"
660 fi
661
662 # Set PHP version variables for C++ standard selection
663 PHP_MAJOR_VERSION=$(echo "$" | cut -d. -f1)
664 PHP_MINOR_VERSION=$(echo "$" | cut -d. -f2)
665
666 echo "Configure environment:"
667 echo " CXXFLAGS: $CXXFLAGS"
668 echo " CFLAGS: $CFLAGS"
669 echo " CPPFLAGS: $CPPFLAGS"
670 echo " PHP Version: $ (Major: $PHP_MAJOR_VERSION, Minor: $PHP_MINOR_VERSION)"
671
672 # Test C++17 support before configure
673 if [[ "$" == "darwin" ]]; then
674 echo "Testing C++17 support before configure:"
675 echo '#include <type_traits>' > test_cpp17.cpp
676 echo 'int main() { std::enable_if_t<true, int> x = 0; return x; }' >> test_cpp17.cpp
677 if clang++ -std=c++17 -stdlib=libc++ test_cpp17.cpp -o test_cpp17 2>/dev/null; then
678 echo "C++17 support confirmed before configure"
679 rm -f test_cpp17.cpp test_cpp17
680 else
681 echo "C++17 support test failed before configure"
682 rm -f test_cpp17.cpp test_cpp17
683 fi
684 fi
400 echo "🔍 Looking for binary directory: $BINARY_NAME"
401 ls -la
685402
686 if [[ "$" == "darwin" ]]; then
687 # Set environment variables for configure
688 if [[ "$PHP_MAJOR_VERSION" -eq 8 && "$PHP_MINOR_VERSION" -ge 2 ]]; then
689 export CXXFLAGS="-std=c++17 -stdlib=libc++"
690 echo "Set C++17 for configure: $CXXFLAGS"
691 elif [[ "$PHP_MAJOR_VERSION" -eq 8 && "$PHP_MINOR_VERSION" -eq 1 ]]; then
692 # PHP 8.1 configure step uses C++14 (PHP requirement)
693 export CXXFLAGS="-std=c++14 -stdlib=libc++"
694 echo "Set C++14 for PHP 8.1 configure: $CXXFLAGS"
695 else
696 export CXXFLAGS="-std=c++14 -stdlib=libc++"
697 echo "Set C++14 for configure: $CXXFLAGS"
403 if [ -d "$BINARY_NAME" ]; then
404 # Create metadata file if it doesn't exist
405 if [ ! -f "$BINARY_NAME/metadata.json" ]; then
406 echo '{"php_version":"$","platform":"$","arch":"$","config":"$","built_at":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'"}' > "$BINARY_NAME/metadata.json"
698407 fi
699 export CFLAGS=""
700 export CPPFLAGS="$CPPFLAGS"
701
702 # Also set CC and CXX explicitly
703 export CC=clang
704 export CXX=clang++
705 echo "Set CC=$CC, CXX=$CXX"
706 fi
707408
708 # Run configure with explicit environment
709 if [[ "$" == "darwin" ]]; then
710 CXXFLAGS="$CXXFLAGS" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" CC="$CC" CXX="$CXX" ./configure \
711 --prefix="$INSTALL_PREFIX" \
712 --with-config-file-path="$INSTALL_PREFIX/lib" \
713 --with-config-file-scan-dir="$INSTALL_PREFIX/lib/conf.d" \
714 --disable-debug \
715 --enable-shared \
716 --with-pic \
717 $FINAL_EXTENSIONS \
718 $EXTRA_CONFIG \
719 $CURL_CONFIG
409 # Create tarball
410 tar -czf "$BINARY_NAME.tar.gz" "$BINARY_NAME"
411 echo "✅ Created tarball: $BINARY_NAME.tar.gz"
412 ls -lh "$BINARY_NAME.tar.gz"
720413 else
721 ./configure \
722 --prefix="$INSTALL_PREFIX" \
723 --with-config-file-path="$INSTALL_PREFIX/lib" \
724 --with-config-file-scan-dir="$INSTALL_PREFIX/lib/conf.d" \
725 --disable-debug \
726 --enable-shared \
727 --with-pic \
728 $FINAL_EXTENSIONS \
729 $EXTRA_CONFIG \
730 $CURL_CONFIG
731 fi
732
733 # Check the generated Makefile for C++ flags
734 if [[ "$" == "darwin" ]]; then
735 echo "Checking Makefile for C++ flags:"
736 grep -E "CXXFLAGS|CXX|std=" Makefile | head -10 || echo "No C++ flags found in Makefile"
414 echo "❌ Binary directory not found: $BINARY_NAME"
415 echo "Available directories:"
416 ls -la
417 exit 1
737418 fi
738419
739 - name: Build PHP
420 - name: Create tarball (Windows)
421 if: matrix.platform == 'win32'
740422 run: |
741 cd ${{ env.PHP_SOURCE_DIR }}
742
743 # Use all available CPU cores for faster builds
744 if [[ "$" == "darwin" ]]; then
745 JOBS=$(sysctl -n hw.ncpu)
746 # Set C++ standard based on PHP version for build
747 PHP_MAJOR_VERSION=$(echo "$" | cut -d. -f1)
748 PHP_MINOR_VERSION=$(echo "$" | cut -d. -f2)
749
750 if [[ "$PHP_MAJOR_VERSION" -eq 8 && "$PHP_MINOR_VERSION" -ge 2 ]]; then
751 export CXXFLAGS="-std=c++17 -stdlib=libc++"
752 echo "Set C++17 flags for macOS build"
753 elif [[ "$PHP_MAJOR_VERSION" -eq 8 && "$PHP_MINOR_VERSION" -eq 1 ]]; then
754 # PHP 8.1 needs C++17 for ICU4C compilation
755 export CXXFLAGS="-std=c++17 -stdlib=libc++"
756 echo "Set C++17 flags for PHP 8.1 (ICU4C compatibility)"
757 else
758 export CXXFLAGS="-std=c++14 -stdlib=libc++"
759 echo "Set C++14 flags for macOS build"
760 fi
761
762 # Keep CFLAGS clean for C compiler
763 export CFLAGS=""
764 export CPPFLAGS="$CPPFLAGS"
765 else
766 JOBS=$(nproc)
767 fi
423 # Ensure binaries directory exists and check for builds
424 if (-not (Test-Path -Path "binaries" -PathType Container)) {
425 Write-Host "❌ Binaries directory not found"
426 Get-ChildItem
427 exit 1
428 }
768429
769 echo "Building PHP with $JOBS parallel jobs"
770 echo "CXXFLAGS: $CXXFLAGS"
771 echo "CFLAGS: $CFLAGS"
772 echo "CPPFLAGS: $CPPFLAGS"
773
774 # Show what compiler is being used
775 echo "Compiler being used:"
776 which gcc || which clang || echo "No compiler found"
777 echo "C++ compiler:"
778 which g++ || which clang++ || echo "No C++ compiler found"
779
780 # Show compiler version and flags
781 echo "Compiler info:"
782 which gcc || which clang || echo "No compiler found"
783 gcc --version 2>/dev/null || clang --version 2>/dev/null || echo "Could not get compiler version"
784
785 # Check available C++ standards
786 echo "Checking available C++ standards:"
787 if command -v clang++ >/dev/null 2>&1; then
788 echo "Available C++ standards for clang++:"
789 clang++ --help | grep -E "std=" || echo "Could not determine available standards"
790 fi
430 cd binaries
431 $BINARY_NAME = "php-$-$-$-$"
432
433 Write-Host "🔍 Looking for binary directory: $BINARY_NAME"
434 Get-ChildItem
435
436 if (Test-Path -Path $BINARY_NAME -PathType Container) {
437 # Create metadata file if it doesn't exist
438 if (-not (Test-Path -Path "$BINARY_NAME\metadata.json")) {
439 $metadata = @{
440 php_version = "$"
441 platform = "$"
442 arch = "$"
443 config = "$"
444 built_at = (Get-Date -Format "yyyy-MM-ddTHH:mm:ssZ")
445 } | ConvertTo-Json
446 $metadata | Out-File -FilePath "$BINARY_NAME\metadata.json" -Encoding UTF8
447 }
448
449 # Create zip archive (Windows equivalent of tarball)
450 Compress-Archive -Path $BINARY_NAME -DestinationPath "$BINARY_NAME.zip" -Force
451 Write-Host "✅ Created archive: $BINARY_NAME.zip"
452 Get-ChildItem "$BINARY_NAME.zip" | Format-List Name, Length
453 } else {
454 Write-Host "❌ Binary directory not found: $BINARY_NAME"
455 Write-Host "Available directories:"
456 Get-ChildItem
457 exit 1
458 }
791459
792 # Test C++ support based on PHP version
793 PHP_MAJOR_VERSION=$(echo "$" | cut -d. -f1)
794 PHP_MINOR_VERSION=$(echo "$" | cut -d. -f2)
795
796 if [[ "$" == "darwin" ]]; then
797 if [[ "$PHP_MAJOR_VERSION" -eq 8 && "$PHP_MINOR_VERSION" -ge 2 ]]; then
798 echo "Testing C++17 support:"
799 echo '#include <type_traits>' > test_cpp.cpp
800 echo 'int main() { std::enable_if_t<true, int> x = 0; return x; }' >> test_cpp.cpp
801 if clang++ -std=c++17 -stdlib=libc++ test_cpp.cpp -o test_cpp 2>/dev/null; then
802 echo "C++17 support confirmed"
803 rm -f test_cpp.cpp test_cpp
804 else
805 echo "C++17 support test failed"
806 rm -f test_cpp.cpp test_cpp
807 fi
808 elif [[ "$PHP_MAJOR_VERSION" -eq 8 && "$PHP_MINOR_VERSION" -eq 1 ]]; then
809 echo "Testing C++17 support for PHP 8.1 (ICU4C compatibility):"
810 echo '#include <type_traits>' > test_cpp.cpp
811 echo 'int main() { std::enable_if_t<true, int> x = 0; return x; }' >> test_cpp.cpp
812 if clang++ -std=c++17 -stdlib=libc++ test_cpp.cpp -o test_cpp 2>/dev/null; then
813 echo "C++17 support confirmed for PHP 8.1"
814 rm -f test_cpp.cpp test_cpp
815 else
816 echo "C++17 support test failed for PHP 8.1"
817 rm -f test_cpp.cpp test_cpp
818 fi
819 else
820 echo "Testing C++14 support:"
821 echo '#include <type_traits>' > test_cpp.cpp
822 echo 'int main() { typename std::enable_if<true, int>::type x = 0; return x; }' >> test_cpp.cpp
823 if clang++ -std=c++14 -stdlib=libc++ test_cpp.cpp -o test_cpp 2>/dev/null; then
824 echo "C++14 support confirmed"
825 rm -f test_cpp.cpp test_cpp
460 - name: Test PHP Binary (Unix)
461 if: matrix.platform != 'win32'
462 run: |
463 BINARY_NAME="php-$-$-$-$"
464 if [ -f "binaries/$BINARY_NAME/bin/php" ]; then
465 echo "✅ PHP binary created successfully"
466 binaries/$BINARY_NAME/bin/php --version
467 echo "📋 All available extensions:"
468 binaries/$BINARY_NAME/bin/php -m
469
470 # Define essential extensions that MUST be present
471 REQUIRED_EXTENSIONS=(
472 "Core" "date" "hash" "json" "pcre" "Reflection" "SPL" "standard"
473 "mbstring" "iconv" "filter" "ctype" "tokenizer" "session" "fileinfo"
474 "phar" "dom" "xml" "xmlreader" "xmlwriter" "simplexml"
475 "curl" "openssl" "zip" "zlib" "calendar" "ftp" "pcntl" "posix"
476 "shmop" "sockets" "exif" "bcmath" "bz2" "gettext" "readline"
477 )
478
479 # Define Zend extensions that need special checking
480 ZEND_EXTENSIONS=("opcache")
481
482 # Test each required extension
483 echo "🧪 Testing essential extensions..."
484 MISSING_EXTENSIONS=()
485 for ext in "${REQUIRED_EXTENSIONS[@]}"; do
486 EXT_LOADED=$(binaries/$BINARY_NAME/bin/php -r "echo extension_loaded('$ext') ? '1' : '0';")
487 if [ "$EXT_LOADED" = "1" ]; then
488 echo "✅ $ext: LOADED"
826489 else
827 echo "C++14 support test failed"
828 rm -f test_cpp.cpp test_cpp
490 echo " $ext: MISSING"
491 MISSING_EXTENSIONS+=("$ext")
829492 fi
830 fi
831 fi
493 done
832494
833 # Pass compiler flags explicitly to make
834 if [[ "$" == "darwin" ]]; then
835 PHP_MAJOR_VERSION=$(echo "$" | cut -d. -f1)
836 PHP_MINOR_VERSION=$(echo "$" | cut -d. -f2)
837
838 if [[ "$PHP_MAJOR_VERSION" -eq 8 && "$PHP_MINOR_VERSION" -ge 2 ]]; then
839 echo "Making with explicit C++17 flags:"
840 echo " CXXFLAGS: -std=c++17 -stdlib=libc++"
841 echo " CFLAGS: (empty)"
842 echo " CPPFLAGS: $CPPFLAGS"
843 make -j$JOBS CXXFLAGS="-std=c++17 -stdlib=libc++" CFLAGS="" CPPFLAGS="$CPPFLAGS"
844 elif [[ "$PHP_MAJOR_VERSION" -eq 8 && "$PHP_MINOR_VERSION" -eq 1 ]]; then
845 echo "Making with explicit C++17 flags for PHP 8.1 (ICU4C compatibility):"
846 echo " CXXFLAGS: -std=c++17 -stdlib=libc++"
847 echo " CFLAGS: (empty)"
848 echo " CPPFLAGS: $CPPFLAGS"
849
850 # Force update Makefile for PHP 8.1 to use C++17
851 echo "Updating Makefile for PHP 8.1 C++17 compatibility..."
852 sed -i.bak 's/-std=c++14/-std=c++17/g' Makefile 2>/dev/null || echo "No C++14 flags found in Makefile to replace"
853 sed -i.bak 's/-std=gnu++14/-std=gnu++17/g' Makefile 2>/dev/null || echo "No gnu++14 flags found in Makefile to replace"
854
855 # Set environment variables to force C++17
856 export CXXFLAGS="-std=c++17 -stdlib=libc++"
857 export CFLAGS=""
858 export CC=clang
859 export CXX=clang++
860 echo "Final CXXFLAGS: $CXXFLAGS"
861
862 # Also update the Makefile to force C++17 for all compilation rules
863 echo "Forcing C++17 in all Makefile compilation rules..."
864 sed -i.bak 's/$(CXX) $(CFLAGS_CXX) $(CXXFLAGS) $(CPPFLAGS_CXX) $(CPPFLAGS) -c/$(CXX) $(CFLAGS_CXX) -std=c++17 -stdlib=libc++ $(CXXFLAGS) $(CPPFLAGS_CXX) $(CPPFLAGS) -c/g' Makefile 2>/dev/null || echo "Could not update Makefile compilation rules"
865
866 # Show what C++ flags are in the Makefile after all updates
867 echo "C++ flags in Makefile after all updates:"
868 grep -E "std=" Makefile | head -10 || echo "No std flags found in Makefile"
869
870 # Set system-wide C++17 flags
871 export CXXFLAGS="-std=c++17 -stdlib=libc++"
872 export CFLAGS=""
873 export CPPFLAGS="$CPPFLAGS"
874 export CC=clang
875 export CXX=clang++
876
877 # Test C++17 compilation before building
878 echo "Testing C++17 compilation before build:"
879 echo '#include <type_traits>' > test_cpp17.cpp
880 echo 'int main() { std::enable_if_t<true, int> x = 0; std::is_same_v<int, int> y = true; return 0; }' >> test_cpp17.cpp
881 if clang++ -std=c++17 -stdlib=libc++ test_cpp17.cpp -o test_cpp17 2>/dev/null; then
882 echo "C++17 compilation test passed"
883 rm -f test_cpp17.cpp test_cpp17
495 # Test Zend extensions separately
496 for ext in "${ZEND_EXTENSIONS[@]}"; do
497 EXT_LOADED=$(binaries/$BINARY_NAME/bin/php -r "echo function_exists('opcache_get_status') ? '1' : '0';")
498 if [ "$EXT_LOADED" = "1" ]; then
499 echo "✅ $ext: LOADED"
884500 else
885 echo "C++17 compilation test failed"
886 rm -f test_cpp17.cpp test_cpp17
501 echo " $ext: MISSING"
502 MISSING_EXTENSIONS+=("$ext")
887503 fi
504 done
888505
889 # Use a more aggressive approach - override the compiler
890 echo "Using aggressive C++17 enforcement..."
891
892 # Create a wrapper script that forces C++17
893 echo '#!/bin/bash' > cxx17_wrapper.sh
894 echo 'exec clang++ -std=c++17 -stdlib=libc++ "$@"' >> cxx17_wrapper.sh
895 chmod +x cxx17_wrapper.sh
506 # Check if any essential extensions are missing
507 if [ ${#MISSING_EXTENSIONS[@]} -gt 0 ]; then
508 echo "❌ Critical extensions missing: ${MISSING_EXTENSIONS[*]}"
509 echo "This build is incomplete and will cause issues with Composer and Laravel."
510 exit 1
511 fi
896512
897 # Use the wrapper script as the C++ compiler
898 make -j$JOBS CXXFLAGS="-std=c++17 -stdlib=libc++" CFLAGS="" CPPFLAGS="$CPPFLAGS" CC="clang" CXX="./cxx17_wrapper.sh"
513 # Test phar extension functionality specifically
514 echo "🧪 Testing phar extension functionality..."
515 PHAR_LOADED=$(binaries/$BINARY_NAME/bin/php -r 'echo extension_loaded("phar") ? "1" : "0";')
516 if [ "$PHAR_LOADED" = "1" ]; then
517 echo "✅ Phar extension is loaded"
518 # Test phar creation (essential for Composer)
519 echo "🧪 Testing phar creation..."
520 echo '<?php
521 if (extension_loaded("phar")) {
522 try {
523 $phar = new Phar("test.phar");
524 $phar->addFromString("test.txt", "Hello World");
525 echo "✅ Phar creation successful\n";
526 unlink("test.phar");
527 } catch (Exception $e) {
528 echo "❌ Phar creation failed: " . $e->getMessage() . "\n";
529 exit(1);
530 }
531 } else {
532 echo "❌ Phar extension not loaded\n";
533 exit(1);
534 }
535 ?>' > test_phar_create.php
536 binaries/$BINARY_NAME/bin/php -d phar.readonly=0 test_phar_create.php
537 rm test_phar_create.php
899538 else
900 echo "Making with explicit C++14 flags:"
901 echo " CXXFLAGS: -std=c++14 -stdlib=libc++"
902 echo " CFLAGS: (empty)"
903 echo " CPPFLAGS: $CPPFLAGS"
904 make -j$JOBS CXXFLAGS="-std=c++14 -stdlib=libc++" CFLAGS="" CPPFLAGS="$CPPFLAGS"
539 echo " Phar extension not loaded - this will break Composer!"
540 exit 1
905541 fi
542
543 # Test Composer compatibility
544 echo "🧪 Testing Composer compatibility..."
545 echo '<?php
546 // Test essential functions for Composer
547 $required_functions = [
548 "iconv", "mb_strlen", "filter_var", "hash", "json_encode",
549 "curl_init", "openssl_get_cert_locations", "file_get_contents"
550 ];
551
552 foreach ($required_functions as $func) {
553 if (function_exists($func)) {
554 echo "✅ Function $func: Available\n";
555 } else {
556 echo "❌ Function $func: Missing\n";
557 exit(1);
558 }
559 }
560
561 // Test essential classes
562 $required_classes = ["Phar", "DOMDocument", "XMLReader", "ZipArchive"];
563 foreach ($required_classes as $class) {
564 if (class_exists($class)) {
565 echo "✅ Class $class: Available\n";
566 } else {
567 echo "❌ Class $class: Missing\n";
568 exit(1);
569 }
570 }
571
572 echo "✅ All Composer compatibility checks passed\n";
573 ?>' > test_composer_compat.php
574 binaries/$BINARY_NAME/bin/php test_composer_compat.php
575 rm test_composer_compat.php
576
577 echo "✅ All PHP binary tests passed successfully!"
906578 else
907 make -j$JOBS
579 echo "❌ PHP binary not found"
580 exit 1
908581 fi
909582
910 - name: Install PHP
583 - name: Test PHP Binary (Windows)
584 if: matrix.platform == 'win32'
911585 run: |
912 cd ${{ env.PHP_SOURCE_DIR }}
913 make install
914
915 # Verify installation
916 INSTALL_PREFIX="$/$"
917 "$INSTALL_PREFIX/bin/php" --version
918 "$INSTALL_PREFIX/bin/php" -m # Show loaded modules
919
920 # Generate a default php.ini to ensure DB extensions are enabled by default
921 echo "Generating default php.ini for configuration: $"
922 EXT_DIR=$("$INSTALL_PREFIX/bin/php-config" --extension-dir 2>/dev/null || echo "")
923 PHP_INI_DIR="$INSTALL_PREFIX/lib"
924 mkdir -p "$PHP_INI_DIR"
925 PHP_INI="$PHP_INI_DIR/php.ini"
926 {
927 echo "; Launchpad php.ini (auto-generated in CI)"
928 echo "memory_limit = 512M"
929 echo "max_execution_time = 300"
930 echo "upload_max_filesize = 64M"
931 echo "post_max_size = 64M"
932 echo "display_errors = On"
933 echo "error_reporting = E_ALL"
934 if [ -n "$EXT_DIR" ]; then
935 echo "extension_dir = \"$EXT_DIR\""
936 fi
937 case "$" in
938 "laravel-postgres")
939 echo "extension=pdo_pgsql"
940 echo "extension=pgsql"
941 ;;
942 "laravel-mysql")
943 echo "extension=pdo_mysql"
944 echo "extension=mysqli"
945 ;;
946 "laravel-sqlite")
947 echo "extension=pdo_sqlite"
948 echo "extension=sqlite3"
949 ;;
950 "enterprise"|"full-stack")
951 echo "extension=pdo_pgsql"
952 echo "extension=pgsql"
953 echo "extension=pdo_mysql"
954 echo "extension=mysqli"
955 echo "extension=pdo_sqlite"
956 echo "extension=sqlite3"
957 ;;
958 *)
959 :
960 ;;
961 esac
962 } > "$PHP_INI"
963 echo "Created $PHP_INI"
964
965 - name: Create binary package
966 run: |
967 cd ${{ env.OUTPUT_DIR }}
968
969 # Create metadata file
970 cat > ${{ env.BINARY_NAME }}/metadata.json << EOF
971 {
972 "php_version": "$",
973 "platform": "$",
974 "architecture": "$",
975 "configuration": "$",
976 "built_at": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
977 "built_by": "GitHub Actions",
978 "commit": "$",
979 "extensions": "$(echo '$' | tr ' ' '\n' | grep -E '^--(enable|with)-' | sed 's/^--[^-]*-//' | sort | tr '\n' ',' | sed 's/,$//')"
586 $BINARY_NAME = "php-$-$-$-$"
587 $phpExeRoot = "binaries\$BINARY_NAME\php.exe"
588 $phpExeBin = "binaries\$BINARY_NAME\bin\php.exe"
589 $PHP = if (Test-Path -Path $phpExeRoot -PathType Leaf) { $phpExeRoot } elseif (Test-Path -Path $phpExeBin -PathType Leaf) { $phpExeBin } else { $null }
590 Write-Host "Checking for binary at: $PHP"
591
592 # List all files in the binary directory to verify structure
593 Write-Host "📂 Binary directory structure:"
594 Get-ChildItem -Path "binaries\$BINARY_NAME" -Recurse | Format-Table Name, Length, LastWriteTime
595
596 # Check if the PHP binary exists
597 if ($PHP -and (Test-Path -Path $PHP -PathType Leaf)) {
598 Write-Host "✅ PHP binary exists at expected location"
599
600 # Get file size to verify it's a real binary (not just a placeholder)
601 $fileSize = (Get-Item $PHP).Length
602 Write-Host "📊 PHP binary size: $fileSize bytes"
603
604 # Test PHP version and extensions
605 Write-Host "🧪 Testing PHP binary..."
606 & $PHP --version
607 Write-Host "📋 All available extensions:"
608 & $PHP -m
609
610 # Define essential extensions that MUST be present
611 $REQUIRED_EXTENSIONS = @(
612 "Core", "date", "hash", "json", "pcre", "Reflection", "SPL", "standard",
613 "mbstring", "iconv", "filter", "ctype", "tokenizer", "session", "fileinfo",
614 "phar", "dom", "xml", "xmlreader", "xmlwriter", "simplexml",
615 "curl", "openssl", "zip", "zlib", "calendar", "ftp",
616 "shmop", "sockets", "exif", "bcmath", "bz2", "gettext", "readline"
617 )
618
619 # Define Zend extensions that need special checking
620 $ZEND_EXTENSIONS = @("opcache")
621
622 # Test each required extension
623 Write-Host "🧪 Testing essential extensions..."
624 $MISSING_EXTENSIONS = @()
625 foreach ($ext in $REQUIRED_EXTENSIONS) {
626 $extLoaded = & $PHP -r "echo extension_loaded('$ext') ? '1' : '0';"
627 if ($extLoaded -eq "1") {
628 Write-Host "✅ $ext`: LOADED"
629 } else {
630 Write-Host "❌ $ext`: MISSING"
631 $MISSING_EXTENSIONS += $ext
632 }
633 }
634
635 # Test Zend extensions separately
636 foreach ($ext in $ZEND_EXTENSIONS) {
637 $extLoaded = & $PHP -r "echo function_exists('opcache_get_status') ? '1' : '0';"
638 if ($extLoaded -eq "1") {
639 Write-Host "✅ $ext`: LOADED"
640 } else {
641 Write-Host "❌ $ext`: MISSING"
642 $MISSING_EXTENSIONS += $ext
643 }
644 }
645
646 # Check if any essential extensions are missing
647 if ($MISSING_EXTENSIONS.Count -gt 0) {
648 Write-Host "❌ Critical extensions missing: $($MISSING_EXTENSIONS -join ', ')"
649 Write-Host "This build is incomplete and will cause issues with Composer and Laravel."
650 exit 1
651 }
652
653 # Test phar extension functionality specifically
654 Write-Host "🧪 Testing phar extension functionality..."
655 $pharLoaded = & $PHP -r 'echo extension_loaded("phar") ? "1" : "0";'
656 if ($pharLoaded -eq "1") {
657 Write-Host "✅ Phar extension is loaded"
658 # Test phar creation (essential for Composer)
659 Write-Host "🧪 Testing phar creation..."
660 $pharTest = & $PHP -d phar.readonly=0 -r 'try { $p = new Phar("test.phar"); $p->addFromString("t.txt", "x"); echo "OK"; unlink("test.phar"); } catch (Exception $e) { echo "ERR: ".$e->getMessage(); exit(1); }'
661 if ($pharTest -eq "OK") {
662 Write-Host "✅ Phar creation successful"
663 } else {
664 Write-Host "❌ Phar creation failed: $pharTest"
665 exit 1
666 }
667 } else {
668 Write-Host "❌ Phar extension not loaded - this will break Composer!"
669 exit 1
670 }
671
672 # Test Composer compatibility
673 Write-Host "🧪 Testing Composer compatibility..."
674 $composerTestContent = "<?php`n// Test essential functions for Composer`n`$required_functions = [`n `"iconv`", `"mb_strlen`", `"filter_var`", `"hash`", `"json_encode`",`n `"curl_init`", `"openssl_get_cert_locations`", `"file_get_contents`"`n];`n`nforeach (`$required_functions as `$func) {`n if (function_exists(`$func)) {`n echo `"✅ Function `$func: Available\n`";`n } else {`n echo `"❌ Function `$func: Missing\n`";`n exit(1);`n }`n}`n`n// Test essential classes`n`$required_classes = [`"Phar`", `"DOMDocument`", `"XMLReader`", `"ZipArchive`"];`nforeach (`$required_classes as `$class) {`n if (class_exists(`$class)) {`n echo `" Class `$class: Available\n`";`n } else {`n echo `" Class `$class: Missing\n`";`n exit(1);`n }`n}`n`necho `" All Composer compatibility checks passed\n`";`n?>"
675 $composerTestContent | Out-File -FilePath "test_composer_compat.php" -Encoding UTF8
676 & $PHP "test_composer_compat.php"
677 Remove-Item "test_composer_compat.php"
678
679 # Check if this is likely a real binary based on file size
680 if ($fileSize -gt 1000000) {
681 Write-Host "✅ PHP binary appears to be a real Windows binary (file size: $fileSize bytes)"
682
683 # Check for DLLs which should be present in a real PHP distribution
684 $dllCount = (Get-ChildItem -Path "binaries\$BINARY_NAME" -Filter "*.dll" -Recurse).Count
685 Write-Host "Found $dllCount DLL files in the PHP distribution"
686
687 if ($dllCount -gt 10) {
688 Write-Host "✅ PHP distribution contains expected DLL files"
689 } else {
690 Write-Host "⚠️ PHP distribution contains fewer DLL files than expected"
691 }
692 } else {
693 Write-Host "⚠️ PHP binary is smaller than expected, might be a placeholder"
694 }
695
696 Write-Host "✅ All PHP binary tests passed successfully!"
697 } else {
698 Write-Host "❌ PHP binary not found at expected location"
699 Write-Host "Directory contents:"
700 if (Test-Path -Path "binaries\$BINARY_NAME") {
701 Get-ChildItem -Path "binaries\$BINARY_NAME" -Recurse
702 } else {
703 Write-Host "Binary directory does not exist"
704 }
705 exit 1
980706 }
981 EOF
982
983 # Create tarball
984 tar -czf ${{ env.BINARY_NAME }}.tar.gz ${{ env.BINARY_NAME }}/
985707
986 # Show package info
987 echo "Created package: $.tar.gz"
988 ls -lh ${{ env.BINARY_NAME }}.tar.gz
989
990 - name: Upload binary artifact
708 - name: Upload PHP Binary (Unix)
709 if: matrix.platform != 'win32'
991710 uses: actions/upload-artifact@v4
992711 with:
993 name: ${{ env.BINARY_NAME }}
994 path: ${{ env.OUTPUT_DIR }}/${{ env.BINARY_NAME }}.tar.gz
995 retention-days: 90
712 name: php-${{ matrix.php_version }}-${{ matrix.platform }}-${{ matrix.arch }}-${{ matrix.config }}
713 path: binaries/php-${{ matrix.php_version }}-${{ matrix.platform }}-${{ matrix.arch }}-${{ matrix.config }}.tar.gz
714 retention-days: 30
996715
997 - name: Upload to GitHub Container Registry (Linux)
998 if: github.event_name == 'push' && github.ref == 'refs/heads/main' && matrix.platform == 'linux'
999 run: |
1000 echo ${{ secrets.GITHUB_TOKEN }} | docker login ${{ env.REGISTRY_URL }} -u ${{ env.REGISTRY_USERNAME }} --password-stdin
1001
1002 # Create a simple Dockerfile for the binary
1003 cd ${{ env.OUTPUT_DIR }}
1004 cat > Dockerfile << EOF
1005 FROM scratch
1006 COPY ${{ env.BINARY_NAME }}.tar.gz /php-binary.tar.gz
1007 EOF
1008
1009 # Build and push
1010 IMAGE_TAG="$/$/php-binaries:$"
1011 docker build -t "$IMAGE_TAG" .
1012 docker push "$IMAGE_TAG"
716 - name: Upload PHP Binary (Windows)
717 if: matrix.platform == 'win32'
718 uses: actions/upload-artifact@v4
719 with:
720 name: php-${{ matrix.php_version }}-${{ matrix.platform }}-${{ matrix.arch }}-${{ matrix.config }}
721 path: binaries/php-${{ matrix.php_version }}-${{ matrix.platform }}-${{ matrix.arch }}-${{ matrix.config }}.zip
722 retention-days: 30
1013723
1014724 # Release job to create GitHub releases with binaries
1015725 create-release:
1016 needs: [check-for-updates, build-matrix, get-php-versions]
726 needs: [check-for-updates, build, get-php-versions]
1017727 runs-on: ubuntu-latest
1018728 if: ((github.event_name == 'push' && github.ref == 'refs/heads/main') || github.event_name == 'workflow_dispatch') && (needs.check-for-updates.outputs.rebuild_needed == 'true' || github.event.inputs.force_rebuild == 'true')
1019729
@@ -1055,14 +765,15 @@ jobs:
1055765 echo "🔍 Current directory structure:"
1056766 ls -la
1057767 echo ""
1058 echo "🔍 Looking for tar.gz files:"
1059 find . -name "*.tar.gz" -type f
768 echo "🔍 Looking for binary files (tar.gz and zip):"
769 find . -name "*.tar.gz" -type f -o -name "*.zip" -type f
1060770 echo ""
1061771
1062772 # Create a temporary JSON array file
1063773 echo "[]" > binaries_array.json
1064774
1065 # Find all tar.gz files recursively and process them
775 # Process tar.gz files (Unix binaries)
776 echo "Processing Unix binaries (.tar.gz files)..."
1066777 for tarball in $(find . -name "*.tar.gz" -type f); do
1067778 filename=$(basename "$tarball")
1068779 size=$(stat -c%s "$tarball" 2>/dev/null || stat -f%z "$tarball")
@@ -1116,6 +827,70 @@ jobs:
1116827 mv temp_array.json binaries_array.json
1117828 done
1118829
830 # Process zip files (Windows binaries)
831 echo "Processing Windows binaries (.zip files)..."
832 for zipfile in $(find . -name "*.zip" -type f); do
833 filename=$(basename "$zipfile")
834 size=$(stat -c%s "$zipfile" 2>/dev/null || stat -f%z "$zipfile")
835
836 echo "Processing: $filename (size: $size bytes)"
837
838 # Parse the binary name to extract components
839 # Expected format: php-8.4.11-win32-x86_64-laravel-mysql.zip
840 binary_name=$(echo "$filename" | sed 's/\.zip$//')
841
842 # Extract components from binary name
843 if [[ "$binary_name" =~ ^php-([^-]+)-([^-]+)-([^-]+)-(.+)$ ]]; then
844 php_version="${BASH_REMATCH[1]}"
845 platform="${BASH_REMATCH[2]}"
846 architecture="${BASH_REMATCH[3]}"
847 configuration="${BASH_REMATCH[4]}"
848 else
849 # Fallback if pattern doesn't match
850 php_version="unknown"
851 platform="unknown"
852 architecture="unknown"
853 configuration="unknown"
854 fi
855
856 # Try to extract metadata from zip if possible
857 # This is more complex with zip files, so we'll use a simpler approach
858 # Create a temporary directory
859 temp_dir="temp_extract_$RANDOM"
860 mkdir -p "$temp_dir"
861
862 # Try to extract just the metadata file
863 unzip -q -j "$zipfile" "*/metadata.json" -d "$temp_dir" 2>/dev/null || echo '{}' > "$temp_dir/metadata.json"
864
865 # Create JSON object for this binary
866 binary_json=$(jq -n \
867 --arg filename "$filename" \
868 --arg size "$size" \
869 --arg php_version "$php_version" \
870 --arg platform "$platform" \
871 --arg architecture "$architecture" \
872 --arg configuration "$configuration" \
873 --arg built_at "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
874 --arg extensions "$(cat "$temp_dir/metadata.json" | jq -r '.extensions // ""' 2>/dev/null || echo '')" \
875 '{
876 filename: $filename,
877 size: ($size | tonumber),
878 php_version: $php_version,
879 platform: $platform,
880 architecture: $architecture,
881 configuration: $configuration,
882 built_at: $built_at,
883 extensions: $extensions
884 }')
885
886 # Add this binary to the array using jq
887 jq --argjson binary "$binary_json" '. += [$binary]' binaries_array.json > temp_array.json
888 mv temp_array.json binaries_array.json
889
890 # Clean up temp directory
891 rm -rf "$temp_dir"
892 done
893
1119894 # Create the final manifest with proper structure and sorted binaries
1120895 jq --arg version "$(date +%Y.%m.%d)" \
1121896 --arg built_at "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
@@ -1135,11 +910,13 @@ jobs:
1135910 cat manifest.json
1136911 echo ""
1137912 echo "📊 Summary:"
1138 echo " - Total binaries found: $(find . -name "*.tar.gz" -type f | wc -l)"
913 echo " - Unix binaries found: $(find . -name "*.tar.gz" -type f | wc -l)"
914 echo " - Windows binaries found: $(find . -name "*.zip" -type f | wc -l)"
915 echo " - Total binaries found: $(find . -name "*.tar.gz" -o -name "*.zip" -type f | wc -l)"
1139916 echo " - Manifest file size: $(stat -c%s manifest.json 2>/dev/null || stat -f%z manifest.json) bytes"
1140917
1141918 - name: Create GitHub Release
1142 uses: softprops/action-gh-release@v1
919 uses: softprops/action-gh-release@v2.3.3
1143920 with:
1144921 tag_name: binaries-${{ github.run_number }}
1145922 name: PHP Binaries - Build ${{ github.run_number }}
@@ -1148,7 +925,7 @@ jobs:
1148925
1149926 > This release contains precompiled PHP binaries optimized for modern PHP usage
1150927
1151 - **Platforms**: Linux (x86_64), macOS (ARM64 & Intel)
928 - **Platforms**: Linux (x86_64), macOS (ARM64 & Intel), Windows (x86_64)
1152929 - **PHP Versions**: ${{ steps.format-versions.outputs.php_versions_string }}
1153930 - **Configuration Options**:
1154931 - `laravel-mysql`: Laravel applications using MySQL or MariaDB
@@ -1168,6 +945,7 @@ jobs:
1168945 See `manifest.json` for detailed information about each binary.
1169946 files: |
1170947 binaries/**/*.tar.gz
948 binaries/**/*.zip
1171949 binaries/manifest.json
1172950 draft: false
1173951 prerelease: false