Repository navigation
155 lines (142 loc) · 6.73 KB
/
Copy pathphp-ext.yml
File metadata and controls
155 lines (142 loc) · 6.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
name: "PHP extension"
# Builds the secretspec-php-native PHP extension (ext-php-rs) as a prebuilt
# shared object for each supported PHP minor x platform, smoke tests that it
# loads and registers its functions, and on a version tag attaches the binaries
# to the GitHub Release.
#
# DISTRIBUTION STATUS (see RELEASE.md): this builds and publishes prebuilt
# extension binaries. Installing them is documented in the PHP SDK docs
# (download + `extension=`, or `docker-php-ext-enable`, or build from source with
# cargo). A one-command PIE install is a follow-up: PIE builds non-Windows
# extensions from source via phpize, which does not apply to a Cargo/ext-php-rs
# extension, so the prebuilt-binary path here is what is validated.
#
# The SDK itself is exercised on every PR by the devenv-based sdks.yml (both the
# extension and the ext-ffi fallback); this workflow only builds the
# distributable extension binaries.
on:
workflow_call:
inputs:
release_tag:
description: Existing GitHub Release tag to upload artifacts to
required: false
type: string
default: ""
workflow_dispatch:
inputs:
release_tag:
description: Existing GitHub Release tag to upload artifacts to
required: false
type: string
default: ""
push:
tags:
- v**
pull_request:
paths:
- "secretspec-php/**"
- ".github/workflows/php-ext.yml"
jobs:
build:
name: php-${{ matrix.php }}-${{ matrix.target }}
runs-on: ${{ matrix.runner }}
permissions:
contents: write # attach binaries to the release (tag runs only)
strategy:
fail-fast: false
matrix:
# Full php x target cross-product: the `include` entries share the
# `target` key with the axis, so they merge in the runner (rather than
# creating standalone combinations). Non-thread-safe (NTS) is the default
# CLI/FPM build. 8.1 is omitted (end of life). ZTS builds are a
# follow-up. On Windows, ext-php-rs's build script downloads the PHP
# devel pack matching the installed php.exe (setup-php installs the
# official windows.php.net build) and links its php8.lib, so no manual
# dev-pack step is needed.
php: ["8.2", "8.3", "8.4"]
target:
- x86_64-unknown-linux-gnu
- aarch64-unknown-linux-gnu
- aarch64-apple-darwin
- x86_64-pc-windows-msvc
include:
- { target: x86_64-unknown-linux-gnu, runner: ubuntu-latest, libext: so }
- { target: aarch64-unknown-linux-gnu, runner: ubuntu-24.04-arm, libext: so }
- { target: aarch64-apple-darwin, runner: macos-latest, libext: so }
- { target: x86_64-pc-windows-msvc, runner: windows-latest, libext: dll }
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Set up PHP ${{ matrix.php }}
uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # 2.37.2
with:
php-version: ${{ matrix.php }}
# php-config + headers, needed by ext-php-rs's build.
tools: none
env:
# Ensure the dev headers are available for the build.
phpts: nts
- name: Install Linux build dependencies (clang for bindgen)
if: runner.os == 'Linux'
run: sudo apt-get update && sudo apt-get install -y llvm-dev libclang-dev clang
- name: Install Rust (pinned by rust-toolchain.toml)
run: rustup toolchain install
# PHP's Windows ABI uses the vectorcall calling convention, which stable
# Rust does not expose; ext-php-rs therefore requires nightly on Windows
# (its own CI builds Windows on nightly, all other platforms on stable).
- name: Install Rust nightly (vectorcall ABI, Windows only)
if: runner.os == 'Windows'
run: rustup toolchain install nightly --profile minimal
# Keyed per target and PHP minor: ext-php-rs's build script generates
# per-PHP-version bindings into the build dir. (The Windows rows build
# on nightly, whose daily version bump naturally expires their cache.)
- name: Cache Rust builds
uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32 # v2
with:
key: ${{ matrix.target }}-php${{ matrix.php }}
- name: Build and stage the extension under its distribution name
id: stage
shell: bash
# Each runner is the target's native arch, so a plain release build emits
# the target's binary (no cross-compilation). build-ext.sh owns the
# platform-to-library-name mapping and stages lib/secretspec.<ext>.
run: |
set -euo pipefail
# RUSTUP_TOOLCHAIN outranks rust-toolchain.toml; see the nightly note.
if [ "${{ runner.os }}" = "Windows" ]; then
export RUSTUP_TOOLCHAIN=nightly
# PHP's Windows loader refuses modules linked with a newer MSVC
# linker than the php.exe core (the official 8.x builds are
# VS16/VS17; the runner's link.exe is newer). rust-lld stamps a
# compatible PE linker version -- the setup ext-php-rs recommends.
export RUSTFLAGS="-C linker=rust-lld"
fi
bash secretspec-php/scripts/build-ext.sh
asset="secretspec-php-native-${{ matrix.php }}-nts-${{ matrix.target }}.${{ matrix.libext }}"
cp "secretspec-php/lib/secretspec.${{ matrix.libext }}" "$asset"
echo "asset=$asset" >> "$GITHUB_OUTPUT"
- name: Smoke test (load the extension, check it registers)
# Every row builds natively, so the runner can load what it built.
shell: bash
run: |
# php.exe needs a Windows path, not Git Bash's /d/a/... form.
dir="$PWD"
case "$(uname -s)" in MINGW*|MSYS*) dir="$(pwd -W)" ;; esac
php -d extension="$dir/${{ steps.stage.outputs.asset }}" -r '
assert(function_exists("secretspec_native_resolve"));
assert(function_exists("secretspec_native_abi_version"));
echo secretspec_native_abi_version(), PHP_EOL;
'
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: php-ext-${{ matrix.php }}-${{ matrix.target }}
path: ${{ steps.stage.outputs.asset }}
- name: Publish extension to the release
if: (github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')) || inputs.release_tag != ''
shell: bash
env:
GH_TOKEN: ${{ github.token }}
RELEASE_ASSET: ${{ steps.stage.outputs.asset }}
RELEASE_TAG: ${{ inputs.release_tag || github.ref_name }}
run: bash scripts/upload-release-asset.sh "$RELEASE_TAG" "$RELEASE_ASSET"