How to get a change log of updgraded dependencies? - php

Is there some change log to check what is updated the last days?
We used composer to update modules, but we are looking for a way to see what exactly was changed the last days.
Can we check this somewhere?

Composer does not store a record of what installs at every time. It simply updates composer.lock with the discrete package versions that were installed.
Since usually composer.lock is stored under a version control system such as git, it tends to be enough. If you want to have an easier way to check what specific versions are installed on different updates, you could always store the result of update on file to see what was upgraded to what:
composer update --no-ansi &> update.log
Or maybe more practical, run composer info > installed.txt and commit that file after each update or require. That way you would have an easy to read and easy to diff file to see what versions were installed along the project lifetime.

Related

How to update symfony flex on production [duplicate]

composer install will install whenever stated in the composer.lock file, but composer update will update all the dependencies and create a new composer.lock file based on what is required in composer.json.
So many said only run composer update in development. But my question is doing composer update did replaced the old composer.lock file, if your app is going to break it will break, because there might be conflict with the new updated dependencies.
I came across with a situation where I must do composer update, the issue is related to pcntl extension. The only solution is to do composer update PHP pcntl module installation
I don't understand why people are afraid of running composer update on production.
TLDR;
Do not run composer update nor composer install in production. Execute it somewhere else and upload the result to the production server, but not to the same directory where the application is hosted. As a general rule, you shouldn't modify the application that's being served while it's being served. Create a different copy of the application and when it's ready replace it with the closest to instantaneous command you can (e.g. mv or ln -s).
But if you HAVE to run either: always run install and create a fresh installation; and never update. install is more predictable and reliable, with update you are at the mercy of any of the project's dependencies.
Composer works recursively. So even if you have very tight version constraints in your composer.json, by running composer update you would be updating not only your dependencies, but your dependencies' dependencies.
While most of the time this won't introduce breakage, sometimes it will. One dependency down the line may introduce a change of behaviour that may impact your code in a way you may have not tested against.
Also, it's basically using the wrong tool for the job. Composer is a dependency management tool, not a deployment tool. To deploy your code to production you should be using some sort of code deployment tool (even if that "tool" is as simple as an FTP upload and a couple of scripts).
The appropriate flow is:
Do all the require and update calls on your development machine, where you can test the project without risk. This generates a composer.lock, which is a known state for the whole project, with discrete installed versions.
Create a new installable version doing install --no-dev. On this step you also should dump an optimized autoloader, run after-install scripts, etc. I usually separate this in more than one step:
composer install --prefer-dist --no-scripts --no-progress --no-suggest --no-interaction --no-dev:
^^ This for a complete, silent installation of everything, excluding development dependencies.
composer dump-autoload --optimize --no-dev
^^ To dump an optimized autoloader script suitable for production.
composer run-script --no-dev post-install-cmd
^^ This is mostly for Symfony, but if you have any post-install scripts to run (e.g. to copy assets to your "public" directory, warm-up some type of cache, anything like that), this would be a good moment to do it.
The result of the above step should be tested (in what typically is a staging environment), and then pushed to production whole (your client code, the vendor folder, the configuration tailored for prod, etc); using whatever deployment method you prefer.
Note that if you use any "slow" push method (FTP, copy, rsync, etc), you shouldn't write directly to the application filesystem, but create a fresh copy of the application and once the file transfer is ready, use a quick method to replace "production" with the new release. A popular and effective way is use a symlink as "production" root, so you only need to update the symlink once all of the above is done and ready, without impacting a running application (that otherwise could be temporarily broken, by virtue of suddenly containing files that belong to different versions of the application).
My thoughts about this are,
The current working state of the system is very important as I would assume some tests have been run against it.
To do composer update would mean that, libraries that are part of the app would have their updates and which may lead to breakage in the system. Because they are libraries that depends on libraries that depends on libraries.
Finally, I would rather do this if composer-update is needed:
Checkout on a dev environment and composer update,
Ensure the app is thoroughly tested on a dev environment
then install on live/production with composer install
My thoughts here :
You should never use composer update without argument.
composer update reads every package listed on composer.json, and updates it to the latest available version compatible with the specified version constraints.
In a perfect world, all librairies would follow semver correctly, and it shouldn't have any side effects. But technically, that is never always true, and you could download a version incompatible with the previous one, or just a version with uncorrected bugs.
So, updating all your packages at once would probably lead to some issues, unless you have the time to check everything on your website to ensure nothing went wrong.
But of course, you'll have to update specific packages sometimes, so using composer update xxx/xxx is useful, assuming you'll check all your implementations of the package.
When the updated package is fully tested, you can commit your code to staging/production, and then run composer install to ensure you'll have the same exact version of package and dependencies on all your platforms.
Long story short, here's the process I use :
composer require xxx/xxx to install new packages
composer update xxx/xxx to update a specific package
composer install on all environments when the package.lock file has been updated.
Additional thoughts
I stumbled once upon an implementation which would give the exact version of the package in composer.json. The developer explained that this way you could use composer update without damage.
I disagree with this option, since even with the exact versions in composer.json, the dependencies are not fixed, and a composer update could lead to potential bugs in them.

