Skip to content

[pull] release from appsmithorg:release#255

Merged
pull[bot] merged 1 commit into
code:releasefrom
appsmithorg:release
Jun 19, 2026
Merged

[pull] release from appsmithorg:release#255
pull[bot] merged 1 commit into
code:releasefrom
appsmithorg:release

Conversation

@pull

@pull pull Bot commented Jun 19, 2026

Copy link
Copy Markdown

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

## Summary

Running Appsmith **Community Edition (CE)** against a MongoDB that was
previously operated by Appsmith **Enterprise Edition (EE)** is an
unsupported EE→CE downgrade — CE migrations and CE code then run against
EE-shaped data and can corrupt it. Today this happens silently.

This PR adds a startup guard that detects the condition **before any
Mongock migration runs** and **hard-stops CE startup** with a clear,
operator-facing log message.

## How it works

- **Where:** inside `MongoConfig.mongockInitializingBeanRunner`,
immediately before `buildInitializingBeanRunner()` — guaranteed to run
before any migration, and where the existing `checkForbiddenIds` already
throws-to-abort.
- **CE-only, no EE change:** the guard call is gated on
`DeploymentProperties.getEdition() == "CE"`. An EE build already reports
edition `"EE"` (hardcoded, binary-determined — not read from config), so
EE skips the guard automatically and can never self-block against its
own database. The edition value is shared via
`DeploymentPropertiesCE.EDITION_CE`.
- **Signal (verified against a live EE→CE database and the EE repo):**
query the Mongock audit collection `mongockChangeLog`. EE records its
`@ChangeUnit` migrations in the **parent** package
`com.appsmith.server.migrations.db.` with an `EE` token in the class
name (e.g. `Migration003EE01...`, `Migration042EE01AddWorkflowPlugin`),
plus a legacy `com.appsmith.server.migrations.DatabaseChangelogEE`. CE
migrations live in the `com.appsmith.server.migrations.db.ce.`
subpackage, and CE has **zero** classes directly in the parent `db`
package. So the DB was used by EE iff `mongockChangeLog` holds a
`changeLogClass` under `...migrations.db.` that is **not** under
`...migrations.db.ce.`, or the legacy `DatabaseChangelogEE`. This keys
on the package layout (the same split Mongock scans), not an `EE` name
token, so a CE class like `db.ce.EeThing` is not misread as EE. Prefixes
are anchored and `Pattern.quote`-escaped.
- **On detection (fail-closed):** log an ERROR banner — stable token
`APPSMITH-EE-DOWNGRADE-BLOCKED`, with `changeId`/`changeLogClass` passed
as CR/LF-stripped SLF4J parameters — then throw to abort startup.
- **On query/infrastructure error (fail-open):** log a warning and
proceed, in a catch that does **not** wrap the abort, so a
flaky/locked-down Mongo never bricks a healthy CE instance.

> Detection was corrected mid-branch: an earlier revision used a
`...migrations.db.ee.` prefix, which does not exist in EE and so never
fired. Verified against a real EE→CE database (84 EE records matched, 0
CE false positives; old rule matched 0).

## Testing

- `EnterpriseDowngradeGuardCEImplTest` (embedded Mongo) — **8/8**: real
EE class present → abort; legacy `DatabaseChangelogEE` → abort; CE-only
(db.ce + legacy `DatabaseChangelog0/2`) → pass; empty collection → pass;
missing collection → pass; `FAILED`-state EE record → abort; CE-package
near-misses (`db.ce.EeThing`) → pass; mixed CE+EE database → abort.
- `EnterpriseDowngradeGuardCEImplUnitTest` (Mockito) — **2/2**:
fail-open when the query throws.
- `spotless:check` and `test-compile` clean. Verified live: CE startup
against an EE database now aborts.

## Follow-ups (not in this PR)

1. **CE invariant guard (recommended).** Add a CE test/ArchUnit
assertion that CE migrations only ever live in `...migrations.db.ce.`
(never directly in the parent `db` package), since the guard treats any
parent-`db` class as EE.
2. **Docs:** replace the placeholder runbook URL behind the
`APPSMITH-EE-DOWNGRADE-BLOCKED` token (`// TODO(docs)`).
3. **Optional EE-side test:** assert EE
`DeploymentProperties.getEdition() == "EE"` so an accidentally-dropped
override is caught in CI rather than at startup.

> No EE-repo code change is required — the edition gate keeps the whole
feature in CE.

🤖 Generated with [Claude Code](https://claude.com/claude-code)


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

## Release Notes

* **New Features**
* Community Edition startup now performs a pre-check for existing
Enterprise Edition migration history to prevent incompatible downgrades.
* If Enterprise migration evidence is detected, startup is stopped with
a clear error message/banner.

* **Bug Fixes**
* Detection includes both current and legacy Enterprise migration
markers and handles mixed scenarios.
* The check is fail-open when audit data can’t be read, avoiding
unnecessary startup blocks.

* **Tests**
* Added unit and integration tests covering blocking vs non-blocking
outcomes, including empty or missing audit data.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

<!-- This is an auto-generated comment: Cypress test results  -->
> [!TIP]
> 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉
> Workflow run:
<https://github.com/appsmithorg/appsmith/actions/runs/27768419055>
> Commit: 57f2657
> <a
href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=27768419055&attempt=1"
target="_blank">Cypress dashboard</a>.
> Tags: `@tag.All`
> Spec:
> <hr>Thu, 18 Jun 2026 15:59:26 UTC
<!-- end of auto-generated comment: Cypress test results  -->

## Automation
/ok-to-test tags="@tag.All"

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@pull pull Bot locked and limited conversation to collaborators Jun 19, 2026
@pull pull Bot added the ⤵️ pull label Jun 19, 2026
@pull pull Bot merged commit b32721f into code:release Jun 19, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant