Skip to main content

Updating your Symfony app from Mercure 0.10 to Mercure 0.11

Last wednesday I updated dikdikdik, a score sheet app for solo whist, so that it now uses Mercure v0.11, instead of v0.10. I use docker-compose for the development environment of dikdikdik, and GitLab CI/CD to run the end-to-end tests with codeception and selenium.

Mercure v0.11

This was not a trivial update, because v0.11 was a major milestone for the Mercure project. In retrospect, I didn't have to change much, but it took me some time to find out what exactly I had to change, especially to make the end-to-end tests running again.

Read more…

Iemand zin om mijn code te reviewen?

Laat ons het hebben over code review. Waarschijnlijk bestaan er verschillende definities van 'code review', ik zal eerst even verduidelijken wat ik met code review bedoel.

In grote lijnen: alvorens er aanpassingen gebeuren aan de broncode van je software, is het de bedoeling dat één van je collega's er eens naar gekeken heeft. Zodat die collega vragen kan stellen, of opmerkingen kan maken.

speelkaart en broncode

Read more…

PHP event sourcing aan de kaarttafel

Vandaag ga ik eens wat dieper in op de inner workings van WDEBELEK, de webtoepassing die ik schreef om online te kaarten (wiezen en gelijkaardige spelletjes).

Want het is niet alleen erg fijn dat we in tijden van quarantaine en avondklok nog kunnen kaarten, het is ook bijzonder cool dat de achterliggende software gebruik maakt van event sourcing; dat is toch alleszins wat ik probeer.

Mijn bedoeling is om jullie in al dit moois in te leiden aan de hand van de wijzigingen in de code die nodig waren voor een nieuwe feature die ik onlangs inbouwde: het opnieuw open leggen van een slag die eigenlijk al opgeraapt was.

playing cards

Read more…

Quarantaine whist with WDEBELEK

Now that the daily number of new COVID-19 infections is increasing, and people are talking about the possibility of local lockdowns, chances increase that card playing evenings will be canceled because of corona reasons.

But, as opposed to the previous lockdown, now there is an easy solution to play solo whist remotely. Because I work on a web application for online card playing: WDEBELEK.

It is still a young application, with a lot of loose ends, but it has been tested extensively, and it seemed to be useful. How does it work:

  1. Find 3 to 5 friends that want to play cards with you.
  2. Start a video conference with these friends, using your favourite video conferencing tool.
  3. Create a card table at
  4. Create invitation links, and pass them on to your friends.
  5. Play cards!

We do have a basic manual, but that's in Dutch. (If anybody wants to translate it to English: let me know.) Anyway, the use of the application should be straight forward.

Source code is freely available under the conditions of the AGPL v3 or later. And you can use the software for fee; that is: as long as my server can handle the load.


kaarten in quarantaine

Selenium web tests on gitlab-ci for an app using Mercure

I recently learned how to use Mercure so that the php/Symfony back-end of my application can send out events that can be picked up by the javascript on my front end. This is really cool technology, you should definitely try this out if you haven't already done so.

Now if you write this kind of software, of course you also want to write some web tests, so that you can automatically check if existing features of your program keep working after you add new things.

gitlab-ci, codeception and mercure

For these kind of tests, I use gitlab-ci and codeception, as I wrote in previous posts. Today I got these test working with a Mercure hub.

You need to use a mercure service in the job running your web tests, which you can configure in .gitlab-ci.yml:

Update 2020-12-03: I use the 0.10 version of the mercure container, because the acceptance test job started failing with 0.11, with these error messages:

Message: "Couldn't connect to server for "http://mercure:3000/.well-known/mercure"." In HandleMessageMiddleware.php line 80:

Couldn't connect to server for "http://mercure:3000/.well-known/mercure".)

So here's the adapted .gitlab-ci.yml-file:

  JWT_KEY: YourSecretKey
  DEMO: 1
  ADDR: ':3000'

# ...

acceptance tests:
  # I would prefer to use a public php-7.3 image with mysqli, but
  # I don't think such a thing exists.
  # So let's reuse the image I created for the dikdikdik web tests.
    - name: mariadb:10.4
      alias: db
    - name: selenium/standalone-chrome
      alias: chrome
    - name: dunglas/mercure
      alias: mercure:v0.10
  # (the rest of the job follows here)

The JWT_KEY should work with the JWT your backend uses to publish events. The port number in ADDR as well. If you use Symfony, as I do, the corresponding configuration of your backend should be in the .env file, e.g.


(Needless to say: don't use the production JWT and token in the source code that is used by gitlab! If you're unsure how to create a JWT, see the section ‘Creating your JWT’ of this excellent blog post.)

Update 2020-12-03: That blog post doesn't exist anymore, but I found another page that covers mercure and the JWT token.

Now the problem I ran into, is similar to the general problem I had with web tests: the chrome container doesn't know where the mercure hub is; the host name ‘mercure’ is not resolved to an ip address.

Update 2022-06-20: The solution described below will still work, but I found a better one. You should just set the FF_NETWORK_PER_BUILD variable to 1 in your .gitlab-ci.yml file, as described in this post. If you want to see how this works for a real life project, you can check out the .gitlab-ci.yml file of dikdikdik, an app to keep track of the scores when playing solo whist.

To fix this, I figure out the IP address of the Mercure hub when I start the job, and I replace the host name of the MERCURE_PUBLISH_URL in the .env file by this IP-address. This works, since my frontend retrieves the publish url from the backend by a rest-call.

This is how that looks like:

    - MERCURE_IP=$(getent hosts mercure | awk '{ print $1 }')
    - echo Mercure IP $MERCURE_IP
    - sed -i "s/mercure:3000/$MERCURE_IP:3000/" .env

You can review the complete job definition in the .gitlab-ci.yml file in the wdebelek repository. The file acceptance/TrickCest.php contains an example test involving server sent events. And hopefully you can see in the pipelines that all tests passed without problems 🤓.

Dependency hell when upgrading symfony from 4.3 to 4.4

Recently I tried to upgrade the symfony version of the dikdikdik wiezen score app from 4.3 to 4.4. As usual, I ended up in dependency hell.

Here's what I got:

