-
Notifications
You must be signed in to change notification settings - Fork 1
STF-1287: Build and publish PIE precompiled binaries on tag #2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
2b9dea7
23f65f3
13b63c1
d3ba4b6
09139ec
1e19b02
7f7bac7
5bbc99f
f831762
c1244be
85589aa
d410dc3
c0f8bf4
ee517c2
0779632
0fb5a42
3da38d4
cf98cf9
b2dd98c
c6939c7
9b1c712
ee52f90
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| version: 2 | ||
| updates: | ||
| # Keeps the SHA-pinned `uses:` refs in release.yml current. Pinning by digest | ||
| # is what makes an action review-able; it is also what makes it go stale | ||
| # without something like this. | ||
| - package-ecosystem: github-actions | ||
| directory: / | ||
| schedule: | ||
| interval: weekly | ||
| day: monday | ||
| time: '14:00' | ||
| cooldown: | ||
| default-days: 7 | ||
|
|
||
| # MaxMind-DB-Reader-php is the extension itself: its ext/ sources are what | ||
| # every lane compiles and what the release tarball ships. Tracking main here | ||
| # is deliberate -- a release bumps this pointer, and the pointer is what | ||
| # defines the release's contents. | ||
| - package-ecosystem: gitsubmodule | ||
| directory: / | ||
| schedule: | ||
| interval: weekly | ||
| day: monday | ||
| time: '14:00' | ||
| cooldown: | ||
| default-days: 7 | ||
| # Not covered by any ecosystem above, and so still bumped by hand: | ||
| # | ||
| # - the digest-pinned php:*-cli-bookworm and php:*-zts-bookworm images, which | ||
| # live in a shell `case` in release.yml. Dependabot's docker ecosystem reads | ||
| # Dockerfiles and compose files, not image references inside a run: script. | ||
| # - the ubuntu:24.04 digest in the smoke job, for the same reason. | ||
| # | ||
| # Raising the Linux glibc floor means editing those digests, which is the point | ||
| # of pinning them -- but nothing will remind us, so they are worth a look | ||
| # whenever the PHP version list here changes. | ||
| # | ||
| # pie is not on that list: it is a mise tool, pinned and checksummed in | ||
| # mise.lock. Dependabot has no mise ecosystem, so nothing bumps it until the | ||
| # planned move to Renovate, whose mise manager understands the github: backend | ||
| # -- and which could take the image digests above too, through a regex manager, | ||
| # which is not something Dependabot can be configured into doing. |
Large diffs are not rendered by default.
| +24 −4 | .github/dependabot.yml | |
| +2 −2 | .github/workflows/clang-addresssanitizer.yml | |
| +2 −2 | .github/workflows/clang-analyzer.yml | |
| +51 −0 | .github/workflows/codeql-analysis.yml | |
| +123 −0 | .github/workflows/dependabot-failure-watcher.yml | |
| +32 −0 | .github/workflows/links.yml | |
| +2 −2 | .github/workflows/lint.yml | |
| +277 −0 | .github/workflows/test-bundled.yml | |
| +12 −12 | .github/workflows/test.yml | |
| +2 −2 | .github/workflows/zizmor.yml | |
| +1 −1 | .gitignore | |
| +3 −0 | .gitmodules | |
| +1 −0 | .php-cs-fixer.php | |
| +19 −0 | CHANGELOG.md | |
| +28 −7 | README.md | |
| +1 −1 | composer.json | |
| +234 −0 | dev-bin/gate-extension.sh | |
| +54 −19 | dev-bin/release.sh | |
| +55 −0 | dev-bin/run-ext-tests.sh | |
| +99 −0 | dev-bin/test-gate-extension.sh | |
| +66 −0 | dev-bin/verify-extension.php | |
| +2 −0 | examples/benchmark.php | |
| +37 −0 | ext/bundled-include/maxminddb_config.h | |
| +114 −19 | ext/config.m4 | |
| +110 −3 | ext/config.w32 | |
| +1 −0 | ext/libmaxminddb | |
| +2 −2 | ext/maxminddb.c | |
| +11 −0 | ext/tests/003-open-basedir.phpt | |
| +54 −0 | lychee.toml | |
| +69 −0 | mise.lock | |
| +10 −0 | mise.toml | |
| +1 −1 | src/MaxMind/Db/Reader.php |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -24,11 +24,15 @@ | |
| "priority": 50, | ||
| "support-zts": true, | ||
| "support-nts": true, | ||
| "download-url-method": "pre-packaged-source", | ||
| "download-url-method": ["pre-packaged-binary", "pre-packaged-source"], | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Verified: the option is opt-in in the submodule's But Either is defensible — just worth deciding deliberately, since right now the tested path and the shipped path differ. On the change itself: I verified the ordering semantics and the asset naming against PIE's own source, and both are correct. This line does what the PR says it does. 🤖 Comment by Claude (Claude Code) on behalf of Will.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Decided, and the option is now declared. You are right that declaring it does not change the default — it is opt-in in Thank you for verifying the ordering semantics and the asset naming against PIE's 🤖 Claude, replying on behalf of Greg. |
||
| "configure-options": [ | ||
| { | ||
| "name": "with-maxminddb", | ||
| "description": "Enable MaxMind DB Reader extension support" | ||
| }, | ||
| { | ||
| "name": "with-maxminddb-bundled", | ||
| "description": "Build the bundled libmaxminddb sources into the extension instead of linking a system library" | ||
| } | ||
| ] | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| #!/usr/bin/env bash | ||
| # | ||
| # Build maxminddb.so from the submodule's ext/ sources and record the fields the | ||
| # published asset name is derived from. Used by both Unix lanes: on Linux inside | ||
| # a digest-pinned container, on macOS directly on the runner. Windows builds | ||
| # through php/php-windows-builder and does not run this. | ||
| # | ||
| # Usage: build-ext.sh <ext-dir> <out-dir> | ||
|
|
||
| set -euo pipefail | ||
|
|
||
| ext_dir="$1" | ||
| out_dir="$2" | ||
|
|
||
| # --with-maxminddb-bundled compiles libmaxminddb's vendored sources into the | ||
| # extension so the published .so needs nothing but libc. config.m4 does refuse | ||
| # this itself -- AC_MSG_ERROR on both a missing --with-maxminddb and missing | ||
| # sources -- so this is not the only thing standing between us and a binary with | ||
| # a dangling libmaxminddb dependency. It is worth keeping because it fires | ||
| # before phpize and says so as a GitHub annotation rather than in autoconf | ||
| # output partway down a job log. | ||
| if [ ! -f "$ext_dir/libmaxminddb/src/maxminddb.c" ]; then | ||
| echo "::error::$ext_dir/libmaxminddb is missing. The submodule must point at a commit that supports --with-maxminddb-bundled." | ||
| exit 1 | ||
| fi | ||
|
|
||
| mkdir -p "$out_dir" | ||
| out_dir="$(cd "$out_dir" && pwd)" # absolute, because the build cd's away | ||
| cd "$ext_dir" | ||
| phpize | ||
| ./configure --with-maxminddb --with-maxminddb-bundled | ||
| make -j"$(getconf _NPROCESSORS_ONLN 2>/dev/null || echo 2)" | ||
| cp modules/maxminddb.so "$out_dir/maxminddb.so" | ||
|
|
||
| # Record these as reported by the PHP that actually built the object, so the | ||
| # asset filename cannot disagree with the binary inside it. | ||
| php-config --version | cut -d. -f1,2 > "$out_dir/php-abi" | ||
| php -r 'echo ZEND_THREAD_SAFE ? "-zts" : "";' > "$out_dir/ts-suffix" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| #!/usr/bin/env bash | ||
| # | ||
| # Collect one release asset out of each staged artifact directory and assert | ||
| # that the set is complete. Run by verify-assets on every run, and again by | ||
| # publish immediately before it uploads, so a pull request exercises the same | ||
| # assertion a release depends on. | ||
| # | ||
| # Usage: collect-assets.sh <dist-dir> <assets-dir> | ||
| # | ||
| # Reads TAG, PHP_VERSIONS, TS_MODES, LINUX_ARCHES and WINDOWS_COUNT. | ||
|
|
||
| set -euo pipefail | ||
|
|
||
| dist="$1" | ||
| assets="$2" | ||
|
|
||
| # shellcheck source=dev-bin/lib.sh | ||
| . "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/lib.sh" | ||
|
|
||
| find "$dist" -type f | sort | ||
|
|
||
| # Every build job stages exactly one file at its artifact root. The Windows | ||
| # action additionally stages a logs/ subdirectory, so select only files one | ||
| # level below an artifact directory and leave the logs out of the release. | ||
| mkdir -p "$assets" | ||
| find "$dist" -mindepth 2 -maxdepth 2 -type f -exec cp -t "$assets/" {} + | ||
|
|
||
| staged="$(find "$dist" -mindepth 2 -maxdepth 2 -type f | wc -l)" | ||
| collected="$(find "$assets" -maxdepth 1 -type f | wc -l)" | ||
| [ "$staged" -eq "$collected" ] || | ||
| fail "Two artifacts contain the same filename ($staged staged, $collected collected)." | ||
|
|
||
| # set -u does not fire on a set-but-empty variable, and arithmetic coerces one | ||
| # to 0 -- so an empty WINDOWS_COUNT would quietly mean "expect no Windows | ||
| # assets", and a release missing all of them would match the expectation and | ||
| # ship. Require a count before using it as one. | ||
| case "${WINDOWS_COUNT:-}" in | ||
| '' | *[!0-9]*) | ||
| fail "WINDOWS_COUNT is '${WINDOWS_COUNT:-}', which is not a count." | ||
| ;; | ||
| esac | ||
|
|
||
| php_count="$(jq 'length' <<<"$PHP_VERSIONS")" | ||
| ts_count="$(jq 'length' <<<"$TS_MODES")" | ||
| arch_count="$(jq 'length' <<<"$LINUX_ARCHES")" | ||
| # Linux (php x ts x arch) + macOS (php x ts). | ||
| binary_count=$((php_count * ts_count * arch_count + php_count * ts_count)) | ||
|
|
||
| # 1 source tarball + the binary lanes + whatever the Windows matrix said it | ||
| # would produce. Everything but WINDOWS_COUNT comes from setup, which is also | ||
| # what each matrix expands, so the expectation cannot drift from what was built | ||
| # -- including when setup hands out the reduced pull-request lists. WINDOWS_COUNT | ||
| # comes from windows-matrix, which derives it from the matrix it emits. | ||
| expected=$((1 + binary_count + WINDOWS_COUNT)) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Critical: an empty Verified:
This is a second, independent route to the same outcome as the case "$WINDOWS_COUNT" in ''|*[!0-9]*) fail "WINDOWS_COUNT is '$WINDOWS_COUNT', not a count." ;; esac🤖 Comment by Claude (Claude Code) on behalf of Will.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Confirmed and fixed.
case "${WINDOWS_COUNT:-}" in
'' | *[!0-9]*) fail "WINDOWS_COUNT is '${WINDOWS_COUNT:-}', which is not a count." ;;
esacVerified against 🤖 Claude, replying on behalf of Greg. |
||
|
|
||
| echo "Expecting $expected assets, found $collected:" | ||
| find "$assets" -maxdepth 1 -type f -printf ' %f\n' | sort | ||
|
|
||
| # This assertion is the point of the job. A release that silently ships the | ||
| # source tarball and zero binaries -- because an artifact glob matched nothing | ||
| # -- looks successful and is not. | ||
| [ "$collected" -eq "$expected" ] || | ||
| fail "Expected $expected release assets but found $collected. Refusing to publish a partial release." | ||
|
|
||
| # Named explicitly because every platform without a prebuilt binary depends on | ||
| # this one file. | ||
| [ -f "$assets/maxminddb-${TAG}.tgz" ] || | ||
| fail "$assets/maxminddb-${TAG}.tgz is missing." | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This paragraph is the only place the minimum PIE version can live, and it does not mention one.
Per
d3ba4b6's commit message, the array form ofdownload-url-methodneeds PIE >= 1.4.0. Older versions do not degrade uniformly:DownloadUrlMethod::tryFrom()→ PHPTypeErrorcount !== 1silently falls back tocomposer-default(src/DependencyResolver/Package.php:96-104), which for this package fetches a GitHub dist zip containing no C sources (they live in a submodule), so the build fails with no explanatory messageThe single string this replaces worked for all of those users. JSON cannot carry a comment, which makes this new paragraph the only user-facing place to say so — and "Elsewhere PIE falls back to building the extension from source" is only true on PIE >= 1.4.0.
Suggest a sentence naming the minimum. This is the one finding in my review with direct user impact.
🤖 Comment by Claude (Claude Code) on behalf of Will.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed, and thank you — the version-by-version breakdown is what made this
actionable rather than a vague "needs 1.4.0".
The README now names the minimum and says that older versions do not fail
uniformly, calling out 1.3.8–1.3.13 specifically, since silently fetching an
archive with no C sources is the case a user has no way to diagnose.
pie --versionis suggested as the check.🤖 Claude, replying on behalf of Greg.