Hey, need help with your Magento, WooCommerce or Laravel project? I have some availalility. Contact me.

Say goodbye to manual updates make: Magento update automatically

Coding tips, Continuous Deployment, Continuous Integration, Cypress, Deployer, End-2-End Testing, GitHub Actions, Magento 2, Magento 2 testing, Testing, Playwright

Automatic Magento Updates. It is the ultimate utopia. Or is it? Is it really possible? How do you manage that? And what if an update contains bugs?

What is Magento

Before we can start updating everything, we need to understand what Magento actually is. You can compare it to ordering a dish of spaghetti. Spaghetti is not just spaghetti; it is also tomato sauce, some basil and parsley, and maybe some cheese.

The same goes for Magento. When we look at what Magento is, we can see that it is actually a bunch of packages that make up Magento. For starters, we have the Magento framework itself, which is a lot of different packages. On top of that, we usually add things like a payment provider and shipping provider, extra functionality like blogs, a theme, and more. All these dependencies need to be updated regularly.

Should I automatically update?

The short answer is yes. The long answer is also yes. I recommend updating everything often if you want to keep your Magento store safe. When you only run your updates when there is a new Magento version, you might struggle to update it as Composer is complaining about everything—dependencies that won't go together, for example. When you keep your store updated, this process becomes much easier.

How do you tackle that?

Automating Magento updates sounds like a really big thing. A lot of moving parts, how do you get started on that? My answer to that is: You don't. At least not with Magento. Take a small side project and try to enable automatic updates over there. When it goes down for some reason, it's not a big deal. But it teaches you how everything works. What the moving parts are. What the bumps in the road are. When you get that under control, you can move on.

When you abstract the lifecycle of an update into a few steps, it will look something like this:

These are way smaller steps, that should make it easier.

MageDispatch.com (ad)

Hey, I'm running a developer focussed newsletter called MageDispatch.com, which is for the community and by the community. Here you can share links that you think that the community should know about. If you like this kind of technical content you will like this newsletter too.

Step 1: Upload the code in GitHub/GitLab/BitBucket/etc.

This is the default for most agencies and projects, but there are always exceptions. The brain of automatic updates is the source code management platform. It holds the code but will also execute the tasks required for testing and deploying your application.

If you don't have your code stored in a code repository, please invest some time in setting it up. It makes projects way more maintainable.

Step 2: Enabling auto-updates

This is an easy win that can improve your life. Several solutions are available that will handle updates for you. The most well-known are Dependabot and Renovate. I've used Dependabot on several projects, but I can't get it to work correctly on Magento projects. It keeps giving errors and refuses to create pull requests for updates. So, I use Renovate for Magento projects.

These systems work pretty simply at their core: They check your composer.json, package.json, etc., and see what versions you are currently using for your dependencies. They will create a pull/merge request to update this dependency to the newer version if there are newer versions. This means you can wake up with an inbox full of pull/merge requests with updates for your Magento project.

To make this even easier, There are tools available that will merge all open PRs into a single one. You can then test that PR and deploy it all at once. Personally, I use this GitHub Action.

An example configuration for Renovate can be found here.

Step 3: Run deployments from your pipelines

Many people may find this idea of making the deployment automatic scary, but it doesn't have to be. Setting up zero downtime deployments can be a bit of a hassle. I've written a blog about how to set this up before: Deploying Magento using Deployer and GitHub Actions.

The same applies here: try it out on a low-risk project first, get some hands-on experience, and then move on to the more important projects. Start by using a manual trigger, like pushing to the main or develop branch, so you can control when the automation runs and learn from the process step by step.

Step 4: Testing

Automatic updates are in place. Semi-automatic deployments are in place. But how do you ensure that nothing breaks?

Tests are the answer here. But people are often afraid for tests. They are hard to implement. And for unit and integration tests, I can relate. But end-2-end tests are way easier to write. You get visual feedback. If you ever worked with jQuery you should be able to get quite far. And when you get stuck a little ChatGPT can go a long way.

Where the writing of end-2-end tests isn't that hard, running them in your pipelines is a challenge on a whole new level. Magento has quite a few dependencies that are required to be up and running before you can run your tests. Think of things like the correct PHP version, a database, ElasticSearch, RabbitMQ and more. You can install all these things in the pipeline, but setting this up takes quite a long time and is error prone.

Is there a better way? I think there is. This is precisely what Docker promises to solve: Having the same environment available on your local machine, testing and production environment. But setting up Docker can be quite a painful challenge. Luckily I found a solution for this: I'm using DDEV for my local development environment, and it's pretty easy to set up.

