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
RFC: Reproducible vendor directory contents #9768
Comments
Looked even more closely at that release:
|
as a proof of concept, updated this will build a
when the
|
We'd have to see what the runtime impact is of touching all files after installation.. That probably adds a bunch of IO for smth that is kind of an edge case. I'm not sure if worth it. Is it needed though? From what you described above, it seems like GitHub already sets the filemtime correctly for all the archives to match the time of the tag, which is what Composer also sees as the release date. So is there any change needed? |
The change could be made to the paths not present in the archives:
for Docker caching to work, the vendor dir needs to be reproducible 100%, not 99% or 99.999997% or the cache hit won't happen. |
Right I fully understand the 100%. I believe we could apply the lock file's mtime to all the files you described. That shouldnt take too much io and should work reasonably well. If no lock file is present we can simply not do this, i don't expect anyone without lock file to care about this, as without lock file it's not going to be reproducible anyway. |
I've created a gist, for this to play around easier: This comment corresponds to git tag
|
With v2, everything in
however, it does not seem to work today. the
Maybe need to consult with docker dudes about how this works... |
I am researching to make the phpMyAdmin builds reproductible. As you can see the composer diffs are quite small in size. diff composer-workstation/autoload_real.php composer-snap-srv/autoload_real.php
5c5
< class ComposerAutoloaderInit1b17b2e8ddd55ea00091a3ad135fce66
---
> class ComposerAutoloaderInit23b49f0010eed1c13908880297e27e4f
27c27
< spl_autoload_register(array('ComposerAutoloaderInit1b17b2e8ddd55ea00091a3ad135fce66', 'loadClassLoader'), true, true);
---
> spl_autoload_register(array('ComposerAutoloaderInit23b49f0010eed1c13908880297e27e4f', 'loadClassLoader'), true, true);
29c29
< spl_autoload_unregister(array('ComposerAutoloaderInit1b17b2e8ddd55ea00091a3ad135fce66', 'loadClassLoader'));
---
> spl_autoload_unregister(array('ComposerAutoloaderInit23b49f0010eed1c13908880297e27e4f', 'loadClassLoader'));
35c35
< call_user_func(\Composer\Autoload\ComposerStaticInit1b17b2e8ddd55ea00091a3ad135fce66::getInitializer($loader));
---
> call_user_func(\Composer\Autoload\ComposerStaticInit23b49f0010eed1c13908880297e27e4f::getInitializer($loader));
56c56
< $includeFiles = Composer\Autoload\ComposerStaticInit1b17b2e8ddd55ea00091a3ad135fce66::$files;
---
> $includeFiles = Composer\Autoload\ComposerStaticInit23b49f0010eed1c13908880297e27e4f::$files;
61c61
< composerRequire1b17b2e8ddd55ea00091a3ad135fce66($fileIdentifier, $file);
---
> composerRequire23b49f0010eed1c13908880297e27e4f($fileIdentifier, $file);
68c68
< function composerRequire1b17b2e8ddd55ea00091a3ad135fce66($fileIdentifier, $file)
---
> function composerRequire23b49f0010eed1c13908880297e27e4f($fileIdentifier, $file)
diff composer-workstation/autoload_static.php composer-snap-srv/autoload_static.php
7c7
< class ComposerStaticInit1b17b2e8ddd55ea00091a3ad135fce66
---
> class ComposerStaticInit23b49f0010eed1c13908880297e27e4f
1682,1685c1682,1685
< $loader->prefixLengthsPsr4 = ComposerStaticInit1b17b2e8ddd55ea00091a3ad135fce66::$prefixLengthsPsr4;
< $loader->prefixDirsPsr4 = ComposerStaticInit1b17b2e8ddd55ea00091a3ad135fce66::$prefixDirsPsr4;
< $loader->prefixesPsr0 = ComposerStaticInit1b17b2e8ddd55ea00091a3ad135fce66::$prefixesPsr0;
< $loader->classMap = ComposerStaticInit1b17b2e8ddd55ea00091a3ad135fce66::$classMap;
---
> $loader->prefixLengthsPsr4 = ComposerStaticInit23b49f0010eed1c13908880297e27e4f::$prefixLengthsPsr4;
> $loader->prefixDirsPsr4 = ComposerStaticInit23b49f0010eed1c13908880297e27e4f::$prefixDirsPsr4;
> $loader->prefixesPsr0 = ComposerStaticInit23b49f0010eed1c13908880297e27e4f::$prefixesPsr0;
> $loader->classMap = ComposerStaticInit23b49f0010eed1c13908880297e27e4f::$classMap; |
@williamdes, yes: |
is there something bad in setting a non random value? |
Well, as long as you set a value specific to your project (so that it does not cause conflicts with an autoloader from |
@glensc have you made any progress on this? Is there any easy step we could take to improve things in Composer? |
I'm also interested in The problematic area in my case is
--- local/vendor/composer/autoload_files.php 1969-12-31 16:00:00.000000000 -0800
+++ remote/vendor/composer/autoload_files.php 1969-12-31 16:00:00.000000000 -0800
@@ -29,8 +29,8 @@
'8a9dc1de0ca7e01f3e08231539562f61' => $vendorDir . '/aws/aws-sdk-php/src/functions.php',
'def43f6c87e4f8dfd0c9e1b1bab14fe8' => $vendorDir . '/symfony/polyfill-iconv/bootstrap.php',
'801c31d8ed748cfa537fa45402288c95' => $vendorDir . '/psy/psysh/src/functions.php',
- '23c18046f52bef3eea034657bafda50f' => $vendorDir . '/symfony/polyfill-php81/bootstrap.php',
'2c102faa651ef8ea5874edb585946bce' => $vendorDir . '/swiftmailer/swiftmailer/lib/swift_required.php',
+ '23c18046f52bef3eea034657bafda50f' => $vendorDir . '/symfony/polyfill-php81/bootstrap.php',
'e8aa6e4b5a1db2f56ae794f1505391a8' => $vendorDir . '/amphp/amp/lib/functions.php',
'76cd0796156622033397994f25b0d8fc' => $vendorDir . '/amphp/amp/lib/Internal/functions.php',
'e39a8b23c42d4e1452234d762b03835a' => $vendorDir . '/ramsey/uuid/src/functions.php', --- local/vendor/composer/autoload_static.php 1969-12-31 16:00:00.000000000 -0800
+++ remote/vendor/composer/autoload_static.php 1969-12-31 16:00:00.000000000 -0800
@@ -30,8 +30,8 @@
'8a9dc1de0ca7e01f3e08231539562f61' => __DIR__ . '/..' . '/aws/aws-sdk-php/src/functions.php',
'def43f6c87e4f8dfd0c9e1b1bab14fe8' => __DIR__ . '/..' . '/symfony/polyfill-iconv/bootstrap.php',
'801c31d8ed748cfa537fa45402288c95' => __DIR__ . '/..' . '/psy/psysh/src/functions.php',
- '23c18046f52bef3eea034657bafda50f' => __DIR__ . '/..' . '/symfony/polyfill-php81/bootstrap.php',
'2c102faa651ef8ea5874edb585946bce' => __DIR__ . '/..' . '/swiftmailer/swiftmailer/lib/swift_required.php',
+ '23c18046f52bef3eea034657bafda50f' => __DIR__ . '/..' . '/symfony/polyfill-php81/bootstrap.php',
'e8aa6e4b5a1db2f56ae794f1505391a8' => __DIR__ . '/..' . '/amphp/amp/lib/functions.php',
'76cd0796156622033397994f25b0d8fc' => __DIR__ . '/..' . '/amphp/amp/lib/Internal/functions.php',
'e39a8b23c42d4e1452234d762b03835a' => __DIR__ . '/..' . '/ramsey/uuid/src/functions.php', Not sure if there's a fantastic fix for this already - browsed the code that creates these files ( At a glance, it seems like our issue could be fixed by applying a We're fixing this for our project by sorting arrays in the Script of dubious quality<?php
if (!isset($argv[1])) {
throw new \Exception('Usage: [path to composer autoload_*.php file');
}
$contents = file_get_contents($argv[1]);
$matches = [];
// autoload_files.php
preg_match('/(return array *\( *)([^\)]+)( *\);)/', $contents, $matches);
if (empty($matches)) {
// autoload_static.php
preg_match('/(public static \$files = array *\( *)([^\)]+)( *\);)/', $contents, $matches);
}
if (count($matches) !== 4) {
throw new \Exception('Expected 4 matches: ' . json_encode($matches));
}
$original = $matches[2];
$newParts = explode(PHP_EOL, $original);
sort($newParts);
$newParts = array_values($newParts);
$new = implode(PHP_EOL, $newParts);
if ($original === $new) {
echo 'No Change' . PHP_EOL;
exit(0);
}
$newContents = str_replace($original, $new, $contents);
echo 'Change' . PHP_EOL;
if (file_put_contents($argv[1], $newContents) === false) {
throw new \RuntimeException('Failed to write new contents');
}
exit(0); |
@AlbinoDrought I believe/hope that part (files autoload order) was fixed by #10617 in 2.2.8. |
Couldn't this be solved with defaulting to something non-random like the project name or FILE or something? |
Not all projects have a name, dir may be machine-dependent.. I'm not sure really if this is worth doing in a non-opt-in manner as it is now. |
Closing as I am not sure what to improve right now, if there is a specific action item please open a new issue with details. |
There has been an issue (and now implemented) to make
composer.phar
build reproducible:I'm looking the same thing for
vendor
reproducibility.The final end goal is to produce identical
vendor/
fromcomposer.lock
if invoked from CIand later copied to docker layer. The assumption is that CI can't share the previous workspace,
so the timestamp information must come from somewhere else.
What I've researched so far, is that:
"composer/ca-bundle@1.2.9"
,2021-01-12T12:15:05Z
(Used inspect in Chrome)composer.lock
writes date for installations, so that could be used for directories as fallback. example: "2021-01-12T12:10:35+00:00"composer.lock
The text was updated successfully, but these errors were encountered: