Skip to content

release

release #6

Workflow file for this run

name: release
# Manually triggered. Pass the version to cut (e.g. 0.1.0); the workflow builds
# the extension for each target and publishes a (draft) GitHub Release with the
# artifacts attached and auto-generated notes.
on:
workflow_dispatch:
inputs:
version:
description: 'Version to release, e.g. 0.1.0 (no leading v)'
required: true
type: string
draft:
description: 'Publish as a draft (review before going live)'
type: boolean
default: true
permissions:
contents: write # create the release
jobs:
# ──────────────────────────────────────────────────────────────────────
# Generic Linux — for self-hosted PHP / Docker on a modern distro.
# Built on Ubuntu 22.04 (glibc 2.35); ships the raw .so.
# ──────────────────────────────────────────────────────────────────────
linux:
name: linux ${{ matrix.arch }} · php ${{ matrix.php }}
runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false
matrix:
include:
- { php: '8.4', arch: x86_64, runner: ubuntu-22.04 }
- { php: '8.4', arch: aarch64, runner: ubuntu-22.04-arm }
- { php: '8.5', arch: x86_64, runner: ubuntu-22.04 }
- { php: '8.5', arch: aarch64, runner: ubuntu-22.04-arm }
steps:
- uses: actions/checkout@v4
- uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
env:
phpts: nts
- uses: dtolnay/rust-toolchain@1.96
# ubuntu-22.04 (kept for glibc 2.35 portability) defaults to clang 14,
# whose emmintrin.h trips a bindgen SSE2 intrinsics bug when parsing the
# PHP headers on x86_64. clang 15+ fixes it; aarch64 never hits it.
- run: sudo apt-get update && sudo apt-get install -y clang-15 libclang-15-dev
- name: Build
run: |
# The clang-14 emmintrin.h SSE2 bug is triggered by the *resource
# directory* (the compiler's builtin headers), not by which libclang
# loads — so pointing LIBCLANG_PATH at v15 isn't enough; bindgen still
# picks up clang-14's headers. Force clang-15's resource dir via
# bindgen's extra-args env, which pins emmintrin.h to the fixed copy.
dir="$(dirname "$(find /usr/lib /usr/lib64 -name 'libclang-15.so*' -print -quit 2>/dev/null)")"
[ -n "$dir" ] && [ "$dir" != "." ] || { echo "::error::libclang-15 not found"; exit 1; }
export LIBCLANG_PATH="$dir"
export BINDGEN_EXTRA_CLANG_ARGS="-resource-dir=$(clang-15 -print-resource-dir)"
echo "LIBCLANG_PATH=$LIBCLANG_PATH"
echo "BINDGEN_EXTRA_CLANG_ARGS=$BINDGEN_EXTRA_CLANG_ARGS"
cargo build --release
- name: Stage artifact
run: |
mkdir -p dist
cp target/release/libphp_quickjs.so \
"dist/php-quickjs-v${{ inputs.version }}-php${{ matrix.php }}-linux-${{ matrix.arch }}.so"
- uses: actions/upload-artifact@v4
with:
name: linux-${{ matrix.php }}-${{ matrix.arch }}
path: dist/*
# ──────────────────────────────────────────────────────────────────────
# AWS Lambda / Bref — built INSIDE the Bref Amazon Linux 2023 image so the
# binary loads on Lambda (glibc 2.34). Packaged as a Bref Lambda layer zip
# (extension + a conf.d ini) and also shipped as the raw .so.
# ──────────────────────────────────────────────────────────────────────
lambda-bref:
name: lambda/bref ${{ matrix.arch }} · php ${{ matrix.php }}
runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false
matrix:
# Bref publishes separate per-arch build images: bref/build-php-XX
# (x86_64) and bref/arm-build-php-XX (arm64).
include:
- { php: '8.4', arch: x86_64, runner: ubuntu-22.04, image: bref/build-php-84 }
- { php: '8.4', arch: arm64, runner: ubuntu-22.04-arm, image: bref/arm-build-php-84 }
- { php: '8.5', arch: x86_64, runner: ubuntu-22.04, image: bref/build-php-85 }
- { php: '8.5', arch: arm64, runner: ubuntu-22.04-arm, image: bref/arm-build-php-85 }
steps:
- uses: actions/checkout@v4
# Build in the Bref build image via `docker run` (rather than a job
# `container:`) so checkout/runner tooling stays on the host. The arm64
# runner pulls the arm64 Bref image and builds an arm64 binary natively.
- name: Build in Bref image (${{ matrix.image }})
# The Bref build images export LD_LIBRARY_PATH/LD_PRELOAD pointing at
# their custom-compiled libs in /opt; dnf (a Python program) segfaults
# when its system modules pick those up. Strip those vars for the dnf
# call only — php-config and cargo still need them afterwards.
run: |
docker run --rm --security-opt seccomp=unconfined \
-v "$PWD":/src --entrypoint /bin/bash \
"${{ matrix.image }}" -lc '
set -euo pipefail
env -u LD_LIBRARY_PATH -u LD_PRELOAD dnf install -y clang clang-devel
curl --proto "=https" --tlsv1.2 -sSf https://sh.rustup.rs \
| sh -s -- -y --default-toolchain none
export PATH="$HOME/.cargo/bin:/opt/bin:$PATH"
export CARGO_TARGET_DIR=/tmp/target
export LIBCLANG_PATH=/usr/lib64
# ext-php-rs locates PHP by shelling out to `which`, which the
# minimal AL2023 image does not ship; point it at Bref'\''s PHP
# directly so detection does not depend on `which`.
export PHP=/opt/bin/php PHP_CONFIG=/opt/bin/php-config
cd /src
cargo build --release # rust-toolchain.toml pins the version
mkdir -p dist
cp /tmp/target/release/libphp_quickjs.so dist/quickjs.so
echo "built against: $(php-config --version), glibc reqs:"
objdump -T dist/quickjs.so | grep -oE "GLIBC_[0-9.]+" | sort -V | uniq | tail -3
'
- name: Package Bref Lambda layer
run: |
ver="${{ inputs.version }}"; php="${{ matrix.php }}"; arch="${{ matrix.arch }}"
# Layer is mounted at /opt on Lambda; Bref scans /opt/bref/etc/php/conf.d.
mkdir -p layer/php-quickjs layer/bref/etc/php/conf.d
cp dist/quickjs.so layer/php-quickjs/quickjs.so
echo 'extension=/opt/php-quickjs/quickjs.so' > layer/bref/etc/php/conf.d/quickjs.ini
( cd layer && zip -qr "../php-quickjs-v${ver}-php${php}-lambda-bref-${arch}.zip" . )
cp dist/quickjs.so "php-quickjs-v${ver}-php${php}-lambda-bref-${arch}.so"
- uses: actions/upload-artifact@v4
with:
name: lambda-bref-${{ matrix.php }}-${{ matrix.arch }}
path: |
php-quickjs-*.zip
php-quickjs-*lambda-bref*.so
# ──────────────────────────────────────────────────────────────────────
# macOS (Apple Silicon) — for local development (not deployable to Lambda).
# Intel (x86_64) is intentionally omitted: the macos-13 runners are scarce
# and Apple Silicon is the standard dev target now.
# ──────────────────────────────────────────────────────────────────────
macos:
name: macos ${{ matrix.arch }} · php ${{ matrix.php }}
runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false
matrix:
include:
- { php: '8.4', arch: arm64, runner: macos-14 }
- { php: '8.5', arch: arm64, runner: macos-14 }
steps:
- uses: actions/checkout@v4
- uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
- uses: dtolnay/rust-toolchain@1.96
- run: cargo build --release
- name: Stage artifact
run: |
mkdir -p dist
cp target/release/libphp_quickjs.dylib \
"dist/php-quickjs-v${{ inputs.version }}-php${{ matrix.php }}-macos-${{ matrix.arch }}.dylib"
- uses: actions/upload-artifact@v4
with:
name: macos-${{ matrix.php }}-${{ matrix.arch }}
path: dist/*
# ──────────────────────────────────────────────────────────────────────
# Collect every artifact and publish the release.
# ──────────────────────────────────────────────────────────────────────
release:
name: publish release
needs: [linux, lambda-bref, macos]
runs-on: ubuntu-latest
steps:
- uses: actions/download-artifact@v4
with:
path: artifacts
merge-multiple: true
- run: ls -lh artifacts
- name: Publish GitHub Release
uses: softprops/action-gh-release@v2
with:
tag_name: v${{ inputs.version }}
name: v${{ inputs.version }}
draft: ${{ inputs.draft }}
generate_release_notes: true
files: artifacts/*