Skip to content

build(docker): make e-dant/watcher install robust#2432

Merged
dunglas merged 2 commits into
mainfrom
fix/watcher-install-robustness
May 16, 2026
Merged

build(docker): make e-dant/watcher install robust#2432
dunglas merged 2 commits into
mainfrom
fix/watcher-install-robustness

Conversation

@dunglas
Copy link
Copy Markdown
Member

@dunglas dunglas commented May 16, 2026

Root cause

runner-php-8-3-31-trixie on https://github.com/php/frankenphp/actions/runs/25961840516/job/76318473755 (PR #2430, linux/amd64) failed with:

curl: (2) no URL specified
tar: Child returned status 1

Two converging issues:

  1. .github/workflows/docker.yaml did not export GITHUB_TOKEN to the bake-action environment. docker-bake.hcl declares secret = [\"id=github-token,env=GITHUB_TOKEN\"], but the Build step's env: block only set SHA, VERSION, PHP_VERSION, BASE_FINGERPRINT. The secret mount resolved to empty, the watcher install fell into the unauthenticated branch, and parallel matrix jobs trivially hit GitHub's 60 req/hr unauth cap. static.yaml's bake step already passes GITHUB_TOKEN; docker.yaml was the outlier.

  2. The watcher install pipeline silently swallows API errors. curl -s (no -f) hides HTTP errors; grep tarball_url | awk | sed | xargs curl -L | tar xz produces empty output when the API response is anything other than a normal release JSON (rate limit message, 5xx, auth fail). xargs curl -L then runs with no URL, and tar xz gets empty stdin — yielding the opaque pair above with no signal as to why.

Fix

  • docker.yaml: pass GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} to the bake Build step's env block (mirrors static.yaml).
  • Dockerfile and alpine.Dockerfile: install jq, rewrite the watcher install with curl -fsSL plus jq -r '.tarball_url // empty' and an explicit empty-URL check that prints a useful error. Heredoc form for readability; logic kept POSIX so it works under both bash (Debian) and ash (Alpine).

Cmake/build flags and final ldconfig step are unchanged.

The watcher install step fetches the latest release tarball URL from
the GitHub API, then pipes the response through grep/awk/sed/xargs
into curl and tar. When the API returns anything that does not include
a tarball_url (rate limit response, 5xx, auth error), the pipeline
silently produces an empty URL and dies with the opaque pair:

    curl: (2) no URL specified
    tar: Child returned status 1

Two converging issues caused this in CI:

1. .github/workflows/docker.yaml's bake step did not export
   GITHUB_TOKEN to the bake-action environment, so the secret mount
   in docker-bake.hcl resolved to empty and the API call ran
   unauthenticated. With the 60 req/hr unauth cap, parallel matrix
   jobs are easy to rate-limit. static.yaml's equivalent bake step
   already passes the token; docker.yaml was the outlier.

2. The Dockerfile pipeline used `curl -s` (no -f, no error surfacing)
   and parsed JSON with grep+awk+sed. Any non-success response sent
   the build down the same opaque tar/curl error path with no clue as
   to why.

Pass GITHUB_TOKEN to the bake step, install jq in both Dockerfile and
alpine.Dockerfile, and rewrite the install with `curl -fsSL` plus
explicit empty-URL detection so failures surface a clear message
instead of a phantom curl/tar error.

Failing run that prompted this: #2430 amd64 job 76318473755
Copilot AI review requested due to automatic review settings May 16, 2026 13:58
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes silent failures in the Docker image build when installing e-dant/watcher. Two converging issues caused opaque curl: (2) no URL specified / tar: Child returned status 1 errors: the bake-action was not receiving GITHUB_TOKEN (so the install hit GitHub's unauthenticated rate limit), and the install pipeline used curl -s plus a grep|awk|sed chain that silently produced an empty URL on any non-release API response.

Changes:

  • Pass GITHUB_TOKEN to the bake Build step in docker.yaml so the id=github-token secret mount actually resolves.
  • Rewrite the watcher install in both Dockerfile and alpine.Dockerfile as a POSIX heredoc using curl -fsSL, jq -r '.tarball_url // empty', and an explicit empty-URL guard with a diagnostic message.
  • Add jq to the build-deps in both Dockerfiles.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
.github/workflows/docker.yaml Adds GITHUB_TOKEN to the bake step env so the id=github-token secret mount is populated.
Dockerfile Installs jq; replaces fragile grep/awk/sed/xargs pipeline with curl -fsSL + jq + empty-URL check in a heredoc; preserves cmake flags and ldconfig.
alpine.Dockerfile Same fix as Dockerfile, adapted for Alpine (apk add jq, no ldconfig).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

editorconfig-checker flagged the heredoc body as space-indented; the
project's .editorconfig requires tabs for *.Dockerfile and Dockerfile
already uses tabs everywhere else.
@dunglas dunglas merged commit 5860768 into main May 16, 2026
88 of 93 checks passed
@dunglas dunglas deleted the fix/watcher-install-robustness branch May 16, 2026 15:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants