Skip to content
intermediate Phase 93 · Composer

Patches and Updates

Patches and updates - composer patches, security updates, upgrade planning

45m
0 problems
Topic Progress 0%

Composer Patches

cweagans/composer-patches

{
    "require": {
        "cweagans/composer-patches": "^1.7"
    },
    "extra": {
        "patches": {
            "magento/module-catalog": [
                {
                    "subject": "Fix product import issue",
                    "url": "patches/magento-catalog-import-fix.patch",
                    "depth": 0
                }
            ],
            "magento/module-checkout": [
                {
                    "subject": "Add custom field to checkout",
                    "url": "https://example.com/patches/checkout-custom-field.patch"
                }
            ]
        }
    }
}

Patch File Format

--- a/Model/Product/Import.php
+++ b/Model/Product/Import.php
@@ -100,10 +100,15 @@
     public function importProducts(array $data)
     {
+        // Custom fix for import issue
+        if (empty($data)) {
+            return [];
+        }
+
         foreach ($data as $item) {
             $this->processItem($item);
         }
     }

Patch Management

namespace Vendor\Patches\Manager;

class PatchManager
{
    private array $patches = [
        [
            'package' => 'magento/module-catalog',
            'subject' => 'Fix product import',
            'file' => 'patches/catalog-import.patch',
            'applied' => true,
        ],
    ];

    public function getStatus(): array
    {
        return $this->patches;
    }

    public function validatePatches(): ValidationResult
    {
        $errors = [];

        foreach ($this->patches as $patch) {
            if (!file_exists($patch['file'])) {
                $errors[] = "Missing patch file: {$patch['file']}";
            }
        }

        return new ValidationResult(empty($errors), $errors);
    }
}

Security Updates

Security Patch Process

namespace Vendor\Security\Update;

class SecurityUpdateManager
{
    private ComposerRunnerInterface $composer;
    private DeploymentInterface $deployment;

    public function applySecurityPatch(string $patchVersion): UpdateResult
    {
        // Step 1: Update composer.json
        $this->updateVersionConstraints($patchVersion);

        // Step 2: Run composer update
        $this->composer->update([
            'magento/*',
            '--with-dependencies',
        ]);

        // Step 3: Apply database updates
        $this->deployment->runSetupUpgrade();

        // Step 4: Clear cache
        $this->deployment->clearCache();

        // Step 5: Deploy static content
        $this->deployment->deployStaticContent();

        return new UpdateResult([
            'version' => $patchVersion,
            'status' => 'applied',
        ]);
    }
}

Security Patch Checklist

namespace Vendor\Security\Checklist;

class SecurityPatchChecklist
{
    public function getChecklist(): array
    {
        return [
            'Backup database',
            'Backup files',
            'Review patch notes',
            'Test in staging',
            'Apply to production',
            'Run setup:upgrade',
            'Clear cache',
            'Deploy static content',
            'Verify site functionality',
            'Monitor logs',
        ];
    }
}

Upgrade Planning

Upgrade Strategy

namespace Vendor\Upgrade\Strategy;

class UpgradePlanner
{
    public function planUpgrade(
        string $currentVersion,
        string $targetVersion
    ): UpgradePlan {
        $steps = [];

        // Step 1: Review release notes
        $steps[] = new UpgradeStep(
            'review',
            'Review release notes and breaking changes'
        );

        // Step 2: Update dependencies
        $steps[] = new UpgradeStep(
            'dependencies',
            'Update composer.json constraints'
        );

        // Step 3: Apply patches
        $steps[] = new UpgradeStep(
            'patches',
            'Review and update custom patches'
        );

        // Step 4: Test
        $steps[] = new UpgradeStep(
            'test',
            'Run full test suite in staging'
        );

        // Step 5: Deploy
        $steps[] = new UpgradeStep(
            'deploy',
            'Deploy to production'
        );

        return new UpgradePlan(
            $currentVersion,
            $targetVersion,
            $steps
        );
    }
}

Version Comparison

namespace Vendor\Upgrade\Compare;

class VersionComparator
{
    public function compare(
        string $from,
        string $to
    ): ComparisonResult {
        $fromParts = explode('.', $from);
        $toParts = explode('.', $to);

        $breakingChanges = [];

        // Major version change = breaking
        if ($fromParts[0] !== $toParts[0]) {
            $breakingChanges[] = 'Major version change - likely breaking changes';
        }

        // Minor version check
        if ($fromParts[1] !== $toParts[1]) {
            $breakingChanges[] = 'Minor version change - new features';
        }

        return new ComparisonResult([
            'from' => $from,
            'to' => $to,
            'breaking_changes' => $breakingChanges,
            'risk_level' => empty($breakingChanges) ? 'low' : 'high',
        ]);
    }
}

Patch Documentation

Patch Log

namespace Vendor\Patches\Log;

class PatchLog
{
    private PatchLogRepositoryInterface $logRepo;

    public function log(
        string $package,
        string $subject,
        string $status,
        ?string $notes = null
    ): void {
        $log = new PatchLogData([
            'package' => $package,
            'subject' => $subject,
            'status' => $status,
            'notes' => $notes,
            'applied_by' => $this->auth->getUser()->getName(),
            'applied_at' => new \DateTime(),
        ]);

        $this->logRepo->save($log);
    }
}

Patch Inventory

namespace Vendor\Patches\Inventory;

class PatchInventory
{
    public function getInventory(): array
    {
        return [
            [
                'id' => 'PATCH-001',
                'package' => 'magento/module-catalog',
                'subject' => 'Fix product import issue',
                'applied_date' => '2024-01-15',
                'applied_by' => 'admin',
                'status' => 'applied',
                'notes' => 'Fixes CSV import validation',
            ],
            [
                'id' => 'PATCH-002',
                'package' => 'magento/module-checkout',
                'subject' => 'Add custom checkout field',
                'applied_date' => '2024-01-20',
                'applied_by' => 'developer',
                'status' => 'applied',
                'notes' => 'Adds company name field',
            ],
        ];
    }
}

Quiz

1. What is a Composer patch?

Question 1 options

2. What should you do before applying security updates?

Question 2 options

3. How do you track applied patches?

Question 3 options

Flashcards

Question

What is a Composer patch?

Answer

Code modification applied via cweagans/composer-patches

Question

What is a security update?

Answer

Patch addressing security vulnerabilities

Question

What is upgrade planning?

Answer

Strategy for moving between major/minor versions

Question

Why track patches?

Answer

For documentation, rollback, and upgrade planning

Revision Notes

Key Takeaways

  • 1. Composer patches apply code modifications automatically
  • 2. Security updates require careful planning and backups
  • 3. Upgrade planning assesses risk and breaking changes
  • 4. Patch documentation tracks applied modifications
  • 5. Always test patches in staging before production

Interview Tips

  • Explain the patch application process
  • Discuss security update procedures
  • Describe upgrade planning methodology
  • Talk about patch documentation best practices

Cheat Sheet

Patches:
  cweagans/composer-patches
  patches in extra section
  .patch or .diff files

Security Updates:
  Backup → Review → Test → Deploy
  composer update with dependencies
  setup:upgrade → cache → static deploy

Upgrade Planning:
  Review release notes
  Update constraints
  Test in staging
  Deploy to production