Composer update has removed my changes

I am working on a Laravel application, and I ran the command composer update in order to install new packages I had added.
I had changed/added some files in the vendor directory before that, and those files that were added have been removed. I have not committed to my vendor directory (another mistake!), hence I can't get them back through git.
Now my questions are:
What happens when composer update is ran?
Why the files removed are not in the Recycle Bin, what has
happened to them? Permanently deleted?
As well, I am well aware that I can roll back my composer update, but that will not give me back my modified files, it would rather install the original files of the previous version.
Please do let me know if there is any other way (even file recovery) would help me to get these changes back.
composer update looks for new versions of installed dependencies and, if found, installs new versions instead of the old ones. It doesn't care whether any changes were made to installed dependencies, because it's looking just at their descriptions stored in the composer.lock file.
The files most likely cannot be recovered with composer for reasons mentioned above. You can try looking for lost files inside the cache directory .composer/cache, but I see no reason whatsoever for the lost files to be there. Yes, they are probably permanently deleted and, if those are critical, you should look for a file recovery program.
You definitely shouldn't store any modifications made to dependencies for the mentioned reasons.
Also, you probably shouldn't add vendor/ to your repository, for all dependencies are tracked with composer.lock anyway, and changing dependencies inside vendor (making them hardcoded) is against composer workflow.
EDIT:
As suggested by Kévin Dunglas, you can also try to look for the lost changes in the local history of your IDE (e.g. in PHPStorm).

Composer & composer.lock in GIT and merge conflicts

