Flag of Ukraine
SymfonyCasts stands united with the people of Ukraine

CI with Travis CI

Keep on Learning!

If you liked what you've learned so far, dive in!
Subscribe to get access to this tutorial plus
video, code and script downloads.

Start your All-Access Pass
Buy just this tutorial for $8.00

With a Subscription, click any sentence in the script to jump to that part of the video!

Login Subscribe

Our bundle is missing only two things: it needs a stable release and it needs continuous integration.

Before we automate our tests, we should probably make sure they still pass:

./vendor/bin/simple-phpunit

Bah! Boo Ryan: I let our tests get a bit out-of-date. The first failure is in FunctionalTest.php in testServiceWiringWithConfiguration().

Of course: we're testing the word_provider option, but that doesn't even exist anymore! We could update this test for the tag system, but it's a little tricky due to the randomness of the classes. To keep us moving, just delete the test. Also delete the configuration we added in the kernel, and the loadFromExtension() call. But, just for the heck of it, I'll keep the custom word provider and tag it to integrate our stub word list.

... lines 1 - 26
class KnpULoremIpsumTestingKernel extends Kernel
{
... lines 29 - 40
public function registerContainerConfiguration(LoaderInterface $loader)
{
$loader->load(function(ContainerBuilder $container) {
$container->register('stub_word_list', StubWordList::class)
->addTag('knpu_ipsum_word_provider');
});
}
... lines 48 - 52
}
... lines 54 - 62

The second failure is in KnpUIpsumTest. Ah yea, the first argument to KnpUIpsum is now an array. Wrap the argument in square brackets, then fix it in all three places.

... lines 1 - 8
class KnpUIpsumTest extends TestCase
{
public function testGetWords()
{
$ipsum = new KnpUIpsum([new KnpUWordProvider()]);
... lines 14 - 23
}
... line 25
public function testGetSentences()
{
$ipsum = new KnpUIpsum([new KnpUWordProvider()]);
... lines 29 - 37
}
... line 39
public function testGetParagraphs()
{
... lines 42 - 43
for ($i = 0; $i < 100; $i++) {
$ipsum = new KnpUIpsum([new KnpUWordProvider()]);
... lines 46 - 64
}
}
}

Ok, try the tests again!

./vendor/bin/simple-phpunit

Yes! They pass.

Adding the .travis.yml File

The standard for continuous integration of open source libraries is definitely Travis CI. And if you go back to the "Best Practices" docs for bundles, near the top, Symfony has an example of a robust Travis configuration file! Awesome!

Copy this entire thing, go back to the bundle, and, at the root, create a new file - .travis.yml. Paste!

language: php
sudo: false
cache:
directories:
- $HOME/.composer/cache/files
- $HOME/symfony-bridge/.phpunit
env:
global:
- PHPUNIT_FLAGS="-v"
- SYMFONY_PHPUNIT_DIR="$HOME/symfony-bridge/.phpunit"
matrix:
fast_finish: true
include:
... lines 16 - 59

Tip

You can use GitHub Actions as an alternative to Travis CI. Here's a configuration example:

# .github/workflows/ci.yaml
name: Lorem Ipsum Bundle CI

on:
  push:
    branches:
      - main

jobs:
  tests:
    name: Testing Lorem Ipsum Bundle
    # https://hub.docker.com/_/ubuntu/
    runs-on: ubuntu-22.04
    strategy:
      fail-fast: true
      matrix:
        php-versions: ['7.2','7.3','7.4']
    steps:
      - name: Checkout
        uses: actions/checkout@v2

      - name: Setup PHP, extensions and composer with shivammathur/setup-php
        uses: shivammathur/setup-php@v2
        with:
          php-version: ${{ matrix.php-versions }}
          extensions: mbstring, xml, ctype, iconv, intl, pdo_sqlite, dom, filter, gd, iconv, json, mbstring, pdo
          tools: composer:v2
        env:
          update: true

      - name: Install Composer dependencies
        run: composer install

      - name: Run tests
        run: SYMFONY_DEPRECATIONS_HELPER=disabled ./vendor/bin/simple-phpunit

We'll talk about some of the specifics of this file in a minute. But first, in your terminal, add everything we've been working on, commit, and push.

Activating Travis CI

With the Travis config file in place, the next step is to activate CI for the repo. Go to travis-ci.org and make sure you're signed in with GitHub. Click the "+" to add a new repository, I'll select the "KnpUniversity" organization and search for lorem.

Huh. Not found. Because it's a new repository, it probably doesn't see it yet. Click the "Sync Account" button to fix that. And... search again. There it is! If it's still not there for you, keep trying "Sync Account": sometimes, it takes several tries.

Activate the repo, then click to view it. To trigger the first build, under "More options", click, ah, "Trigger build"! You don't need to fill in any info on the modal.

Oh, and from now on, a new build will happen automatically whenever you push. We only need to trigger the first build manually. And... go go go!

Adjusting PHP & Symfony Version Support

While this is working, let's go look at the .travis.yml file. It's... well... super robust: it tests the library on multiple PHP version, uses special flags to test with the lowest version of your library's dependencies and even tests against multiple versions of Symfony. Honestly, it's a bit ugly, but the result is impressive.

Back on Travis CI, uh oh, we're starting to see failures! No! Let's click on one of them. Interesting... it's some PHP version issue! Remember, we decided to support only PHP 7.1.3 or higher. But... we're testing the bundle against PHP 7.0! We could allow PHP 7.0... but let's stay with 7.1.3. In the Travis matrix, delete the 7.0 test, and change the --prefer-lowest to use 7.1.

... lines 1 - 12
matrix:
... line 14
include:
... lines 16 - 18
- php: 7.1
... lines 20 - 21
# Test the latest stable release
- php: 7.1
- php: 7.2
... lines 25 - 58

Go back to the main Travis page again. Hmm: two failures at the bottom deal with something called symfony/lts. These make sure that Symfony works with the LTS - long-term support version - of Symfony 2 - so Symfony 2.8 - as well as the LTS of version 3 - so Symfony 3.4. Click into the LTS version 3 build. Ah, it can't install the packages: symfony/lts v3 conflicts with symfony/http-kernel version 4.

The test is trying to install version 3 of our Symfony dependencies, but that doesn't work, because our bundle requries everything at version 4!

And... that's maybe ok! If we only want to support Symfony 4, we can just delete that test. But I think we should at least support Symfony 3.4 - the latest LTS.

To do that, in composer.json, change the version to ^3.4 || ^4.0. Use this for all of our Symfony libraries.

... lines 1 - 11
"require": {
... line 13
"symfony/config": "^3.4 || ^4.0",
"symfony/dependency-injection": "^3.4 || ^4.0",
"symfony/http-kernel": "^3.4 || ^4.0"
},
"require-dev": {
"symfony/framework-bundle": "^3.4 || ^4.0",
"symfony/phpunit-bridge": "^3.4 || ^4.0",
"symfony/browser-kit": "^3.4 || ^4.0"
},
... lines 23 - 34

The cool thing is, we don't actually know whether or not our bundle works with Symfony 3.4. But... we don't care! The tests will tell us if there are any problems.

Also, in .travis.yml, remove the lts v2 test.

Ok, find your terminal, add, commit with a message, and... push!

This should immediately trigger a build. Click "Current"... there it is!

Let's fast-forward... they're starting to pass... and... cool! The first 5 pass! The last one is still running and, actually, that's going to fail! But don't worry about it: this is testing our bundle agains the latest, unreleased version of Symfony, so we don't care too much if it fails. But, I'll show you why it's failing in a minute.

Tagging Version 1.0

Now that our tests are passing - woo! - it's time to tag our first, official release. You can do this from the command line, but I kinda like the GitHub interface. Set the version to v1.0.0, give it a title, and describe the release. This is where I'd normally include more details about new features or bugs we fixed. Then, publish!

You can also do pre-releases, which is a good idea if you don't want to create a stable version 1.0.0 immediately. On Packagist, the release should show up here automatically. But, I'm impatient, so click "Update" and... yes! There's our version 1.0.0!

Oh, before I forget, back on Travis, go to "Build History", click master and, as promised, the last one failed. I just want to show you why: it failed because of a deprecation warning:

Referencing controllers with a single colon is deprecated in Symfony 4.1.