The even better thing about DDEV is that they offer a GitHub Action. By adding a single line to your workflow file, you can have an environment up and running in your Continuous Integration Pipeline:

- name: Setup DDEV
  uses: ddev/github-action-setup-ddev@v1

They also have support for GitLab available.

What to test?

This is a question that I can't answer for you as each store is different. But I can give you some guidance on this. I always start by testing the main flows of a webshop: adding a product to the cart and seeing if we can access the checkout. Can a user register as a customer and log in? From there, I start to add deviations: Can we alter the amounts in the shopping cart? Can we remove a product from the cart? Can a customer add and remove an address?

Testing these paths goes a long way toward making the tests reliable. When you have these covered, you can add store-specific tests.

Where do these tests run against?

A lot of people confuse this: End 2 end tests are a browser that clicks through your site. But they need a running Magento website to run against. In the situation described here, it might be confusing where this website is hosted. The answer is simple: It's hosted within the pipeline. It only exists while the pipeline is running. When it stops, the environment is thrown away and doesn't exist anymore.

The advantage of this is that you can test each update in isolation. If something breaks, you know exactly what caused the error. Also, this is fantastic for testing: You can create a customer in your test without worrying that this user already exists the next time the test runs.

Cypress vs Playwright

When you dive into End 2 End testing, you will see that there are 2 systems used: Cypress and Playwright. Which do you choose? Ultimately, they both do the same: Letting you automate browser actions. But after having them used both excessively, my favor goes to Playwright. And I'm seeing more and more people choosing Playwright. But use whatever you like best.

Tying it all together

We now have automatic updates in place. We have tests in place. We have automated our deployments. How do we tie this all together? That solution is pretty simple.

For this, we need to inform Renovate that it is allowed to merge the PRs if all tests pass. We can do that by adding these lines:

"schedule": [
  "on Monday through Thursday after 1:00am before 7:00am"
],
"automergeSchedule": [
  "on Monday through Thursday after 1:00am before 7:00am"
],

I tried this with a separate schedule and automergeSchedule, but I found out that Renovate started to merge PRs at moments I didn't want to. So now I have them synced and that works as expected. I do this only on Monday through Thursday as that's my personal preference, but you can configure this to whatever you like. Deployments during the night are preferred to limit the downtime on essential moments.

So what happens now?

We have enabled everything, but what happens now? Every night these steps happen on your repository:

  • Renovate reads your composer.json, package.json and other manifest files in your repository.

  • It compares the installed versions to the available versions.

  • For each dependency that has a new version available, it will create a Pull/Merge request.

  • Creating this Pull/Merge request will kick off the test action. This will test the changes.

  • When all tests are green the Pull/Merge request will be merged into your master or main branch.

  • The main/master branch is automatically deployed to your production environment.

Can’t we really update Magento?

Well, Renovate will create a PR for the upgrade itself. If all tests are green, nothing stops you from letting Renovate merge this. But is that really what you want? I wouldn't recommend it.

But we can still make our lives easier. Upgrading Magento used to be a big pain in the ass. But nowadays, there is the Ampersand upgrade patch helper. That will compare the version of your Magento installation with the new version and see which files are changed. It will then check your Magento project and see which templates are overridden.

Elgentos created the Upgrade GUI, which builds upon the upgrade patch helper by creating a small program that allows you to compare the changes visually.

But to be able to use that GUI, you still need to execute a few commands, which can be cumbersome. The good news is that we can automate this. I have created a GitHub action that you can manually trigger. This executes the required steps for you in your CI. The result are the files you need for the Upgrade GUI. So you download them, point the GUI to the right folder and you can compare the new Magento version. You can find this action here:
https://gist.github.com/michielgerritsen/e4c7ab5b627ccce2142d000678046b9c

Conclusion

Writing it down here might make it look as simple as "do these five things, and it will work." In theory, that is how it works, but we all know it does not always work like this. From my first project to the current Magento projects, it took quite a while to get to the point where I am now. Figuring out each step takes time.

That's why I emphasize the need to start on a small project where you can make mistakes. Setting up the deployment for the first time can be scary, as any mistake will take the site offline. And spoiler: You will make mistakes. But doing that on a small project is not a big deal.

But investing time and energy in this has improved my life as a developer. This article talks mainly about updates, but when we have implemented everything, these tests will also run for customizations you, as a developer, make. We all make mistakes, whether we like them or not. With this we will have a safeguard in place that helps us make sure everything works as expected.

My customers also benefit from this: Their webshop runs more reliably. They know it is always running on the latest versions. They can spend less time worrying about their webshop and more on what they do best: Selling.

So all in all a win-win for everyone.