Here's our situation :
We have 3 different Laravel projects and all 3 projects rely on our Core project.
This Core project is a separate Laravel package hosted on our private repo and is used as a dependency for other projects.
Before, whenever something would change in the Core project we woud just run a composer update ourvendor/ourcorepackage on our servers for each project to pull in the core changes. However as of lately composer seems to suffer from serious memory issues when we try to run the update on our Digital Ocean staging environment with 512 MB Ram. See : https://github.com/composer/composer/issues/1898
The solution I always come across is people saying that you should always run composer install on your production servers. I can relate to that in terms of security because it can be dangerous if you update to a new version of some 3rd party package that can possibly break your code. But in our case we only update our own core package so we know what we're doing but this memory issue forces us to use the composer install method because it is less memory demanding.
So basically this is our current workflow :
When something changes in our core package we need to run a composer
update ourvendor/ourpackage on each project LOCALLY This generates a
composer.lock file
We commit the composer.lock file in our repo
On the servers for each project we run a git pull and run a composer
install. This will only update our core package and runs much faster
and has no memory issues vs composer update
However this solution raises 2 issues :
Since we're working with multiple devs on the same project we sometimes end up having merge conflicts for the composer.lock file when pulling in the changes locally.
Running a git pull on the server gives an error : Your local changes to the following files would be overwritten by merge: composer.lock
Please, commit your changes or stash them before you can merge.
So what am I supposed to do here? Before the pull on the server remove the composer.lock file?
How should we handle the merge conflicts for the composer.lock file?
It's a shame that composer update suffers from memory issues because that method seems much more logical. Just update the package you want and no hassle with the composer.lock file..
Please advice how a correct workflow with GIT and composer should be in our case and how to solve the conflicts above ?
Many thanks for your input
How can you test that a core update (or any other dependency that gets updated) doesn't break things in the projects using it if the developer don't do this step themselves?
That's why the usual workflow is expecting the composer update being run on a development machine having enough RAM (i.e. probably more than 1GB set as memory limit for PHP), and the update should be triggered manually by the developer (and if triggered automatically by a continuous integration build, the memory requirements apply to this machine as well).
There is no way around this memory requirement. A web server with only 512 MB RAM installed might be able to function as a staging server with barely any concurrent users present, but it shouldn't be used to update the Composer dependencies.
Personally I fix the merge conflicts in the composer.lock with a very easy system: Delete the lock file and run composer update. This will update all dependencies to the latest versions that satisfy the version requirements, and create a new working composer.lock file that get's committed during the merge.
I am not afraid to potentially update everything, because either it works as expected, or my tests will catch errors quickly.
I do select the 3rd party packages I use carefully:
they have to tag their versions, preferably using semantic versioning.
I do not use any branches for release versions (the rare occasions that someone used them during development were painful)
they should ship a new major version if they make backwards incompatible changes
the locally developed packages also follow these requirements
This works with around 270 packages served by our local Satis instance (probably also a factor to consider when trying to reduce memory footprint - only the packages known to Composer can end up in memory: Compare the ten thousand packages potentially available on packagist.org with 270 local packages). 60 packages of the 270 are locally developed by 20 developers, and randomly releasing new versions. The update failures in the last 2 years are very rare, and should be handled like other bugs: If a tagged version is detected to be incompatible, we release a bugfix release reverting the change, and tag the original change with a new major release, if the incompatible change is necessary.
So the workflow you ask for is probably like this:
Anytime, any developer should be able to run composer update on their local machine.
They should be able to detect if this breaks things on their local machine.
If nothing is broken, they commit the changes including the composer.lock file to Git
The staging server only runs composer install and will use exactly the versions that the developer used on his machine.
If nothing is broken on staging, that version is ready to be used on production.
Merging an already committed version on another developers machine will likely show merge conflicts with composer.lock.
Resolve conflicts on all other files.
The composer.lock file should be deleted.
From here, the workflow is like above, i.e.:
The developer should be able to run composer update on his local machine.
They should be able to detect if this breaks things on his local machine.
If nothing is broken... and so on.
Another approach (without doing composer update):
Copy your new (and deleted) lines from composer.json into a separate text file.
Use entire remote composer.json and composer.lock files.
During merge conflict mode do:
composer install
For every new package your wrote down in step 1 run composer require vendor/package:version
For every removed package your wrote down in step 1 run composer remove vendor/package
Testing!, Commiting, done!
This method will keep locks from remote branch (maybe master or develop branches), and only updates your new packages.
Sometime composer update can break things.
What I do is.
Discard all of my changes on composer.lock
Merge composer.json
Run composer install so that packages get installed according to composer.lock.
Take one of your package and run composer require vendor/package if you
added that package or composer remove vendor/package if you removed it.
if there are multiple packages it will be installed automatically from composer.json

Faster composer install