Starting in Symfony 4.1, you should refer to your controllers with two colons in your route. To stay compatible with 4.0, we'll leave it.

Installing the Stable Release

Now that we finally have a stable release, let's install it in our app. At your terminal, first remove the bundle:

composer remove knpuniversity/lorem-ipsum-bundle

Wait.... then re-add it:

composer require knpuniversity/lorem-ipsum-bundle

Yes! It got v1.0.0.

We have an awesome bundle! It's tested, it's extendable, it's on GitHub, it has continuous integration, it can bake you a cake and it has a stable release.

I hope you learned a ton about creating re-usable bundles... and even more about how Symfony works in general. As always, if you have any questions or comments, talk to us down in the comments section.

All right guys, seeya next time.

Leave a comment!

17
Login or Register to join the conversation
Boolean T. Avatar
Boolean T. Avatar Boolean T. | posted 2 years ago | edited

Hello, it's me again :)
Unfortunately, for some reason ./vendor/bin/simple-phpunit install didn't work as expected. I see the message: <i>No such file or directory (errno 2) in /home/travis/build/BooleanType/symfony_knpu_lorem_ipsum_bundle/vendor/symfony/phpunit-bridge/bin/simple-phpunit.php</i>. This introduces other errors related to the package. I can't figure it out, 'cause I have no experience with Travis CI and similar tools.

Here is my problem build (it exited with 0, but without tests. symfony/phpunit-bridge has been though installed): https://travis-ci.com/github/BooleanType/symfony_knpu_lorem_ipsum_bundle/jobs/486041211

And here is my simplified travis.yml:


language: php
sudo: false
cache:
    directories:
        - $HOME/.composer/cache/files
        - $HOME/symfony-bridge/.phpunit

env:
    global:
        - PHPUNIT_FLAGS="-v"
        - SYMFONY_PHPUNIT_DIR="$HOME/symfony-bridge/.phpunit"

matrix:
    fast_finish: true
    include:
          # Minimum supported dependencies with the latest and oldest PHP version       
        - php: 7.4
          env: COMPOSER_FLAGS="--prefer-stable --prefer-lowest" SYMFONY_DEPRECATIONS_HELPER="max[direct]=0"
        
          # Test the latest stable release
        - php: 7.4
          env: COVERAGE=true PHPUNIT_FLAGS="-v --coverage-text"

          # Latest commit to master
        - php: 7.4
          env: STABILITY="dev"

    allow_failures:
          # Dev-master is allowed to fail.
        - env: STABILITY="dev"

before_install:
    - if [[ $COVERAGE != true ]]; then phpenv config-rm xdebug.ini || true; fi
    - if ! [ -z "$STABILITY" ]; then composer config minimum-stability ${STABILITY}; fi;
    - if ! [ -v "$DEPENDENCIES" ]; then composer require --no-update ${DEPENDENCIES}; fi;
    # Prevent '/home/travis/build/BooleanType/symfony_knpu_lorem_ipsum_bundle/composer.phar: Permission denied'
    # https://nofluffjuststuff.com/blog/brian_kotek/2013/06/grails_travis_ci_and_permission_denied
    - chmod +x composer.phar

install:
    - composer update ${COMPOSER_FLAGS} --prefer-dist --no-interaction
    - ./vendor/bin/simple-phpunit install

script:
    - composer validate --strict --no-check-lock
    # simple-phpunit is the PHPUnit wrapper provided by the PHPUnit Bridge component and
    # it helps with testing legacy code and deprecations (composer require symfony/phpunit-bridge)
    - ./vendor/bin/simple-phpunit $PHPUNIT_FLAGS

Can you please help me with this? It's the last step for me to say, that my bundle works 100% well :)

Reply

Hey Boolean!

Your bundle is using Symfony 5.2 (phpunit-bridge and framework) and this course was developed under Symfony 4. The way to work with PHPUnit has changed so you will have to update the commands on your TravisCI config. Double-check that after install your bundle's vendor you have a this file bin/phpunit if you do, then you only have to execute it, the first time it runs it will install PHPUnit, you may want to cache the installation folder for performance reasons but that's another topic. Give it a try and let me know if it worked

Cheers!

