ci: fallback on gh when the php.net API is down#2233
Conversation
There was a problem hiding this comment.
Pull request overview
This PR improves CI resilience when php.net’s releases API is unavailable (e.g., blocked by the php.net CDN) by adding a fallback mechanism to infer the latest PHP patch version via GitHub.
Changes:
- Add php.net → GitHub (
gh) fallback logic to determine the latest PHP version whenPHP_VERSIONisn’t set. - Update the sanitizers workflow to use the same fallback and to handle fetching either php.net
.xzarchives or GitHub.tar.gzarchives.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| build-static.sh | Adds php.net API lookup with a GitHub (gh) fallback to resolve the latest patch version for a given minor series. |
| .github/workflows/sanitizers.yaml | Adds fallback logic for determining the PHP version and adjusts extraction to support GitHub tarballs. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
build-static.sh
Outdated
| json=$(curl -s "https://www.php.net/releases/index.php?json&version=$input") | ||
| latest=$(echo "$json" | jq -r '.version') | ||
| latest=$(echo "$json" | jq -r '.version' 2>/dev/null) | ||
|
|
||
| if [[ "$latest" == "$input"* ]]; then | ||
| echo "$latest" | ||
| else | ||
| echo "$input" | ||
| return | ||
| fi | ||
|
|
||
| # Fallback: use the latest GitHub release from php/php-src | ||
| if type "gh" >/dev/null 2>&1; then | ||
| latest=$(gh release list --repo php/php-src --exclude-drafts --exclude-pre-releases --json tagName --jq "[.[].tagName | select(startswith(\"php-${input}.\"))] | first | ltrimstr(\"php-\")") | ||
| fi |
There was a problem hiding this comment.
Because this script runs with set -o errexit, failures in the command substitutions here (curl unreachable/blocked, jq parse error on non-JSON response, or gh failing due to auth/rate limit) will abort the whole script before the fallback logic can run. To make the fallback effective, wrap these calls in if ...; then ...; fi blocks (or append || true) and treat empty/"null" outputs as non-fatal so the function can continue to the GitHub/default path.
| if curl -fsSL 'https://www.php.net/releases/index.php?json&max=1&version=8.5' -o version.json 2>/dev/null; then | ||
| version="$(jq -r 'keys[0]' version.json)" | ||
| archive="$(jq -r '.[] .source[] | select(.filename |endswith(".xz")) | "https://www.php.net/distributions/" + .filename' version.json)" | ||
| if [ -n "$version" ] && [ "$version" != "null" ] && [ -n "$archive" ] && [ "$archive" != "null" ]; then | ||
| echo "version=$version" >> "$GITHUB_OUTPUT" | ||
| echo "archive=$archive" >> "$GITHUB_OUTPUT" | ||
| exit 0 | ||
| fi | ||
| fi | ||
| # Fallback: use the latest GitHub release from php/php-src | ||
| version=$(gh release list --repo php/php-src --exclude-drafts --exclude-pre-releases --json tagName --jq '[.[].tagName | select(startswith("php-8.5."))] | first | ltrimstr("php-")') | ||
| echo "version=$version" >> "$GITHUB_OUTPUT" | ||
| echo "archive=https://github.com/php/php-src/archive/refs/tags/php-${version}.tar.gz" >> "$GITHUB_OUTPUT" |
There was a problem hiding this comment.
GitHub Actions runs bash steps with -e by default, so if php.net returns a 200 with HTML (CDN block page) jq will error and the step will fail before reaching the GitHub fallback. Consider making the jq reads non-fatal (e.g., redirect stderr and || true) and only using the parsed values when they’re non-empty/non-"null". Similarly, guard the gh release list call (and verify version is non-empty) so the workflow fails with a clear message if both sources are unavailable.
.github/workflows/sanitizers.yaml
Outdated
| fi | ||
| # Fallback: use the latest GitHub release from php/php-src | ||
| version=$(gh release list --repo php/php-src --exclude-drafts --exclude-pre-releases --json tagName --jq '[.[].tagName | select(startswith("php-8.5."))] | first | ltrimstr("php-")') |
There was a problem hiding this comment.
If gh fails as well, jq should return null. This will break without a verbose error. Should we extract the version fetch and check its value exists and is not null? This way we can print something like Failed to determine PHP version from both php.net and GitHub and exit early
Edit: well Copilot was faster than me at typing 😄
Unfortunately, GitHub Actions is often blocked by the php.net CDN. This patch adds a fallback to use GitHub to try to determine the PHP version to use. This is less ideal because PHP currently doesn't use GitHub extensively, and distribution archives aren't available in the GitHub releases, only on php.net.