A composer install normally takes a few minutes. And on a production environment it's feels too slow.
Is it possible to make a composer install to a temp directory and then switch it? If that is possible the downtime should be about zero.
Or are there any other way to do a composer install faster?
I created a composer plugin to download packages in parallel.
https://packagist.org/packages/hirak/prestissimo
$ composer global require hirak/prestissimo
Please try it. In my environment, composer install become 10 times faster.
You can sometimes speed up composer install significantly by using the --prefer-dist flag, which just happens to be recommended for production use:
--prefer-dist: Reverse of --prefer-source, composer will install from dist if possible. This can speed up installs substantially on build servers and other use cases where you typically do not run updates of the vendors.
composer install docs here: http://getcomposer.org/doc/03-cli.md#install
Edited To Clarify Sometimes
I say it sometimes speeds up composer install because there are plenty of factors that go into it feeling slow, not the least of which are network performance and the current Github status. A slow install can be really frustrating, but it's not always b/c of Composer.
You are asking two different and unrelated things.
Yes, it is a solution to build the next version of your site in a separate directory then put it in place after you moved the old version out of the way. It is, actually, the best solution.
This is how the deployment scripts I build work:
prepare the next version of the site in a separate directory (let's say /var/www/new); the following list of items and their order is not static, some projects need a different flow:
get the last version of the code from the repo;
remove the files that are not needed on the live site (.gitignore, IDE project files, placeholders etc);
run composer install;
copy/generate the configuration files containing the settings for the live servers (the ones stored in the repository contain dummy values);
change the user and permissions of all files; make some directories writable by the web server;
create symlinks, directories etc; for example, the directory that contains the user uploaded files is somewhere outside the server directory and a symlink to it is created during deploy to make its content available through the web server;
move the live code out of the way; I use mv to move the entire directory (/var/www/html to /var/www/old, for example);
move the prepared new version to the proper place (mv /var/www/new /var/www/html);
move the previous version into the archive (after I remove the content of vendor and other files that do not change or are external).
The advantages:
the downtime is zero (microseconds, probably, between steps #2 and #3);
a failed build doesn't affect the live site (if handled properly);
reverting to the previous version (if needed) can be done easily.
Regarding the other question, the only way I know to speed composer up is to avoid running it using a PHP that loads the xdebug extension. The xdebug extension shouldn't be loaded on the production server anyway.

Understanding symfony2 deps

I'm working with symfony2 for some time and I don't really get the correct way to work with the vendors.
So here is what I'm doing:
I have the deps and deps.lock files in my git while I ignore the whole vendors folder. Now when I install the application to a new server, I do a php bin/vendors install to pull the vendors onto the server. I get the message that I have to use install --reinstall and do that.
From my understanding, the versions should now be the exact same as on my development machine, as both deps and deps.lock are the same. But it seems that the deps.lock gets (partly) ignored?
There is also a vendors update command, which I read should not be used. BUt I didn't get the idea what it really does.
So I'm a bit confused now as of what command should be used when and what it is supposed to do. Maybe someone can shed some light on this topic! I'm especially interested in the correct way to use the vendors command both local and on the server so the vendors are in the correct version on both systems!
install and update both fetch new code from the git repositories specified in your deps file
install checks for hashes in you deps.lock files for each library. If it finds something, it checkouts the commit corresponding to the hash. If it does not, it checkouts the tag or branch in your deps.lock if one is specified and creates an entry in the deps.lock file
update is useful when you want to update to a new version of symfony (or any library in the deps file). If you one day, you feel like updating, you can read this post I wrote about the update process.
To sum up, I always use update on all machines, and I try to always specify a version for each library, so that the production environment does not get updated to an unstable version unexpectedly.
install --reinstall is the same as install but it also deletes vendor folder content before doing installation.
vendors update updates all your vendors to the latest version or version specified in your deps file and updates your deps.lock file. But you rarely need it, don't know where you read "should not be used".
If you look inside vendors file, you can see this line:
if (is_dir($vendorDir.'/symfony') && !is_dir($vendorDir.'/symfony/.git') && !in_array('--reinstall', $argv))
...Try to run ./bin/vendors install --reinstall...
So you have vendor/symfony folder without .git in it.
have you download the standard edition which already contains the vendors, that's why it displays this message to use "install - reinstall"
I personally made ​​php bin / install-reinstall vendors in the deployement project

Categories