Reply
Boolean T. Avatar
Boolean T. Avatar Boolean T. | MolloKhan | posted 2 years ago | edited

Hi!
It looks like I don't have bin/.phpunit in my bundle's vendor.
In my <i>local</i> bundle I have the following vendor/bin structure:


│   .phpunit.result.cache
│   simple-phpunit
│   simple-phpunit.bat
│   var-dump-server
│   var-dump-server.bat
│
└───.phpunit
    │   .phpunit-8.3-0.md5
    │   phpunit.xsd
    │
    └───phpunit-8.3-0
        │   .editorconfig
        │   ...

And in Travis CI it looks this way (no .phpunit folder):


$ cd vendor/bin
$ ls -a
.  ..  simple-phpunit  var-dump-server

symfony/phpunit-bridge` is installed In Travis for sure:


$ cd ./vendor/symfony/phpunit-bridge

$ ls -a
.		     composer.json		  Legacy
..		     ConstraintTrait.php	  LICENSE
bin		     CoverageListener.php	  README.md
bootstrap.php	     DeprecationErrorHandler	  SetUpTearDownTrait.php
CHANGELOG.md	     DeprecationErrorHandler.php  SymfonyTestsListener.php
ClassExistsMock.php  DnsMock.php		  TextUI
ClockMock.php	     ExpectDeprecationTrait.php

But ./vendor/bin/simple-phpunit install doesn't work. Maybe, I run this command in wrong dir? 'Cause I've tried another way: I execute simple-phpunit directly in vendor/bin and revert dir back after installation (for correct execution of the follow-up ./vendor/bin/simple-phpunit $PHPUNIT_FLAGS command) ( https://travis-ci.com/github/BooleanType/symfony_knpu_lorem_ipsum_bundle/jobs/486804070 ):


install:
    - composer update ${COMPOSER_FLAGS} --prefer-dist --no-interaction
    - cd vendor/bin
    - ./simple-phpunit
    - cd ../..
    - ls -a

In case of commands above php-unit was installed, but finally I saw <i>"The command "./simple-phpunit" failed and exited with 2 during ."</i> message, which I suppose (but not sure) goes from "simple-phpunit" file (command is "${dir}/simple-phpunit" "$@"). Of course, cd ../.. next command doesn't even execute.

So, I still don't get, why ./vendor/bin/simple-phpunit install doesn't install php-unit and what else I can do to fix it. I've also tried to apply configurations from other bundles (like knpuniversity/KnpUGuardBundle or knpuniversity/oauth2-client-bundle), but no success.

Reply

Hmm, that's odd. I'd expect you to have a bin/phpunit file after have installed symfony/phpunit-bridge on version 5, and then, after running phpunit you should get a bin/.phpunit folder with the current PHPUnit installation. That's how the symfony-phpunit-bridge works

Can you double check if you got the bin/.phpunit directory after executing PHPUnit?

Reply
Boolean T. Avatar
Boolean T. Avatar Boolean T. | MolloKhan | posted 2 years ago | edited

Here is my changed install section ( https://travis-ci.com/github/BooleanType/symfony_knpu_lorem_ipsum_bundle/jobs/488857369 ):


install:
    # Here symfony/phpunit-bridge (v5.2.0) is installed:
    - composer update ${COMPOSER_FLAGS} --prefer-dist --no-interaction 
    - cd ./vendor/bin/
    # For ls -a I see the following: .  ..  simple-phpunit  var-dump-server
    # There is no phpunit file - only simple-phpunit
    - ls -a
    # Return to source folder:
    - cd ../..
    # Try to install phpunit with simple-phpunit file. See a lot of warnings like 
    # "No such file or directory (errno 2) in /home/travis/build/BooleanType/symfony_knpu_lorem_ipsum_bundle/vendor/symfony/phpunit-bridge/bin/simple-phpunit.php on line 217"
    - ./vendor/bin/simple-phpunit install
    # Want to see if some files/dirs have been occured after command above:
    - cd ./vendor/bin/
    # Still see this: .  ..  simple-phpunit  var-dump-server
    - ls -a
    - cd ../..

Maybe, I do something wrong, but it looks I don't have .phpunit after running ./vendor/bin/simple-phpunit install command.

Reply

Hey Boolean_Type,

Hm, your config looks ok to me, but just in case take a look at a similar one that works well: https://github.com/KnpLabs/... - do you see any difference? It works well for that bundle, I see a successful (green) build in January. Looking at your error messages from the output I only can say that most probably your have some incompatibility issues with the installed Symfony's PHPUnit bridge and the version of PHP you use in your Travis. I'd recommend you to try to upgrade the PHPUnit bridge to the latest available or try this config but on a different (lower) PHP version, e.g. 7.3 of 7.2 and see if you will still have same issues, but that's really weird, probably we miss something important in your config if it works for others well.

If you want to dig further - probably take a look at the specific lines in that "simple-phpunit.php" - you can see the exact lines in the error output, it may give you some hits about what's wrong, etc.

It depends on your needs of course, but I'd recommend you to take a look at GitHub Actions instead. You can see that Symfony (and a lot of other bundles/libraries) are moved to it from Travis. I understand, it's not the answer why your config does not work, but it's a good alternative way that's most popular lately.

I hope this helps!

Cheers!

Reply
Boolean T. Avatar
Boolean T. Avatar Boolean T. | Victor | posted 2 years ago | edited

Hah, you see, finally it's passed ( https://travis-ci.com/github/BooleanType/symfony_knpu_lorem_ipsum_bundle/builds/219543164 ).
As I wrote in previous comment ( http://disq.us/p/2ffcp0u ), phpunit was installed successfully, when I executed simple-phpunit <i>directly from it's directory</i>. So, I was close.
What I've done today:


env:
    global:
        ...
        # If not to set XDEBUG_MODE, "SebastianBergmann\CodeCoverage\RuntimeException: XDEBUG_MODE=coverage or xdebug.mode=coverage has to be set" is thrown.
        - XDEBUG_MODE=coverage
...
install:
    - composer update ${COMPOSER_FLAGS} --prefer-dist --no-interaction 
     # Change directory and install phpunit.
    - cd ./vendor/bin/ 
    - ./simple-phpunit install

script:
    # Change directory back to bundle's root.
    - cd ../..
    - ./vendor/bin/simple-phpunit $PHPUNIT_FLAGS

I don't know, why it's working exactly this way, but I'm happy to see green jobs at least :)

1 Reply

Hey Boolean_Type,

Yay awesome job! Thank you for sharing your final solution with others! Though, I still don't see an important change that made it working :/ Anyway, I'm glad you got it working, well done!

Cheers!

1 Reply
Boolean T. Avatar
Boolean T. Avatar Boolean T. | Victor | posted 2 years ago | edited

Thank you for the reply!
I've tried:
1) to change PHP version (7.2, 7.3, 7.4)
2) to copy travis.yml content from KnpMarkdownBundle to my appropriate file. Also modified it in different ways;
3) my phpunit-bridge is already latest, but I changed to version set in KnpMarkdownBundle;
4) changed phpunit.xml content according to content in KnpMarkdownBundle.
Generally, 68 attempts to run tests in Travis - and no success :-D
Really don't know, what can be wrong. But by and large, it's not a problem, 'cause I wanted it to be successful, only because Travis is used in <i>this cast</i>. I don't use it in real life yet. And thanks for your advice I already know, that I should pay attention to GitHub Actions, not to Travis, if I have a possibility to choose.
Thank you very much for supporting and for such nice cast!

Reply
Alexandre C. Avatar
Alexandre C. Avatar Alexandre C. | posted 3 years ago | edited

Hi there , hi team,

Thanks for the awesome job you do everyday!

I'm currently working on a new application for my company, this application is kind of the same infrastructure as Carlos Eduardo's commented a year ago. We have multiple clients that need the same product but this one must be configurable for their needs.

In fact, it's not only configurable, because some part of the application work completely differently, so we must be able to override part of the code.

To do this, we followed this tutorial and it looks like it works kinda good.
Unfortunately, we have a strong problem with the JS & CSS files.

We don't know if we need to use Webpack in our bundle to generate the minified JS in the bundle in import them in the main project with "assets:install" or if we should write the JS in the Bundle, require it in the main project and use Webpack there ?

It's probably not easy to understand but I can simplify this : what's the best way to manage the JS files in a bundle ?
And moreover, how to do this in a clean way ? Can I use Webpack in a Bundle ?

Thank again for your job and I hope I have been clear in my questions!
Alex

Reply

Hi Ryan,

Noticed that Symfony\Component\Config\Definition\Builder\TreeBuilder has gone through a few changes lately.

If I use:

$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root('package_key');

I get a warning that a tree builder without a root is deprecated since Symfony 4.2

And if I use:

$treeBuilder = new TreeBuilder('package_key');
$rootNode = $treeBuilder->root('package_key');

I get a deprecated since Symfony 4.3 warning.

And If I use:

$treeBuilder = new TreeBuilder('package_key');
$rootNode = $treeBuilder->getRootNode();

It's not valid for versions lower than 4.2.

Does this mean that I should use getRootNode and target only 4.2 and above? Or is there a way round it?

Kind regards,

Nigel

Reply

Hey hurnell

You can try something like:


$treeBuilder = new TreeBuilder('package_key');
if (method_exists($treeBuilder, 'getRootNode')) {
    $rootNode = $treeBuilder->getRootNode();
} else {
    $rootNode = $treeBuilder->root('package_key');
}

Cheers!

Reply
Carlos Avatar

Hey!! Great course! Thanks.

Here's the thing... I watched all this tutorial with the major goal to heal a doubt that I'm facing in the last days. We're rebuilding some corporative systems of our customers and what we're aiming is to build one modular ERP system. You know... it is that traditional concept of share some modules between customers, adding customized functionalities where some of them need, add special modules to others, and there it goes...

Before I even know exactly what was and what was the purpose of a Symfony Bundle, I was able to swear that bundles was the right approach to build the modules of our new ERP. But now I'm really confused. One thing that made me confused is that way of dealing with routes. It's really harder to build all the routes inside bundles and config the way they're exposed when compared to the annotations way.
If you could hand me some insights to try to understand what is the best architecture to build this modular ERP with Symfony.
One way I'm tempted to go is to build each module like a totally separated application, and share only the authentication among them. What do you think?

Thanks again!!!

Reply

Hey Carlos!

Oh boy - yes, this is a great question! The answer... as always is... it depends :p. And there are several good options. The big "it depends" sorta depends on how you want to "host" the app and how data is stored. For example, consider these 2 extremes:

1) You create one app with one database, and simply segregate everything based on looking up stuff in the database. For example, maybe when you access client1.yourerpsystem.com, you look up the client based on the host name from some Client entity and determine the "look" and enabled features based on flags in there. You more or less just have if statements in your app that hide/show links and deny access to not-enabled features. Pretty much each Entity has a relation back to Client so that you can determine which records are for which client. Or, you can use some tricks to use a different database name for each client to avoid that.

2) Each Client literally has their own, completely independent Symfony application that is deployed to its own server (or however you deploy) with its own database. There is absolutely nothing shared between different clients - and you even maybe deploy them separately (allowing client A to be on version "1.1" of your site and client B to be on version "1.2").

These are the 2 extremes - and there are more options kind of "in the middle". What you need depends a lot on your requirements. System (1) is simpler in some way (just one "deployment" and 1 app to manage) but more complex in other ways (need to separate data via the relation to Client).

A lot of this comes down to: what is the best/worst way to enable/disable features across multiple clients. With situation (2) [or even another version of situation 2 where you have 1 app, but each client has its own kernel with different bundles enabled/disabled]) you *could* enable/disable features by enabling and disabling bundles. One real-world complication to think about is that you would really need to make sure each bundle that can be turned on/off is truly standalone. You would also need to setup your CI system to test the app with all combination of the bundles being on and off, to avoid accidentally relying on some optional feature from a bundle.

So... I'll stop right there - because a lot of the other pros and cons start to just depend on which type of option you are "leaning" towards. I will say one more thing: the "really cool" (but not really that important, imo) advantage to multiple bundles is that when you disable a bundle, all the routes and services of that bundle are literally not included in your application. That means there is no performance penalty for including unused features in your cache. But, that performance impact may not be that big, and the result is probably more complexity. I have built one of these apps before, and it was more like option (A). It WAS still complex... because feature flags are complex, but it was doable from day 1.

If you have more questions after all that long talking, let me know!

Cheers!

1 Reply
Carlos Avatar

Hey Ryan!! Thanks for another lesson!!

Since our customers all have their own IT infrastructure, all ERP systems will be deployed separately.
We're thinking that each module (CRM, Finance, Sales, etc) could be a separated Symfony application, sharing the same database (tables like crm_, fin_, sal_, etc) and one core module to orchestrate the Security (authentication), configuration and the main menu with the links to each application. So it would be like this:

/erpname-core
/erpname-crm
/erpname-finance
/erpname-sales
/erpname-etc..

Then if some customer doesn't need the "sales" module for instance, we just don't deploy it.
The authentication inside each module could be with the API Token idea.

Then I'll use the Symfony Bundles only to share codes that would be used by all modules, something like erpname-utilsbundle or erpname-basebundle.

Can you imagine some negative points in using this approach?

Reply

Hey Carlos!

Hmm, actually, this sounds really nice to me :). The downside is that multiple applications means multiple things to deploy and more to manage (e.g. upgrading Symfony versions multiple times, once for each version). Sl obviously, your deploy mechanism will need to be very automated to ease this. Also, it depends on how "big" version 1 needs to be and how many resources you have. For example, if you were a small startup, you might need to reduce the complexity somewhat (maybe). But if you're a bit bigger or already know you will have a certain number of customers, this approach makes more sense.

So, the downside as I mentioned would just be complexity (a lot of moving pieces to keep track of). You could reduce that by building each application into one project. What I mean is, you would have just 1 Symfony app, but you would have multiple "kernels". This is a bit more advanced, but you would have a "CRM" kernel that boots up all the bundles it needs and runs 100% independent, and another "Finance" kernel that does the same. These would function like separate apps, but living in the same codebase (so you wouldn't need to manage so many shared bundles across many apps, or worry about upgrading Symfony in multiple apps).

Cheers!

1 Reply
Carlos Avatar

Great!! Thank you very much!!! I'll that a look at this multiple kernels architecture.

1 Reply
Cat in space

"Houston: no signs of life"
Start the conversation!

This tutorial is built using Symfony 4, but most of the concepts apply fine to Symfony 5!

What PHP libraries does this tutorial use?

// composer.json
{
    "require": {
        "php": "^7.1.3",
        "ext-iconv": "*",
        "doctrine/annotations": "^1.8", // v1.8.0
        "knplabs/knp-markdown-bundle": "^1.7", // 1.7.0
        "knpuniversity/lorem-ipsum-bundle": "*@dev", // dev-master
        "nexylan/slack-bundle": "^2.0,<2.2", // v2.0.1
        "php-http/guzzle6-adapter": "^1.1", // v1.1.1
        "sensio/framework-extra-bundle": "^5.1", // v5.1.6
        "symfony/asset": "^4.0", // v4.0.6
        "symfony/console": "^4.0", // v4.0.6
        "symfony/flex": "^1.0", // v1.18.7
        "symfony/framework-bundle": "^4.0", // v4.0.6
        "symfony/lts": "^4@dev", // dev-master
        "symfony/twig-bundle": "^4.0", // v4.0.6
        "symfony/web-server-bundle": "^4.0", // v4.0.6
        "symfony/yaml": "^4.0", // v4.0.6
        "weaverryan_test/lorem-ipsum-bundle": "^1.0" // v1.0.0
    },
    "require-dev": {
        "easycorp/easy-log-handler": "^1.0.2", // v1.0.4
        "sensiolabs/security-checker": "^4.1", // v4.1.8
        "symfony/debug-bundle": "^3.3|^4.0", // v4.0.6
        "symfony/dotenv": "^4.0", // v4.0.6
        "symfony/maker-bundle": "^1.0", // v1.1.1
        "symfony/monolog-bundle": "^3.0", // v3.2.0
        "symfony/phpunit-bridge": "^3.3|^4.0", // v4.3.3
        "symfony/stopwatch": "^3.3|^4.0", // v4.0.6
        "symfony/var-dumper": "^3.3|^4.0", // v4.0.6
        "symfony/web-profiler-bundle": "^3.3|^4.0" // v4.0.6
    }
}
userVoice