From 2339e45305e926a16953b3d294f7a6edccbb5c16 Mon Sep 17 00:00:00 2001 From: Tsvetan Stoychev Date: Wed, 23 Sep 2026 20:07:33 +0300 Subject: [PATCH 1/4] Align Composer package and public Basicrum naming --- .github/workflows/ci.yml | 2 +- CHANGELOG.md | 9 +- README.md | 24 ++++- composer.json | 12 ++- docs/PACKAGE-NAMING-MIGRATION.md | 99 +++++++++++++++++++ etc/acl.xml | 2 +- etc/adminhtml/system.xml | 2 +- tests/integration/README.md | 2 +- tests/integration/admin.spec.js | 5 +- tests/integration/build-artifact.sh | 4 +- tests/integration/docker/install-artifact.sh | 2 +- tests/integration/release-gate.sh | 2 +- tests/integration/test-artifact.php | 2 +- tests/php/run.php | 10 ++ .../templates/system/config/logo.phtml | 2 +- 15 files changed, 160 insertions(+), 19 deletions(-) create mode 100644 docs/PACKAGE-NAMING-MIGRATION.md diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e4695df..8f73174 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,7 +17,7 @@ jobs: uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - name: Validate Composer metadata strictly - run: docker run --rm -v "$GITHUB_WORKSPACE:/app" -w /app composer:2.10 validate --strict --no-check-publish + run: docker run --rm -v "$GITHUB_WORKSPACE:/app" -w /app composer:2.10 validate --strict - name: Check optimized production classmap run: | diff --git a/CHANGELOG.md b/CHANGELOG.md index 758871e..96aff6f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -Notable changes to the Basicrum Analytics module are recorded here. +Notable changes to Basicrum for Magento 2 are recorded here. ## [Unreleased] @@ -28,6 +28,13 @@ Notable changes to the Basicrum Analytics module are recorded here. ### Changed +- **Breaking packaging change:** the Composer name is now + `basicrum/basicrum-magento-2`, with the public title "Basicrum for Magento 2" + and distribution filename `basicrum-magento-2.zip`. The old Composer name + conflicts with the new package; no compatibility replacement is declared. + Magento module/namespace/ACL identifiers and configuration paths are unchanged + by this packaging change. Packagist registration and release publication are + separate, pending maintainer steps; historical tags are not rewritten. - **Breaking:** Magento 2 `p_type` now uses Magento 1's exact 27 named labels for equivalent native pages, including `Checkout Success`, account/address, wishlist, guest-order, and PayPal billing-agreement pages. HTTP 404 takes diff --git a/README.md b/README.md index f68cfde..657f33a 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Basicrum Analytics for Magento 2 +# Basicrum for Magento 2 Basicrum adds Boomerang real user monitoring (RUM) to a Magento 2 storefront. Monitoring is fail-closed: no Basicrum storefront scripts are emitted unless @@ -24,12 +24,21 @@ verification scope, skips, and remaining release requirements. ## Installation -Install a published package with Composer: +The Composer package is being renamed to `basicrum/basicrum-magento-2`. +This source change does not register the new Packagist listing or publish a +release. After the new package's `0.1.0` release is published, install it with: ```sh -composer require basicrum/basicrum-analytics +composer require 'basicrum/basicrum-magento-2:^0.1' ``` +The version constraint deliberately excludes the historical `0.0.x` releases, +which may also appear under the new name when Packagist imports the repository. +Do not drop the constraint to make an unpublished release install. Until +`0.1.0` is available, use a reviewed source checkout for development only. +See the [package migration checklist](https://github.com/basicrum/basicrum-magento-2/blob/main/docs/PACKAGE-NAMING-MIGRATION.md) +for the separate maintainer steps and existing-installation considerations. + For a manual source installation, place this module at the exact path below. The casing is required on case-sensitive filesystems: @@ -53,7 +62,7 @@ static content using the store's normal deployment process as well. ## Configuration -Open **Stores > Configuration > Basicrum Analytics**. Every setting supports +Open **Stores > Configuration > Basicrum > Basicrum for Magento 2**. Every setting supports Magento default, website, and store inheritance. Display-only status, version, and callback instructions have no inheritance controls or stored values. Visitor Consent and Privacy open expanded each time you visit the page. You @@ -155,6 +164,13 @@ Automatic consent-provider adapters are not part of Phase 1. No data migration renames, deletes, or heuristically rewrites stored settings. Review the following before enabling the upgraded module: +- The Composer package name changes from `basicrum/basicrum-analytics` to + `basicrum/basicrum-magento-2`. The two packages must not be installed together; + Composer rejects that combination. Change the project requirement explicitly + when the new release is available; this is not an automatic or + backward-compatible replacement. A manual `app/code` copy must not coexist + with a Composer installation either. No stored configuration is deleted. + - Magento 2 `p_type` labels now match Magento 1, including capitalization and spaces. This intentionally changes existing report groupings; historical beacons are not migrated and no legacy-label mode is provided. Update any diff --git a/composer.json b/composer.json index 2b2ba1c..4dd983c 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,12 @@ { - "name": "basicrum/basicrum-analytics", - "description": "Basicrum real user monitoring for Magento 2", + "name": "basicrum/basicrum-magento-2", + "description": "Basicrum real user monitoring (RUM) for Magento 2", "type": "magento2-module", + "homepage": "https://github.com/basicrum/basicrum-magento-2", + "support": { + "issues": "https://github.com/basicrum/basicrum-magento-2/issues", + "docs": "https://github.com/basicrum/basicrum-magento-2#readme" + }, "authors": [ { "name": "Tsvetan Stoychev", @@ -16,6 +21,9 @@ "magento/module-csp": "^100.4", "magento/module-store": "^101.1" }, + "conflict": { + "basicrum/basicrum-analytics": "*" + }, "archive": { "exclude": [ "/.github", "/.gitignore", "/.gitattributes", "/.test-results", diff --git a/docs/PACKAGE-NAMING-MIGRATION.md b/docs/PACKAGE-NAMING-MIGRATION.md new file mode 100644 index 0000000..9f187dd --- /dev/null +++ b/docs/PACKAGE-NAMING-MIGRATION.md @@ -0,0 +1,99 @@ +# Composer and Packagist naming migration + +## Scope and identity + +This repository prepares the rename; it does not register, abandon, publish or +delete any Packagist package, create a release tag, or approve a module license. + +| Surface | Canonical value | +| --- | --- | +| Composer / Packagist | `basicrum/basicrum-magento-2` | +| Public title and Admin section | Basicrum for Magento 2 | +| Description | Basicrum real user monitoring (RUM) for Magento 2 | +| Distribution ZIP | `basicrum-magento-2.zip` | +| Magento module (unchanged) | `Basicrum_Analytics` | +| PHP namespace (unchanged) | `Basicrum\Analytics` | +| Configuration paths (unchanged) | `basicrum/*` | + +The ACL resource, layout aliases, JavaScript identifiers, Beacon Endpoint and +Brum Site ID names also stay unchanged. Historical tags, the existing MIT +declaration and third-party notices are preserved. + +## Composer decision + +The new package declares `conflict: {"basicrum/basicrum-analytics": "*"}`. +Both packages must not be installed together. There is no `replace`, `provide`, +compatibility metapackage, class alias or automatic upgrade: this is an +intentional package-name break, not a promise to satisfy old dependencies. +Composer cannot detect a duplicate manually installed `app/code` copy. + +Package names come from the default branch during VCS import. Composer can +therefore expose historical tags under the new name without changing those +tags. An unversioned `composer require` could select the old `0.0.2` code before +the new release exists. The README uses `basicrum/basicrum-magento-2:^0.1` +and explicitly makes installation conditional on publication of `0.1.0`. +Do not present `dev-main` or an imported `0.0.x` tag as the new stable release. + +## Maintainer checklist — not executed by this change + +1. Merge the naming change into the repository's default branch, `main`. + A feature branch alone does not establish the new Packagist identity. +2. Before publishing `0.1.0`, obtain the owner's approval for the missing root + LICENSE text and run the release gate against the exact clean commit to be + tagged. CI success is not license approval. Keep the Composer `version` + field absent. Do not move, delete or reuse `0.0.1` or `0.0.2`. +3. Publish the approved new `0.1.0` tag as a separate release action, **before + submitting the new Packagist listing**. Packagist's generated install command + has no version constraint and could otherwise select old `0.0.2` code. +4. As an authorized `basicrum` maintainer, submit the same repository URL to + Packagist under `basicrum/basicrum-magento-2`. Configure/verify its GitHub + update hook and trigger an update if needed. Do not assume updating the old + listing renames it. Verify `0.1.0` is the newest stable version, with the + intended source commit, description, support links and README. + Inspect imported historical versions; their appearance is not evidence that + `0.0.x` contains the new implementation. Verify a clean disposable Magento + Composer install using `^0.1`, including `Basicrum_Analytics` registration. +5. Once the new stable package is available and verified, mark + `basicrum/basicrum-analytics` abandoned in the **old listing's Packagist UI**, + with `basicrum/basicrum-magento-2` as the suggested alternative. Do not add an + `abandoned` field to the renamed package's `composer.json`. Keep the old + listing and historical versions; do not delete them or expect download + statistics to transfer. Abandonment is a notice, not a lock-file migration. + +## Existing development installations + +After the new release is available, review the project's dependency graph and +change the old requirement explicitly. For a project that directly requires +the old package, the intended Composer transaction is: + +```sh +composer remove basicrum/basicrum-analytics --no-update +composer require 'basicrum/basicrum-magento-2:^0.1' +``` + +Back up and review the resulting `composer.json` / `composer.lock` diff. If a +different package still requires the old name, stop and update that dependency +deliberately; do not bypass the conflict. This transaction only changes Composer +packages. It does not migrate the historical module-name capitalization, +Magento's enabled-module configuration, or third-party customizations. Review +the README's upgrade notes and Magento deployment steps. Remove any duplicate +manual installation through the project's normal deployment process, preserve +stored settings, and rebuild compiled DI/static assets and caches as documented. + +## Review and sources + +CLI consultations used `grok-4.7` at high reasoning effort (reported +`grok-4.7-build`) and `claude-opus-5-5` at maximum effort. Both recommended an explicit conflict +without `replace` / `provide`. Opus also identified the old-tag install trap +and recommended publishing the new stable tag before submitting the listing. +An initial Grok claim that old tags stay confined to the old name was corrected +against Composer source. A fixed `support.source` URL is deliberately omitted: +Composer's GitHub driver supplies a version-specific source link instead. +Tests guard package identity and dependency semantics; the native Admin test +checks the exact rendered section name and logo caption rather than adding a +repository-wide branding scan. + +- [Packagist maintainer rename procedure](https://github.com/composer/packagist/issues/47) +- [Composer conflict semantics](https://getcomposer.org/doc/04-schema.md#conflict) +- [Composer VCS name normalization, including historical tags](https://github.com/composer/composer/blob/2.10.3/src/Composer/Repository/VcsRepository.php#L432-L438) +- [Packagist publication and update hooks](https://packagist.org/about) diff --git a/etc/acl.xml b/etc/acl.xml index a520e94..64054f2 100644 --- a/etc/acl.xml +++ b/etc/acl.xml @@ -7,7 +7,7 @@ - + diff --git a/etc/adminhtml/system.xml b/etc/adminhtml/system.xml index ccdf185..e28d4fd 100644 --- a/etc/adminhtml/system.xml +++ b/etc/adminhtml/system.xml @@ -7,7 +7,7 @@
- + basicrum Basicrum_Analytics::basicrum_analytics { await page.goto(configurationUrl, { waitUntil: "domcontentloaded" }); const basicrumSection = page - .locator("#system_config_tabs a") - .filter({ hasText: "Basicrum Analytics" }); + .locator("#system_config_tabs") + .getByRole("link", { name: "Basicrum for Magento 2", exact: true }); const basicrumUrl = await basicrumSection.getAttribute("href"); expect(basicrumUrl).toBeTruthy(); const response = await page.goto(basicrumUrl, { waitUntil: "networkidle" }); @@ -52,6 +52,7 @@ test("Basicrum configuration renders in Magento Admin", async ({ page }) => { return logo.isVisible(); }) .toBe(true); + await expect(logo.locator("span")).toHaveText("Basicrum for Magento 2"); await expect(page.getByText("Monitoring Status", { exact: true })).toBeVisible(); await expect(page.getByText("Beacon Endpoint", { exact: true })).toBeVisible(); await expect(page.getByText("Brum Site ID", { exact: true })).toBeVisible(); diff --git a/tests/integration/build-artifact.sh b/tests/integration/build-artifact.sh index ab5acf5..c3a6536 100644 --- a/tests/integration/build-artifact.sh +++ b/tests/integration/build-artifact.sh @@ -4,5 +4,5 @@ module_root=$(CDPATH= cd -- "$(dirname -- "$0")/../.." && pwd) cd "$module_root" mkdir -p .test-results/package candidate_commit=$(sh tests/integration/check-candidate.sh) -git archive --format=zip --output=.test-results/package/basicrum-analytics.zip "$candidate_commit" -php tests/integration/check-artifact.php .test-results/package/basicrum-analytics.zip +git archive --format=zip --output=.test-results/package/basicrum-magento-2.zip "$candidate_commit" +php tests/integration/check-artifact.php .test-results/package/basicrum-magento-2.zip diff --git a/tests/integration/docker/install-artifact.sh b/tests/integration/docker/install-artifact.sh index ac134e4..d97b3a9 100644 --- a/tests/integration/docker/install-artifact.sh +++ b/tests/integration/docker/install-artifact.sh @@ -3,7 +3,7 @@ set -eu test "${BASICRUM_DISPOSABLE_MAGENTO:-}" = 1 test "${MAGENTO_ROOT:-}" = /var/www/html module_root=$(CDPATH= cd -- "$(dirname -- "$0")/../../.." && pwd) -artifact="$module_root/.test-results/package/basicrum-analytics.zip" +artifact="$module_root/.test-results/package/basicrum-magento-2.zip" php "$module_root/tests/integration/check-artifact.php" "$artifact" cd "$MAGENTO_ROOT" # Exact destination inside this disposable stack. Do not delete stale files: diff --git a/tests/integration/release-gate.sh b/tests/integration/release-gate.sh index e91403e..02fd930 100755 --- a/tests/integration/release-gate.sh +++ b/tests/integration/release-gate.sh @@ -37,7 +37,7 @@ module_root=$(CDPATH= cd -- "$(dirname -- "$0")/../.." && pwd) magento="${MAGENTO_ROOT}/bin/magento" candidate_commit=$(sh "$module_root/tests/integration/check-candidate.sh") echo "Checking Basicrum candidate ${candidate_commit} for ${BASICRUM_RELEASE_TAG}." -artifact=${BASICRUM_ARTIFACT:-$module_root/.test-results/package/basicrum-analytics.zip} +artifact=${BASICRUM_ARTIFACT:-$module_root/.test-results/package/basicrum-magento-2.zip} php "$module_root/tests/integration/check-artifact.php" "$artifact" php "$module_root/tests/integration/check-installed-candidate.php" diff --git a/tests/integration/test-artifact.php b/tests/integration/test-artifact.php index 0f363f6..999d8be 100644 --- a/tests/integration/test-artifact.php +++ b/tests/integration/test-artifact.php @@ -2,7 +2,7 @@ declare(strict_types=1); // Run after build-artifact.sh; mutate temporary copies, never the candidate ZIP. -$artifact = $argv[1] ?? dirname(__DIR__, 2) . '/.test-results/package/basicrum-analytics.zip'; +$artifact = $argv[1] ?? dirname(__DIR__, 2) . '/.test-results/package/basicrum-magento-2.zip'; if (!is_file($artifact)) { throw new RuntimeException('Build the candidate ZIP before running archive regression checks.'); } diff --git a/tests/php/run.php b/tests/php/run.php index 6ce9d09..ac81562 100644 --- a/tests/php/run.php +++ b/tests/php/run.php @@ -223,6 +223,16 @@ 512, JSON_THROW_ON_ERROR ); + basicrum_assert_same('basicrum/basicrum-magento-2', $composer['name'], 'canonical Composer package name'); + basicrum_assert_same('magento2-module', $composer['type'], 'Magento package type'); + basicrum_assert_same( + ['basicrum/basicrum-analytics' => '*'], + $composer['conflict'] ?? [], + 'old and new Composer packages cannot be installed together' + ); + foreach (['replace', 'provide'] as $alias) { + basicrum_assert_false(isset($composer[$alias]), 'no backward-compatible Composer alias: ' . $alias); + } basicrum_assert_same('^102.0', $composer['require']['magento/module-backend'], 'Backend dependency'); basicrum_assert_same('^101.2', $composer['require']['magento/module-config'], 'Config dependency'); basicrum_assert_same('^100.4', $composer['require']['magento/module-csp'], 'CSP dependency'); diff --git a/view/adminhtml/templates/system/config/logo.phtml b/view/adminhtml/templates/system/config/logo.phtml index 88ec2d5..3c14fc0 100644 --- a/view/adminhtml/templates/system/config/logo.phtml +++ b/view/adminhtml/templates/system/config/logo.phtml @@ -10,5 +10,5 @@ width="48" height="48" alt="escapeHtmlAttr(__('Basicrum logo')) ?>" /> - escapeHtml(__('Basicrum Analytics')) ?> + escapeHtml(__('Basicrum for Magento 2')) ?> From 22df8905e7c519a6f8b9ff14abd1d42585e0fc3f Mon Sep 17 00:00:00 2001 From: Tsvetan Stoychev Date: Wed, 23 Sep 2026 20:13:32 +0300 Subject: [PATCH 2/4] Retain Basicrum Analytics as the public title --- CHANGELOG.md | 4 ++-- README.md | 4 ++-- docs/PACKAGE-NAMING-MIGRATION.md | 2 +- etc/acl.xml | 2 +- etc/adminhtml/system.xml | 2 +- tests/integration/admin.spec.js | 4 ++-- view/adminhtml/templates/system/config/logo.phtml | 2 +- 7 files changed, 10 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 96aff6f..60889d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -Notable changes to Basicrum for Magento 2 are recorded here. +Notable changes to Basicrum Analytics are recorded here. ## [Unreleased] @@ -29,7 +29,7 @@ Notable changes to Basicrum for Magento 2 are recorded here. ### Changed - **Breaking packaging change:** the Composer name is now - `basicrum/basicrum-magento-2`, with the public title "Basicrum for Magento 2" + `basicrum/basicrum-magento-2`, retaining the public title "Basicrum Analytics" and distribution filename `basicrum-magento-2.zip`. The old Composer name conflicts with the new package; no compatibility replacement is declared. Magento module/namespace/ACL identifiers and configuration paths are unchanged diff --git a/README.md b/README.md index 657f33a..15dc79d 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Basicrum for Magento 2 +# Basicrum Analytics Basicrum adds Boomerang real user monitoring (RUM) to a Magento 2 storefront. Monitoring is fail-closed: no Basicrum storefront scripts are emitted unless @@ -62,7 +62,7 @@ static content using the store's normal deployment process as well. ## Configuration -Open **Stores > Configuration > Basicrum > Basicrum for Magento 2**. Every setting supports +Open **Stores > Configuration > Basicrum > Basicrum Analytics**. Every setting supports Magento default, website, and store inheritance. Display-only status, version, and callback instructions have no inheritance controls or stored values. Visitor Consent and Privacy open expanded each time you visit the page. You diff --git a/docs/PACKAGE-NAMING-MIGRATION.md b/docs/PACKAGE-NAMING-MIGRATION.md index 9f187dd..8d19d16 100644 --- a/docs/PACKAGE-NAMING-MIGRATION.md +++ b/docs/PACKAGE-NAMING-MIGRATION.md @@ -8,7 +8,7 @@ delete any Packagist package, create a release tag, or approve a module license. | Surface | Canonical value | | --- | --- | | Composer / Packagist | `basicrum/basicrum-magento-2` | -| Public title and Admin section | Basicrum for Magento 2 | +| Public title and Admin section | Basicrum Analytics | | Description | Basicrum real user monitoring (RUM) for Magento 2 | | Distribution ZIP | `basicrum-magento-2.zip` | | Magento module (unchanged) | `Basicrum_Analytics` | diff --git a/etc/acl.xml b/etc/acl.xml index 64054f2..a520e94 100644 --- a/etc/acl.xml +++ b/etc/acl.xml @@ -7,7 +7,7 @@ - + diff --git a/etc/adminhtml/system.xml b/etc/adminhtml/system.xml index e28d4fd..ccdf185 100644 --- a/etc/adminhtml/system.xml +++ b/etc/adminhtml/system.xml @@ -7,7 +7,7 @@
- + basicrum Basicrum_Analytics::basicrum_analytics { const basicrumSection = page .locator("#system_config_tabs") - .getByRole("link", { name: "Basicrum for Magento 2", exact: true }); + .getByRole("link", { name: "Basicrum Analytics", exact: true }); const basicrumUrl = await basicrumSection.getAttribute("href"); expect(basicrumUrl).toBeTruthy(); const response = await page.goto(basicrumUrl, { waitUntil: "networkidle" }); @@ -52,7 +52,7 @@ test("Basicrum configuration renders in Magento Admin", async ({ page }) => { return logo.isVisible(); }) .toBe(true); - await expect(logo.locator("span")).toHaveText("Basicrum for Magento 2"); + await expect(logo.locator("span")).toHaveText("Basicrum Analytics"); await expect(page.getByText("Monitoring Status", { exact: true })).toBeVisible(); await expect(page.getByText("Beacon Endpoint", { exact: true })).toBeVisible(); await expect(page.getByText("Brum Site ID", { exact: true })).toBeVisible(); diff --git a/view/adminhtml/templates/system/config/logo.phtml b/view/adminhtml/templates/system/config/logo.phtml index 3c14fc0..88ec2d5 100644 --- a/view/adminhtml/templates/system/config/logo.phtml +++ b/view/adminhtml/templates/system/config/logo.phtml @@ -10,5 +10,5 @@ width="48" height="48" alt="escapeHtmlAttr(__('Basicrum logo')) ?>" /> - escapeHtml(__('Basicrum for Magento 2')) ?> + escapeHtml(__('Basicrum Analytics')) ?> From dfc500197242ac46b11aa3b0bcb2f33347f63552 Mon Sep 17 00:00:00 2001 From: Tsvetan Stoychev Date: Wed, 23 Sep 2026 20:56:19 +0300 Subject: [PATCH 3/4] Fix Packagist rename imports and native Admin navigation --- .github/workflows/ci.yml | 3 + CHANGELOG.md | 10 +++- README.md | 21 +++++-- composer.json | 3 - docs/PACKAGE-NAMING-MIGRATION.md | 34 ++++++++--- tests/integration/admin.spec.js | 25 ++++++-- tests/php/check-composer-import.php | 93 +++++++++++++++++++++++++++++ tests/php/run.php | 5 -- 8 files changed, 166 insertions(+), 28 deletions(-) create mode 100644 tests/php/check-composer-import.php diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8f73174..9a8044a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,6 +19,9 @@ jobs: - name: Validate Composer metadata strictly run: docker run --rm -v "$GITHUB_WORKSPACE:/app" -w /app composer:2.10 validate --strict + - name: Validate VCS imports before and after the package rename + run: docker run --rm --network none -v "$GITHUB_WORKSPACE:/app:ro" -w /app composer:2.10 php tests/php/check-composer-import.php /usr/bin/composer + - name: Check optimized production classmap run: | docker run --rm -v "$GITHUB_WORKSPACE:/app" -w /app composer:2.10 dump-autoload --optimize --strict-psr --no-dev --no-scripts --no-plugins --no-interaction diff --git a/CHANGELOG.md b/CHANGELOG.md index 60889d7..c1345f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,8 +30,10 @@ Notable changes to Basicrum Analytics are recorded here. - **Breaking packaging change:** the Composer name is now `basicrum/basicrum-magento-2`, retaining the public title "Basicrum Analytics" - and distribution filename `basicrum-magento-2.zip`. The old Composer name - conflicts with the new package; no compatibility replacement is declared. + and distribution filename `basicrum-magento-2.zip`. No compatibility + replacement is declared. The old-name conflict is omitted during the rename + because VCS imports under the old default-branch name reject it as a self-conflict. + Remove the old package explicitly; Composer does not prevent co-installation. Magento module/namespace/ACL identifiers and configuration paths are unchanged by this packaging change. Packagist registration and release publication are separate, pending maintainer steps; historical tags are not rewritten. @@ -72,6 +74,10 @@ Notable changes to Basicrum Analytics are recorded here. ### Fixed +- The Admin integration test opens Magento's native Basicrum navigation group + before selecting the exact settings link, which is hidden when collapsed. +- Validate rename branches through Composer's validating VCS importer in CI, + including the pre-merge old-name default branch that root validation misses. - Fresh disposable Magento provisioning no longer writes the Admin Usage setting after disabling its owning module. Configuration failures still stop the job. - Release ZIPs and expected hashes now come from committed files; ignored local diff --git a/README.md b/README.md index 15dc79d..c7f0fe7 100644 --- a/README.md +++ b/README.md @@ -166,9 +166,10 @@ Review the following before enabling the upgraded module: - The Composer package name changes from `basicrum/basicrum-analytics` to `basicrum/basicrum-magento-2`. The two packages must not be installed together; - Composer rejects that combination. Change the project requirement explicitly - when the new release is available; this is not an automatic or - backward-compatible replacement. A manual `app/code` copy must not coexist + Composer does not prevent that combination during the naming transition. + Remove the old requirement and check the resolved lock file for old-name + transitive dependencies when the new release is available; this is not an + automatic or backward-compatible replacement. A manual `app/code` copy must not coexist with a Composer installation either. No stored configuration is deleted. - Magento 2 `p_type` labels now match Magento 1, including capitalization and @@ -256,8 +257,18 @@ blocked unnonced inline negative control. The fixture is never packaged with the extension. This is separate from the report-only homepage FPC checks; it does not certify nonce handling on cacheable pages or custom strict-dynamic policies. See the integration README for fixture installation and scope. -The regular CI workflow runs strict Composer 2.10 validation and optimized -production classmap checks plus the fast PHP and Chromium checks. The Chromium +The regular CI workflow runs strict Composer 2.10 validation, a validating VCS +import regression before and after the default-branch rename, and optimized +production classmap checks plus the fast PHP and Chromium checks. The VCS test +uses the real Composer importer on a temporary local Git repository containing +the candidate metadata and a synthetic historical tag; it needs no network or +Packagist account. Run it with: + +```sh +docker run --rm --network none -v "$PWD:/app:ro" -w /app composer:2.10 php tests/php/check-composer-import.php /usr/bin/composer +``` + +This is not a live Packagist update or a Magento Composer installation. The Chromium job uploads an HTML report with traces from failed test attempts, retained for seven days. A flaky pass still fails the job; retries do not hide failures. Additional CI checks run Magento-aware PHPStan level 8 and Magento coding diff --git a/composer.json b/composer.json index 4dd983c..9af7f45 100644 --- a/composer.json +++ b/composer.json @@ -21,9 +21,6 @@ "magento/module-csp": "^100.4", "magento/module-store": "^101.1" }, - "conflict": { - "basicrum/basicrum-analytics": "*" - }, "archive": { "exclude": [ "/.github", "/.gitignore", "/.gitattributes", "/.test-results", diff --git a/docs/PACKAGE-NAMING-MIGRATION.md b/docs/PACKAGE-NAMING-MIGRATION.md index 8d19d16..2359e7f 100644 --- a/docs/PACKAGE-NAMING-MIGRATION.md +++ b/docs/PACKAGE-NAMING-MIGRATION.md @@ -21,8 +21,21 @@ declaration and third-party notices are preserved. ## Composer decision -The new package declares `conflict: {"basicrum/basicrum-analytics": "*"}`. -Both packages must not be installed together. There is no `replace`, `provide`, +The rename does not declare a conflict with `basicrum/basicrum-analytics`. +While `main` still uses that old name, Composer's VCS importer assigns it to +the rename branch too. An old-name conflict then becomes a self-conflict and +Packagist rejects the branch, even though standalone `composer validate` passes. +The initial PR declared that conflict; the Packagist update failure exposed this +import-stage gap. CI now exercises Composer's validating VCS importer with both +old-name and new-name default branches, the real candidate metadata, and a +synthetic historical tag in a disposable local Git repository. + +Both packages must not be installed together, but **Composer does not enforce +that restriction during this transition**. Remove the old requirement explicitly +and inspect the resolved lock file for transitive old-name dependencies. +Any later conflict declaration requires a separately verified migration step, +including successful imports for the affected Packagist listings; it is not +automatically safe merely because this PR was merged. There is no `replace`, `provide`, compatibility metapackage, class alias or automatic upgrade: this is an intentional package-name break, not a promise to satisfy old dependencies. Composer cannot detect a duplicate manually installed `app/code` copy. @@ -38,6 +51,10 @@ Do not present `dev-main` or an imported `0.0.x` tag as the new stable release. 1. Merge the naming change into the repository's default branch, `main`. A feature branch alone does not establish the new Packagist identity. + After the corrected branch is pushed, verify that the old listing's next + update no longer rejects it for a self-conflict. If the hook has not retried, + an authorized maintainer can trigger an update. Repeat the import check after + merging; a local test does not certify the hosted updater's state. 2. Before publishing `0.1.0`, obtain the owner's approval for the missing root LICENSE text and run the release gate against the exact clean commit to be tagged. CI success is not license approval. Keep the Composer `version` @@ -73,7 +90,8 @@ composer require 'basicrum/basicrum-magento-2:^0.1' Back up and review the resulting `composer.json` / `composer.lock` diff. If a different package still requires the old name, stop and update that dependency -deliberately; do not bypass the conflict. This transaction only changes Composer +deliberately. Do not deploy a lock file containing both names; there is no +solver-level conflict guard in this rename. This transaction only changes Composer packages. It does not migrate the historical module-name capitalization, Magento's enabled-module configuration, or third-party customizations. Review the README's upgrade notes and Magento deployment steps. Remove any duplicate @@ -83,15 +101,17 @@ stored settings, and rebuild compiled DI/static assets and caches as documented. ## Review and sources CLI consultations used `grok-4.7` at high reasoning effort (reported -`grok-4.7-build`) and `claude-opus-5-5` at maximum effort. Both recommended an explicit conflict -without `replace` / `provide`. Opus also identified the old-tag install trap +`grok-4.7-build`) and `claude-opus-5-5` at maximum effort. Both initially recommended an explicit +conflict without `replace` / `provide`. We removed that conflict +after the Packagist failure and a local reproduction using Composer's validating +VCS importer; the no-alias decision remains. Opus also identified the old-tag install trap and recommended publishing the new stable tag before submitting the listing. An initial Grok claim that old tags stay confined to the old name was corrected against Composer source. A fixed `support.source` URL is deliberately omitted: Composer's GitHub driver supplies a version-specific source link instead. Tests guard package identity and dependency semantics; the native Admin test -checks the exact rendered section name and logo caption rather than adding a -repository-wide branding scan. +opens Magento's native collapsible navigation before checking the exact rendered +section name and logo caption rather than adding a repository-wide branding scan. - [Packagist maintainer rename procedure](https://github.com/composer/packagist/issues/47) - [Composer conflict semantics](https://getcomposer.org/doc/04-schema.md#conflict) diff --git a/tests/integration/admin.spec.js b/tests/integration/admin.spec.js index a494028..58d65d7 100644 --- a/tests/integration/admin.spec.js +++ b/tests/integration/admin.spec.js @@ -34,12 +34,25 @@ test("Basicrum configuration renders in Magento Admin", async ({ page }) => { expect(configurationUrl).toBeTruthy(); await page.goto(configurationUrl, { waitUntil: "domcontentloaded" }); - const basicrumSection = page - .locator("#system_config_tabs") - .getByRole("link", { name: "Basicrum Analytics", exact: true }); - const basicrumUrl = await basicrumSection.getAttribute("href"); - expect(basicrumUrl).toBeTruthy(); - const response = await page.goto(basicrumUrl, { waitUntil: "networkidle" }); + const configTabs = page.locator("#system_config_tabs"); + // Magento initializes this group as a collapsible. Hidden links are not + // accessible by role until the group is opened through its native control. + // The tab's accessible name also contains Magento's expand/collapse icon. + const basicrumTab = configTabs.getByRole("tab").filter({ + has: page.getByText("Basicrum", { exact: true }) + }); + await expect(basicrumTab).toBeVisible(); + if ((await basicrumTab.getAttribute("aria-expanded")) !== "true") { + await basicrumTab.click(); + } + await expect(basicrumTab).toHaveAttribute("aria-expanded", "true"); + const basicrumSection = configTabs.getByRole("link", { name: "Basicrum Analytics", exact: true }); + await expect(basicrumSection).toBeVisible(); + const [response] = await Promise.all([ + page.waitForNavigation({ waitUntil: "networkidle" }), + basicrumSection.click() + ]); + expect(response).toBeTruthy(); expectAdminCsp(response.headers()); const generalSettings = page.locator('a[href="#basicrum_general-link"]'); diff --git a/tests/php/check-composer-import.php b/tests/php/check-composer-import.php new file mode 100644 index 0000000..4ec03fb --- /dev/null +++ b/tests/php/check-composer-import.php @@ -0,0 +1,93 @@ +execute($command, $output) !== 0) { + throw new RuntimeException('Fixture Git command failed: ' . $process->getErrorOutput()); + } +}; +$writeManifest = static function (array $data) use ($fixture): void { + file_put_contents($fixture . '/composer.json', json_encode($data, JSON_THROW_ON_ERROR)); +}; +$checkImport = static function (string $expectedName) use ($fixture, $process): void { + $io = new BufferIO(); + $config = new Config(false); + $config->merge(['config' => ['home' => $fixture, 'cache-dir' => $fixture . '/cache']]); + $repository = new VcsRepository( + ['type' => 'git', 'url' => $fixture], + $io, + $config, + new HttpDownloader($io, $config), + null, + $process + ); + $repository->setLoader(new ValidatingArrayLoader(new ArrayLoader())); + $packages = $repository->getPackages(); + if ($repository->hadInvalidBranches()) { + throw new RuntimeException('Invalid VCS branch under ' . $expectedName . ":\n" . $io->getOutput()); + } + foreach ($packages as $package) { + if ($package->getName() !== $expectedName) { + throw new RuntimeException('VCS import did not use the default branch package name.'); + } + } + foreach (['dev-main', 'dev-rename', '0.0.2'] as $version) { + if ($repository->findPackage($expectedName, $version) === null) { + throw new RuntimeException('VCS import omitted ' . $expectedName . ' ' . $version); + } + } + echo 'PASS: validated default branch, rename branch and historical tag under ' . $expectedName . ".\n"; +}; + +try { + $git(['init', '--initial-branch=main', '--template=']); + $git(['config', 'user.name', 'Basicrum test']); + $git(['config', 'user.email', 'test@example.test']); + $git(['config', 'commit.gpgsign', 'false']); + // A tiny synthetic historical release; the rename branch uses real metadata. + $writeManifest(['name' => $oldName, 'description' => 'VCS import fixture', 'license' => 'MIT']); + $git(['add', 'composer.json']); + $git(['commit', '-m', 'Historical package']); + $git(['tag', '0.0.2']); + $git(['checkout', '-b', 'rename']); + $writeManifest($candidate); + $git(['commit', '-am', 'Candidate package metadata']); + $git(['checkout', 'main']); + $checkImport($oldName); + + // Model the same repository after the naming change reaches its default branch. + $writeManifest($candidate); + $git(['commit', '-am', 'Rename on default branch']); + $checkImport($newName); +} finally { + // This random directory was created above and contains only this test's fixture. + (new Filesystem())->removeDirectory($fixture); +} diff --git a/tests/php/run.php b/tests/php/run.php index ac81562..dc0aa39 100644 --- a/tests/php/run.php +++ b/tests/php/run.php @@ -225,11 +225,6 @@ ); basicrum_assert_same('basicrum/basicrum-magento-2', $composer['name'], 'canonical Composer package name'); basicrum_assert_same('magento2-module', $composer['type'], 'Magento package type'); - basicrum_assert_same( - ['basicrum/basicrum-analytics' => '*'], - $composer['conflict'] ?? [], - 'old and new Composer packages cannot be installed together' - ); foreach (['replace', 'provide'] as $alias) { basicrum_assert_false(isset($composer[$alias]), 'no backward-compatible Composer alias: ' . $alias); } From b369c72bda669fdedd4e311669396280d7857098 Mon Sep 17 00:00:00 2001 From: Tsvetan Stoychev Date: Wed, 23 Sep 2026 20:58:34 +0300 Subject: [PATCH 4/4] Rebuild search index for repeatable native verification --- CHANGELOG.md | 2 ++ tests/integration/README.md | 3 +++ tests/integration/release-gate.sh | 3 +++ 3 files changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c1345f4..b78575c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -78,6 +78,8 @@ Notable changes to Basicrum Analytics are recorded here. before selecting the exact settings link, which is hidden when collapsed. - Validate rename branches through Composer's validating VCS importer in CI, including the pre-merge old-name default branch that root validation misses. +- Rebuild the disposable Magento catalog search index before native browser + checks, including when retained application/database volumes outlive OpenSearch data. - Fresh disposable Magento provisioning no longer writes the Admin Usage setting after disabling its owning module. Configuration failures still stop the job. - Release ZIPs and expected hashes now come from committed files; ignored local diff --git a/tests/integration/README.md b/tests/integration/README.md index b42d8a9..42f7887 100644 --- a/tests/integration/README.md +++ b/tests/integration/README.md @@ -32,6 +32,9 @@ For subsequent runs after `down`, first recreate the containers with `docker compose -f tests/integration/docker/compose.yaml up -d`. Application/database volumes are retained; do not reprovision them. Git's `safe.directory` is baked into the PHP image and survives container recreation. +OpenSearch data is not persisted by this test stack. The release gate rebuilds +`catalogsearch_fulltext` through Magento's standard indexer before browser checks, +so a reused installation does not depend on an old search index or background cron. After harness Dockerfile changes, run `docker compose -f tests/integration/docker/compose.yaml build php` before `up -d`. First-time `start.sh` installs npm dependencies using the caller's UID/GID so the bind-mounted checkout does not acquire root-owned `node_modules`. diff --git a/tests/integration/release-gate.sh b/tests/integration/release-gate.sh index 02fd930..9a5a20f 100755 --- a/tests/integration/release-gate.sh +++ b/tests/integration/release-gate.sh @@ -47,6 +47,9 @@ sh "$module_root/tests/integration/install-csp-fixture.sh" "$magento" setup:upgrade "$magento" setup:di:compile "$magento" setup:static-content:deploy -f en_US +# Reused disposable stacks may retain the database but lose OpenSearch data. +# No cron runs here, and setup:upgrade can invalidate scheduled indexers. +"$magento" indexer:reindex catalogsearch_fulltext php "$module_root/tests/integration/config-save.php" cd "$module_root"