Skip to content

Commit 79f9c1b

Browse files
authored
CEXT-772: Add support for deployments on Commerce Cloud (#99)
1 parent 78d05b7 commit 79f9c1b

File tree

9 files changed

+311
-26
lines changed

9 files changed

+311
-26
lines changed

config/schema.error.yaml

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@
139139
!php/const Magento\MagentoCloud\App\Error::BUILD_WRONG_BRAINTREE_VARIABLE:
140140
step: validate-config
141141
title: 'Remove Magento Braintree module configuration which is no longer supported in Adobe Commerce and Magento Open Source 2.4 and later versions.'
142-
suggestion: 'Support for the Braintree module is no longer included with Magento 2.4.0 and later. Remove the CONFIG__STORES__DEFAULT__PAYMENT__BRAINTREE__CHANNEL variable from the variables section of the .magento.app.yaml file. For Braintree payment support, use an official extension from the Commerce Marketplace instead.'
142+
suggestion: 'Support for the Braintree module is no longer included with Magento 2.4.0 and later. Remove the CONFIG__STORES__DEFAULT__PAYMENT__BRAINTREE__CHANNEL variable from the variables section of the `.magento.app.yaml` file. For Braintree payment support, use an official extension from the Commerce Marketplace instead.'
143143
stage: build
144144
type: critical
145145
!php/const Magento\MagentoCloud\App\Error::DEPLOY_WRONG_CACHE_CONFIGURATION:
@@ -334,7 +334,7 @@
334334
!php/const Magento\MagentoCloud\App\Error::DEPLOY_WRONG_BRAINTREE_VARIABLE:
335335
step: validate-config
336336
title: 'Remove Magento Braintree module configuration which is no longer supported in Adobe Commerce or Magento Open Source 2.4 and later versions.'
337-
suggestion: 'Support for the Braintree module is no longer included with Adobe Commerce or Magento Open Source 2.4.0 and later. Remove the CONFIG__STORES__DEFAULT__PAYMENT__BRAINTREE__CHANNEL variable from the variables section of the .magento.app.yaml file. For Braintree support, use an official Braintree Payments extension from the Commerce Marketplace instead.'
337+
suggestion: 'Support for the Braintree module is no longer included with Adobe Commerce or Magento Open Source 2.4.0 and later. Remove the CONFIG__STORES__DEFAULT__PAYMENT__BRAINTREE__CHANNEL variable from the variables section of the `.magento.app.yaml` file. For Braintree support, use an official Braintree Payments extension from the Commerce Marketplace instead.'
338338
stage: deploy
339339
type: critical
340340
!php/const Magento\MagentoCloud\App\Error::DEPLOY_ES_SERVICE_NOT_INSTALLED:
@@ -430,6 +430,16 @@
430430
suggestion: ''
431431
stage: general
432432
type: critical
433+
!php/const Magento\MagentoCloud\App\Error::GLOBAL_EVENTING_MODULE_GENERATE_FAILED:
434+
title: 'Unable to generate a module for eventing'
435+
suggestion: 'Check the `cloud.log` for more information.'
436+
stage: general
437+
type: critical
438+
!php/const Magento\MagentoCloud\App\Error::GLOBAL_EVENTING_MODULE_ENABLEMENT_FAILED:
439+
title: 'Unable to enable a module for eventing'
440+
suggestion: 'Check the `cloud.log` for more information.'
441+
stage: general
442+
type: critical
433443
# Warning errors
434444
!php/const Magento\MagentoCloud\App\Error::WARN_CONFIG_PHP_NOT_EXISTS:
435445
title: 'File app/etc/config.php does not exist'

config/schema.yaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -706,6 +706,17 @@ variables:
706706
config:
707707
region: us-east-1
708708
bucket: test-bucket
709+
ENABLE_EVENTING:
710+
description: Enables commerce eventing.
711+
type: boolean
712+
stages:
713+
- global
714+
default:
715+
global: false
716+
examples:
717+
- stage:
718+
global:
719+
ENABLE_EVENTING: true
709720

710721
# Environment variables
711722
ENV_RELATIONSHIPS:

dist/error-codes.md

Lines changed: 26 additions & 24 deletions
Large diffs are not rendered by default.

scenario/build/generate.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
<step name="set-report-dir-nesting-level" type="Magento\MagentoCloud\Step\Build\SetReportDirNestingLevel" priority="700"/>
2929
<step name="marshall-files" type="Magento\MagentoCloud\Step\Build\MarshallFiles" priority="800"/>
3030
<step name="copy-sample-data" type="Magento\MagentoCloud\Step\Build\CopySampleData" priority="900"/>
31+
<step name="enable-eventing" type="Magento\MagentoCloud\Step\Build\EnableEventing" priority="950" />
3132
<step name="compile-di" type="Magento\MagentoCloud\Step\Build\CompileDi" priority="1000"/>
3233
<step name="dump-autoload" type="Magento\MagentoCloud\Step\Build\ComposerDumpAutoload" priority="1100"/>
3334
<step name="deploy-static-content" type="Magento\MagentoCloud\Step\Build\DeployStaticContent" priority="1200">

src/App/Error.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ class Error
9494
public const GLOBAL_CONFIG_PARSE_FAILED = 244;
9595
public const GLOBAL_CONFIG_UNABLE_TO_READ = 245;
9696
public const GLOBAL_CONFIG_UNABLE_TO_READ_SCHEMA_YAML = 246;
97+
public const GLOBAL_EVENTING_MODULE_GENERATE_FAILED = 247;
98+
public const GLOBAL_EVENTING_MODULE_ENABLEMENT_FAILED = 248;
9799

98100
/**
99101
* Build

src/Config/StageConfigInterface.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ interface StageConfigInterface
4242
public const VAR_SCD_MATRIX = 'SCD_MATRIX';
4343
public const VAR_SCD_NO_PARENT = 'SCD_NO_PARENT';
4444
public const VAR_X_FRAME_CONFIGURATION = 'X_FRAME_CONFIGURATION';
45+
public const VAR_ENABLE_EVENTING = 'ENABLE_EVENTING';
4546

4647
/**
4748
* Settings for deployment from git.

src/Step/Build/EnableEventing.php

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\MagentoCloud\Step\Build;
9+
10+
use Magento\MagentoCloud\App\Error;
11+
use Magento\MagentoCloud\Config\ConfigException;
12+
use Magento\MagentoCloud\Config\GlobalSection;
13+
use Magento\MagentoCloud\Config\StageConfigInterface;
14+
use Magento\MagentoCloud\Shell\MagentoShell;
15+
use Magento\MagentoCloud\Shell\ShellException;
16+
use Magento\MagentoCloud\Shell\ShellFactory;
17+
use Magento\MagentoCloud\Step\StepException;
18+
use Magento\MagentoCloud\Step\StepInterface;
19+
use Psr\Log\LoggerInterface;
20+
21+
/**
22+
* Runs a command to generate a module for eventing and enables this module in case when
23+
* it is enabled in configuration
24+
*/
25+
class EnableEventing implements StepInterface
26+
{
27+
/**
28+
* @var LoggerInterface
29+
*/
30+
private $logger;
31+
32+
/**
33+
* @var MagentoShell
34+
*/
35+
private $magentoShell;
36+
37+
/**
38+
* @var GlobalSection
39+
*/
40+
private $globalConfig;
41+
42+
/**
43+
* @param LoggerInterface $logger
44+
* @param ShellFactory $shellFactory
45+
* @param GlobalSection $globalConfig
46+
*/
47+
public function __construct(
48+
LoggerInterface $logger,
49+
ShellFactory $shellFactory,
50+
GlobalSection $globalConfig
51+
) {
52+
$this->logger = $logger;
53+
$this->magentoShell = $shellFactory->createMagento();
54+
$this->globalConfig = $globalConfig;
55+
}
56+
57+
/**
58+
* Generates and enables a module for eventing if @see StageConfigInterface::VAR_ENABLE_EVENTING set to true
59+
*
60+
* {@inheritDoc}
61+
*/
62+
public function execute()
63+
{
64+
try {
65+
if (!$this->globalConfig->get(StageConfigInterface::VAR_ENABLE_EVENTING)) {
66+
return;
67+
}
68+
} catch (ConfigException $e) {
69+
throw new StepException($e->getMessage(), $e->getCode(), $e);
70+
}
71+
72+
try {
73+
$this->logger->notice('Generating module for eventing');
74+
$this->magentoShell->execute('events:generate:module');
75+
} catch (ShellException $e) {
76+
$this->logger->error(
77+
'Failed to generate the Magento_AdobeCommerceEvents module. ' .
78+
'Refer to the eventing documentation to determine if all required modules are have been installed. ' .
79+
'Error: ' . $e->getMessage()
80+
);
81+
throw new StepException($e->getMessage(), Error::GLOBAL_EVENTING_MODULE_GENERATE_FAILED, $e);
82+
}
83+
84+
try {
85+
$this->logger->notice('Enabling module for eventing');
86+
$this->magentoShell->execute('module:enable Magento_AdobeCommerceEvents');
87+
} catch (ShellException $e) {
88+
$this->logger->error('Failed to enable module for eventing: ' . $e->getMessage());
89+
throw new StepException($e->getMessage(), Error::GLOBAL_EVENTING_MODULE_ENABLEMENT_FAILED, $e);
90+
}
91+
}
92+
}

src/Test/Unit/Config/SchemaTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ public function testGetDefaultsForGlobalSection(): void
174174
StageConfigInterface::VAR_DEPLOY_FROM_GIT_OPTIONS => [],
175175
StageConfigInterface::VAR_MIN_LOGGING_LEVEL => '',
176176
StageConfigInterface::VAR_X_FRAME_CONFIGURATION => 'SAMEORIGIN',
177+
StageConfigInterface::VAR_ENABLE_EVENTING => false,
177178
],
178179
$this->schema->getDefaults(StageConfigInterface::STAGE_GLOBAL)
179180
);
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\MagentoCloud\Test\Unit\Step\Build;
9+
10+
use Magento\MagentoCloud\App\Error;
11+
use Magento\MagentoCloud\Config\GlobalSection;
12+
use Magento\MagentoCloud\Config\StageConfigInterface;
13+
use Magento\MagentoCloud\Shell\MagentoShell;
14+
use Magento\MagentoCloud\Shell\ShellException;
15+
use Magento\MagentoCloud\Shell\ShellFactory;
16+
use Magento\MagentoCloud\Step\Build\EnableEventing;
17+
use Magento\MagentoCloud\Step\StepException;
18+
use PHPUnit\Framework\MockObject\MockObject;
19+
use PHPUnit\Framework\TestCase;
20+
use Psr\Log\LoggerInterface;
21+
22+
/**
23+
* @inheritDoc
24+
*/
25+
class EnableEventingTest extends TestCase
26+
{
27+
/**
28+
* @var EnableEventing
29+
*/
30+
private $step;
31+
32+
/**
33+
* @var LoggerInterface|MockObject
34+
*/
35+
private $loggerMock;
36+
37+
/**
38+
* @var MagentoShell|MockObject
39+
*/
40+
private $magentoShellMock;
41+
42+
/**
43+
* @var GlobalSection|MockObject
44+
*/
45+
private $globalConfigMock;
46+
47+
/**
48+
* @inheritdoc
49+
*/
50+
protected function setUp(): void
51+
{
52+
$this->loggerMock = $this->getMockForAbstractClass(LoggerInterface::class);
53+
$this->magentoShellMock = $this->createMock(MagentoShell::class);
54+
/** @var ShellFactory|MockObject $shellFactoryMock */
55+
$shellFactoryMock = $this->createMock(ShellFactory::class);
56+
$shellFactoryMock->expects($this->once())
57+
->method('createMagento')
58+
->willReturn($this->magentoShellMock);
59+
$this->globalConfigMock = $this->createMock(GlobalSection::class);
60+
61+
$this->step = new EnableEventing(
62+
$this->loggerMock,
63+
$shellFactoryMock,
64+
$this->globalConfigMock
65+
);
66+
}
67+
68+
/**
69+
* @return void
70+
* @throws \Magento\MagentoCloud\Step\StepException
71+
*/
72+
public function testExecuteEventingNotEnabled()
73+
{
74+
$this->globalConfigMock->expects(self::once())
75+
->method('get')
76+
->with(StageConfigInterface::VAR_ENABLE_EVENTING)
77+
->willReturn(false);
78+
79+
$this->magentoShellMock->expects(self::never())
80+
->method('execute');
81+
$this->loggerMock->expects(self::never())
82+
->method('notice');
83+
84+
$this->step->execute();
85+
}
86+
87+
/**
88+
* @return void
89+
* @throws \Magento\MagentoCloud\Step\StepException
90+
*/
91+
public function testExecuteGenerateCommandFailed()
92+
{
93+
$this->expectException(StepException::class);
94+
$this->expectExceptionMessage('error during module generation');
95+
$this->expectExceptionCode(Error::GLOBAL_EVENTING_MODULE_GENERATE_FAILED);
96+
97+
$this->globalConfigMock->expects(self::once())
98+
->method('get')
99+
->with(StageConfigInterface::VAR_ENABLE_EVENTING)
100+
->willReturn(true);
101+
$this->magentoShellMock->expects(self::once())
102+
->method('execute')
103+
->with('events:generate:module')
104+
->willThrowException(new ShellException('error during module generation'));
105+
$this->loggerMock->expects(self::once())
106+
->method('notice');
107+
$this->loggerMock->expects(self::once())
108+
->method('error');
109+
110+
$this->step->execute();
111+
}
112+
113+
/**
114+
* @return void
115+
* @throws \Magento\MagentoCloud\Step\StepException
116+
*/
117+
public function testExecuteEnableModuleCommandFailed()
118+
{
119+
$this->expectException(StepException::class);
120+
$this->expectExceptionMessage('error during module enablement');
121+
$this->expectExceptionCode(Error::GLOBAL_EVENTING_MODULE_ENABLEMENT_FAILED);
122+
123+
$this->globalConfigMock->expects(self::once())
124+
->method('get')
125+
->with(StageConfigInterface::VAR_ENABLE_EVENTING)
126+
->willReturn(true);
127+
$this->magentoShellMock->expects(self::at(0))
128+
->method('execute')
129+
->with('events:generate:module');
130+
$this->magentoShellMock->expects(self::at(1))
131+
->method('execute')
132+
->with('module:enable Magento_AdobeCommerceEvents')
133+
->willThrowException(new ShellException('error during module enablement'));
134+
$this->loggerMock->expects(self::exactly(2))
135+
->method('notice');
136+
$this->loggerMock->expects(self::once())
137+
->method('error');
138+
139+
$this->step->execute();
140+
}
141+
142+
/**
143+
* @return void
144+
* @throws \Magento\MagentoCloud\Step\StepException
145+
*/
146+
public function testExecuteSuccess()
147+
{
148+
$this->globalConfigMock->expects(self::once())
149+
->method('get')
150+
->with(StageConfigInterface::VAR_ENABLE_EVENTING)
151+
->willReturn(true);
152+
$this->magentoShellMock->expects(self::at(0))
153+
->method('execute')
154+
->with('events:generate:module');
155+
$this->magentoShellMock->expects(self::at(1))
156+
->method('execute')
157+
->with('module:enable Magento_AdobeCommerceEvents');
158+
$this->loggerMock->expects(self::exactly(2))
159+
->method('notice');
160+
$this->loggerMock->expects(self::never())
161+
->method('error');
162+
163+
$this->step->execute();
164+
}
165+
}

0 commit comments

Comments
 (0)