Release asset downloads are replaced by the repository's preferred dist mirror
Maintainer thường phản hồi trong vòng 1 ngày
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 3/5
- Thời gian dự kiến
- 1-2 ngày
- Mức phù hợp với người mới
- 68/100
Hướng nghiên cứu
Start with src/ComposerIntegration/Listeners/OverrideDownloadUrlInstallListener.php, around the setDistUrl() call identified in the issue. Trace how the release asset URL, dist mirrors, and shasum are passed to Composer, then check the install path for pre-packaged archives and binaries. Done means preferred mirrors and repository checksums no longer redirect or reject release assets; verify with the reproduction cases described in the issue and the relevant tests.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
What are you trying to do?
We install extensions from our company's Private Packagist instead of packagist.org:
pie repository:add composer https://repo.packagist.com/<org>/
pie repository:remove packagist.org
This works for all our extensions except mongodb/mongodb-extension. It is the only one we use that downloads a release asset (pre-packaged-source) instead of the Git sources.
What platform, and PIE version are you using?
🥧 PHP Installer for Extensions (PIE) 1.5.3, from The PHP Foundation
You are running PHP 8.5.12
Target PHP installation: 8.5.12 nts, on Linux/OSX/etc x86_64 (from /usr/local/bin/php)
Debian 13, official php:8.5-cli Docker image. The code involved is the same on 1.6.x.
Steps to reproduce the issue
You don't need a Private Packagist account. What matters is this entry in its packages.json:
"mirrors": [{"dist-url": "https://repo.packagist.com/<org>/dists/%package%/%version%/r%reference%.%type%", "preferred": true}]
The script below builds a local repository with the same kind of entry. It uses Packagist's metadata for mongodb/mongodb-extension 2.5.4 and a local mirror. Like Private Packagist, the mirror serves a zip even when the URL ends in .tar.
Dockerfile:
FROM php:8.5-cli
COPY --from=ghcr.io/php/pie:1.5.3-bin /pie /usr/local/bin/pie
RUN apt-get update && apt-get install -y --no-install-recommends zip unzip
COPY repro.sh /repro.sh
CMD ["sh", "/repro.sh"]
repro.sh:
#!/bin/sh
set -eu
# A local Composer repository with Packagist's metadata for mongodb/mongodb-extension 2.5.4,
# plus a preferred dist mirror (set NO_MIRROR=1 to leave it out).
mkdir -p /tmp/repo
curl -fsS https://repo.packagist.org/p2/mongodb/mongodb-extension.json -o /tmp/p2.json
cp /usr/local/bin/pie /tmp/pie.phar
php -r '
require "phar:///tmp/pie.phar/vendor/autoload.php";
$versions = Composer\MetadataMinifier\MetadataMinifier::expand(
json_decode(file_get_contents("/tmp/p2.json"), true)["packages"]["mongodb/mongodb-extension"]
);
$package = current(array_filter($versions, fn ($v) => $v["version"] === "2.5.4"));
$repository = ["packages" => ["mongodb/mongodb-extension" => ["2.5.4" => $package]]];
if (!getenv("NO_MIRROR")) {
$repository["mirrors"] = [[
"dist-url" => "file:///tmp/mirror/%package%/%version%/r%reference%.%type%",
"preferred" => true,
]];
}
file_put_contents("/tmp/repo/packages.json", json_encode($repository, JSON_UNESCAPED_SLASHES));
echo $package["dist"]["reference"];
' > /tmp/ref
# Private Packagist answers the mirror URL with a zip of the Git tree, even when the URL ends in .tar.
# A placeholder zip is enough to show the problem.
dir=/tmp/mirror/mongodb/mongodb-extension/2.5.4.0
mkdir -p "$dir" && cd /tmp && echo placeholder > README && zip -q tree.zip README
cp tree.zip "$dir/r$(cat /tmp/ref).tar"
pie repository:add composer file:///tmp/repo > /dev/null
pie repository:remove packagist.org > /dev/null
pie download -v mongodb/mongodb-extension:2.5.4
docker build -t pie-mirror-repro .docker run --rm pie-mirror-reprofails.docker run --rm -e NO_MIRROR=1 pie-mirror-reproworks. It is the same repository, without the mirror.
The script makes a few anonymous calls to the GitHub API.
What do you expect to happen?
PIE finds the release asset and downloads it, like it does without the mirror:
Found prebuilt archive: https://api.github.com/repos/mongodb/mongo-php-driver/releases/assets/622600426
What is actually happening
PIE finds the release asset, but Composer downloads the file from the mirror instead. With -vvv:
Reading file:///tmp/mirror/mongodb/mongodb-extension/2.5.4.0/r7fc68847e9c8972fdf8a2b1672d54d1a2f1af55d.tar
The file name ends in .tar because PIE set the package type to tar. But the mirror doesn't have the release asset: it only has a zip of the Git sources, and it serves that zip whatever extension the URL asks for. Composer picks the extractor from the package type, not from the file content, so it tries to open a zip as a tar and fails.
Here is what I think happens, in OverrideDownloadUrlInstallListener:
- PIE replaces the package's dist URL with the asset URL (
setDistUrl()), and its type withtar(setDistType('tar')). - The package still has the mirrors it got from the repository.
- Composer builds the list of URLs to try (
Package::getUrls()) and puts a preferred mirror first. - That mirror URL is built from the original Git reference. So it points to the mirror's copy of the Git sources, not to the asset.
Even if the extraction worked, the build would fail: the Git sources of mongodb don't include libmongoc (it's a submodule). That's why the extension provides a release tarball.
Complete logs/output
Output with -v (trace shortened):
Found prebuilt archive: https://api.github.com/repos/mongodb/mongo-php-driver/releases/assets/622600426
Note: dist-sha integrity check is not available for prebuilt-binary URLs; HTTPS to the release-asset origin is the only integrity guarantee.
Package operations: 1 install, 0 updates, 0 removals
- Downloading mongodb/mongodb-extension (2.5.4)
- Installing mongodb/mongodb-extension (2.5.4): Extracting archive
Install of mongodb/mongodb-extension failed
In TarDownloader.php line 37:
[UnexpectedValueException]
phar tar error: "/root/.pie/php8.5_bb964103ae9a6d0b6235bc461ca8d9e5/vendor/
composer/tmp-48b694735bedb1b4a54573a3ddf7c72d.tar" already exists as a regu
lar phar and must be deleted from disk prior to creating as a tar-based pha
r
Exception trace:
PharData->__construct() at phar:///usr/local/bin/pie/vendor/composer/composer/src/Composer/Downloader/TarDownloader.php:37
Anything else?
The same code path is used by pre-packaged-binary and windows-binary. There, the mirror doesn't even need to misbehave. When the asset is a .zip, the type stays zip, so the mirror correctly serves the zip of the Git sources, and it extracts fine. PIE only fails later. I tried it with asgrim/example-pie-extension 2.0.10 on php:8.4-cli, with a mirror holding the real GitHub zipball: PIE stops with Expected pre-packaged binary does not exist. Without the mirror, it downloads the asset and installs.
pie.lock also stores the mirrors, so --from-lock has the same problem.
There is a second, smaller gap on the same line: the package also keeps the repository's shasum. Packagist has an empty one for mongodb, so it doesn't show here. When a repository does publish one, Composer checks the asset against it and fails with The checksum verification of the file failed. The note in the output above says the opposite. I checked it by adding a dummy shasum to the local repository.
This change fixes all of the above for me:
$composerPackage->setDistUrl($matchedReleaseAsset->url);
+ // Mirrors and the shasum describe the repository's dist (the Git sources), not the release asset
+ $composerPackage->setDistMirrors(null);
+ $composerPackage->setDistSha1Checksum(null);
I patched the 1.5.3 phar with it and ran each case again:
- mongodb with the mirror: the asset is downloaded and extracted;
- mongodb with a dummy shasum, with or without the mirror: same;
asgrim/example-pie-extensionwith the mirror: installed;- our real Private Packagist: mongodb builds and loads.
I haven't run PIE's test suite. I'm happy to open a PR if you agree with the fix.
- Ngôn ngữ chính
- PHP
- Star
- 2.1k
- Fork
- 76
- Merge trung bình
- 16 giờ 58 phút
- Pull request đã merge (30 ngày)
- 19
Chuẩn bị môi trường
- Có Dockerfile hoặc tệp Docker Compose
- Có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của php/pie
-
Investigate flaky ubi9/rocky e2e testsCó thể đã có người làm @asgrim đã nhận 3 ngày trước. Đang mởmaintainer investigating
php/pie#785 · 1 người được giao ·
Maintainer thường phản hồi trong vòng 1 ngày
-
When --from-lock is used, --no-dev becomes a no-opCó thể đã có người làm @asgrim đã nhận 9 ngày trước. Đang mởmaintainer investigating
php/pie#778 · 2 bình luận · 1 người được giao ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Do not duplicate an ext in pie show output for dev versionsCó thể đã có người làm @asgrim đã nhận 26 ngày trước. Đang mởenhancement maintainer investigating
php/pie#746 · 1 người được giao ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Allow building from existing sources on diskCó thể làm lại được @asgrim đã nhận 37 ngày trước và không có pull request nào đang mở. Đang mởenhancement maintainer investigating
php/pie#738 · 2 bình luận · 1 người được giao ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Optionally remove build-only dependencies and bloat after installCó thể làm lại được @asgrim đã nhận 159 ngày trước và không có pull request nào đang mở. Đang mởenhancement maintainer investigating
php/pie#618 · 2 bình luận · 5 reaction · 1 người được giao ·
Maintainer thường phản hồi trong vòng 1 ngày
Issue tương tự
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 64/100
backdrop-contrib/paragraphs#299 ·
-
tech-debt
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
landsman/adminer-desktop#206 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Explosm: Cyanide & Happiness failed with: https://explosm.net/comics/latest#comic resulted in 307Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
RSS-Bridge/rss-bridge#5154 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
[Sync EN] calendar: document the ValueErrors thrown for invalid calendar IDs and dates (#6005)Đang mởsync-en
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 90/100
Maintainer thường phản hồi trong vòng 2 ngày