Build PHP (macOS) #13
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Build PHP (macOS) | |
| # Required repository secrets (same names as nativephp-php-bin-mobile): | |
| # R2_ACCESS_KEY_ID - Cloudflare R2 access key | |
| # R2_SECRET_ACCESS_KEY - Cloudflare R2 secret key | |
| permissions: | |
| contents: read | |
| on: | |
| schedule: | |
| # Every Friday at midnight UTC (matches the mobile build trigger). | |
| - cron: '0 0 * * 5' | |
| workflow_dispatch: | |
| inputs: | |
| version: | |
| description: 'PHP version to build' | |
| type: choice | |
| options: | |
| - all | |
| - "8.3" | |
| - "8.4" | |
| - "8.5" | |
| default: all | |
| env: | |
| SPC_VERSION: 2.8.5 | |
| SPC_BUILD_OS: mac | |
| # Each branch uploads to its own directory: main/, feature-x/, etc. | |
| R2_PREFIX: ${{ format('{0}/', github.ref_name) }} | |
| R2_ENDPOINT: https://713f4e1d515cf082921cdf5122bf1739.r2.cloudflarestorage.com | |
| R2_BUCKET: nativephplibs | |
| jobs: | |
| build: | |
| name: ${{ matrix.version }} ${{ matrix.os }} | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| version: ${{ fromJSON((github.event.inputs.version || 'all') == 'all' && '["8.3","8.4","8.5"]' || format('["{0}"]', github.event.inputs.version)) }} | |
| os: [macos-15-intel, macos-latest] | |
| include: | |
| - os: macos-15-intel | |
| arch: x64 | |
| spc_asset: spc-macos-x86_64.tar.gz | |
| - os: macos-latest | |
| arch: arm64 | |
| spc_asset: spc-macos-aarch64.tar.gz | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Download SPC | |
| shell: bash | |
| run: | | |
| cd .. | |
| curl -fsSL -o spc.tar.gz "https://github.com/crazywhalecc/static-php-cli/releases/download/${SPC_VERSION}/${{ matrix.spc_asset }}" | |
| tar -xzf spc.tar.gz | |
| chmod +x spc | |
| mkdir -p static-php-cli/bin | |
| mv spc static-php-cli/bin/ | |
| - name: Install build dependencies | |
| run: brew install automake gzip | |
| - name: Setup system PHP | |
| uses: shivammathur/setup-php@v2 | |
| with: | |
| php-version: 8.3 | |
| tools: pecl, composer | |
| extensions: curl, openssl, mbstring, sodium, tokenizer, filter | |
| ini-values: memory_limit=-1 | |
| - name: SPC doctor | |
| run: | | |
| cd ../static-php-cli | |
| ./bin/spc doctor | |
| - name: Read PHP extensions from file | |
| shell: bash | |
| run: | | |
| EXTENSIONS=$(php -r "echo trim(file_get_contents('php-extensions.txt'));") | |
| EXT_HASH=$(php -r "echo md5(getenv('EXTENSIONS'));") | |
| echo "PHP_EXTENSIONS=$EXTENSIONS" >> $GITHUB_ENV | |
| echo "PHP_EXT_HASH=$EXT_HASH" >> $GITHUB_ENV | |
| - name: Read PHP libraries from file | |
| shell: bash | |
| run: | | |
| LIBRARIES=$(php -r "echo trim(file_get_contents('php-libraries.txt'));") | |
| echo "PHP_LIBS=$LIBRARIES" >> $GITHUB_ENV | |
| - id: cache-spc-downloads | |
| uses: actions/cache@v5 | |
| with: | |
| path: ../static-php-cli/downloads | |
| key: spc-downloads-${{ env.PHP_EXT_HASH }} | |
| - name: Download PHP extension sources | |
| if: steps.cache-spc-downloads.outputs.cache-hit != 'true' | |
| run: | | |
| cd ../static-php-cli | |
| ./bin/spc download --with-php=${{ matrix.version }} --for-extensions "${{ env.PHP_EXTENSIONS }}" --prefer-pre-built | |
| - name: Build PHP | |
| run: | | |
| cd ../static-php-cli | |
| ./bin/spc build --build-cli "${{ env.PHP_EXTENSIONS }}" --with-libs="${{ env.PHP_LIBS }}" --debug | |
| - name: Get built PHP version | |
| shell: bash | |
| run: | | |
| PHP_VERSION_FULL=$(../static-php-cli/buildroot/bin/php -r "echo PHP_VERSION;") | |
| echo "PHP_VERSION_FULL=$PHP_VERSION_FULL" >> $GITHUB_ENV | |
| - name: Create bin directories | |
| run: | | |
| mkdir -p bin/${{ env.SPC_BUILD_OS }}/${{ matrix.arch }} | |
| mkdir -p license-files | |
| mkdir -p build-meta | |
| - name: Zip PHP binary, copy metadata | |
| shell: bash | |
| run: | | |
| rm -f bin/${{ env.SPC_BUILD_OS }}/${{ matrix.arch }}/php-${{ matrix.version }}.zip | |
| mkdir -p tmp-bin | |
| cp ../static-php-cli/buildroot/bin/php tmp-bin/ | |
| cd tmp-bin | |
| zip ../bin/${{ env.SPC_BUILD_OS }}/${{ matrix.arch }}/php-${{ matrix.version }}.zip php | |
| cd .. | |
| rm -rf tmp-bin | |
| cp ../static-php-cli/buildroot/license/* license-files/ | |
| cp ../static-php-cli/buildroot/build-extensions.json build-meta/build-extensions-${{ env.SPC_BUILD_OS }}.json | |
| cp ../static-php-cli/buildroot/build-libraries.json build-meta/build-libraries-${{ env.SPC_BUILD_OS }}.json | |
| # Upload the built zip (and a sha256 sidecar) to R2 instead of committing | |
| # it to git. Mirrors nativephp-php-bin-mobile/.github/workflows/build.yml: | |
| # same `aws s3 cp` tooling, R2_* secrets, endpoint and --cache-control. | |
| - name: Upload to R2 | |
| shell: bash | |
| env: | |
| AWS_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }} | |
| AWS_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }} | |
| AWS_DEFAULT_REGION: auto | |
| run: | | |
| ZIP="bin/${SPC_BUILD_OS}/${{ matrix.arch }}/php-${{ matrix.version }}.zip" | |
| DEST="${R2_PREFIX}desktop/${SPC_BUILD_OS}/${{ matrix.arch }}/php-${{ matrix.version }}.zip" | |
| # Compute the checksum and upload it as a sidecar first. | |
| SHA=$(shasum -a 256 "$ZIP" | awk '{print $1}') | |
| echo "$SHA $(basename "$ZIP")" > "$ZIP.sha256" | |
| echo "Uploading $ZIP -> ${DEST} (sha256=$SHA)" | |
| aws s3 cp "$ZIP" "s3://${R2_BUCKET}/${DEST}" \ | |
| --endpoint-url "$R2_ENDPOINT" \ | |
| --cache-control "public, max-age=31536000, immutable" | |
| aws s3 cp "$ZIP.sha256" "s3://${R2_BUCKET}/${DEST}.sha256" \ | |
| --endpoint-url "$R2_ENDPOINT" \ | |
| --content-type "text/plain" \ | |
| --cache-control "public, max-age=31536000, immutable" | |
| # Regenerate the branch manifest from everything currently in R2. Runs after | |
| # all build jobs; safe because it lists the whole bucket prefix, so it always | |
| # reflects every platform/version actually uploaded (mac, linux, win). | |
| manifest: | |
| needs: build | |
| # Run even if some matrix legs failed, so the manifest still reflects the | |
| # binaries that DID upload. Skip only on cancellation. The generator lists | |
| # the live bucket, so it never references a missing object. | |
| if: always() && needs.build.result != 'cancelled' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Generate and upload versions.json | |
| shell: bash | |
| env: | |
| AWS_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }} | |
| AWS_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }} | |
| AWS_DEFAULT_REGION: auto | |
| BUCKET: ${{ env.R2_BUCKET }} | |
| BASE_URL: https://bin.nativephp.com | |
| run: | | |
| chmod +x .github/scripts/generate-versions-json.sh | |
| .github/scripts/generate-versions-json.sh > versions.json | |
| echo "versions.json:" | |
| cat versions.json | |
| # Manifest LAST, after every binary it references is already in R2. | |
| aws s3 cp versions.json "s3://${R2_BUCKET}/${R2_PREFIX}desktop/versions.json" \ | |
| --endpoint-url "$R2_ENDPOINT" \ | |
| --content-type "application/json" \ | |
| --cache-control "no-cache, no-store" |