$ composer update symfony/*
Loading composer repositories with package information
Updating dependencies (including require-dev)
Restricting packages listed in "symfony/symfony" to "4.4.*"
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - Conclusion: don't install symfony/validator v4.4.7
    - Conclusion: don't install symfony/validator v4.4.6
    - Conclusion: don't install symfony/validator v4.4.5
    - Conclusion: don't install symfony/validator v4.4.4
    - Conclusion: don't install symfony/validator v4.4.3
    - Conclusion: don't install symfony/validator v4.4.2
    - Conclusion: don't install symfony/validator v4.4.1
    - symfony/validator v4.4.0 conflicts with doctrine/lexer[v1.0.1].
    - symfony/validator v4.4.0 conflicts with doctrine/lexer[v1.0.1].
    - symfony/validator v4.4.0 conflicts with doctrine/lexer[v1.0.1].
    - Installation request for symfony/validator 4.4.* -> satisfiable by symfony/validator[v4.4.0, v4.4.1, v4.4.2, v4.4.3, v4.4.4, v4.4.5, v4.4.6, v4.4.7].
    - Installation request for doctrine/lexer (locked at v1.0.1) -> satisfiable by doctrine/lexer[v1.0.1].

I ran composer require doctrine/lexer, hoping that this would give me some clues:

$ composer depends doctrine/lexer
doctrine/annotations  v1.8.0   requires  doctrine/lexer (1.*)
doctrine/common       v2.10.0  requires  doctrine/lexer (^1.0)

I guess that doctrine must have been the problem.

So I uninstalled doctrine (composer remove symfony/orm-pack), upgraded symfony (that worked, 🎉), put the doctrine configuration files back in place, and reinstalled doctrine (composer require symfony/orm-pack).

It did update something, but then I got this error:

Executing script cache:clear [KO]
Script cache:clear returned with error code 255
!!  PHP Fatal error:  Uncaught Symfony\Component\Debug\Exception\ClassNotFoundException: Attempted to load class "DoctrineCacheBundle" from namespace "Doctrine\Bundle\DoctrineCacheBundle".
!!  Did you forget a "use" statement for another namespace?

After some searching on the internet, I found out that I had to remove the line

Doctrine\Bundle\DoctrineCacheBundle\DoctrineCacheBundle::class => ['all' => true],

from app.php to fix that one.

Of course now I had various other issues, but the dependency hell was fixed, so I am glad I can share this with you.

Dikdikdik: a Wiezen (Solo Whist) score app

For some time I've been working on a web application that helps you keeping track of the score if you want to play the Wiezen card game. Wiezen, as we play it, is called solo whist on Wikipedia.

Yesterday this score application (in Dutch, sorry) reached version 1.0. So I thought it would be appropriate to announce this release on my blog.

Admittedly, the user interface leaves a lot to be desired. But it turned out a very cool application (imho), with a nice event sourced backend, and gitlab pipelines that automatically test new source code. 🤓

The score app follows the whist game rules as set by Rijk van Afdronk vzw. The application can be tested (as long as my vps doesn't die) at; source code can be found on gitlab.

can only get this once!

Plastic prullen

Vanmorgen las ik in De Morgen een column waarin Sofie Guns een pleidooi voert tegen plastic rommel, die je op verschillende plaatsen krijgt, als cadeautje voor de kinderen. Of voor jezelf, zo je wil. Het artikel zit achter een paywall, maar de auteur hekelt de dubbelzinnige houding van supermarkten als het op ecologie aankomt. Stoffen zakjes om fruit in mee te nemen kwamen in de plaats van exemplaren in plastic, en herbruikbare tassen worden overal gepromoot. Maar tegelijkertijd delen supermarkten vaak gratis en ongevraagd plastic emoji's, bouwblokjes, en andere brol uit, netjes verpakt in een plastic jasje. Die dingen worden misschien geproduceerd aan de andere kant van de wereld, leggen een hele reis af met boot, vliegtuig en/of vrachtwagen, om hier in het beste geval terug in een vuilnisbak te verdwijnen. Of in het slechtste geval naast de weg, en uiteindelijk in de plastic soup ergens op zee.

Afgelopen weekend zijn we met de kinderen zwerfvuil gaan opruimen in de gemeente. We vonden voornamelijk sigarettenpeuken en lege drankblikjes naast de weg, maar er zat toch ook een aanzienlijke hoeveelheid plastic in onze volle afvalzakken. Dus alle lof voor het pleidooi van Sofie Guns: er is al plasticafval genoeg op de wereld, we hebben geen exra rommel nodig.

Na de opruimactie kregen de vrijwilligers een kom soep en een broodje, en nog een bedankje. In de vorm van... Gratis plastic rommel. Ingepakt in plastic, u vriendelijk aangeboden door de Vlaamse overheid.

plastic autoboompjes

Daar zakt mijn broek dus van af.

Ik wil een oproep doen. Kreeg u ook zo'n geurboompje, en gebruikt u het niet, steek het bij mij in de brievenbus. Ik zal ze verzamelen. En dan lever ik ze terug af bij de Vlaamse overheid, dan kunnen ze ze volgend jaar opnieuw uitdelen. Want mijn kinderen leerden op school dat het altijd beter is om afval te hergebruiken.

gitlab-ci and yarn

For my previous post, on gitlab-ci and codeception, I created a small project on gitlab that runs selenium webtests during gitlab-ci. The project being tested is just a small vue.js-application.

Recently I rewrote that small application; now it uses a single file vue component. I'm not completely sure what I've done, but it seems to work, and it involves webpack encore and yarn.

Running yarn from gitlab-ci

Now the challenge was to run yarn from gitlab-ci. I was looking for a docker container with yarn (even tried to build one myself), but it took me some time before I discovered that yarn is included in the node-container.

So I now use this node container in an extra task of the build stage in my .gitlab-ci.yaml. I create an artifact with the generated javascript, which is used in the test stage. That seems to work.

As I said before, I am new to vue, and it's the first time I use yarn and webpack. So maybe I am making some obvious mistakes. Please let me know if there are things that can be done in a better way.