[Contribuição de Tony Evers, arquiteto técnico sênior, Adobe]{class="badge informative" title="Contribuição de Tony Evers"}

O padrão de arquitetura de referência global de pacotes separados

Estas informações se aplicam a:

No local
Adobe Commerce Cloud
Adobe Commerce as a Cloud Service
Adobe Commerce Optimizer
Sim
Sim
Não
Não

Este guia explica como configurar o Adobe Commerce com o padrão GRA (Global Reference Architecture) de pacotes separados.

O padrão GRA de pacotes separados envolve um repositório Git para cada pacote comum e um repositório Git para cada instância do Adobe Commerce. Pacotes comuns são expostos por meio do Composer com um repositório de compositor privado.

Esse padrão de arquitetura de referência global é completamente baseado no Composer e foi projetado para obter o máximo benefício de todos os recursos do Composer.

Um diagrama que mostra onde o código está armazenado em um padrão GRA de Pacotes Separados {align="center"}

Vantagens e desvantagens deste padrão

Vantagens

  • Reutilização de código por meio de repositórios de código compartilhados
  • Flexibilidade total na instalação de pacotes, cada pacote de GRA pode ser atualizado, rebaixado ou ter backport individualmente
  • Suporte completo para controle de versão semântico
  • Não é necessária nenhuma ferramenta especial, infraestrutura complexa ou estratégia especial de ramificação
  • Suporte para todos os tipos de encapsulamento que o Composer suporta

Desvantagens:

  • O desenvolvimento dentro deste padrão GRA é ligeiramente mais difícil no início, há uma pequena curva de aprendizagem
  • Possível implantar combinações de pacotes que não foram desenvolvidos na mesma configuração; necessidade de procedimentos de teste rigorosos

Configurar o Adobe Commerce com o padrão GRA de pacotes separados

A estrutura de diretório

A estrutura de diretório final de uma instalação completa do Adobe Commerce com o padrão GRA de pacotes separados é semelhante a:

.
├── app/
│   └── etc/
│       └── config.php
├── composer.json
└── composer.lock

Os diretórios app/code, app/i18n e app/design foram omitidos na finalidade. A GRA Pacotes separados instala cada pacote do Composer. Mesmo que o pacote seja instalado somente em uma única instância do Adobe Commerce.

Preparar o repositório de armazenamento

Crie um repositório para a primeira instância do Adobe Commerce, que representa uma loja da Web para a Marca X.

mkdir gra-separate-brand-x
cd gra-separate-brand-x
composer create-project --repository-url=https://repo.magento.com/ magento/project-enterprise-edition .
git init
git remote add origin git@github.com:AntonEvers/gra-separate-brand-x.git
git add composer.json composer.lock
git commit -m 'initialize Brand X repository'
git push -u origin main

Instale o Adobe Commerce com bin/magento setup:install. Confirme o app/etc/config.php resultante.

Criar repositórios de packages

Cada pacote neste padrão de arquitetura de referência global tem seu próprio repositório Git. Abaixo estão exemplos de pacotes que contêm módulos Adobe Commerce representando um módulo GRA, um módulo de terceiros e um módulo local.

Use os exemplos para criar seus próprios pacotes.

Criar repositórios de metapackage

Metapackages controlam o escopo da base de código comum GRA neste padrão GRA. Eles definem o que está na base: qual combinação de versões de pacote é sempre instalada em conjunto. Um exemplo:

{
    "name": "antonevers/gra-meta-foundation",
    "type": "metapackage",
    "require": {
        "antonevers/gra-component-foundation": "~1.0",
        "antonevers/module-gra": "~1.0",
        "antonevers/module-3rdparty": "~1.0",
        "magento/composer-dependency-version-audit-plugin": "~0.1",
        "magento/composer-root-update-plugin": "~2.0",
        "magento/product-enterprise-edition": "2.4.6-p3"
    }
}

O trecho acima é o composer.json de um metapackage. Porque os metapackages contêm apenas um arquivo composer.json e nenhum outro código. O código acima também é o metapackage completo. Hospede-o em um repositório Git e você tem um repositório instalável do metapackage composer. Ele requer um módulo GRA de exemplo e um módulo de terceiros, bem como o núcleo do Adobe Commerce. Também requer o gra-component-foundation, que será explicado no próximo capítulo.

Os metapackages são uma maneira de agrupar pacotes sem criar dependências entre eles. Assim, mesmo quando não há dependência técnica entre os pacotes, com um metapackage você pode fazer com que eles sejam instalados juntos. Se você precisar desse metapackage no projeto, qualquer pacote ou metapackage exigido pelo metapackage será instalado. Portanto, se você criar um projeto de compositor em branco e precisar apenas desse pacote, o Composer instalará o Adobe Commerce e o GRA e o módulo de terceiros.

Dessa forma, você pode garantir que cada armazenamento contenha o mesmo conjunto de pacotes fundamentais.

Você pode definir de forma semelhante um metapackage que define store x. Ele requer o metapackage de fundação, exigindo a fundação GRA completa, além de um módulo local:

{
    "name": "antonevers/gra-meta-brand-x",
    "type": "metapackage",
    "require": {
        "antonevers/gra-meta-foundation": "~1.0",
        "antonevers/module-local": "~1.0"
    }
}

O metapackage Brand-X é opcional. Você também pode pular o metapackage da marca e exigir essas dependências diretamente no projeto do Composer da loja. A vantagem de criar um metappackage para módulos locais é que você não tem ramificações de recursos e solicitações de pull de recursos no repositório Git da loja, somente nos repositórios de packages. É uma medida de segurança. Além disso, você pode optar por aplicar o controle de versão semântico nos repositórios de packages e usar diferentes tags Git em seu projeto principal, por exemplo, para rastrear releases nomeadas. Depende de você.

Arquivos de base GRA fora do diretório do fornecedor

Às vezes, é necessário armazenar arquivos fora do diretório do fornecedor. Como .gitignore, arquivos que vão para o diretório dev/ ou arquivos de verificação de domínio. O tipo de pacote do componente magento2 foi projetado para essa finalidade. Olhe para https://github.com/AntonEvers/gra-component-foundation.

{
    "name": "antonevers/gra-component-foundation",
    "type": "magento2-component",
    "require": {
        "magento/magento-composer-installer": "*"
    },
    "extra": {
        "map": [
            [
                "src/gitignore",
                ".gitignore"
            ]
        ]
    }
}

Este pacote tem o componente tipo magento2 e contém um diretório src que hospeda arquivos copiados para o diretório raiz do Adobe Commerce. O mapeamento neste arquivo copia /src/gitignore para /.gitignore no projeto Composer principal.

Dessa forma, você também pode tornar arquivos fora do diretório de fornecedores parte da sua base GRA.

Desenvolver um módulo de base de GRA

O desenvolvimento ocorre dentro do diretório de fornecedor. Peça ao Composer para instalar seus pacotes de base a partir da origem. Ao fazer isso, o verifica os pacotes do Git em vez de instalá-los de um arquivo baixado.

rm -r vendor/antonevers/*
composer install --prefer-source

Com este comando, foi feito o check-out dos pacotes no namespace antonevers usando o Git. Ao entrar no diretório vendor/antonevers/module-gra, você também estará inserindo o repositório Git module-gra. Agora é possível criar, finalizar e mesclar ramificações no local e desenvolver dessa maneira, diretamente do diretório do fornecedor.

Incluir módulos de terceiros na base de GRA

Add third-party packages to the GRA metapackage. If third-party code is not available to be installed from a Composer repository, then create a package for it. Create a Git repo, add the packages contents (everything that would be in app/code/Vendor/Package) and make sure that there is a valid composer.json file at the root of the repository. You can now install this package through Composer.

Set up a private Composer repository

A private repository is not mandatory in global reference architecture. It makes deployments and installation faster, reduces repository configuration in composer.json, and it increases security. Credentials to other Composer repositories and the Adobe Commerce marketplace are stored in your private repository. No more sensitive credentials bundled with the code or on developers’ machines.

Additionally, some private repositories offer extra functionalities such as email notifications when one of your stores contains a security vulnerability in one of its dependencies.

The slowness issue is what occurs when you have multiple VCS repositories in composer.json. Each Composer repository needs to be read when doing upgrades and having 50 repositories for 50 packages has at least 50 times the overhead of just a single Composer repository.

A diagram showing where slowness occurs when a composer repository is missing {align="center"}

Include a Composer mirror in the form of a private Composer repository. The mirror contains a copy of all packages from other Composer repositories as well as all Git hosted packages. With a private Composer repository, you additionally get fine grained access control.

With Git synchronization, a private Composer repository automatically detects new packages in your Git repositories as well as new versions of existing packages.

You can host your own private repository with Satis: https://composer.github.io/satis/. See an example public repository at https://antonevers.github.io/gra-composer-repository/. This repo is used as the composer repository in the code examples. Additional measures are necessary to make a Satis repository private.

There are solutions that you can configure and forget about: Private Packagist https://packagist.com/, which is made by the same people that wrote Composer or JFrog Artifactory https://jfrog.com/artifactory/.

Deliver code

With metapackages, there are 3 steps to deliver code.

  1. Merge changes into packages and version the changed packages.
  2. (Opcional, somente se novos pacotes forem adicionados) Exigir os novos pacotes em metapackages e criar a versão dos metapackages.
  3. (Opcional, somente se novos pacotes forem adicionados) Exigir os novos metapackages no Adobe Commerce e implantar.

O escopo de implantação é controlado com versões de pacote. A criação de uma versão estável de um pacote significa que ele está pronto para a implantação de produção.

Para criar uma nova versão, execute a atualização do Composer no projeto Composer principal, que contém a instalação de armazenamento completo. Todas as versões mais recentes dos pacotes são instaladas.

Controle de versão

Controle de versão em pacotes separados GRA é um sinônimo de módulos de marcação no Git. As tags Git criam versões numeradas dos seus pacotes que o Composer instala.
A abordagem de controle de versão correta permite que seus pacotes fluam automaticamente e, ao mesmo tempo, permaneçam seguros.

Dois exemplos:

{
    "name": "antonevers/gra-meta-foundation",
    "type": "metapackage",
    "require": {
        "antonevers/gra-component-foundation": "1.1.4",
        "antonevers/module-gra": "1.0.0",
        "antonevers/module-3rdparty": "1.3.89"
    }
}

Este exemplo mostra uma definição estrita de dependências. 3 pacotes são necessários nas versões exatas. A atualização do Composer com este metapackage na sua instalação não faz nada. Ele sempre instala esses três pacotes nessas versões exatas, mesmo se uma versão mais recente estiver disponível.

{
    "name": "antonevers/gra-meta-foundation",
    "type": "metapackage",
    "require": {
        "antonevers/gra-component-foundation": "~1.0",
        "antonevers/module-gra": "~1.0",
        "antonevers/module-3rdparty": "~1.0"
    }
}

Este exemplo mostra uma definição ampla de dependências. Com ~1.0, qualquer versão desses pacotes poderá ser instalada se forem maiores ou iguais a 1.0.0 e menores que 2.0.0, com preferência pela versão mais alta disponível. Você pode saber mais sobre como definir dependências de versão em https://getcomposer.org/doc/articles/versions.md:

O operador ~ é melhor explicado pelo exemplo: ~1.2 é equivalente a >=1.2 <2.0.0, enquanto ~1.2.3 é equivalente a >=1.2.3 <1.3.0.

Assim que você lançar uma nova versão de qualquer um dos pacotes mencionados, ela será instalada automaticamente com a atualização do Composer.

Aplicar controle de versão semântico. Você pode aprender tudo sobre o controle de versão semântico em https://semver.org/. Especialmente, as Perguntas frequentes são obrigatórias. Com o controle de versão semântico, os números em “1.0.0” são chamados de MAJOR.MINOR.PATCH. As versões secundárias e de patch de um pacote devem ser introduzidas com segurança, sem quebrar o aplicativo.
Você pode incluir patches automaticamente e escolher atualizações secundárias manualmente. Esteja ciente de que isso custa despesas gerais adicionais ao selecionar cada pequena alteração manualmente:

{
    "name": "antonevers/gra-meta-foundation",
    "type": "metapackage",
    "require": {
        "antonevers/gra-component-foundation": "~1.1.0",
        "antonevers/module-gra": "~1.0.0",
        "antonevers/module-3rdparty": "~1.3.0"
    }
}

É claro que tudo isso só funciona se você aplicar o controle de versão semântico de forma consistente, sempre. E não apenas em metapackages, mas os requisitos de seus pacotes regulares também devem definir dependências livremente. Se você tiver uma dependência estrita no sistema, esse pacote será limitado à definição estrita.

Encontre essas dependências estritas digitando composer depends &lt;nome do pacote>. Consulte https://getcomposer.org/doc/03-cli.md#depends-why para obter mais informações.

Estratégia de ramificação

É possível usar várias estratégias de ramificação para suportar esse padrão de estratégia de referência global, desde que a ramificação principal seja a única ramificação na qual você cria a versão dos seus pacotes. Se você analisar a versão em várias ramificações, isso apresenta o risco de perder aleatoriamente a funcionalidade entre as versões. Criar apenas versões estáveis na ramificação principal.

Criar ramificações de recursos somente nos repositórios de packages. Não nos repositórios de instalação da loja. Permaneça capaz de introduzir qualquer alteração na sua loja apenas usando o Composer. Evite a necessidade de mesclagens Git no repositório de implantação.

Tipos de ramificação comuns em estratégias e repositórios de ramificação nos quais devem existir:

Ramificações de recursos: existem em seus repositórios de pacotes, em nenhum outro lugar.

Ramificações de versão: são criadas em qualquer repositório: pacotes, metapackages, repositórios de instalação de armazenamento. Ao planejar uma versão, agrupe as alterações nas ramificações de lançamento dos pacotes antes de fazer o controle de versão. Suponha que você esteja preparando uma versão com o nome de código “Unicórnio”. Você pode criar uma ramificação de unicórnio de versão em pacotes com alterações. Mescle qualquer coisa nele e exija “dev-release-unicorn as 1.4.0” em seu metapackage. Saiba mais sobre aliases para ver o que está acontecendo lá: https://getcomposer.org/doc/articles/aliases.md.

Ramificações de controle de qualidade/desenvolvimento: semelhante às ramificações de lançamento.

Ramificação principal: deve existir em todos os repositórios e sempre deve ser a ramificação que representa um estado de produção ou pronto para produção. A ramificação principal é onde você marca o código para versões de lançamento.
Escolha uma estratégia de ramificação com pouca sobrecarga de manutenção. Por exemplo, mesclar a ramificação principal de volta às ramificações de controle de qualidade, UAT, versão ou desenvolvimento após uma versão de hotfix é uma tarefa de manutenção de sobrecarga. Quanto mais packages, mais repositórios e mais tarefas de overhead repetitivas.

Use uma ferramenta como mixu/gr para executar operações de rotina em vários repositórios Git em um lote: https://github.com/mixu/gr

Nomeação de convenções

Com o padrão GRA de Pacotes Separados, os pacotes fazem parte da base GRA se o metapackage de base os exigir. Adicione ou remova pacotes do metapackage para movê-los para dentro e para fora da base.

Os metapackages oferecem flexibilidade ao escopo de instalação dos pacotes. É extremamente importante que os nomes dos pacotes não contenham palavras relacionadas ao uso pretendido do pacote. O nome antonevers/module-gra-store-locator pode se tornar confuso quando você decide retirar esse pacote da base GRA. Evite o escopo (GRA, fundação, local). Evite a região (EMEA, Espanha, Global). Definitivamente, evite o nome do armazenamento para o qual um pacote é criado. Escolha nomes que se relacionam apenas à funcionalidade que é adicionada no pacote. Dessa forma, você pode reutilizá-los em qualquer lugar que desejar, também em cenários futuros imprevistos. O nome antonevers/module-store-locator seria excelente.

Verifique se os pacotes relacionados são exibidos juntos nas visões gerais. Crie nomes de genéricos para específicos. Então, antonevers/module-b2b-tax-free ao invés de antonevers/tax-free-module-b2b.

Exemplos de código

Os exemplos de código desta publicação do blog foram combinados em um conjunto de repositórios Git, que podem ser usados para reproduzir com a prova de conceito.

recommendation-more-help
commerce-learn-help-home