Git for Source Code Management vs Release Management in Magento 2 (Quick Note)

An interesting discussion thread on Twitter was what should be in .gitignore for a Magento 2 project? For example, should the vendor directory be in .gitignore or not? A useful question on this is in Stack Exchange.

Ignore vendor, commit composer.lock

Quite a few have said on twitter the norm for a PHP project is to commit your composer.lock file to git and use .gitignore to exclude the vendor directory. The composer.lock file holds the precise version numbers of the composer packages used to build the site, so the vendor directory in theory can be easily reconstructed whenever needed using composer install.

(Note: you need to be careful to not do a composer update at the wrong time, as it will update the composer.lock file with the latest applicable version numbers.)

Benefits:

  • It is how many PHP projects do things.
  • Your git repository is smaller. This saves disk space obviously, but also just makes it easier when browsing the repository so you can focus on the code that was developed for the project.
  • It does lock down the version numbers, even when dependencies in json accepts ranges of version numbers, including patterns.

Disadvantages:

  • You need to do a composer install to get the contents of the vendor directory, say if you are going to run the code through a CICD pipeline.
  • Running composer install makes the CICD pipeline slower as done every time. A Composer download cache can help a lot, but it does still take time. Composer can be slow to run (reported as very slow if you have insufficient memory).

All up, I would agree and lean towards not committing the vendor directory and commit the composer.lock file makes sense, if your objective is to put the project source code under source code version control.

However…

The above is really focused on the developer experience. If my goal was to capture a production release flow (e.g. snapshot exactly what is pushed to production each time), then there is the possibility that a Composer package will change after it is released. This should not happen, but mistakes do occur. In that case, personally I can see the benefit in snapshotting the whole code base including the vendor directory.

Now there are other ways to do the latter. For example, build Docker images and save the Docker images away instead of using git. This will capture the whole environment, not just the PHP code.

For myself, I am watching the Stack Exchange question with interest. Nothing like real-world experience to learn from.

What to put in .gitignore?

The Stack Exchange question response by Alex currently points at the Composer CE project template .gitignore file. This file is quite long. Why? Magento 2 has been moving towards putting more and more under the vendor directory. But it is not 100% there yet. Many of the files are used to create the overall directory structure, meaning Magento released files and custom project files are mixed into the one directory tree at present. So this .gitignore file has been set up to ignore files that are shipped with Magento, but are currently not installed in the vendor directory. Over time the plan is to reduce the length of this list – get as much as possible to be installed under the vendor directory, ideally all of it.

Conclusions

Most likely, the approach of committing composer.lock and ignoring the vendor directory will suit most people. But it is important to understand the distinction between that approach and committing the entire directory tree.

There is also more planned functionality which is to allow a module to reside anywhere (not just under app/code). Good progress has been made here, but it is not complete. When supported, this will open up additional possibilities in terms of source code management. For example, it may be all custom modules and themes are not stored under the same directory tree as the M2 installation. That opens up more options when deciding the directory structure and source code management scheme.

So, which way do you prefer and why?  (I think it’s safe to say there will be more changes here, so express your voice and say which you prefer and why!)

7 comments

  1. Interesting related reading from NPM and Ruby projects: The npm Debacle Was Partly Your Fault (and here’s what you can do about it) | Let’s Code JavaScript (http://www.letscodejavascript.com/v3/blog/2014/03/the_npm_debacle) from Erfan Imani’s Tweet

  2. You know, I’ve never really been comfortable with using source control as part of the deployment process. Perhaps one can use `composer install` to build the deployment package, but not to actually do the deployment. IMHO, the deployment package should be one that is completely self-sufficient. If one needs to connect to a third party system to do a code deployment then a large opening is opened for bad things to potentially happen. Having a deployment fail is only the tip of the iceberg-of-bad-things-that-can-happen, IMHO.

  3. Gordon Knoppe · · Reply

    I agree with Kevin Schroeder. Personally I advocate a lean repository which does not commit vendor code to the repository. This should not materially affect your build/CI process as composer.lock and composer cache means a rebuild of the entire code base will be relatively snappy (less than 30 secs on my MacBook Air).

    See https://github.com/gordonknoppe/m2-sample-project/tree/ce/src

    Deployment should not involve a git clone / pull / whatever. Compose your project, perform compilation, generate static assets, and then create an artifact. This artifact can now be shipped to production.

    1. Gordon, would it safe to say that you (and I suppose perhaps Kevin also) are essentially advocating a clean seperation between build (which by necessity would involve source control) and deployment (which should involve only pre-built artifacts)?

      I tend to favor this approach myself, but wasn’t sure if that’s what you were describing…

      1. Bryan, that’s exactly what I’m describing.

        Unfortunately, with Magento 2 creating a build artifact (including DI compilation and deployed static assets) requires a DB connection to an environment specific database in the build environment. This means that you would end up with environment artifacts such as “build-102918-stage.tar.gz” and “build-102918-production.tar.gz”.

  4. grunt/gulp can help refreshing.

  5. mmenozzi · · Reply

    IMHO putting 3rd party code under vcs is totally wrong. Keep in mind that with Magento 1.x this practice is very common and I think that this is the reason why there’s a t-shirt with Ben Marks face and the claim “hey, did you just edit the core”.
    I mean that if we put “vendor” under vcs we have the core under vcs and this allows someone to edit the core. The same is for 3rd party modules or themes.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: