From ff99639b94682140270c6eae4200b08801681816 Mon Sep 17 00:00:00 2001 From: Ryan Hoerr Date: Mon, 10 Nov 2025 21:59:09 -0500 Subject: [PATCH 01/12] feature: generate additional release metapackages by definition (WIP) --- .../mageos-release-build-config.js | 58 ++++++++++ src/build-config/packages-config.js | 38 ++++++- src/make/mageos-release.js | 18 +--- src/mirror-build-tools.js | 65 ++++++++--- src/package-modules.js | 85 +++++++++++++++ src/release-branch-build-tools.js | 39 +++---- src/release-build-tools.js | 101 +++++------------- src/type/metapackage-definition.js | 57 ++++++++++ src/type/repository-build-definition.js | 31 +++--- 9 files changed, 348 insertions(+), 144 deletions(-) create mode 100644 src/type/metapackage-definition.js diff --git a/src/build-config/mageos-release-build-config.js b/src/build-config/mageos-release-build-config.js index 02a90f3..2c6a640 100644 --- a/src/build-config/mageos-release-build-config.js +++ b/src/build-config/mageos-release-build-config.js @@ -1,6 +1,7 @@ const packagesConfig = require('./packages-config'); const {mergeBuildConfigs} = require('../utils'); +const {updateComposerConfigFromMagentoToMageOs} = require('../release-build-tools'); const releaseBuildConfig = { 'magento2': { @@ -13,6 +14,63 @@ const releaseBuildConfig = { composerJsonPath: `${__dirname}/../../resource/composer-templates/mage-os/magento2-base/template.json`, } ], + extraMetapackages: [ + { + // @TODO: Change full name to just the package name? + name: 'mage-os/project-community-edition', + type: 'project', + description: 'Mage-OS Community Edition Project', + // @TODO: I don't think this is right + basePackage: 'magento2-base', + historyPath: 'project-community-edition', + transform: [ + (composerConfig, instruction, release) => { + updateComposerConfigFromMagentoToMageOs(instruction, release, composerConfig); + return composerConfig; + } + ] + }, + { + name: 'mage-os/product-community-edition', + type: 'metapackage', + description: 'Mage-OS Community Edition', + basePackage: 'magento2-base', + historyPath: 'product-community-edition', + transform: [ + (composerConfig, instruction, release) => { + updateComposerConfigFromMagentoToMageOs(instruction, release, composerConfig) + + // Add upstreamRelease to composer extra data for reference + composerConfig.extra = composerConfig.extra || {}; + composerConfig.extra.magento_version = release.replaceVersions['magento/product-community-edition']; + + return composerConfig + } + ] + }, + { + name: 'mage-os/project-minimal', + type: 'metapackage', + description: 'Mage-OS Minimal Edition Project', + basePackage: 'magento2-base', + exclude: [ + 'mage-os/module-page-builder', + 'mage-os/module-adobe-*' + ], + historyPath: 'project-minimal' + }, + { + name: 'mage-os/product-minimal', + type: 'metapackage', + description: 'Mage-OS Minimal Edition', + basePackage: 'magento2-base', + exclude: [ + 'mage-os/module-page-builder', + 'mage-os/module-adobe-*' + ], + historyPath: 'product-minimal' + } + ] }, 'security-package': { repoUrl: 'https://github.com/mage-os/mageos-security-package.git', diff --git a/src/build-config/packages-config.js b/src/build-config/packages-config.js index 88591bd..8667c02 100644 --- a/src/build-config/packages-config.js +++ b/src/build-config/packages-config.js @@ -2,9 +2,6 @@ const packageDefs = { 'magento2': { repoUrl: 'https://github.com/mage-os/mirror-magento2.git', - magentoCommunityEditionProject: true, - magentoCommunityEditionMetapackage: true, - packageDirs: [ {label: 'Magento Core Modules', dir: 'app/code/Magento'}, {label: 'Magento Language packages', dir: 'app/i18n/Magento'} @@ -69,6 +66,41 @@ const packageDefs = { }, ], packageMetaFromDirs: [], + extraMetapackages: [ + { + // @TODO: Change full name to just the package name? + name: 'magento/project-community-edition', + type: 'project', + description: 'Magento Community Edition Project', + // @TODO: I don't think this is right + basePackage: 'magento2-base', + historyPath: 'project-community-edition', + transform: [ + (composerConfig, instruction, release) => { + updateComposerConfigFromMagentoToMageOs(instruction, release, composerConfig); + return composerConfig; + } + ] + }, + { + name: 'magento/product-community-edition', + type: 'metapackage', + description: 'Magento Community Edition', + basePackage: 'magento2-base', + historyPath: 'product-community-edition', + transform: [ + (composerConfig, instruction, release) => { + updateComposerConfigFromMagentoToMageOs(instruction, release, composerConfig) + + // Add upstreamRelease to composer extra data for reference + composerConfig.extra = composerConfig.extra || {}; + composerConfig.extra.magento_version = release.replaceVersions['magento/product-community-edition']; + + return composerConfig + } + ] + } + ] }, 'security-package': { repoUrl: 'https://github.com/mage-os/mirror-security-package.git', diff --git a/src/make/mageos-release.js b/src/make/mageos-release.js index a3b8ce4..0dc4485 100644 --- a/src/make/mageos-release.js +++ b/src/make/mageos-release.js @@ -84,21 +84,9 @@ let distroRelease = new buildState({ if (! skipHistory) { console.log(`Building previous ${mageosVendor} releases`) for (const instruction of releaseInstructions) { - // set vendor for product-community-edition and project-community-edition meta packages - if (instruction.magentoCommunityEditionProject || instruction.magentoCommunityEditionMetapackage) { - instruction.vendor = mageosVendor - } - if (instruction.magentoCommunityEditionMetapackage) { - // update product package magento dependencies taken from the root composer.json to given vendor - const productPackage = `${mageosVendor}/product-community-edition`; - - instruction.transform[productPackage] = instruction.transform[productPackage] || []; - instruction.transform[productPackage].push((composerConfig, instruction, release) => { - updateComposerConfigFromMagentoToMageOs(instruction, release, composerConfig) - return composerConfig - }) - } - await processMirrorInstruction(instruction) + instruction.vendor = mageosVendor; + + await processMirrorInstruction(instruction); } } diff --git a/src/mirror-build-tools.js b/src/mirror-build-tools.js index b19d972..7f9a3ba 100644 --- a/src/mirror-build-tools.js +++ b/src/mirror-build-tools.js @@ -5,10 +5,10 @@ const zip = require('jszip'); const { createPackagesForRef, createPackageForRef, - createMagentoCommunityEditionMetapackage, - createMagentoCommunityEditionProject, createMetaPackageFromRepoDir, - archiveFilePath + archiveFilePath, + getAdditionalDependencies, + createComposerJsonOnlyPackage } = require('./package-modules'); const repositoryBuildDefinition = require('./type/repository-build-definition'); const packageDefinition = require('./type/package-definition'); @@ -242,6 +242,52 @@ async function replacePackageFiles(package) { }); } +/** + * @param {repositoryBuildDefinition} instruction + * @param {Object} metapackage + * @returns {Array} Packaged tags + */ +async function createMetaPackagesSinceTag(instruction, metapackage) { + const tags = await listTagsFrom(instruction.repoUrl, instruction.fromTag, instruction.skipTags); + console.log(`Versions to process for metapackage ${metapackage.name}: ${tags.join(', ')}`); + for (const tag of tags) { + console.log(`Processing ${tag}`); + let release = new buildState({ + ref: tag, + fallbackVersion: tag, + dependencyVersions: (instruction.fixVersions?.[tag] ?? {}) + }); + // Try to load additional dependencies from resource history + /** + * @TODO: This isn't quite right, but I haven't wrapped my head around it yet. + * additional gives `require` only, we need to merge it into the base json for the version + * create... loads ./composer.json for the given release tag, and adds/transforms based on the ref history. + */ + let additionalDeps = await getAdditionalDependencies(metapackage.name, tag); + await createComposerJsonOnlyPackage( + instruction, + release, + metapackage.name, + tag, + composerConfig => { + // If additionalDeps found, use them + if (additionalDeps) { + // @TODO: I don't think so + Object.assign(composerConfig, {require: additionalDeps}); + } + // Apply transforms if any + if (metapackage.transform) { + for (const fn of metapackage.transform) { + composerConfig = fn(composerConfig, instruction, release); + } + } + return composerConfig; + } + ); + } + return tags; +} + /** * @param {repositoryBuildDefinition} instruction * @returns {Promise} @@ -277,16 +323,9 @@ async function processMirrorInstruction(instruction) { await replacePackageFiles(packageReplacement); } - if (instruction.magentoCommunityEditionMetapackage) { - console.log('Packaging Magento Community Edition Product Metapackage'); - tags = await createMagentoCommunityEditionMetapackagesSinceTag(instruction); - console.log('Magento Community Edition Product Metapackage', tags); - } - - if (instruction.magentoCommunityEditionProject) { - console.log('Packaging Magento Community Edition Project'); - tags = await createProjectPackagesSinceTag(instruction); - console.log('Magento Community Edition Project', tags); + for (const metapackage of instruction.extraMetapackages) { + console.log(`Packaging ${metapackage.name}`); + tags = await createMetaPackagesSinceTag(instruction, metapackage); } repo.clearCache(); diff --git a/src/package-modules.js b/src/package-modules.js index bdb68b8..6064c04 100644 --- a/src/package-modules.js +++ b/src/package-modules.js @@ -711,6 +711,90 @@ async function createMetaPackageFromRepoDir(instruction, package, release) { return {[name]: version} } +async function getBaseDependencies(instruction, basePackage) { + try { + const composerJson = await readComposerJson(instruction.repoUrl, '', instruction.ref); + const composerConfig = JSON.parse(composerJson); + return composerConfig.require || {}; + } catch (error) { + console.warn(`Could not load base dependencies from ${basePackage}: ${error.message}`); + return {}; + } +} + +function filterDependencies(dependencies, include, exclude) { + const filtered = {}; + + for (const [pkg, version] of Object.entries(dependencies)) { + if (exclude && exclude.some(pattern => { + return pattern.endsWith('*') + ? pkg.startsWith(pattern.slice(0, -1)) + : pkg === pattern; + })) { + continue; + } + + // @TODO: I don't think this is flexible enough. There's no additive ability. This also doesn't wildcard like excludes. + if (!include || include.length === 0 || include.includes(pkg)) { + filtered[pkg] = version; + } + } + + return filtered; +} + +async function createMetaPackage(instruction, metapackage, release) { + // Determine dependencies with base and filters + let dependencies = {}; + if (metapackage.basePackage) { + dependencies = await getBaseDependencies(instruction, metapackage.basePackage); + } + + dependencies = filterDependencies( + dependencies, + metapackage.include, + metapackage.exclude + ); + + // Create package config + let composerConfig = { + name: metapackage.name, + type: metapackage.type, + description: metapackage.description, + require: dependencies, + version: release.version || release.ref + }; + + // Apply transforms + composerConfig = metapackage.transform.reduce( + (config, fn) => fn(config, instruction, release), + composerConfig + ); + + if (instruction.transform[metapackage.name]) { + composerConfig = instruction.transform[metapackage.name].reduce( + (config, fn) => fn(config, instruction, release), + composerConfig + ); + } + + // Create package + const files = [{ + filepath: 'composer.json', + mtime: new Date(stableMtime), + contentBuffer: Buffer.from(JSON.stringify(composerConfig, null, 2), 'utf8'), + isExecutable: false + }]; + + const packageFilepath = archiveFilePath(metapackage.name, composerConfig.version); + + if (!isInAdditionalPackages(metapackage.name, composerConfig.version)) { + await writePackage(packageFilepath, files); + } + + return {[metapackage.name]: composerConfig.version}; +} + module.exports = { setArchiveBaseDir(newArchiveBaseDir) { archiveBaseDir = newArchiveBaseDir; @@ -723,6 +807,7 @@ module.exports = { createMagentoCommunityEditionMetapackage, createMagentoCommunityEditionProject, createMetaPackageFromRepoDir, + createMetaPackage, getLatestTag, archiveFilePath, diff --git a/src/release-branch-build-tools.js b/src/release-branch-build-tools.js index 1c0db79..eb94b32 100644 --- a/src/release-branch-build-tools.js +++ b/src/release-branch-build-tools.js @@ -2,8 +2,7 @@ const repo = require("./repository"); const { createPackagesForRef, createPackageForRef, - createMagentoCommunityEditionMetapackage, - createMagentoCommunityEditionProject, + createMetaPackage, createMetaPackageFromRepoDir, determinePackagesForRef, determinePackageForRef, @@ -46,17 +45,18 @@ async function getPackagesForBuildInstruction(instruction) { Object.assign(packages, toBeBuilt); } - if (instruction.magentoCommunityEditionMetapackage) { - console.log('Inspecting Magento Community Edition Product Metapackage'); - toBeBuilt = await determineMagentoCommunityEditionMetapackage(instruction.repoUrl, baseVersionsOnRef); - Object.assign(packages, toBeBuilt); - } + // @TODO: Update this code + // if (instruction.magentoCommunityEditionMetapackage) { + // console.log('Inspecting Magento Community Edition Product Metapackage'); + // toBeBuilt = await determineMagentoCommunityEditionMetapackage(instruction.repoUrl, baseVersionsOnRef); + // Object.assign(packages, toBeBuilt); + // } - if (instruction.magentoCommunityEditionProject) { - console.log('Inspecting Magento Community Edition Project'); - toBeBuilt = await determineMagentoCommunityEditionProject(instruction.repoUrl, baseVersionsOnRef); - Object.assign(packages, toBeBuilt); - } + // if (instruction.magentoCommunityEditionProject) { + // console.log('Inspecting Magento Community Edition Project'); + // toBeBuilt = await determineMagentoCommunityEditionProject(instruction.repoUrl, baseVersionsOnRef); + // Object.assign(packages, toBeBuilt); + // } repo.clearCache(); return packages; @@ -146,18 +146,9 @@ async function processBuildInstruction(instruction, release) { Object.assign(packages, built); } - if (instruction.magentoCommunityEditionMetapackage) { - console.log('Packaging Magento Community Edition Product Metapackage'); - built = await createMagentoCommunityEditionMetapackage(instruction, release); - Object.assign(packages, built); - } - - if (instruction.magentoCommunityEditionProject) { - console.log('Packaging Magento Community Edition Project'); - built = await createMagentoCommunityEditionProject( - instruction, - release - ); + for (const metapackage of (instruction.extraMetapackages || [])) { + console.log(`Building metapackage ${metapackage.name}`); + const built = await createMetaPackage(instruction, metapackage, release); Object.assign(packages, built); } diff --git a/src/release-build-tools.js b/src/release-build-tools.js index c59ae00..6d85be3 100644 --- a/src/release-build-tools.js +++ b/src/release-build-tools.js @@ -4,11 +4,12 @@ const repo = require("./repository"); const {accessSync, constants} = require("fs"); const fs = require("fs/promises"); const path = require("path"); -const {readComposerJson, createMagentoCommunityEditionMetapackage, +const { + readComposerJson, createPackagesForRef, createPackageForRef, - createMetaPackageFromRepoDir, - createMagentoCommunityEditionProject + createMetaPackage, + createMetaPackageFromRepoDir } = require('./package-modules'); const {isOnPackagist} = require('./packagist'); const repositoryBuildDefinition = require('./type/repository-build-definition'); @@ -235,61 +236,6 @@ async function prepPackageForRelease(instruction, package, release, workingCopyP await fs.writeFile(file, JSON.stringify(composerConfig, null, 2), 'utf8'); } -/** - * @param {repositoryBuildDefinition} instruction - * @param {buildState} release - * @returns {Promise<{}>} - */ -async function buildMageOsProductCommunityEditionMetapackage(instruction, release) { - console.log('Packaging Mage-OS Community Edition Product Metapackage'); - - return createMagentoCommunityEditionMetapackage( - instruction, - release, - { - transform: { - [`${instruction.vendor}/product-community-edition`]: [ - (composerConfig) => { - updateComposerConfigFromMagentoToMageOs(instruction, release, composerConfig) - - // Add upstreamRelease to composer extra data for reference - composerConfig.extra = composerConfig.extra || {}; - composerConfig.extra.magento_version = release.replaceVersions['magento/product-community-edition']; - - return composerConfig - } - ] - } - } - ) -} - -/** - * @param {repositoryBuildDefinition} instruction - * @param {buildState} release - * @returns {Promise} - */ -async function buildMageOsProjectCommunityEditionMetapackage(instruction, release) { - console.log('Packaging Mage-OS Community Edition Project'); - - return createMagentoCommunityEditionProject( - instruction, - release, - { - description: 'Community-built eCommerce Platform for Growth', - transform: { - [`${instruction.vendor}/project-community-edition`]: [ - (composerConfig) => { - updateComposerConfigFromMagentoToMageOs(instruction, release, composerConfig) - return composerConfig - } - ] - } - } - ) -} - - module.exports = { validateVersionString, updateComposerConfigFromMagentoToMageOs, @@ -351,18 +297,19 @@ module.exports = { await prepPackageForRelease(instruction, package, release, workingCopyPath); } - if (instruction.magentoCommunityEditionMetapackage) { - // nothing to do - the product-community-edition metapackage composer.json is built from a template - } + // @TODO: Update this code + // if (instruction.magentoCommunityEditionMetapackage) { + // // nothing to do - the product-community-edition metapackage composer.json is built from a template + // } - if (instruction.magentoCommunityEditionProject) { - // update the base composer.json for releasing (doesn't happen for the base package because that uses a composer.json template) - const metapackage = new packageDefinition({ - 'label': 'Mage-OS Community Edition Project Metapackage', - 'dir': '' - }); - await prepPackageForRelease(instruction, metapackage, release, workingCopyPath); - } + // if (instruction.magentoCommunityEditionProject) { + // // update the base composer.json for releasing (doesn't happen for the base package because that uses a composer.json template) + // const metapackage = new packageDefinition({ + // 'label': 'Mage-OS Community Edition Project Metapackage', + // 'dir': '' + // }); + // await prepPackageForRelease(instruction, metapackage, release, workingCopyPath); + // } return workBranch }, @@ -406,14 +353,14 @@ module.exports = { Object.assign(packages, built) } - if (instruction.magentoCommunityEditionMetapackage) { - const built = await buildMageOsProductCommunityEditionMetapackage(instruction, release) - Object.assign(packages, built) - } - - if (instruction.magentoCommunityEditionProject) { - const built = await buildMageOsProjectCommunityEditionMetapackage(instruction, release) - Object.assign(packages, built) + for (const metapackage of (instruction.extraMetapackages || [])) { + console.log(`Building metapackage ${metapackage.name}`); + const built = await createMetaPackage( + instruction, + metapackage, + release + ); + Object.assign(packages, built); } return packages diff --git a/src/type/metapackage-definition.js b/src/type/metapackage-definition.js new file mode 100644 index 0000000..4abd6fb --- /dev/null +++ b/src/type/metapackage-definition.js @@ -0,0 +1,57 @@ +class metapackageDefinition { + /** + * @type String Package name + */ + name = ''; + + /** + * @type String Package type + */ + type = 'metapackage'; + + /** + * @type String Package description + */ + description = ''; + + /** + * @type String|null Base package to extend from + */ + basePackage = null; + + /** + * @type Array Packages to include in the metapackage + */ + include = []; + + /** + * @type Array Packages to exclude from the metapackage + */ + exclude = []; + + /** + * @type Array Transform functions to apply + */ + transform = []; + + /** + * @type String|null Path to history file + */ + historyPath = null; + + /** + * @param {{name: String, type: String, description: String, basePackage: String, include: Array, exclude: Array, transform: Array, historyPath: String}} config + */ + constructor(config = {}) { + this.name = config.name || this.name; + this.type = config.type || this.type; + this.description = config.description || this.description; + this.basePackage = config.basePackage || this.basePackage; + this.include = config.include || this.include; + this.exclude = config.exclude || this.exclude; + this.transform = config.transform || this.transform; + this.historyPath = config.historyPath || this.historyPath; + } +} + +module.exports = metapackageDefinition; diff --git a/src/type/repository-build-definition.js b/src/type/repository-build-definition.js index f394730..e32c900 100644 --- a/src/type/repository-build-definition.js +++ b/src/type/repository-build-definition.js @@ -3,6 +3,7 @@ const extraRefToRelease = require('./extra-ref-to-release'); const packageDefinition = require('./package-definition'); const packageReplacement = require('./package-replacement'); +const metapackageDefinition = require('./metapackage-definition'); /** * Defines release build instructions for a git repository. @@ -31,14 +32,9 @@ class repositoryBuildDefinition { packageMetaFromDirs = []; /** - * @type Boolean Whether this package is a Magento project metapackage + * @type Array Create additional metapackages as defined */ - magentoCommunityEditionProject = false; - - /** - * @type Boolean Whether this package is a Magento product metapackage - */ - magentoCommunityEditionMetapackage = false; + extraMetapackages = []; /** * @type String Package vendor to use @@ -83,13 +79,10 @@ class repositoryBuildDefinition { extraRefToRelease = []; /** - * @param {{repoUrl: String, packageDirs: Array, packageIndividual: Array, packageMetaFromDirs: Array, magentoCommunityEditionProject: boolean, magentoCommunityEditionMetapackage: boolean, vendor: String, ref: String, fromTag: String, skipTags: {Object}, transform: Object., fixVersions: {Object}, packageReplacements: {Object}, extraRefToRelease: Array}} + * @param {{repoUrl: String, packageDirs: Array, packageIndividual: Array, packageMetaFromDirs: Array, vendor: String, ref: String, fromTag: String, skipTags: {Object}, transform: Object., fixVersions: {Object}, packageReplacements: {Object}, extraRefToRelease: Array, extraMetapackages: Array}} */ constructor(options) { this.repoUrl = options.repoUrl || this.repoUrl; - - this.magentoCommunityEditionProject = options.magentoCommunityEditionProject || this.magentoCommunityEditionProject; - this.magentoCommunityEditionMetapackage = options.magentoCommunityEditionMetapackage || this.magentoCommunityEditionMetapackage; this.vendor = options.vendor || this.vendor; this.ref = options.ref || this.ref; @@ -101,9 +94,10 @@ class repositoryBuildDefinition { this.packageDirs = this.initPackageDefinitions(options.packageDirs || []); this.packageIndividual = this.initPackageDefinitions(options.packageIndividual || []); this.packageMetaFromDirs = this.initPackageDefinitions(options.packageMetaFromDirs || []); - + this.packageReplacements = this.initPackageReplacements(options.packageReplacements || []); this.extraRefToRelease = this.initExtraRefsToRelease(options.extraRefToRelease || []); + this.extraMetapackages = this.initMetapackageDefinitions(options.extraMetapackages || []); } /** @@ -144,6 +138,19 @@ class repositoryBuildDefinition { return instances; } + + /** + * @param {Array<{}>} metapackages + * @returns {Array} + */ + initMetapackageDefinitions(metapackages) { + let instances = []; + metapackages.forEach(element => { + instances.push(new metapackageDefinition(element)); + }); + + return instances; + } }; module.exports = repositoryBuildDefinition; From 0ca2f2c52d6d20c0ac9dcf70a480fa1c49aa5191 Mon Sep 17 00:00:00 2001 From: Ryan Hoerr Date: Wed, 12 Nov 2025 22:48:27 -0500 Subject: [PATCH 02/12] Continued implementing additional release metapackages by definition (WIP) --- .../mageos-release-build-config.js | 14 +- src/build-config/packages-config.js | 92 ++++++-- src/make/mageos-nightly.js | 9 +- src/make/mageos-release.js | 8 +- src/make/mirror.js | 9 +- src/mirror-build-tools.js | 69 +----- src/package-modules.js | 198 ++---------------- src/release-branch-build-tools.js | 18 +- src/release-build-tools.js | 6 +- src/type/build-state.js | 8 +- 10 files changed, 136 insertions(+), 295 deletions(-) diff --git a/src/build-config/mageos-release-build-config.js b/src/build-config/mageos-release-build-config.js index 2c6a640..2a5c775 100644 --- a/src/build-config/mageos-release-build-config.js +++ b/src/build-config/mageos-release-build-config.js @@ -16,12 +16,10 @@ const releaseBuildConfig = { ], extraMetapackages: [ { - // @TODO: Change full name to just the package name? - name: 'mage-os/project-community-edition', + name: 'project-community-edition', type: 'project', description: 'Mage-OS Community Edition Project', - // @TODO: I don't think this is right - basePackage: 'magento2-base', + basePackage: '', historyPath: 'project-community-edition', transform: [ (composerConfig, instruction, release) => { @@ -31,10 +29,10 @@ const releaseBuildConfig = { ] }, { - name: 'mage-os/product-community-edition', + name: 'product-community-edition', type: 'metapackage', description: 'Mage-OS Community Edition', - basePackage: 'magento2-base', + basePackage: '', historyPath: 'product-community-edition', transform: [ (composerConfig, instruction, release) => { @@ -49,7 +47,7 @@ const releaseBuildConfig = { ] }, { - name: 'mage-os/project-minimal', + name: 'project-minimal', type: 'metapackage', description: 'Mage-OS Minimal Edition Project', basePackage: 'magento2-base', @@ -60,7 +58,7 @@ const releaseBuildConfig = { historyPath: 'project-minimal' }, { - name: 'mage-os/product-minimal', + name: 'product-minimal', type: 'metapackage', description: 'Mage-OS Minimal Edition', basePackage: 'magento2-base', diff --git a/src/build-config/packages-config.js b/src/build-config/packages-config.js index 8667c02..6248b08 100644 --- a/src/build-config/packages-config.js +++ b/src/build-config/packages-config.js @@ -1,3 +1,9 @@ +const { + getVersionStability, + setDependencyVersions, + getAdditionalDependencies +} = require('../mirror-build-tools'); + const packageDefs = { 'magento2': { repoUrl: 'https://github.com/mage-os/mirror-magento2.git', @@ -68,35 +74,91 @@ const packageDefs = { packageMetaFromDirs: [], extraMetapackages: [ { - // @TODO: Change full name to just the package name? - name: 'magento/project-community-edition', + name: 'project-community-edition', type: 'project', description: 'Magento Community Edition Project', - // @TODO: I don't think this is right - basePackage: 'magento2-base', + basePackage: '', historyPath: 'project-community-edition', transform: [ - (composerConfig, instruction, release) => { - updateComposerConfigFromMagentoToMageOs(instruction, release, composerConfig); - return composerConfig; + // @TODO: Param types + async (composerConfig, instruction, release) => { + // TODO: Should really have metapackage.name in here + const packageName = `${instruction.vendor}/project-community-edition`; + const version = release.version || release.dependencyVersions[packageName] || release.ref; + + // read release history or dependencies-template for project metapackage + const additionalDependencies = await getAdditionalDependencies(packageName, release.ref) + + composerConfig = Object.assign({}, composerConfig, { + name: packageName, + description: 'eCommerce Platform for Growth (Community Edition)', + extra: {'magento-force': 'override'}, + version: release.version || release.dependencyVersions[packageName] || release.ref, + repositories: [{type: 'composer', url: release.composerRepoUrl}], + 'minimum-stability': getVersionStability(version), + require: Object.assign( + {[`${packageName}`]: version}, + additionalDependencies + ) + }); + + for (const k of ['replace', 'suggest']) { + delete composerConfig[k]; + } + + setDependencyVersions(instruction, release, composerConfig); + + if (instruction?.transform[packageName]) { + composerConfig = instruction.transform[packageName].reduce( + (config, transformFn) => transformFn(config, instruction, release), + composerConfig + ) + } } ] }, { - name: 'magento/product-community-edition', + name: 'product-community-edition', type: 'metapackage', description: 'Magento Community Edition', - basePackage: 'magento2-base', + basePackage: '', historyPath: 'product-community-edition', + // TODO: Add 'fromTag' transform: [ - (composerConfig, instruction, release) => { - updateComposerConfigFromMagentoToMageOs(instruction, release, composerConfig) + async (composerConfig, instruction, release) => { + const packageName = `${instruction.vendor}/project-community-edition`; + + // This method is in package-modules, and checks history and falls back to composer-templates + // We should find a way to consolidate or abstract this for other instances + const additionalDependencies = await getAdditionalDependencies(packageName, release.ref) + + let composerConfig = Object.assign({}, composerConfig, { + name: packageName, + description: 'eCommerce Platform for Growth (Community Edition)', + type: 'metapackage', + require: Object.assign( + {}, + refComposerConfig.require, + refComposerConfig.replace, + additionalDependencies, + {[`${instruction.vendor}/magento2-base`]: version} + ), + version + }); - // Add upstreamRelease to composer extra data for reference - composerConfig.extra = composerConfig.extra || {}; - composerConfig.extra.magento_version = release.replaceVersions['magento/product-community-edition']; + for (const k of ['autoload', 'autoload-dev', 'config', 'conflict', 'extra', 'minimum-stability', 'replace', 'require-dev', 'suggest']) { + delete composerConfig[k]; + } + setDependencyVersions(instruction, release, composerConfig); - return composerConfig + if (instruction.transform[packageName]) { + composerConfig = instruction.transform[packageName].reduce( + (config, transformFn) => transformFn(config, instruction, release), + composerConfig + ); + } + + return composerConfig; } ] } diff --git a/src/make/mageos-nightly.js b/src/make/mageos-nightly.js index 4eb4e17..b86bea7 100644 --- a/src/make/mageos-nightly.js +++ b/src/make/mageos-nightly.js @@ -1,6 +1,6 @@ const repo = require('./../repository'); const parseOptions = require('parse-options'); -const {setArchiveBaseDir, setMageosPackageRepoUrl} = require('./../package-modules'); +const {setArchiveBaseDir} = require('./../package-modules'); const {processNightlyBuildInstructions} = require('./../release-branch-build-tools'); const {buildConfig: branchBuildInstructions} = require('./../build-config/mageos-nightly-build-config'); @@ -31,9 +31,10 @@ if (options.gitRepoDir) { repo.setStorageDir(options.gitRepoDir); } -if (options.repoUrl) { - setMageosPackageRepoUrl(options.repoUrl); -} +// @TODO: Update to use buildState +// if (options.repoUrl) { +// setMageosPackageRepoUrl(options.repoUrl); +// } processNightlyBuildInstructions(branchBuildInstructions); diff --git a/src/make/mageos-release.js b/src/make/mageos-release.js index 0dc4485..3850a60 100644 --- a/src/make/mageos-release.js +++ b/src/make/mageos-release.js @@ -7,11 +7,9 @@ const { prepRelease, processBuildInstructions, validateVersionString, - updateComposerConfigFromMagentoToMageOs, } = require('./../release-build-tools'); const { setArchiveBaseDir, - setMageosPackageRepoUrl, } = require("../package-modules"); const {buildConfig: releaseInstructions} = require('./../build-config/mageos-release-build-config'); const {processMirrorInstruction} = require("../mirror-build-tools"); @@ -51,12 +49,9 @@ if (options.gitRepoDir) { repo.setStorageDir(options.gitRepoDir); } -if (options.repoUrl) { - setMageosPackageRepoUrl(options.repoUrl); -} - const mageosRelease = options.mageosRelease || ''; const mageosVendor = options.mageosVendor || 'mage-os'; +const mageosRepoUrl = options.repoUrl || 'https://repo.mage-os.org/'; const upstreamRelease = options.upstreamRelease || ''; const releaseRefsFile = options.releaseRefsFile || path.join(__dirname, `./../build-config/${mageosVendor}-release-refs/${mageosRelease}.js`); @@ -73,6 +68,7 @@ const releaseRefs = fs.existsSync(releaseRefsFile) let distroRelease = new buildState({ version: mageosRelease, + composerRepoUrl: mageosRepoUrl, fallbackVersion: mageosRelease, dependencyVersions: {'*': mageosRelease} }); diff --git a/src/make/mirror.js b/src/make/mirror.js index 4a00376..c11747d 100644 --- a/src/make/mirror.js +++ b/src/make/mirror.js @@ -1,6 +1,6 @@ const repo = require('./../repository'); const parseOptions = require('parse-options'); -const {setArchiveBaseDir, setMageosPackageRepoUrl} = require('./../package-modules'); +const {setArchiveBaseDir} = require('./../package-modules'); const {copyAdditionalPackages, processMirrorInstruction} = require('./../mirror-build-tools'); const {buildConfig: mirrorInstructions} = require('./../build-config/mirror-build-config'); @@ -32,9 +32,10 @@ if (options.gitRepoDir) { repo.setStorageDir(options.gitRepoDir); } -if (options.repoUrl) { - setMageosPackageRepoUrl(options.repoUrl); -} +// @TODO: Update to use buildState +// if (options.repoUrl) { +// setMageosPackageRepoUrl(options.repoUrl); +// } (async () => { diff --git a/src/mirror-build-tools.js b/src/mirror-build-tools.js index 7f9a3ba..940547a 100644 --- a/src/mirror-build-tools.js +++ b/src/mirror-build-tools.js @@ -55,54 +55,6 @@ async function copyAdditionalPackages(archiveDir) { } } -/** - * @param {repositoryBuildDefinition} instruction - * @returns {Array} Packaged tags - */ -async function createMagentoCommunityEditionMetapackagesSinceTag(instruction) { - const tags = await listTagsFrom(instruction.repoUrl, instruction.fromTag, instruction.skipTags); - console.log(`Versions to process: ${tags.join(', ')}`); - for (const tag of tags) { - console.log(`Processing ${tag}`); - - let release = new buildState({ - ref: tag, - fallbackVersion: tag, - dependencyVersions: (instruction.fixVersions?.[tag] ?? {}) - }); - - await createMagentoCommunityEditionMetapackage( - instruction, - release - ); - } - return tags; -} - -/** - * @param {repositoryBuildDefinition} instruction - * @returns {Array} Packaged tags - */ -async function createProjectPackagesSinceTag(instruction) { - const tags = await listTagsFrom(instruction.repoUrl, instruction.fromTag, instruction.skipTags); - console.log(`Versions to process: ${tags.join(', ')}`); - for (const tag of tags) { - console.log(`Processing ${tag}`); - - let release = new buildState({ - ref: tag, - fallbackVersion: tag, - dependencyVersions: (instruction.fixVersions?.[tag] ?? {}) - }); - - await createMagentoCommunityEditionProject( - instruction, - release - ); - } - return tags; -} - /** * @param {repositoryBuildDefinition} instruction * @param {packageDefinition} package @@ -248,34 +200,25 @@ async function replacePackageFiles(package) { * @returns {Array} Packaged tags */ async function createMetaPackagesSinceTag(instruction, metapackage) { + const packageName = instruction.vendor + '/' + metapackage.name; const tags = await listTagsFrom(instruction.repoUrl, instruction.fromTag, instruction.skipTags); - console.log(`Versions to process for metapackage ${metapackage.name}: ${tags.join(', ')}`); + console.log(`Versions to process for metapackage ${packageName}: ${tags.join(', ')}`); + for (const tag of tags) { console.log(`Processing ${tag}`); let release = new buildState({ ref: tag, + // @TODO: We need composerRepoUrl for mirror/history build, but we don't have a buildState for it fallbackVersion: tag, dependencyVersions: (instruction.fixVersions?.[tag] ?? {}) }); - // Try to load additional dependencies from resource history - /** - * @TODO: This isn't quite right, but I haven't wrapped my head around it yet. - * additional gives `require` only, we need to merge it into the base json for the version - * create... loads ./composer.json for the given release tag, and adds/transforms based on the ref history. - */ - let additionalDeps = await getAdditionalDependencies(metapackage.name, tag); + await createComposerJsonOnlyPackage( instruction, release, - metapackage.name, + packageName, tag, composerConfig => { - // If additionalDeps found, use them - if (additionalDeps) { - // @TODO: I don't think so - Object.assign(composerConfig, {require: additionalDeps}); - } - // Apply transforms if any if (metapackage.transform) { for (const fn of metapackage.transform) { composerConfig = fn(composerConfig, instruction, release); diff --git a/src/package-modules.js b/src/package-modules.js index 6064c04..3f22a29 100644 --- a/src/package-modules.js +++ b/src/package-modules.js @@ -11,8 +11,6 @@ const buildState = require('./type/build-state'); let archiveBaseDir = 'packages'; -let mageosPackageRepoUrl = 'https://repo.mage-os.org/'; - const stableMtime = '2022-02-22 22:02:22.000Z'; function report() { @@ -402,6 +400,18 @@ async function createComposerJsonOnlyPackage(instruction, release, name, version isExecutable: false, }]; + // Special case - in these releases the base package also contained a .gitignore file in addition to the composer.json file. + // The .gitignore file is identical for those two releases. However, it is not the same as the .gitignore file in the tagged release, + // so we copy it from resource/history/magento/project-community-edition/2.4.0-gitignore + if (name === 'magento/project-community-edition' && (release.ref === '2.4.0' || release.ref === '2.4.0-p1')) { + files.push({ + filepath: '.gitignore', + mtime: new Date(stableMtime), + contentBuffer: fs.readFileSync(`${__dirname}/../resource/history/magento/project-community-edition/2.4.0-gitignore`), + isExecutable: false, + }) + } + // @todo: Check version vs instruction.ref vs release.version here. Is this necessary to track separately? Is this fallback needed? const packageFilepath = archiveFilePath(name, version || release.ref); return {packageFilepath, files} @@ -485,169 +495,6 @@ async function createPackagesForRef(instruction, package, release) { return built; } -async function determineMagentoCommunityEditionMetapackage(repoUrl, ref, release) { - const version = release || ref; - return {'magento/product-community-edition': version}; -} - -/** - * @param {repositoryBuildDefinition} instruction - * @param {buildState} release - * @param {{transform:{}}} options - * @returns {Promise<{}>} - */ -async function createMagentoCommunityEditionMetapackage(instruction, release, options) { - const defaults = { - transform: {}, - }; - const {transform} = Object.assign(defaults, (options || {})) - - const packageName = `${instruction.vendor}/product-community-edition` - const version = release.version || release.dependencyVersions[packageName] || release.ref; - const { - packageFilepath, - files - } = await createComposerJsonOnlyPackage( - instruction, - release, - packageName, - version, - async (refComposerConfig) => { - // read release history or dependencies-template for product metapackage - const additionalDependencies = await getAdditionalDependencies(packageName, release.ref) - - let composerConfig = Object.assign({}, refComposerConfig, { - name: packageName, - description: 'eCommerce Platform for Growth (Community Edition)', - type: 'metapackage', - require: Object.assign( - {}, - refComposerConfig.require, - refComposerConfig.replace, - additionalDependencies, - {[`${instruction.vendor}/magento2-base`]: version} - ), - version - }); - - for (const k of ['autoload', 'autoload-dev', 'config', 'conflict', 'extra', 'minimum-stability', 'replace', 'require-dev', 'suggest']) { - delete composerConfig[k]; - } - setDependencyVersions(instruction, release, composerConfig); - - if (instruction.transform[packageName]) { - composerConfig = instruction.transform[packageName].reduce( - (config, transformFn) => transformFn(config, instruction, release), - composerConfig - ); - } - if (transform[packageName]) { - composerConfig = transform[packageName].reduce( - (config, transformFn) => transformFn(config, instruction, release), - composerConfig - ); - } - - return composerConfig; - } - ); - - if (! isInAdditionalPackages(packageName, version)) { - await writePackage(packageFilepath, files); - } - - return {[packageName]: version}; -} - -async function determineMagentoCommunityEditionProject(url, ref, release) { - const version = release || ref; - return {'magento/project-community-edition': version} -} - -/** - * Options: - * release: Release version to use in composer.json version tag and in the package archive name. Defaults to ref - * dependencyVersions: composer package:version dependency map. Dependencies for packages in the map will be set to the given versions - * - * @param {repositoryBuildDefinition} instruction - * @param {buildState} release - * @param {{description:String|undefined, transform: Array}} options - * @returns {Promise<{}>} - */ -async function createMagentoCommunityEditionProject(instruction, release, options) { - const defaults = { - description: 'eCommerce Platform for Growth (Community Edition)', - transform: {}, - }; - const {description, transform} = Object.assign(defaults, (options || {})) - const name = `${instruction.vendor}/project-community-edition`; - const version = release.version || release.dependencyVersions[name] || release.ref; - const minimumStability = getVersionStability(version); - const {packageFilepath, files} = await createComposerJsonOnlyPackage( - instruction, - release, - name, - version, - async (refComposerConfig) => { - // read release history or dependencies-template for project metapackage - const additionalDependencies = await getAdditionalDependencies(name, release.ref) - - // Build project metapackage composer.json - let composerConfig = Object.assign(refComposerConfig, { - name: name, - description: description, - extra: {'magento-force': 'override'}, - version: version, - repositories: [{type: 'composer', url: mageosPackageRepoUrl}], - 'minimum-stability': minimumStability, - require: Object.assign( - {[`${instruction.vendor}/product-community-edition`]: version}, - additionalDependencies - ) - }); - - for (const k of ['replace', 'suggest']) { - delete composerConfig[k]; - } - - setDependencyVersions(instruction, release, composerConfig); - - if (instruction?.transform[name]) { - composerConfig = instruction.transform[name].reduce( - (config, transformFn) => transformFn(config, instruction, release), - composerConfig - ) - } - if (transform[name]) { - composerConfig = transform[name].reduce( - (config, transformFn) => transformFn(config, instruction, release), - composerConfig - ) - } - - return composerConfig; - } - ); - - // Special case - in these releases the base package also contained a .gitignore file in addition to the composer.json file. - // The .gitignore file is identical for those two releases. However, it is not the same as the .gitignore file in the tagged release, - // so we copy it from resource/history/magento/project-community-edition/2.4.0-gitignore - if (name === 'magento/project-community-edition' && (release.ref === '2.4.0' || release.ref === '2.4.0-p1')) { - files.push({ - filepath: '.gitignore', - mtime: new Date(stableMtime), - contentBuffer: fs.readFileSync(`${__dirname}/../resource/history/magento/project-community-edition/2.4.0-gitignore`), - isExecutable: false, - }) - } - - if (! isInAdditionalPackages(name, version)) { - await writePackage(packageFilepath, files); - } - - return {[name]: version} -} - /** * @param {String} url The URL of the source git repository * @param {String} dir The directory path to the git repository @@ -744,6 +591,8 @@ function filterDependencies(dependencies, include, exclude) { } async function createMetaPackage(instruction, metapackage, release) { + const packageName = instruction.vendor + '/' + metapackage.name; + // Determine dependencies with base and filters let dependencies = {}; if (metapackage.basePackage) { @@ -758,7 +607,7 @@ async function createMetaPackage(instruction, metapackage, release) { // Create package config let composerConfig = { - name: metapackage.name, + name: packageName, type: metapackage.type, description: metapackage.description, require: dependencies, @@ -771,8 +620,8 @@ async function createMetaPackage(instruction, metapackage, release) { composerConfig ); - if (instruction.transform[metapackage.name]) { - composerConfig = instruction.transform[metapackage.name].reduce( + if (instruction.transform[packageName]) { + composerConfig = instruction.transform[packageName].reduce( (config, fn) => fn(config, instruction, release), composerConfig ); @@ -786,26 +635,21 @@ async function createMetaPackage(instruction, metapackage, release) { isExecutable: false }]; - const packageFilepath = archiveFilePath(metapackage.name, composerConfig.version); + const packageFilepath = archiveFilePath(packageName, composerConfig.version); - if (!isInAdditionalPackages(metapackage.name, composerConfig.version)) { + if (!isInAdditionalPackages(packageName, composerConfig.version)) { await writePackage(packageFilepath, files); } - return {[metapackage.name]: composerConfig.version}; + return {[packageName]: composerConfig.version}; } module.exports = { setArchiveBaseDir(newArchiveBaseDir) { archiveBaseDir = newArchiveBaseDir; }, - setMageosPackageRepoUrl(newMirrorUrl) { - mageosPackageRepoUrl = newMirrorUrl; - }, createPackageForRef, createPackagesForRef, - createMagentoCommunityEditionMetapackage, - createMagentoCommunityEditionProject, createMetaPackageFromRepoDir, createMetaPackage, @@ -818,4 +662,6 @@ module.exports = { determineMagentoCommunityEditionMetapackage, determineMagentoCommunityEditionProject, determineMetaPackageFromRepoDir, + + getAdditionalDependencies, } diff --git a/src/release-branch-build-tools.js b/src/release-branch-build-tools.js index eb94b32..ace3784 100644 --- a/src/release-branch-build-tools.js +++ b/src/release-branch-build-tools.js @@ -7,8 +7,6 @@ const { determinePackagesForRef, determinePackageForRef, determineMetaPackageFromRepoDir, - determineMagentoCommunityEditionMetapackage, - determineMagentoCommunityEditionProject, getLatestTag } = require('./package-modules'); const repositoryBuildDefinition = require("./type/repository-build-definition"); @@ -45,18 +43,10 @@ async function getPackagesForBuildInstruction(instruction) { Object.assign(packages, toBeBuilt); } - // @TODO: Update this code - // if (instruction.magentoCommunityEditionMetapackage) { - // console.log('Inspecting Magento Community Edition Product Metapackage'); - // toBeBuilt = await determineMagentoCommunityEditionMetapackage(instruction.repoUrl, baseVersionsOnRef); - // Object.assign(packages, toBeBuilt); - // } - - // if (instruction.magentoCommunityEditionProject) { - // console.log('Inspecting Magento Community Edition Project'); - // toBeBuilt = await determineMagentoCommunityEditionProject(instruction.repoUrl, baseVersionsOnRef); - // Object.assign(packages, toBeBuilt); - // } + for (const metapackage of (instruction.extraMetapackages || [])) { + console.log(`Inspecting ${metapackage.name}`); + packages[`${instruction.vendor}/${metapackage.name}`] = baseVersionsOnRef; + } repo.clearCache(); return packages; diff --git a/src/release-build-tools.js b/src/release-build-tools.js index 6d85be3..e0b9fa4 100644 --- a/src/release-build-tools.js +++ b/src/release-build-tools.js @@ -298,10 +298,8 @@ module.exports = { } // @TODO: Update this code - // if (instruction.magentoCommunityEditionMetapackage) { - // // nothing to do - the product-community-edition metapackage composer.json is built from a template - // } - + // TODO: Maybe a problem here. Does this store and pull historical versions of the metapackage from the repo? + // If so, how would we extend that for additional metapackages? // if (instruction.magentoCommunityEditionProject) { // // update the base composer.json for releasing (doesn't happen for the base package because that uses a composer.json template) // const metapackage = new packageDefinition({ diff --git a/src/type/build-state.js b/src/type/build-state.js index a4de52c..4a60b13 100644 --- a/src/type/build-state.js +++ b/src/type/build-state.js @@ -20,6 +20,11 @@ class buildState { */ version = null; + /** + * @type String|null Git Repository URL + */ + composerRepoUrl = null; + /** * @type {String|null} Fallback version to use in composer.json version tag and * in the package archive name (used for nightly releases) @@ -39,13 +44,14 @@ class buildState { replaceVersions = {}; /** - * @param {{ref: String, origRef: String, version: String, fallbackVersion: String, dependencyVersions: Object., replaceVersions: Object.}}} options + * @param {{ref: String, origRef: String, version: String, composerRepoUrl: String, fallbackVersion: String, dependencyVersions: Object., replaceVersions: Object.}}} options */ constructor(options) { this.ref = options.ref || this.ref; this.origRef = options.origRef || this.origRef; this.version = options.version || this.version; this.fallbackVersion = options.fallbackVersion || this.fallbackVersion; + this.composerRepoUrl = options.composerRepoUrl || this.composerRepoUrl; this.dependencyVersions = options.dependencyVersions || this.dependencyVersions; this.replaceVersions = options.replaceVersions || this.replaceVersions; } From 26af45ff33aa8618c6065305da2322b3f9d78e86 Mon Sep 17 00:00:00 2001 From: Ryan Hoerr Date: Thu, 13 Nov 2025 21:23:37 -0500 Subject: [PATCH 03/12] add fromTag support for metapackages and update build context handling --- .../mageos-release-build-config.js | 4 +++ src/build-config/packages-config.js | 25 +++++++++++++------ src/make/mageos-nightly.js | 9 +++---- src/make/mirror.js | 9 +++---- src/mirror-build-tools.js | 21 ++++++++++------ src/package-modules.js | 5 ++-- src/release-build-tools.js | 20 +++++++-------- src/type/metapackage-definition.js | 8 +++++- 8 files changed, 62 insertions(+), 39 deletions(-) diff --git a/src/build-config/mageos-release-build-config.js b/src/build-config/mageos-release-build-config.js index 2a5c775..1f6c375 100644 --- a/src/build-config/mageos-release-build-config.js +++ b/src/build-config/mageos-release-build-config.js @@ -18,6 +18,7 @@ const releaseBuildConfig = { { name: 'project-community-edition', type: 'project', + fromTag: '1.0.0', description: 'Mage-OS Community Edition Project', basePackage: '', historyPath: 'project-community-edition', @@ -31,6 +32,7 @@ const releaseBuildConfig = { { name: 'product-community-edition', type: 'metapackage', + fromTag: '1.0.0', description: 'Mage-OS Community Edition', basePackage: '', historyPath: 'product-community-edition', @@ -49,6 +51,7 @@ const releaseBuildConfig = { { name: 'project-minimal', type: 'metapackage', + fromTag: '3.0.0', description: 'Mage-OS Minimal Edition Project', basePackage: 'magento2-base', exclude: [ @@ -60,6 +63,7 @@ const releaseBuildConfig = { { name: 'product-minimal', type: 'metapackage', + fromTag: '3.0.0', description: 'Mage-OS Minimal Edition', basePackage: 'magento2-base', exclude: [ diff --git a/src/build-config/packages-config.js b/src/build-config/packages-config.js index 6248b08..425a06d 100644 --- a/src/build-config/packages-config.js +++ b/src/build-config/packages-config.js @@ -3,6 +3,8 @@ const { setDependencyVersions, getAdditionalDependencies } = require('../mirror-build-tools'); +const buildState = require('../type/build-state'); +const repositoryBuildDefinition = require('../type/repository-build-definition'); const packageDefs = { 'magento2': { @@ -80,10 +82,14 @@ const packageDefs = { basePackage: '', historyPath: 'project-community-edition', transform: [ - // @TODO: Param types - async (composerConfig, instruction, release) => { - // TODO: Should really have metapackage.name in here - const packageName = `${instruction.vendor}/project-community-edition`; + /** + * @param {{}} composerConfig + * @param {repositoryBuildDefinition} instruction + * @param {metapackageDefinition} metapackage + * @param {buildState} release + */ + async (composerConfig, instruction, metapackage, release) => { + const packageName = `${instruction.vendor}/${metapackage.name}`; const version = release.version || release.dependencyVersions[packageName] || release.ref; // read release history or dependencies-template for project metapackage @@ -123,10 +129,15 @@ const packageDefs = { description: 'Magento Community Edition', basePackage: '', historyPath: 'product-community-edition', - // TODO: Add 'fromTag' transform: [ - async (composerConfig, instruction, release) => { - const packageName = `${instruction.vendor}/project-community-edition`; + /** + * @param {{}} composerConfig + * @param {repositoryBuildDefinition} instruction + * @param {metapackageDefinition} metapackage + * @param {buildState} release + */ + async (composerConfig, instruction, metapackage, release) => { + const packageName = `${instruction.vendor}/${metapackage.name}`; // This method is in package-modules, and checks history and falls back to composer-templates // We should find a way to consolidate or abstract this for other instances diff --git a/src/make/mageos-nightly.js b/src/make/mageos-nightly.js index b86bea7..8b25000 100644 --- a/src/make/mageos-nightly.js +++ b/src/make/mageos-nightly.js @@ -31,10 +31,9 @@ if (options.gitRepoDir) { repo.setStorageDir(options.gitRepoDir); } -// @TODO: Update to use buildState -// if (options.repoUrl) { -// setMageosPackageRepoUrl(options.repoUrl); -// } +let releaseContext = new buildState({ + composerRepoUrl: options.repoUrl || 'https://nightly.mage-os.org/', +}); -processNightlyBuildInstructions(branchBuildInstructions); +processNightlyBuildInstructions(branchBuildInstructions, releaseContext); diff --git a/src/make/mirror.js b/src/make/mirror.js index c11747d..83e05b7 100644 --- a/src/make/mirror.js +++ b/src/make/mirror.js @@ -32,16 +32,15 @@ if (options.gitRepoDir) { repo.setStorageDir(options.gitRepoDir); } -// @TODO: Update to use buildState -// if (options.repoUrl) { -// setMageosPackageRepoUrl(options.repoUrl); -// } +let releaseContext = new buildState({ + composerRepoUrl: options.repoUrl || 'https://mirror.mage-os.org/', +}); (async () => { try { for (const instruction of mirrorInstructions) { - await processMirrorInstruction(instruction); + await processMirrorInstruction(instruction, releaseContext); } await copyAdditionalPackages(archiveDir); } catch (exception) { diff --git a/src/mirror-build-tools.js b/src/mirror-build-tools.js index 940547a..c11c67b 100644 --- a/src/mirror-build-tools.js +++ b/src/mirror-build-tools.js @@ -7,7 +7,6 @@ const { createPackageForRef, createMetaPackageFromRepoDir, archiveFilePath, - getAdditionalDependencies, createComposerJsonOnlyPackage } = require('./package-modules'); const repositoryBuildDefinition = require('./type/repository-build-definition'); @@ -197,18 +196,23 @@ async function replacePackageFiles(package) { /** * @param {repositoryBuildDefinition} instruction * @param {Object} metapackage + * @param {buildState} releaseContext * @returns {Array} Packaged tags */ -async function createMetaPackagesSinceTag(instruction, metapackage) { - const packageName = instruction.vendor + '/' + metapackage.name; - const tags = await listTagsFrom(instruction.repoUrl, instruction.fromTag, instruction.skipTags); +async function createMetaPackagesSinceTag(instruction, metapackage, releaseContext) { + const packageName = `${instruction.vendor}/${metapackage.name}`; + const tags = await listTagsFrom( + instruction.repoUrl, + metapackage.fromTag || instruction.fromTag, + instruction.skipTags + ); console.log(`Versions to process for metapackage ${packageName}: ${tags.join(', ')}`); for (const tag of tags) { console.log(`Processing ${tag}`); let release = new buildState({ ref: tag, - // @TODO: We need composerRepoUrl for mirror/history build, but we don't have a buildState for it + composerRepoUrl: releaseContext.composerRepoUrl, fallbackVersion: tag, dependencyVersions: (instruction.fixVersions?.[tag] ?? {}) }); @@ -221,7 +225,7 @@ async function createMetaPackagesSinceTag(instruction, metapackage) { composerConfig => { if (metapackage.transform) { for (const fn of metapackage.transform) { - composerConfig = fn(composerConfig, instruction, release); + composerConfig = fn(composerConfig, instruction, metapackage, release); } } return composerConfig; @@ -233,9 +237,10 @@ async function createMetaPackagesSinceTag(instruction, metapackage) { /** * @param {repositoryBuildDefinition} instruction + * @param {buildState} releaseContext * @returns {Promise} */ -async function processMirrorInstruction(instruction) { +async function processMirrorInstruction(instruction, releaseContext) { let tags = []; await Promise.all( @@ -268,7 +273,7 @@ async function processMirrorInstruction(instruction) { for (const metapackage of instruction.extraMetapackages) { console.log(`Packaging ${metapackage.name}`); - tags = await createMetaPackagesSinceTag(instruction, metapackage); + tags = await createMetaPackagesSinceTag(instruction, metapackage, releaseContext); } repo.clearCache(); diff --git a/src/package-modules.js b/src/package-modules.js index 3f22a29..6808694 100644 --- a/src/package-modules.js +++ b/src/package-modules.js @@ -591,7 +591,7 @@ function filterDependencies(dependencies, include, exclude) { } async function createMetaPackage(instruction, metapackage, release) { - const packageName = instruction.vendor + '/' + metapackage.name; + const packageName = `${instruction.vendor}/${metapackage.name}`; // Determine dependencies with base and filters let dependencies = {}; @@ -616,7 +616,7 @@ async function createMetaPackage(instruction, metapackage, release) { // Apply transforms composerConfig = metapackage.transform.reduce( - (config, fn) => fn(config, instruction, release), + (config, fn) => fn(config, instruction, metapackage, release), composerConfig ); @@ -652,6 +652,7 @@ module.exports = { createPackagesForRef, createMetaPackageFromRepoDir, createMetaPackage, + createComposerJsonOnlyPackage, getLatestTag, archiveFilePath, diff --git a/src/release-build-tools.js b/src/release-build-tools.js index e0b9fa4..3311e3d 100644 --- a/src/release-build-tools.js +++ b/src/release-build-tools.js @@ -297,17 +297,15 @@ module.exports = { await prepPackageForRelease(instruction, package, release, workingCopyPath); } - // @TODO: Update this code - // TODO: Maybe a problem here. Does this store and pull historical versions of the metapackage from the repo? - // If so, how would we extend that for additional metapackages? - // if (instruction.magentoCommunityEditionProject) { - // // update the base composer.json for releasing (doesn't happen for the base package because that uses a composer.json template) - // const metapackage = new packageDefinition({ - // 'label': 'Mage-OS Community Edition Project Metapackage', - // 'dir': '' - // }); - // await prepPackageForRelease(instruction, metapackage, release, workingCopyPath); - // } + for (const metapackage of (instruction.extraMetapackages || [])) { + if (metapackage.name === 'project-community-edition') { + const package = new packageDefinition({ + label: metapackage.description || metapackage.name, + dir: '', // metapackages typically at repo root + }); + await prepPackageForRelease(instruction, package, release, workingCopyPath); + } + } return workBranch }, diff --git a/src/type/metapackage-definition.js b/src/type/metapackage-definition.js index 4abd6fb..d856654 100644 --- a/src/type/metapackage-definition.js +++ b/src/type/metapackage-definition.js @@ -40,7 +40,12 @@ class metapackageDefinition { historyPath = null; /** - * @param {{name: String, type: String, description: String, basePackage: String, include: Array, exclude: Array, transform: Array, historyPath: String}} config + * @type String|null Tag to build from (e.g. a git tag) + */ + fromTag = null; + + /** + * @param {{name: String, type: String, description: String, basePackage: String, include: Array, exclude: Array, transform: Array, historyPath: String, fromTag: String}} config */ constructor(config = {}) { this.name = config.name || this.name; @@ -51,6 +56,7 @@ class metapackageDefinition { this.exclude = config.exclude || this.exclude; this.transform = config.transform || this.transform; this.historyPath = config.historyPath || this.historyPath; + this.fromTag = config.fromTag || this.fromTag; } } From 63f21232e261795bdde35b335c71e4d53bb5719d Mon Sep 17 00:00:00 2001 From: Ryan Hoerr Date: Thu, 13 Nov 2025 21:33:05 -0500 Subject: [PATCH 04/12] refactor: streamline handling of community edition metapackage in release process --- src/release-build-tools.js | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/release-build-tools.js b/src/release-build-tools.js index 3311e3d..107cb04 100644 --- a/src/release-build-tools.js +++ b/src/release-build-tools.js @@ -297,14 +297,13 @@ module.exports = { await prepPackageForRelease(instruction, package, release, workingCopyPath); } - for (const metapackage of (instruction.extraMetapackages || [])) { - if (metapackage.name === 'project-community-edition') { - const package = new packageDefinition({ - label: metapackage.description || metapackage.name, - dir: '', // metapackages typically at repo root - }); - await prepPackageForRelease(instruction, package, release, workingCopyPath); - } + const communityEdition = (instruction.extraMetapackages || []).find(package => package.name === 'project-community-edition'); + if (communityEdition) { + const package = new packageDefinition({ + label: communityEdition.description || communityEdition.name, + dir: '', // metapackages typically at repo root + }); + await prepPackageForRelease(instruction, package, release, workingCopyPath); } return workBranch From b7686f11fe7f1105a8a4e3f2a9abbb05210382e0 Mon Sep 17 00:00:00 2001 From: Ryan Hoerr Date: Thu, 13 Nov 2025 23:02:51 -0500 Subject: [PATCH 05/12] Fixes from testing --- .../mageos-release-build-config.js | 89 ++++++++++++++++++- src/build-config/packages-config.js | 16 ++-- src/package-modules.js | 13 +-- src/utils.js | 1 - 4 files changed, 105 insertions(+), 14 deletions(-) diff --git a/src/build-config/mageos-release-build-config.js b/src/build-config/mageos-release-build-config.js index 1f6c375..75f0e6c 100644 --- a/src/build-config/mageos-release-build-config.js +++ b/src/build-config/mageos-release-build-config.js @@ -1,3 +1,10 @@ +const { + getVersionStability, + setDependencyVersions, + getAdditionalDependencies +} = require('../package-modules'); +const buildState = require('../type/build-state'); +const repositoryBuildDefinition = require('../type/repository-build-definition'); const packagesConfig = require('./packages-config'); const {mergeBuildConfigs} = require('../utils'); @@ -23,7 +30,46 @@ const releaseBuildConfig = { basePackage: '', historyPath: 'project-community-edition', transform: [ - (composerConfig, instruction, release) => { + /** + * @param {{}} composerConfig + * @param {repositoryBuildDefinition} instruction + * @param {metapackageDefinition} metapackage + * @param {buildState} release + */ + async (composerConfig, instruction, metapackage, release) => { + const packageName = `${instruction.vendor}/${metapackage.name}`; + const version = release.version || release.dependencyVersions[packageName] || release.ref; + + // read release history or dependencies-template for project metapackage + const additionalDependencies = await getAdditionalDependencies(packageName, release.ref) + + composerConfig = Object.assign({}, composerConfig, { + name: packageName, + description: 'eCommerce Platform for Growth (Community Edition)', + extra: {'magento-force': 'override'}, + version: release.version || release.dependencyVersions[packageName] || release.ref, + repositories: [{type: 'composer', url: release.composerRepoUrl}], + 'minimum-stability': getVersionStability(version), + require: Object.assign( + {[`${packageName}`]: version}, + additionalDependencies + ) + }); + + for (const k of ['replace', 'suggest']) { + delete composerConfig[k]; + } + + setDependencyVersions(instruction, release, composerConfig); + + if (instruction?.transform[packageName]) { + composerConfig = instruction.transform[packageName].reduce( + (config, transformFn) => transformFn(config, instruction, release), + composerConfig + ) + } + + // TODO: Issue with composerConfig promise not resolving before then next one executes updateComposerConfigFromMagentoToMageOs(instruction, release, composerConfig); return composerConfig; } @@ -37,7 +83,46 @@ const releaseBuildConfig = { basePackage: '', historyPath: 'product-community-edition', transform: [ - (composerConfig, instruction, release) => { + /** + * @param {{}} composerConfig + * @param {repositoryBuildDefinition} instruction + * @param {metapackageDefinition} metapackage + * @param {buildState} release + */ + async (composerConfig, instruction, metapackage, release) => { + const packageName = `${instruction.vendor}/${metapackage.name}`; + const version = release.version || release.dependencyVersions[packageName] || release.ref; + + // This method is in package-modules, and checks history and falls back to composer-templates + // We should find a way to consolidate or abstract this for other instances + const additionalDependencies = await getAdditionalDependencies(packageName, release.ref) + + composerConfig = Object.assign({}, composerConfig, { + name: packageName, + description: 'eCommerce Platform for Growth (Community Edition)', + type: 'metapackage', + require: Object.assign( + {}, + composerConfig.require, + composerConfig.replace, + additionalDependencies, + {[`${instruction.vendor}/magento2-base`]: version} + ), + version: version + }); + + for (const k of ['autoload', 'autoload-dev', 'config', 'conflict', 'extra', 'minimum-stability', 'replace', 'require-dev', 'suggest']) { + delete composerConfig[k]; + } + setDependencyVersions(instruction, release, composerConfig); + + if (instruction.transform[packageName]) { + composerConfig = instruction.transform[packageName].reduce( + (config, transformFn) => transformFn(config, instruction, release), + composerConfig + ); + } + updateComposerConfigFromMagentoToMageOs(instruction, release, composerConfig) // Add upstreamRelease to composer extra data for reference diff --git a/src/build-config/packages-config.js b/src/build-config/packages-config.js index 425a06d..07daf79 100644 --- a/src/build-config/packages-config.js +++ b/src/build-config/packages-config.js @@ -2,7 +2,7 @@ const { getVersionStability, setDependencyVersions, getAdditionalDependencies -} = require('../mirror-build-tools'); +} = require('../package-modules'); const buildState = require('../type/build-state'); const repositoryBuildDefinition = require('../type/repository-build-definition'); @@ -89,6 +89,7 @@ const packageDefs = { * @param {buildState} release */ async (composerConfig, instruction, metapackage, release) => { + // TODO: Refactor, extract these into separate modules const packageName = `${instruction.vendor}/${metapackage.name}`; const version = release.version || release.dependencyVersions[packageName] || release.ref; @@ -120,6 +121,8 @@ const packageDefs = { composerConfig ) } + + return composerConfig; } ] }, @@ -138,23 +141,24 @@ const packageDefs = { */ async (composerConfig, instruction, metapackage, release) => { const packageName = `${instruction.vendor}/${metapackage.name}`; + const version = release.version || release.dependencyVersions[packageName] || release.ref; // This method is in package-modules, and checks history and falls back to composer-templates // We should find a way to consolidate or abstract this for other instances const additionalDependencies = await getAdditionalDependencies(packageName, release.ref) - let composerConfig = Object.assign({}, composerConfig, { + composerConfig = Object.assign({}, composerConfig, { name: packageName, description: 'eCommerce Platform for Growth (Community Edition)', type: 'metapackage', require: Object.assign( {}, - refComposerConfig.require, - refComposerConfig.replace, + composerConfig.require, + composerConfig.replace, additionalDependencies, - {[`${instruction.vendor}/magento2-base`]: version} + {[`${instruction.vendor}/magento2-base`]: release.version} ), - version + version: release.version }); for (const k of ['autoload', 'autoload-dev', 'config', 'conflict', 'extra', 'minimum-stability', 'replace', 'require-dev', 'suggest']) { diff --git a/src/package-modules.js b/src/package-modules.js index 6808694..73eb12a 100644 --- a/src/package-modules.js +++ b/src/package-modules.js @@ -591,7 +591,7 @@ function filterDependencies(dependencies, include, exclude) { } async function createMetaPackage(instruction, metapackage, release) { - const packageName = `${instruction.vendor}/${metapackage.name}`; + const packageName = `magento/${metapackage.name}`; // Has to be Magento here. Trust me. reasons. // Determine dependencies with base and filters let dependencies = {}; @@ -615,13 +615,13 @@ async function createMetaPackage(instruction, metapackage, release) { }; // Apply transforms - composerConfig = metapackage.transform.reduce( + composerConfig = await metapackage.transform.reduce( (config, fn) => fn(config, instruction, metapackage, release), composerConfig ); if (instruction.transform[packageName]) { - composerConfig = instruction.transform[packageName].reduce( + composerConfig = await instruction.transform[packageName].reduce( (config, fn) => fn(config, instruction, release), composerConfig ); @@ -635,6 +635,9 @@ async function createMetaPackage(instruction, metapackage, release) { isExecutable: false }]; + // Update packageName with final vendor + packageName = `${instruction.vendor}/${metapackage.name}`; + const packageFilepath = archiveFilePath(packageName, composerConfig.version); if (!isInAdditionalPackages(packageName, composerConfig.version)) { @@ -660,9 +663,9 @@ module.exports = { determinePackageForRef, determinePackagesForRef, - determineMagentoCommunityEditionMetapackage, - determineMagentoCommunityEditionProject, determineMetaPackageFromRepoDir, + getVersionStability, + setDependencyVersions, getAdditionalDependencies, } diff --git a/src/utils.js b/src/utils.js index 4ecdafb..c9c7a84 100644 --- a/src/utils.js +++ b/src/utils.js @@ -2,7 +2,6 @@ const compareVersions = require("compare-versions"); const http = require('https'); const {URL} = require('url'); const repositoryBuildDefinition = require('./type/repository-build-definition'); -const packagesConfig = require("./build-config/packages-config"); /** * If a and b are the same, return 0. Return pos number if a > b, or neg number if a < b From dba1c1c777166183b7dd2ca0d6fd9f657cf6e19c Mon Sep 17 00:00:00 2001 From: Ryan Hoerr Date: Thu, 20 Nov 2025 23:10:20 -0500 Subject: [PATCH 06/12] Refactoring and fixes --- .../mageos-release-build-config.js | 151 +++++------------- src/build-config/packages-config.js | 99 +----------- .../mage-os-community-edition.js | 38 +++++ .../magento-community-edition.js | 83 ++++++++++ src/package-modules.js | 89 +++-------- src/type/metapackage-definition.js | 26 +-- 6 files changed, 186 insertions(+), 300 deletions(-) create mode 100644 src/build-metapackage/mage-os-community-edition.js create mode 100644 src/build-metapackage/magento-community-edition.js diff --git a/src/build-config/mageos-release-build-config.js b/src/build-config/mageos-release-build-config.js index 75f0e6c..852a9cb 100644 --- a/src/build-config/mageos-release-build-config.js +++ b/src/build-config/mageos-release-build-config.js @@ -1,14 +1,14 @@ const { - getVersionStability, - setDependencyVersions, - getAdditionalDependencies -} = require('../package-modules'); -const buildState = require('../type/build-state'); -const repositoryBuildDefinition = require('../type/repository-build-definition'); + transformMagentoCommunityEditionProject, + transformMagentoCommunityEditionProduct +} = require('../build-metapackage/magento-community-edition'); +const { + transformMageOSCommunityEditionProject, + transformMageOSCommunityEditionProduct +} = require('../build-metapackage/mage-os-community-edition'); const packagesConfig = require('./packages-config'); const {mergeBuildConfigs} = require('../utils'); -const {updateComposerConfigFromMagentoToMageOs} = require('../release-build-tools'); const releaseBuildConfig = { 'magento2': { @@ -27,52 +27,9 @@ const releaseBuildConfig = { type: 'project', fromTag: '1.0.0', description: 'Mage-OS Community Edition Project', - basePackage: '', - historyPath: 'project-community-edition', transform: [ - /** - * @param {{}} composerConfig - * @param {repositoryBuildDefinition} instruction - * @param {metapackageDefinition} metapackage - * @param {buildState} release - */ - async (composerConfig, instruction, metapackage, release) => { - const packageName = `${instruction.vendor}/${metapackage.name}`; - const version = release.version || release.dependencyVersions[packageName] || release.ref; - - // read release history or dependencies-template for project metapackage - const additionalDependencies = await getAdditionalDependencies(packageName, release.ref) - - composerConfig = Object.assign({}, composerConfig, { - name: packageName, - description: 'eCommerce Platform for Growth (Community Edition)', - extra: {'magento-force': 'override'}, - version: release.version || release.dependencyVersions[packageName] || release.ref, - repositories: [{type: 'composer', url: release.composerRepoUrl}], - 'minimum-stability': getVersionStability(version), - require: Object.assign( - {[`${packageName}`]: version}, - additionalDependencies - ) - }); - - for (const k of ['replace', 'suggest']) { - delete composerConfig[k]; - } - - setDependencyVersions(instruction, release, composerConfig); - - if (instruction?.transform[packageName]) { - composerConfig = instruction.transform[packageName].reduce( - (config, transformFn) => transformFn(config, instruction, release), - composerConfig - ) - } - - // TODO: Issue with composerConfig promise not resolving before then next one executes - updateComposerConfigFromMagentoToMageOs(instruction, release, composerConfig); - return composerConfig; - } + transformMagentoCommunityEditionProject, + transformMageOSCommunityEditionProject, ] }, { @@ -80,82 +37,46 @@ const releaseBuildConfig = { type: 'metapackage', fromTag: '1.0.0', description: 'Mage-OS Community Edition', - basePackage: '', - historyPath: 'product-community-edition', transform: [ - /** - * @param {{}} composerConfig - * @param {repositoryBuildDefinition} instruction - * @param {metapackageDefinition} metapackage - * @param {buildState} release - */ - async (composerConfig, instruction, metapackage, release) => { - const packageName = `${instruction.vendor}/${metapackage.name}`; - const version = release.version || release.dependencyVersions[packageName] || release.ref; - - // This method is in package-modules, and checks history and falls back to composer-templates - // We should find a way to consolidate or abstract this for other instances - const additionalDependencies = await getAdditionalDependencies(packageName, release.ref) - - composerConfig = Object.assign({}, composerConfig, { - name: packageName, - description: 'eCommerce Platform for Growth (Community Edition)', - type: 'metapackage', - require: Object.assign( - {}, - composerConfig.require, - composerConfig.replace, - additionalDependencies, - {[`${instruction.vendor}/magento2-base`]: version} - ), - version: version - }); - - for (const k of ['autoload', 'autoload-dev', 'config', 'conflict', 'extra', 'minimum-stability', 'replace', 'require-dev', 'suggest']) { - delete composerConfig[k]; - } - setDependencyVersions(instruction, release, composerConfig); - - if (instruction.transform[packageName]) { - composerConfig = instruction.transform[packageName].reduce( - (config, transformFn) => transformFn(config, instruction, release), - composerConfig - ); - } - - updateComposerConfigFromMagentoToMageOs(instruction, release, composerConfig) - - // Add upstreamRelease to composer extra data for reference - composerConfig.extra = composerConfig.extra || {}; - composerConfig.extra.magento_version = release.replaceVersions['magento/product-community-edition']; - - return composerConfig - } + transformMagentoCommunityEditionProduct, + transformMageOSCommunityEditionProduct, ] }, { name: 'project-minimal', - type: 'metapackage', + type: 'project', fromTag: '3.0.0', description: 'Mage-OS Minimal Edition Project', - basePackage: 'magento2-base', - exclude: [ - 'mage-os/module-page-builder', - 'mage-os/module-adobe-*' - ], - historyPath: 'project-minimal' + transform: [ + transformMagentoCommunityEditionProject, + transformMageOSCommunityEditionProject, + ] }, { name: 'product-minimal', type: 'metapackage', fromTag: '3.0.0', description: 'Mage-OS Minimal Edition', - basePackage: 'magento2-base', - exclude: [ - 'mage-os/module-page-builder', - 'mage-os/module-adobe-*' - ], - historyPath: 'product-minimal' + transform: [ + transformMagentoCommunityEditionProduct, + transformMageOSCommunityEditionProduct, + /** + * @param {{}} composerConfig + * @param {repositoryBuildDefinition} instruction + * @param {metapackageDefinition} metapackage + * @param {buildState} release + */ + async (composerConfig, instruction, metapackage, release) => { + // Mock removing inventory and graphql packages for minimal edition + for (const pkg of Object.keys(composerConfig.require)) { + if (pkg.includes('-graph-ql') || pkg.includes('-inventory')) { + delete composerConfig.require[pkg]; + } + } + + return composerConfig; + } + ] } ] }, diff --git a/src/build-config/packages-config.js b/src/build-config/packages-config.js index 07daf79..09c999c 100644 --- a/src/build-config/packages-config.js +++ b/src/build-config/packages-config.js @@ -1,10 +1,7 @@ const { - getVersionStability, - setDependencyVersions, - getAdditionalDependencies -} = require('../package-modules'); -const buildState = require('../type/build-state'); -const repositoryBuildDefinition = require('../type/repository-build-definition'); + transformMagentoCommunityEditionProject, + transformMagentoCommunityEditionProduct +} = require('../build-metapackage/magento-community-edition'); const packageDefs = { 'magento2': { @@ -79,102 +76,16 @@ const packageDefs = { name: 'project-community-edition', type: 'project', description: 'Magento Community Edition Project', - basePackage: '', - historyPath: 'project-community-edition', transform: [ - /** - * @param {{}} composerConfig - * @param {repositoryBuildDefinition} instruction - * @param {metapackageDefinition} metapackage - * @param {buildState} release - */ - async (composerConfig, instruction, metapackage, release) => { - // TODO: Refactor, extract these into separate modules - const packageName = `${instruction.vendor}/${metapackage.name}`; - const version = release.version || release.dependencyVersions[packageName] || release.ref; - - // read release history or dependencies-template for project metapackage - const additionalDependencies = await getAdditionalDependencies(packageName, release.ref) - - composerConfig = Object.assign({}, composerConfig, { - name: packageName, - description: 'eCommerce Platform for Growth (Community Edition)', - extra: {'magento-force': 'override'}, - version: release.version || release.dependencyVersions[packageName] || release.ref, - repositories: [{type: 'composer', url: release.composerRepoUrl}], - 'minimum-stability': getVersionStability(version), - require: Object.assign( - {[`${packageName}`]: version}, - additionalDependencies - ) - }); - - for (const k of ['replace', 'suggest']) { - delete composerConfig[k]; - } - - setDependencyVersions(instruction, release, composerConfig); - - if (instruction?.transform[packageName]) { - composerConfig = instruction.transform[packageName].reduce( - (config, transformFn) => transformFn(config, instruction, release), - composerConfig - ) - } - - return composerConfig; - } + transformMagentoCommunityEditionProject ] }, { name: 'product-community-edition', type: 'metapackage', description: 'Magento Community Edition', - basePackage: '', - historyPath: 'product-community-edition', transform: [ - /** - * @param {{}} composerConfig - * @param {repositoryBuildDefinition} instruction - * @param {metapackageDefinition} metapackage - * @param {buildState} release - */ - async (composerConfig, instruction, metapackage, release) => { - const packageName = `${instruction.vendor}/${metapackage.name}`; - const version = release.version || release.dependencyVersions[packageName] || release.ref; - - // This method is in package-modules, and checks history and falls back to composer-templates - // We should find a way to consolidate or abstract this for other instances - const additionalDependencies = await getAdditionalDependencies(packageName, release.ref) - - composerConfig = Object.assign({}, composerConfig, { - name: packageName, - description: 'eCommerce Platform for Growth (Community Edition)', - type: 'metapackage', - require: Object.assign( - {}, - composerConfig.require, - composerConfig.replace, - additionalDependencies, - {[`${instruction.vendor}/magento2-base`]: release.version} - ), - version: release.version - }); - - for (const k of ['autoload', 'autoload-dev', 'config', 'conflict', 'extra', 'minimum-stability', 'replace', 'require-dev', 'suggest']) { - delete composerConfig[k]; - } - setDependencyVersions(instruction, release, composerConfig); - - if (instruction.transform[packageName]) { - composerConfig = instruction.transform[packageName].reduce( - (config, transformFn) => transformFn(config, instruction, release), - composerConfig - ); - } - - return composerConfig; - } + transformMagentoCommunityEditionProduct ] } ] diff --git a/src/build-metapackage/mage-os-community-edition.js b/src/build-metapackage/mage-os-community-edition.js new file mode 100644 index 0000000..e8ff0d2 --- /dev/null +++ b/src/build-metapackage/mage-os-community-edition.js @@ -0,0 +1,38 @@ +const buildState = require('../type/build-state'); +const metapackageDefinition = require('../type/metapackage-definition'); +const repositoryBuildDefinition = require('../type/repository-build-definition'); +const { + updateComposerConfigFromMagentoToMageOs +} = require('../release-build-tools'); + +/** + * @param {{}} composerConfig + * @param {repositoryBuildDefinition} instruction + * @param {metapackageDefinition} metapackage + * @param {buildState} release + */ +async function transformMageOSCommunityEditionProject(composerConfig, instruction, metapackage, release) { + updateComposerConfigFromMagentoToMageOs(instruction, release, composerConfig); + return composerConfig; +} + +/** + * @param {{}} composerConfig + * @param {repositoryBuildDefinition} instruction + * @param {metapackageDefinition} metapackage + * @param {buildState} release + */ +async function transformMageOSCommunityEditionProduct(composerConfig, instruction, metapackage, release) { + updateComposerConfigFromMagentoToMageOs(instruction, release, composerConfig) + + // Add upstreamRelease to composer extra data for reference + composerConfig.extra = composerConfig.extra || {}; + composerConfig.extra.magento_version = release.replaceVersions['magento/product-community-edition']; + + return composerConfig +} + +module.exports = { + transformMageOSCommunityEditionProject, + transformMageOSCommunityEditionProduct, +}; diff --git a/src/build-metapackage/magento-community-edition.js b/src/build-metapackage/magento-community-edition.js new file mode 100644 index 0000000..6e6d974 --- /dev/null +++ b/src/build-metapackage/magento-community-edition.js @@ -0,0 +1,83 @@ +const { + getVersionStability, + setDependencyVersions, + getAdditionalDependencies +} = require('../package-modules'); +const buildState = require('../type/build-state'); +const metapackageDefinition = require('../type/metapackage-definition'); +const repositoryBuildDefinition = require('../type/repository-build-definition'); + +/** + * @param {{}} composerConfig + * @param {repositoryBuildDefinition} instruction + * @param {metapackageDefinition} metapackage + * @param {buildState} release + */ +async function transformMagentoCommunityEditionProject(composerConfig, instruction, metapackage, release) { + const packageName = `${instruction.vendor}/${metapackage.name}`; + const version = release.version || release.dependencyVersions[packageName] || release.ref; + + // read release history or dependencies-template for project metapackage + const additionalDependencies = await getAdditionalDependencies( + `${instruction.vendor}/project-community-edition`, + release.ref + ) + + composerConfig = Object.assign({}, composerConfig, { + description: 'Community-built eCommerce Platform for Growth', + extra: {'magento-force': 'override'}, + repositories: [{type: 'composer', url: release.composerRepoUrl}], + 'minimum-stability': getVersionStability(version), + require: Object.assign( + {[`${packageName}`]: version}, + additionalDependencies + ) + }); + + for (const k of ['replace', 'suggest']) { + delete composerConfig[k]; + } + + setDependencyVersions(instruction, release, composerConfig); + + return composerConfig; +} + +/** + * @param {{}} composerConfig + * @param {repositoryBuildDefinition} instruction + * @param {metapackageDefinition} metapackage + * @param {buildState} release + */ +async function transformMagentoCommunityEditionProduct(composerConfig, instruction, metapackage, release) { + const packageName = `${instruction.vendor}/${metapackage.name}`; + const version = release.version || release.dependencyVersions[packageName] || release.ref; + + // This method is in package-modules, and checks history and falls back to composer-templates + // We should find a way to consolidate or abstract this for other instances + const additionalDependencies = await getAdditionalDependencies(packageName, release.ref) + + composerConfig = Object.assign({}, composerConfig, { + description: 'eCommerce Platform for Growth (Community Edition)', + type: 'metapackage', + require: Object.assign( + {}, + composerConfig.require, + composerConfig.replace, + additionalDependencies, + {[`${instruction.vendor}/magento2-base`]: release.version} + ), + }); + + for (const k of ['autoload', 'autoload-dev', 'config', 'conflict', 'extra', 'minimum-stability', 'replace', 'require-dev', 'suggest']) { + delete composerConfig[k]; + } + setDependencyVersions(instruction, release, composerConfig); + + return composerConfig; +} + +module.exports = { + transformMagentoCommunityEditionProject, + transformMagentoCommunityEditionProduct, +}; diff --git a/src/package-modules.js b/src/package-modules.js index 73eb12a..bf0edd9 100644 --- a/src/package-modules.js +++ b/src/package-modules.js @@ -335,10 +335,9 @@ async function createPackageForRef(instruction, package, release) { setDependencyVersions(instruction, release, composerConfig); if (instruction.transform[name]) { - composerConfig = instruction.transform[name].reduce( - (config, transformFn) => transformFn(config, instruction, release), - composerConfig - ); + for (const fn of instruction.transform[name]) { + composerConfig = await fn(composerConfig, instruction, release); + } } const filesInZip = files.map(file => { @@ -537,10 +536,9 @@ async function createMetaPackageFromRepoDir(instruction, package, release) { setDependencyVersions(instruction, release, composerConfig); if (instruction.transform[name]) { - composerConfig = instruction.transform[name].reduce( - (config, transformFn) => transformFn(config, instruction, release), - composerConfig - ); + for (const fn of instruction.transform[name]) { + composerConfig = await fn(composerConfig, instruction, release); + } } const files = [{ @@ -558,73 +556,32 @@ async function createMetaPackageFromRepoDir(instruction, package, release) { return {[name]: version} } -async function getBaseDependencies(instruction, basePackage) { - try { - const composerJson = await readComposerJson(instruction.repoUrl, '', instruction.ref); - const composerConfig = JSON.parse(composerJson); - return composerConfig.require || {}; - } catch (error) { - console.warn(`Could not load base dependencies from ${basePackage}: ${error.message}`); - return {}; - } -} - -function filterDependencies(dependencies, include, exclude) { - const filtered = {}; - - for (const [pkg, version] of Object.entries(dependencies)) { - if (exclude && exclude.some(pattern => { - return pattern.endsWith('*') - ? pkg.startsWith(pattern.slice(0, -1)) - : pkg === pattern; - })) { - continue; - } - - // @TODO: I don't think this is flexible enough. There's no additive ability. This also doesn't wildcard like excludes. - if (!include || include.length === 0 || include.includes(pkg)) { - filtered[pkg] = version; - } - } - - return filtered; -} - async function createMetaPackage(instruction, metapackage, release) { - const packageName = `magento/${metapackage.name}`; // Has to be Magento here. Trust me. reasons. + let packageName = `magento/${metapackage.name}`; // Has to be Magento here for transforms. - // Determine dependencies with base and filters - let dependencies = {}; - if (metapackage.basePackage) { - dependencies = await getBaseDependencies(instruction, metapackage.basePackage); - } - - dependencies = filterDependencies( - dependencies, - metapackage.include, - metapackage.exclude - ); + // Fetch base composer config + const composerJson = await readComposerJson(instruction.repoUrl, '', release.ref); + let composerConfig = JSON.parse(composerJson); - // Create package config - let composerConfig = { + // Create specific package config + composerConfig = Object.assign(composerConfig, { name: packageName, + description: composerConfig.description || '', type: metapackage.type, - description: metapackage.description, - require: dependencies, + license: composerConfig.license || [], + require: composerConfig.require || {}, version: release.version || release.ref - }; + }); // Apply transforms - composerConfig = await metapackage.transform.reduce( - (config, fn) => fn(config, instruction, metapackage, release), - composerConfig - ); - if (instruction.transform[packageName]) { - composerConfig = await instruction.transform[packageName].reduce( - (config, fn) => fn(config, instruction, release), - composerConfig - ); + for (const fn of instruction.transform[packageName]) { + composerConfig = await fn(composerConfig, instruction, release); + } + } + + for (const fn of metapackage.transform) { + composerConfig = await fn(composerConfig, instruction, metapackage, release); } // Create package diff --git a/src/type/metapackage-definition.js b/src/type/metapackage-definition.js index d856654..17ee393 100644 --- a/src/type/metapackage-definition.js +++ b/src/type/metapackage-definition.js @@ -14,48 +14,24 @@ class metapackageDefinition { */ description = ''; - /** - * @type String|null Base package to extend from - */ - basePackage = null; - - /** - * @type Array Packages to include in the metapackage - */ - include = []; - - /** - * @type Array Packages to exclude from the metapackage - */ - exclude = []; - /** * @type Array Transform functions to apply */ transform = []; - /** - * @type String|null Path to history file - */ - historyPath = null; - /** * @type String|null Tag to build from (e.g. a git tag) */ fromTag = null; /** - * @param {{name: String, type: String, description: String, basePackage: String, include: Array, exclude: Array, transform: Array, historyPath: String, fromTag: String}} config + * @param {{name: String, type: String, description: String, transform: Array, fromTag: String}} config */ constructor(config = {}) { this.name = config.name || this.name; this.type = config.type || this.type; this.description = config.description || this.description; - this.basePackage = config.basePackage || this.basePackage; - this.include = config.include || this.include; - this.exclude = config.exclude || this.exclude; this.transform = config.transform || this.transform; - this.historyPath = config.historyPath || this.historyPath; this.fromTag = config.fromTag || this.fromTag; } } From 94bb15337626268f645eed82f4f17f85ad0dd763 Mon Sep 17 00:00:00 2001 From: Ryan Hoerr Date: Sun, 23 Nov 2025 20:26:53 -0500 Subject: [PATCH 07/12] Fixed build discrepancies --- .../product-community-edition/1.0.0.json | 3 +++ .../product-community-edition/1.0.1.json | 3 +++ .../product-community-edition/1.0.2.json | 3 +++ .../product-community-edition/1.0.3.json | 3 +++ .../product-community-edition/1.0.4.json | 3 +++ .../product-community-edition/1.0.5.json | 3 +++ .../product-community-edition/1.0.6.json | 3 +++ .../product-community-edition/1.1.0.json | 3 +++ .../product-community-edition/1.1.1.json | 3 +++ .../product-community-edition/1.2.0.json | 3 +++ .../product-community-edition/1.3.0.json | 3 +++ .../product-community-edition/1.3.1.json | 3 +++ .../mage-os-community-edition.js | 15 ++++++++++++--- .../magento-community-edition.js | 18 +++++++++++------- src/make/mageos-release.js | 2 +- src/make/mirror.js | 1 + src/mirror-build-tools.js | 4 ++-- src/package-modules.js | 18 +++++++++++++----- 18 files changed, 76 insertions(+), 18 deletions(-) diff --git a/resource/history/mage-os/product-community-edition/1.0.0.json b/resource/history/mage-os/product-community-edition/1.0.0.json index e9f3781..243ec0e 100644 --- a/resource/history/mage-os/product-community-edition/1.0.0.json +++ b/resource/history/mage-os/product-community-edition/1.0.0.json @@ -3,5 +3,8 @@ "mage-os/security-package": "1.0.0", "mage-os/inventory-metapackage": "1.0.0", "mage-os/page-builder": "1.0.0" + }, + "extra": { + "magento_version": "2.4.6-p2" } } diff --git a/resource/history/mage-os/product-community-edition/1.0.1.json b/resource/history/mage-os/product-community-edition/1.0.1.json index e9f3781..37a9856 100644 --- a/resource/history/mage-os/product-community-edition/1.0.1.json +++ b/resource/history/mage-os/product-community-edition/1.0.1.json @@ -3,5 +3,8 @@ "mage-os/security-package": "1.0.0", "mage-os/inventory-metapackage": "1.0.0", "mage-os/page-builder": "1.0.0" + }, + "extra": { + "magento_version": "2.4.6-p3" } } diff --git a/resource/history/mage-os/product-community-edition/1.0.2.json b/resource/history/mage-os/product-community-edition/1.0.2.json index 2fcde68..032fa08 100644 --- a/resource/history/mage-os/product-community-edition/1.0.2.json +++ b/resource/history/mage-os/product-community-edition/1.0.2.json @@ -3,5 +3,8 @@ "mage-os/security-package": "1.0.2", "mage-os/inventory-metapackage": "1.0.2", "mage-os/page-builder": "1.0.2" + }, + "extra": { + "magento_version": "2.4.7-p1" } } diff --git a/resource/history/mage-os/product-community-edition/1.0.3.json b/resource/history/mage-os/product-community-edition/1.0.3.json index 6ae3e46..df5c16d 100644 --- a/resource/history/mage-os/product-community-edition/1.0.3.json +++ b/resource/history/mage-os/product-community-edition/1.0.3.json @@ -3,5 +3,8 @@ "mage-os/security-package": "1.0.3", "mage-os/inventory-metapackage": "1.0.3", "mage-os/page-builder": "1.0.3" + }, + "extra": { + "magento_version": "2.4.7-p1" } } diff --git a/resource/history/mage-os/product-community-edition/1.0.4.json b/resource/history/mage-os/product-community-edition/1.0.4.json index b7e2f12..05808e3 100644 --- a/resource/history/mage-os/product-community-edition/1.0.4.json +++ b/resource/history/mage-os/product-community-edition/1.0.4.json @@ -3,5 +3,8 @@ "mage-os/security-package": "1.0.4", "mage-os/inventory-metapackage": "1.0.4", "mage-os/page-builder": "1.0.4" + }, + "extra": { + "magento_version": "2.4.7-p2" } } diff --git a/resource/history/mage-os/product-community-edition/1.0.5.json b/resource/history/mage-os/product-community-edition/1.0.5.json index 6e87670..ec5ee25 100644 --- a/resource/history/mage-os/product-community-edition/1.0.5.json +++ b/resource/history/mage-os/product-community-edition/1.0.5.json @@ -3,5 +3,8 @@ "mage-os/security-package": "1.0.5", "mage-os/inventory-metapackage": "1.0.5", "mage-os/page-builder": "1.0.5" + }, + "extra": { + "magento_version": "2.4.7-p3" } } diff --git a/resource/history/mage-os/product-community-edition/1.0.6.json b/resource/history/mage-os/product-community-edition/1.0.6.json index 3b7a415..360bc6d 100644 --- a/resource/history/mage-os/product-community-edition/1.0.6.json +++ b/resource/history/mage-os/product-community-edition/1.0.6.json @@ -3,5 +3,8 @@ "mage-os/security-package": "1.0.6", "mage-os/inventory-metapackage": "1.0.6", "mage-os/page-builder": "1.0.6" + }, + "extra": { + "magento_version": "2.4.7-p4" } } diff --git a/resource/history/mage-os/product-community-edition/1.1.0.json b/resource/history/mage-os/product-community-edition/1.1.0.json index 5a8ec8b..c92587d 100644 --- a/resource/history/mage-os/product-community-edition/1.1.0.json +++ b/resource/history/mage-os/product-community-edition/1.1.0.json @@ -5,5 +5,8 @@ "mage-os/inventory-metapackage": "1.1.0", "mage-os/page-builder": "1.1.0", "mage-os/theme-adminhtml-m137": "1.1.0" + }, + "extra": { + "magento_version": "2.4.8" } } diff --git a/resource/history/mage-os/product-community-edition/1.1.1.json b/resource/history/mage-os/product-community-edition/1.1.1.json index f262814..adc7f7b 100644 --- a/resource/history/mage-os/product-community-edition/1.1.1.json +++ b/resource/history/mage-os/product-community-edition/1.1.1.json @@ -5,5 +5,8 @@ "mage-os/inventory-metapackage": "1.1.1", "mage-os/page-builder": "1.1.1", "mage-os/theme-adminhtml-m137": "1.1.1" + }, + "extra": { + "magento_version": "2.4.8" } } diff --git a/resource/history/mage-os/product-community-edition/1.2.0.json b/resource/history/mage-os/product-community-edition/1.2.0.json index 4bd9fc3..46fe99a 100644 --- a/resource/history/mage-os/product-community-edition/1.2.0.json +++ b/resource/history/mage-os/product-community-edition/1.2.0.json @@ -5,5 +5,8 @@ "mage-os/inventory-metapackage": "1.2.0", "mage-os/page-builder": "1.2.0", "mage-os/theme-adminhtml-m137": "1.2.0" + }, + "extra": { + "magento_version": "2.4.8-p1" } } diff --git a/resource/history/mage-os/product-community-edition/1.3.0.json b/resource/history/mage-os/product-community-edition/1.3.0.json index 4fec04a..da37369 100644 --- a/resource/history/mage-os/product-community-edition/1.3.0.json +++ b/resource/history/mage-os/product-community-edition/1.3.0.json @@ -5,5 +5,8 @@ "mage-os/inventory-metapackage": "1.3.0", "mage-os/page-builder": "1.3.0", "mage-os/theme-adminhtml-m137": "1.3.0" + }, + "extra": { + "magento_version": "2.4.8-p2" } } diff --git a/resource/history/mage-os/product-community-edition/1.3.1.json b/resource/history/mage-os/product-community-edition/1.3.1.json index 0b422df..e05add5 100644 --- a/resource/history/mage-os/product-community-edition/1.3.1.json +++ b/resource/history/mage-os/product-community-edition/1.3.1.json @@ -5,5 +5,8 @@ "mage-os/inventory-metapackage": "1.3.1", "mage-os/page-builder": "1.3.1", "mage-os/theme-adminhtml-m137": "1.3.1" + }, + "extra": { + "magento_version": "2.4.8-p2" } } diff --git a/src/build-metapackage/mage-os-community-edition.js b/src/build-metapackage/mage-os-community-edition.js index e8ff0d2..7097f96 100644 --- a/src/build-metapackage/mage-os-community-edition.js +++ b/src/build-metapackage/mage-os-community-edition.js @@ -1,6 +1,7 @@ const buildState = require('../type/build-state'); const metapackageDefinition = require('../type/metapackage-definition'); const repositoryBuildDefinition = require('../type/repository-build-definition'); +const {compareVersions} = require('../utils'); const { updateComposerConfigFromMagentoToMageOs } = require('../release-build-tools'); @@ -13,6 +14,12 @@ const { */ async function transformMageOSCommunityEditionProject(composerConfig, instruction, metapackage, release) { updateComposerConfigFromMagentoToMageOs(instruction, release, composerConfig); + + // Versions 2.0.0 and below had a different description + if (compareVersions(composerConfig.version, '2.0.0') <= 0) { + composerConfig.description = 'eCommerce Platform for Growth (Community Edition)'; + } + return composerConfig; } @@ -25,9 +32,11 @@ async function transformMageOSCommunityEditionProject(composerConfig, instructio async function transformMageOSCommunityEditionProduct(composerConfig, instruction, metapackage, release) { updateComposerConfigFromMagentoToMageOs(instruction, release, composerConfig) - // Add upstreamRelease to composer extra data for reference - composerConfig.extra = composerConfig.extra || {}; - composerConfig.extra.magento_version = release.replaceVersions['magento/product-community-edition']; + if (release.replaceVersions['magento/product-community-edition']) { + // Add upstreamRelease to composer extra data for reference + composerConfig.extra = composerConfig.extra || {}; + composerConfig.extra.magento_version = release.replaceVersions['magento/product-community-edition']; + } return composerConfig } diff --git a/src/build-metapackage/magento-community-edition.js b/src/build-metapackage/magento-community-edition.js index 6e6d974..70d48d6 100644 --- a/src/build-metapackage/magento-community-edition.js +++ b/src/build-metapackage/magento-community-edition.js @@ -15,6 +15,7 @@ const repositoryBuildDefinition = require('../type/repository-build-definition') */ async function transformMagentoCommunityEditionProject(composerConfig, instruction, metapackage, release) { const packageName = `${instruction.vendor}/${metapackage.name}`; + const productName = `${instruction.vendor}/` + metapackage.name.replace('project-', 'product-'); const version = release.version || release.dependencyVersions[packageName] || release.ref; // read release history or dependencies-template for project metapackage @@ -23,14 +24,15 @@ async function transformMagentoCommunityEditionProject(composerConfig, instructi release.ref ) - composerConfig = Object.assign({}, composerConfig, { + composerConfig = Object.assign({}, composerConfig, additionalDependencies, { + name: packageName, description: 'Community-built eCommerce Platform for Growth', extra: {'magento-force': 'override'}, repositories: [{type: 'composer', url: release.composerRepoUrl}], 'minimum-stability': getVersionStability(version), require: Object.assign( - {[`${packageName}`]: version}, - additionalDependencies + {[`${productName}`]: version}, + additionalDependencies.require ) }); @@ -51,25 +53,27 @@ async function transformMagentoCommunityEditionProject(composerConfig, instructi */ async function transformMagentoCommunityEditionProduct(composerConfig, instruction, metapackage, release) { const packageName = `${instruction.vendor}/${metapackage.name}`; - const version = release.version || release.dependencyVersions[packageName] || release.ref; // This method is in package-modules, and checks history and falls back to composer-templates // We should find a way to consolidate or abstract this for other instances const additionalDependencies = await getAdditionalDependencies(packageName, release.ref) - composerConfig = Object.assign({}, composerConfig, { + delete composerConfig.extra; + + composerConfig = Object.assign({}, composerConfig, additionalDependencies, { + name: packageName, description: 'eCommerce Platform for Growth (Community Edition)', type: 'metapackage', require: Object.assign( {}, composerConfig.require, composerConfig.replace, - additionalDependencies, + additionalDependencies.require, {[`${instruction.vendor}/magento2-base`]: release.version} ), }); - for (const k of ['autoload', 'autoload-dev', 'config', 'conflict', 'extra', 'minimum-stability', 'replace', 'require-dev', 'suggest']) { + for (const k of ['autoload', 'autoload-dev', 'config', 'conflict', 'minimum-stability', 'replace', 'require-dev', 'suggest']) { delete composerConfig[k]; } setDependencyVersions(instruction, release, composerConfig); diff --git a/src/make/mageos-release.js b/src/make/mageos-release.js index 3850a60..0de82f1 100644 --- a/src/make/mageos-release.js +++ b/src/make/mageos-release.js @@ -82,7 +82,7 @@ let distroRelease = new buildState({ for (const instruction of releaseInstructions) { instruction.vendor = mageosVendor; - await processMirrorInstruction(instruction); + await processMirrorInstruction(instruction, distroRelease); } } diff --git a/src/make/mirror.js b/src/make/mirror.js index 83e05b7..d47d238 100644 --- a/src/make/mirror.js +++ b/src/make/mirror.js @@ -3,6 +3,7 @@ const parseOptions = require('parse-options'); const {setArchiveBaseDir} = require('./../package-modules'); const {copyAdditionalPackages, processMirrorInstruction} = require('./../mirror-build-tools'); const {buildConfig: mirrorInstructions} = require('./../build-config/mirror-build-config'); +const buildState = require('../type/build-state'); const options = parseOptions( diff --git a/src/mirror-build-tools.js b/src/mirror-build-tools.js index c11c67b..8751c53 100644 --- a/src/mirror-build-tools.js +++ b/src/mirror-build-tools.js @@ -222,10 +222,10 @@ async function createMetaPackagesSinceTag(instruction, metapackage, releaseConte release, packageName, tag, - composerConfig => { + async composerConfig => { if (metapackage.transform) { for (const fn of metapackage.transform) { - composerConfig = fn(composerConfig, instruction, metapackage, release); + composerConfig = await fn(composerConfig, instruction, metapackage, release); } } return composerConfig; diff --git a/src/package-modules.js b/src/package-modules.js index bf0edd9..d777331 100644 --- a/src/package-modules.js +++ b/src/package-modules.js @@ -413,6 +413,11 @@ async function createComposerJsonOnlyPackage(instruction, release, name, version // @todo: Check version vs instruction.ref vs release.version here. Is this necessary to track separately? Is this fallback needed? const packageFilepath = archiveFilePath(name, version || release.ref); + + if (!isInAdditionalPackages(name, composerConfig.version)) { + await writePackage(packageFilepath, files); + } + return {packageFilepath, files} } @@ -424,20 +429,23 @@ async function getLatestTag(url) { async function getLatestDependencies(dir) { if (!fs.existsSync(`${dir}/dependencies-template.json`)) { - return {}; + return { + require: {} + }; } const template = JSON.parse(fs.readFileSync(`${dir}/dependencies-template.json`, 'utf8')); return Object.entries(template.dependencies).reduce(async (deps, [dependency, url]) => { - const tag = url.slice(0, 4) === 'http' ? await getLatestTag(url) : url; - return Object.assign(await deps, {[dependency]: tag}); - }, Promise.resolve({})); + const tag = url.slice(0, 4) === 'http' ? await getLatestTag(url) : url; + return Object.assign(await deps, {[dependency]: tag}); + }, Promise.resolve({})) + .then(requireObj => ({ require: requireObj })); } async function getAdditionalDependencies(packageName, ref) { const dir = `${__dirname}/../resource/history/${packageName}`; const file = `${dir}/${ref}.json`; return fs.existsSync(file) - ? JSON.parse(fs.readFileSync(file, 'utf8')).require + ? JSON.parse(fs.readFileSync(file, 'utf8')) : await getLatestDependencies(`${__dirname}/../resource/composer-templates/${packageName}`); } From 74967556dd1c063a5962fb2c3e968db7592f1a8d Mon Sep 17 00:00:00 2001 From: Ryan Hoerr Date: Sun, 23 Nov 2025 20:28:42 -0500 Subject: [PATCH 08/12] Removed independently published packages from build config --- .../mageos-release-build-config.js | 208 ------------------ 1 file changed, 208 deletions(-) diff --git a/src/build-config/mageos-release-build-config.js b/src/build-config/mageos-release-build-config.js index 852a9cb..37858f2 100644 --- a/src/build-config/mageos-release-build-config.js +++ b/src/build-config/mageos-release-build-config.js @@ -190,214 +190,6 @@ const releaseBuildConfig = { ref: 'main', fromTag: '1.0.0', }, - // 'theme-adminhtml-m137': { - // repoUrl: 'https://github.com/mage-os-lab/theme-adminhtml-m137.git', - // ref: 'main', - // fromTag: '1.0.0', - // packageDirs: [], - // packageIndividual: [ - // { - // label: 'theme-adminhtml-m137', - // dir: '' - // } - // ], - // packageMetaFromDirs: [], - // }, - // 'module-theme-adminhtml-switcher': { - // repoUrl: 'https://github.com/mage-os-lab/module-theme-adminhtml-switcher.git', - // ref: 'main', - // fromTag: '1.0.0', - // packageDirs: [], - // packageIndividual: [ - // { - // label: 'module-theme-adminhtml-switcher', - // dir: '' - // } - // ], - // packageMetaFromDirs: [], - // }, - // 'mageos-async-events-sinks': { - // repoUrl: 'https://github.com/mage-os/mageos-async-events-sinks.git', - // ref: 'main', - // fromTag: '1.0.0', - // packageDirs: [], - // packageIndividual: [ - // { - // label: 'mageos-async-events-sinks', - // dir: '' - // } - // ], - // packageMetaFromDirs: [], - // }, - // 'mageos-async-events-admin-ui': { - // repoUrl: 'https://github.com/mage-os/mageos-async-events-admin-ui.git', - // ref: 'main', - // fromTag: '1.0.0', - // packageDirs: [], - // packageIndividual: [ - // { - // label: 'mageos-async-events-admin-ui', - // dir: '' - // } - // ], - // packageMetaFromDirs: [], - // }, - // // 'mageos-async-events-azure': { - // // repoUrl: 'https://github.com/mage-os/mageos-async-events-azure.git', - // // ref: 'main', - // // fromTag: '1.0.0', - // // packageDirs: [], - // // packageIndividual: [ - // // { - // // label: 'mageos-async-events-azure', - // // dir: '' - // // } - // // ], - // // packageMetaFromDirs: [], - // // }, - // 'mageos-async-events': { - // repoUrl: 'https://github.com/mage-os/mageos-async-events.git', - // ref: '4.x', - // fromTag: '1.0.0', - // packageDirs: [], - // packageIndividual: [ - // { - // label: 'mageos-async-events', - // dir: '' - // } - // ], - // packageMetaFromDirs: [], - // }, - // 'mageos-async-events-aws': { - // repoUrl: 'https://github.com/mage-os/mageos-async-events-aws.git', - // ref: 'main', - // fromTag: '1.0.0', - // packageDirs: [], - // packageIndividual: [ - // { - // label: 'mageos-async-events-aws', - // dir: '' - // } - // ], - // packageMetaFromDirs: [], - // }, - // 'mageos-async-events-gcp': { - // repoUrl: 'https://github.com/mage-os/mageos-async-events-gcp.git', - // ref: 'main', - // fromTag: '1.0.0', - // packageDirs: [], - // packageIndividual: [ - // { - // label: 'mageos-async-events-gcp', - // dir: '' - // } - // ], - // packageMetaFromDirs: [], - // }, - // 'mageos-common-async-events': { - // repoUrl: 'https://github.com/mage-os/mageos-common-async-events.git', - // ref: 'main', - // fromTag: '1.0.0', - // packageDirs: [], - // packageIndividual: [ - // { - // label: 'mageos-common-async-events', - // dir: '' - // } - // ], - // packageMetaFromDirs: [], - // }, - // 'module-inventory-reservations-grid': { - // repoUrl: 'https://github.com/mage-os-lab/module-inventory-reservations-grid.git', - // ref: 'main', - // fromTag: '1.0.0', - // packageDirs: [], - // packageIndividual: [ - // { - // label: 'module-inventory-reservations-grid', - // dir: '' - // } - // ], - // packageMetaFromDirs: [], - // }, - // 'module-automatic-translation': { - // repoUrl: 'https://github.com/mage-os-lab/module-automatic-translation.git', - // ref: 'main', - // fromTag: '1.0.0', - // packageDirs: [], - // packageIndividual: [ - // { - // label: 'module-automatic-translation', - // dir: '' - // } - // ], - // packageMetaFromDirs: [], - // }, - // 'web-installer': { - // repoUrl: 'https://github.com/mage-os-lab/web-installer.git', - // ref: 'main', - // fromTag: '1.0.0', - // packageDirs: [], - // packageIndividual: [ - // { - // label: 'web-installer', - // dir: '' - // } - // ], - // packageMetaFromDirs: [], - // }, - // 'module-meta-robots-tag': { - // repoUrl: 'https://github.com/mage-os-lab/module-meta-robots-tag.git', - // ref: 'main', - // fromTag: '1.0.0', - // packageDirs: [], - // packageIndividual: [ - // { - // label: 'module-meta-robots-tag', - // dir: '' - // } - // ], - // packageMetaFromDirs: [], - // }, - // 'module-catalog-data-ai': { - // repoUrl: 'https://github.com/mage-os-lab/module-catalog-data-ai.git', - // ref: 'main', - // fromTag: '1.0.0', - // packageDirs: [], - // packageIndividual: [ - // { - // label: 'module-catalog-data-ai', - // dir: '' - // } - // ], - // packageMetaFromDirs: [], - // }, - // 'module-pagebuilder-template-import-export': { - // repoUrl: 'https://github.com/mage-os-lab/module-pagebuilder-template-import-export.git', - // ref: 'master', - // fromTag: '1.0.0', - // packageDirs: [], - // packageIndividual: [ - // { - // label: 'module-pagebuilder-template-import-export', - // dir: '' - // } - // ], - // packageMetaFromDirs: [], - // }, - // 'module-admin-assistant': { - // repoUrl: 'https://github.com/mage-os-lab/module-admin-assistant.git', - // ref: 'main', - // fromTag: '1.0.0', - // packageDirs: [], - // packageIndividual: [ - // { - // label: 'module-admin-assistant', - // dir: '' - // } - // ], - // packageMetaFromDirs: [], - // }, }; module.exports = { From 3aa39ac0ef8fb571f04de1898ae3ec589f806ed1 Mon Sep 17 00:00:00 2001 From: Ryan Hoerr Date: Sun, 23 Nov 2025 20:33:45 -0500 Subject: [PATCH 09/12] Removed 'minimal' metapackage test case --- .../mageos-release-build-config.js | 36 ------------------- 1 file changed, 36 deletions(-) diff --git a/src/build-config/mageos-release-build-config.js b/src/build-config/mageos-release-build-config.js index 37858f2..a1138fa 100644 --- a/src/build-config/mageos-release-build-config.js +++ b/src/build-config/mageos-release-build-config.js @@ -41,42 +41,6 @@ const releaseBuildConfig = { transformMagentoCommunityEditionProduct, transformMageOSCommunityEditionProduct, ] - }, - { - name: 'project-minimal', - type: 'project', - fromTag: '3.0.0', - description: 'Mage-OS Minimal Edition Project', - transform: [ - transformMagentoCommunityEditionProject, - transformMageOSCommunityEditionProject, - ] - }, - { - name: 'product-minimal', - type: 'metapackage', - fromTag: '3.0.0', - description: 'Mage-OS Minimal Edition', - transform: [ - transformMagentoCommunityEditionProduct, - transformMageOSCommunityEditionProduct, - /** - * @param {{}} composerConfig - * @param {repositoryBuildDefinition} instruction - * @param {metapackageDefinition} metapackage - * @param {buildState} release - */ - async (composerConfig, instruction, metapackage, release) => { - // Mock removing inventory and graphql packages for minimal edition - for (const pkg of Object.keys(composerConfig.require)) { - if (pkg.includes('-graph-ql') || pkg.includes('-inventory')) { - delete composerConfig.require[pkg]; - } - } - - return composerConfig; - } - ] } ] }, From dc4157f768d6c5fc45ca5665414027201dbab11d Mon Sep 17 00:00:00 2001 From: Ryan Hoerr Date: Mon, 24 Nov 2025 22:54:42 -0500 Subject: [PATCH 10/12] fix: do not rebuild composer files for mirror metapackages if we already have it in full --- .../magento-community-edition.js | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/build-metapackage/magento-community-edition.js b/src/build-metapackage/magento-community-edition.js index 70d48d6..7997c68 100644 --- a/src/build-metapackage/magento-community-edition.js +++ b/src/build-metapackage/magento-community-edition.js @@ -19,10 +19,12 @@ async function transformMagentoCommunityEditionProject(composerConfig, instructi const version = release.version || release.dependencyVersions[packageName] || release.ref; // read release history or dependencies-template for project metapackage - const additionalDependencies = await getAdditionalDependencies( - `${instruction.vendor}/project-community-edition`, - release.ref - ) + const additionalDependencies = await getAdditionalDependencies(packageName, release.ref) + + // If this is not a new release, and additionalDependencies looks like a full composer config, use it directly. + if (release.dependencyVersions['*'] === undefined && additionalDependencies['prefer-stable'] !== undefined) { + return additionalDependencies; + } composerConfig = Object.assign({}, composerConfig, additionalDependencies, { name: packageName, @@ -58,6 +60,11 @@ async function transformMagentoCommunityEditionProduct(composerConfig, instructi // We should find a way to consolidate or abstract this for other instances const additionalDependencies = await getAdditionalDependencies(packageName, release.ref) + // If this is not a new release, and additionalDependencies looks like a full composer config, use it directly. + if (release.dependencyVersions['*'] === undefined && additionalDependencies['prefer-stable'] !== undefined) { + return additionalDependencies; + } + delete composerConfig.extra; composerConfig = Object.assign({}, composerConfig, additionalDependencies, { From 7db744657491bd498eca397a5a0ef001f162449c Mon Sep 17 00:00:00 2001 From: Ryan Hoerr Date: Sun, 14 Dec 2025 13:16:18 -0500 Subject: [PATCH 11/12] refactor: adjusted method name and comment per review; some cleanup --- .../magento-community-edition.js | 38 ++++++------- src/package-modules.js | 55 ++++++++++--------- src/release-build-tools.js | 24 ++++---- 3 files changed, 59 insertions(+), 58 deletions(-) diff --git a/src/build-metapackage/magento-community-edition.js b/src/build-metapackage/magento-community-edition.js index 7997c68..b297b65 100644 --- a/src/build-metapackage/magento-community-edition.js +++ b/src/build-metapackage/magento-community-edition.js @@ -1,17 +1,17 @@ const { getVersionStability, setDependencyVersions, - getAdditionalDependencies + getAdditionalConfiguration } = require('../package-modules'); const buildState = require('../type/build-state'); const metapackageDefinition = require('../type/metapackage-definition'); const repositoryBuildDefinition = require('../type/repository-build-definition'); /** - * @param {{}} composerConfig - * @param {repositoryBuildDefinition} instruction + * @param {{}} composerConfig + * @param {repositoryBuildDefinition} instruction * @param {metapackageDefinition} metapackage - * @param {buildState} release + * @param {buildState} release */ async function transformMagentoCommunityEditionProject(composerConfig, instruction, metapackage, release) { const packageName = `${instruction.vendor}/${metapackage.name}`; @@ -19,14 +19,14 @@ async function transformMagentoCommunityEditionProject(composerConfig, instructi const version = release.version || release.dependencyVersions[packageName] || release.ref; // read release history or dependencies-template for project metapackage - const additionalDependencies = await getAdditionalDependencies(packageName, release.ref) + const additionalConfig = await getAdditionalConfiguration(packageName, release.ref) - // If this is not a new release, and additionalDependencies looks like a full composer config, use it directly. - if (release.dependencyVersions['*'] === undefined && additionalDependencies['prefer-stable'] !== undefined) { - return additionalDependencies; + // If this is not a new release, and additionalConfig looks like a full composer config, use it directly. + if (release.dependencyVersions['*'] === undefined && additionalConfig['prefer-stable'] !== undefined) { + return additionalConfig; } - composerConfig = Object.assign({}, composerConfig, additionalDependencies, { + composerConfig = Object.assign({}, composerConfig, additionalConfig, { name: packageName, description: 'Community-built eCommerce Platform for Growth', extra: {'magento-force': 'override'}, @@ -34,7 +34,7 @@ async function transformMagentoCommunityEditionProject(composerConfig, instructi 'minimum-stability': getVersionStability(version), require: Object.assign( {[`${productName}`]: version}, - additionalDependencies.require + additionalConfig.require ) }); @@ -48,26 +48,26 @@ async function transformMagentoCommunityEditionProject(composerConfig, instructi } /** - * @param {{}} composerConfig - * @param {repositoryBuildDefinition} instruction + * @param {{}} composerConfig + * @param {repositoryBuildDefinition} instruction * @param {metapackageDefinition} metapackage - * @param {buildState} release + * @param {buildState} release */ async function transformMagentoCommunityEditionProduct(composerConfig, instruction, metapackage, release) { const packageName = `${instruction.vendor}/${metapackage.name}`; // This method is in package-modules, and checks history and falls back to composer-templates // We should find a way to consolidate or abstract this for other instances - const additionalDependencies = await getAdditionalDependencies(packageName, release.ref) + const additionalConfig = await getAdditionalConfiguration(packageName, release.ref) - // If this is not a new release, and additionalDependencies looks like a full composer config, use it directly. - if (release.dependencyVersions['*'] === undefined && additionalDependencies['prefer-stable'] !== undefined) { - return additionalDependencies; + // If this is not a new release, and additionalConfig looks like a full composer config, use it directly. + if (release.dependencyVersions['*'] === undefined && additionalConfig['prefer-stable'] !== undefined) { + return additionalConfig; } delete composerConfig.extra; - composerConfig = Object.assign({}, composerConfig, additionalDependencies, { + composerConfig = Object.assign({}, composerConfig, additionalConfig, { name: packageName, description: 'eCommerce Platform for Growth (Community Edition)', type: 'metapackage', @@ -75,7 +75,7 @@ async function transformMagentoCommunityEditionProduct(composerConfig, instructi {}, composerConfig.require, composerConfig.replace, - additionalDependencies.require, + additionalConfig.require, {[`${instruction.vendor}/magento2-base`]: release.version} ), }); diff --git a/src/package-modules.js b/src/package-modules.js index d777331..5351308 100644 --- a/src/package-modules.js +++ b/src/package-modules.js @@ -83,9 +83,9 @@ async function writePackage(packageFilepath, files) { } /** - * @param {repositoryBuildDefinition} instruction - * @param {packageDefinition} package - * @param {String} ref + * @param {repositoryBuildDefinition} instruction + * @param {packageDefinition} package + * @param {String} ref * @returns {String} */ async function getComposerJson(instruction, package, ref) { @@ -105,7 +105,7 @@ async function getComposerJson(instruction, package, ref) { */ function getVersionStability(version) { version = version.toLowerCase(); - + if (version.startsWith('dev-') || version.includes('-dev')) { return 'dev'; } @@ -123,13 +123,13 @@ function getVersionStability(version) { } /** - * @param {repositoryBuildDefinition} instruction - * @param {packageDefinition} package - * @param {*} magentoName - * @param {*} composerJson - * @param {*} definedVersion - * @param {*} fallbackVersion - * @returns + * @param {repositoryBuildDefinition} instruction + * @param {packageDefinition} package + * @param {*} magentoName + * @param {*} composerJson + * @param {*} definedVersion + * @param {*} fallbackVersion + * @returns */ function chooseNameAndVersion(instruction, package, magentoName, composerJson, definedVersion, fallbackVersion) { let composerConfig = JSON.parse(composerJson); @@ -192,8 +192,8 @@ function setDependencyVersions(instruction, release, composerConfig) { * * Only used for release-branch builds (not mirror builds). * - * @param {repositoryBuildDefinition} instruction - * @param {packageDefinition} package + * @param {repositoryBuildDefinition} instruction + * @param {packageDefinition} package * @returns {Promise>} */ async function determinePackageForRef(instruction, package, ref) { @@ -225,8 +225,8 @@ async function determinePackageForRef(instruction, package, ref) { * * Only used for release-branch builds (not mirror builds). * - * @param {repositoryBuildDefinition} instruction - * @param {packageDefinition} package + * @param {repositoryBuildDefinition} instruction + * @param {packageDefinition} package * @returns {Promise>} */ async function determinePackagesForRef(instruction, package, ref) { @@ -241,7 +241,7 @@ async function determinePackagesForRef(instruction, package, ref) { } /** - * @param {repositoryBuildDefinition} instruction + * @param {repositoryBuildDefinition} instruction * @param {packageDefinition} package * @param {buildState} release * @returns {Promise<{}>} @@ -381,7 +381,7 @@ function isInAdditionalPackages(name, version) { } /** - * @param {repositoryBuildDefinition} instruction + * @param {repositoryBuildDefinition} instruction * @param {buildState} release * @param {String} name The composer name to use in the composer.json and for the package archive * @param {String|undefined} version Release version to use in the package archive name. Defaults to ref @@ -413,7 +413,7 @@ async function createComposerJsonOnlyPackage(instruction, release, name, version // @todo: Check version vs instruction.ref vs release.version here. Is this necessary to track separately? Is this fallback needed? const packageFilepath = archiveFilePath(name, version || release.ref); - + if (!isInAdditionalPackages(name, composerConfig.version)) { await writePackage(packageFilepath, files); } @@ -427,7 +427,7 @@ async function getLatestTag(url) { return tags[tags.length - 1]; } -async function getLatestDependencies(dir) { +async function getLatestConfiguration(dir) { if (!fs.existsSync(`${dir}/dependencies-template.json`)) { return { require: {} @@ -441,17 +441,17 @@ async function getLatestDependencies(dir) { .then(requireObj => ({ require: requireObj })); } -async function getAdditionalDependencies(packageName, ref) { +async function getAdditionalConfiguration(packageName, ref) { const dir = `${__dirname}/../resource/history/${packageName}`; const file = `${dir}/${ref}.json`; return fs.existsSync(file) ? JSON.parse(fs.readFileSync(file, 'utf8')) - : await getLatestDependencies(`${__dirname}/../resource/composer-templates/${packageName}`); + : await getLatestConfiguration(`${__dirname}/../resource/composer-templates/${packageName}`); } /** - * @param {repositoryBuildDefinition} instruction - * @param {packageDefinition} package + * @param {repositoryBuildDefinition} instruction + * @param {packageDefinition} package * @returns Array */ async function findModulesToBuild(instruction, package, ref) { @@ -467,8 +467,8 @@ async function findModulesToBuild(instruction, package, ref) { } /** - * @param {repositoryBuildDefinition} instruction - * @param {packageDefinition} package + * @param {repositoryBuildDefinition} instruction + * @param {packageDefinition} package * @param {buildState} release * @returns {Promise<{}>} */ @@ -604,7 +604,7 @@ async function createMetaPackage(instruction, metapackage, release) { packageName = `${instruction.vendor}/${metapackage.name}`; const packageFilepath = archiveFilePath(packageName, composerConfig.version); - + if (!isInAdditionalPackages(packageName, composerConfig.version)) { await writePackage(packageFilepath, files); } @@ -632,5 +632,6 @@ module.exports = { getVersionStability, setDependencyVersions, - getAdditionalDependencies, + getAdditionalDependencies: getAdditionalConfiguration, + getAdditionalConfiguration } diff --git a/src/release-build-tools.js b/src/release-build-tools.js index 107cb04..c7bc022 100644 --- a/src/release-build-tools.js +++ b/src/release-build-tools.js @@ -130,7 +130,7 @@ function updateMapFromMagentoToMageOs(obj, vendor) { } /** - * @param {repositoryBuildDefinition} instruction + * @param {repositoryBuildDefinition} instruction * @param {buildState} release * @param {{}} composerConfig */ @@ -142,7 +142,7 @@ function updateComposerDepsFromMagentoToMageOs(instruction, release, composerCon } /** - * @param {repositoryBuildDefinition} instruction + * @param {repositoryBuildDefinition} instruction * @param {buildState} release * @param {{}} composerConfigPart * @param {String} dependencyType @@ -157,7 +157,7 @@ function setMageOsDependencyVersion(instruction, release, composerConfigPart, de // Note: Original code here was just "release.version". The remainder are probably mostly unnecessary. Point for later refinement. composerConfigPart[packageName] = release.version || release.fallbackVersion || release.dependencyVersions[packageName] || release.dependencyVersions['*']; } - + if (dependencyType === 'suggest' && packageName.endsWith('-sample-data')) { composerConfigPart[packageName] = `Sample Data version: ${release.version || release.fallbackVersion}`; } @@ -167,7 +167,7 @@ function setMageOsDependencyVersion(instruction, release, composerConfigPart, de } /** - * @param {repositoryBuildDefinition} instruction + * @param {repositoryBuildDefinition} instruction * @param {buildState} release * @param {{}} composerConfig */ @@ -178,7 +178,7 @@ function updateComposerDepsVersionForMageOs(instruction, release, composerConfig } /** - * @param {repositoryBuildDefinition} instruction + * @param {repositoryBuildDefinition} instruction * @param {buildState} release * @param {{}} composerConfig */ @@ -197,7 +197,7 @@ function updateComposerPluginConfigForMageOs(instruction, release, composerConfi * * This also happens for the "replace" section, before the given replaceVersionMap is merged. * - * @param {repositoryBuildDefinition} instruction + * @param {repositoryBuildDefinition} instruction * @param {buildState} release * @param {{}} composerConfig */ @@ -206,7 +206,7 @@ function updateComposerConfigFromMagentoToMageOs(instruction, release, composerC composerConfig.version = release.version || release.ref; composerConfig.name = setMageOsVendor(composerConfig.name, instruction.vendor); - + updateComposerDepsFromMagentoToMageOs(instruction, release, composerConfig); updateComposerDepsVersionForMageOs(instruction, release, composerConfig); updateComposerPluginConfigForMageOs(instruction, release, composerConfig); @@ -217,10 +217,10 @@ function updateComposerConfigFromMagentoToMageOs(instruction, release, composerC } /** - * @param {repositoryBuildDefinition} instruction + * @param {repositoryBuildDefinition} instruction * @param {packageDefinition} package * @param {buildState} release - * @param {String} workingCopyPath + * @param {String} workingCopyPath */ async function prepPackageForRelease(instruction, package, release, workingCopyPath) { console.log(`Preparing ${package.label}`); @@ -245,7 +245,7 @@ module.exports = { return getInstalledPackageMap(dir); }, /** - * @param {repositoryBuildDefinition} instruction + * @param {repositoryBuildDefinition} instruction * @param {buildState} release * @returns {void} */ @@ -301,7 +301,7 @@ module.exports = { if (communityEdition) { const package = new packageDefinition({ label: communityEdition.description || communityEdition.name, - dir: '', // metapackages typically at repo root + dir: '', // communityEdition metapackages use the root ./composer.json. Others generally use ./_metapackage/. }); await prepPackageForRelease(instruction, package, release, workingCopyPath); } @@ -310,7 +310,7 @@ module.exports = { }, /** - * @param {repositoryBuildDefinition} instruction + * @param {repositoryBuildDefinition} instruction * @param {buildState} release * @returns {Object.} A map of built packages:versions */ From 12f283b2a8c9cdc5efbf2dc3f3c35ae49eb8617a Mon Sep 17 00:00:00 2001 From: Ryan Hoerr Date: Sun, 14 Dec 2025 15:04:00 -0500 Subject: [PATCH 12/12] fix: ensure only first-party replacements are moved to composer requirements --- src/build-metapackage/magento-community-edition.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/build-metapackage/magento-community-edition.js b/src/build-metapackage/magento-community-edition.js index b297b65..b1ca123 100644 --- a/src/build-metapackage/magento-community-edition.js +++ b/src/build-metapackage/magento-community-edition.js @@ -67,6 +67,12 @@ async function transformMagentoCommunityEditionProduct(composerConfig, instructi delete composerConfig.extra; + // For all entries in composerConfig.replace, pull all first-party replacements (magento/ modules) for requirements. + const replace = composerConfig?.replace ?? {}; + const vendorReplacements = Object.fromEntries( + Object.entries(replace).filter(([pkg]) => pkg.startsWith(`${instruction.vendor}/`) || pkg.startsWith('magento/')) + ); + composerConfig = Object.assign({}, composerConfig, additionalConfig, { name: packageName, description: 'eCommerce Platform for Growth (Community Edition)', @@ -74,9 +80,9 @@ async function transformMagentoCommunityEditionProduct(composerConfig, instructi require: Object.assign( {}, composerConfig.require, - composerConfig.replace, + vendorReplacements, additionalConfig.require, - {[`${instruction.vendor}/magento2-base`]: release.version} + {[`${instruction.vendor}/magento2-base`]: release.version || composerConfig.version} ), });