Global reference architecture examples
This topic describes common ways of organizing a global reference architecture (GRA) code base. Although the separate packages option is preferred, some situations require one of the other options described below.
Definitions
- Global Reference Architecture (GRA): Also known as White Label Architecture or Common Code Base. This is the module distribution architecture for a multi-instance setup.
- Multi-instance setup: The same client uses separate Adobe Commerce installations for separate regions or brands. Each installation has shared as well as unique modules.
- Single-instance setup: There is only one Adobe Commerce installation. Multiple copies of the source code may exist for different test environments, but there is only one version of the production code.
Option 1: Separate packages
See Composer project structure best practices for setting up this method.
The most flexible way to manage GRA Composer packages is through metapackages. Metapackages contain a composer.json
file only, which defines other package dependencies. Create metapackages using Private Packagist repositories.
Main project composer.json
{
"name": "example-client/region-1",
"description": "Example Client Region 1",
"type": "project",
"require": {
"magento/product-enterprise-edition": "2.3.5",
"example-client/meta-region-1": "~1.0"
},
"minimum-stability": "dev",
"prefer-stable": true,
"repositories": [
{"type": "composer", "url": "https://repo.packagist.com/example-client/"},
{"packagist.org": false}
]
}
example-client/meta-region-1 composer.json
{
"name": "example-client/meta-region-1",
"description": "Region 1 meta package",
"type": "metapackage",
"require": {
"example-client/meta-gra": "~1.0",
"example-client/theme-frontend-region1",
"example-client/language-es-es",
"ingenico/ogone-client"
}
}
example-client/meta-gra composer.json
{
"name": "example-client/meta-gra",
"description": "GRA meta package",
"type": "metapackage",
"require": {
"geoip2/geoip2": "~2.0",
"magento-services/module-stackify-logger": "~1.1",
"example-client/sap-connector",
"example-client/service-chat",
"example-client/store-locator"
}
}
Each module, language pack, theme, and library has its own Git repository. Each Git repository synchronizes to the Private Packagist repository automatically and generates a package there as long as there is a composer.json
file in the root of the Git repository.
Options 2: Bulk packages
Below is an example of multiple modules inside a single Composer package.
A bulk package can only include packages of the same type. For example, if you have multiple packages for Adobe Commerce modules, themes, language packs, and libraries, you must create separate bulk packages for each type.
The file structure inside the vendor directory should look like the following example. However, check your project to see what should be included in your Git repository):
.
└── example-client/
└── gra/
└── src/
├── SapConnector/
│ ├── etc/
│ └── registration.php
├── ServiceChat/
│ ├── etc/
│ └── registration.php
├── StoreLocator/
│ ├── etc/
│ └── registration.php
└── composer.json
The composer.json
file should look like this:
{
"name": "example-client/gra",
"description": "GRA Modules",
"require": {
"magento/magento-composer-installer": "*"
},
"type": "magento2-module",
"autoload": {
"files": [
"src/SapConnector/registration.php",
"src/ServiceChat/registration.php",
"src/StoreLocator/registration.php"
],
"psr-4": {
"ExampleClient\\SapConnector\\": "src/SapConnector",
"ExampleClient\\ServiceChat\\": "src/ServiceChat",
"ExampleClient\\StoreLocator\\": "src/StoreLocator"
}
}
}
Option 3: Split Git
This architecture uses four Git repositories to store code:
core
: Contains the Adobe Commerce core installation. Is used to upgrade Adobe Commerce versions.GRA
: Contains GRA code. All GRA modules, language packs, white label themes, and libraries.brand/region
: Each brand or region has its own repository with only brand- or region-specific code.release
: All of the above are merged into this Git repository. Only merge commits are allowed here.
To set up this option:
-
Create the four repository types in Git. Create the
core
andGRA
repositories only once. Create onebrand/region
and onerelease
repository for each brand.Suggested repository names:
m2-core
m2-gra
m2-region-x
/m2-brand-x
(for example,m2-emea
/m2-adobe
)m2-release-region-x
/m2-release-brand-x
(for example,m2-release-emea
/m2-release-adobe
)
-
Create a
release/
directory and run the following to create a shared Git history for all repos.code language-bash git init git remote add origin git@github.com:example-client/m2-release-brand-x.git git remote add core git@github.com:example-client/m2-core.git git remote add gra git@github.com:example-client/m2-gra.git git remote add region-x git@github.com:example-client/m2-region-x.git touch .gitkeep git add .gitkeep git commit -m 'initialize repository' git push -u origin master git push core master git push gra master git push region-x master
-
Clone each repository, except
core
, in a different directory on your computer.code language-bash git clone git@github.com:example-client/m2-release-brand-x.git git clone git@github.com:example-client/m2-region-x.git git clone git@github.com:example-client/m2-gra.git
-
Install Adobe Commerce with Composer. Remove the
.gitignore
file, add thecore
remote, add and commit the code, and push.code language-bash composer create-project --repository-url=https://repo.magento.com/ magento/project-enterprise-edition m2-core cd m2-core git init rm .gitignore git remote add origin git@github.com:example-client/m2-core.git git fetch git checkout .gitkeep git add --all git commit -m 'install Adobe Commerce' git push
-
In the
GRA
repository, create the following directories:app/code/
app/design/
app/i18n/
lib/
-
Add code. Remove the
.gitignore
file, add and commit the code, add the remote, and push. -
In the
brand/region
repository. Do the same as inGRA
repository and keep in mind that files must be unique. You cannot include the same file in both this repository and theGRA
repository. -
In the
release
repository, apply the merge.code language-bash git clone git@github.com:example-client/m2-release-brand-x.git cd m2-release-brand-x git remote add core git@github.com:example-client/m2-core.git git remote add gra git@github.com:example-client/m2-gra.git git remote add region-x git@github.com:example-client/m2-region-x.git git fetch --all git merge core/master gra/master brand-a/master git push
-
Remove the
.gitkeep
file. -
Deploy the
release
repository to the production, test, QA, and development servers. Upgradingcore
,GRA
, andbrand
code is as easy running the following commands:code language-bash git fetch --all git merge core/master gra/master brand-a/master git push
Option 4: Monorepo (recommended)
This strategy closely mimics the way that the Magento Open Source Git repository works.
All code is developed and tested in a single repository. Automation distills packages from this single repository, which can be installed on UAT and production environments using Composer.
The monorepo option offers you the ease of working in a single repository, while also providing the flexibility of composing instances with packages.
Versioning and package distillation is done through automation, using GitHub Actions or GitLab Actions.
See the following resources for more information about this automation:
Do not mix strategies
It is not advisable to use a combined approach using Composer for GRA packages and the app/
directory for brand or region packages.
You not only get all advantages but also all disadvantages of both methods. You should pick one or the other (Git or Composer), to work optimally.
Solutions to avoid
-
Module naming conventions to signify GRA or brand
Naming modules to signify GRA or brand leads to lack of flexibility. Instead, use Composer metapackages to determine which group a module belongs to. For example, for customer VF, package
vf/meta-gra
contains references to all GRA packages and can be installed using thecomposer require vf/meta-gra
command. Packagevf/meta-kipling
contains references to all Kipling specific packages and to thevf/meta-gra
package. Modules are namedvf/module-sales
andvf/module-sap
for example. This naming convention allows you to move packages between brand and GRA status, with low impact. -
Adobe Commerce core upgrades per instance
Schedule Adobe Commerce core upgrades, including patch upgrades, for different brands or regions to be executed as close together as possible. Supporting multiple Adobe Commerce versions for shared modules leads to forking of modules due to compatibility constraints and more than doubles the maintenance effort. Prevent this increased effort by making sure that all instances are running on the same Adobe Commerce version before continuing regular development.