Skip to content

Improved E2E MySQL setup performance#28525

Open
9larsons wants to merge 1 commit into
mainfrom
codex/e2e-combine-mysql-setup
Open

Improved E2E MySQL setup performance#28525
9larsons wants to merge 1 commit into
mainfrom
codex/e2e-combine-mysql-setup

Conversation

@9larsons

Copy link
Copy Markdown
Contributor

Summary

  • combined the browser E2E MySQL test database create/restore/configure path into one Docker exec
  • kept the existing public MySQL helper methods intact for other callers
  • added SQL identifier/string and shell argument escaping for the new combined command

Why

Every isolated browser E2E environment creates a database, restores the snapshot, updates site_uuid, and sometimes writes Stripe settings. Those operations previously used multiple Docker exec calls per environment. Combining the hot setup path preserves the same database isolation model while reducing repeated Docker exec overhead.

Testing

  • pnpm --filter @tryghost/e2e test:types
  • pre-commit staged ESLint hook for e2e/helpers/environment/service-managers/mysql-manager.ts
  • git diff --check
  • Functional smoke with disposable MySQL 8 tmpfs container:
    • created a source DB with a settings table
    • created the default /tmp/dump.sql snapshot through MySQLManager.createSnapshot()
    • ran MySQLManager.setupTestDatabase() with Stripe settings enabled
    • verified restored settings rows:
      • site_uuid = new-site-uuid
      • stripe_publishable_key = pk_test_e2e
      • stripe_secret_key = sk_test_e2e
  • Synthetic setup loop through the actual method on the same container:
    • 80ms, 45ms, 38ms, 38ms, 37ms for five create/restore/configure/drop cycles on the small dump

Notes

The benchmark loop uses a tiny synthetic dump, so it is a correctness and overhead smoke rather than a full Ghost E2E runtime estimate. Earlier investigation on a Ghost-sized dump showed combining Docker execs saved roughly 0.17s per environment cycle locally.

no ref

Browser E2E setup clones and configures a MySQL database for every isolated environment. Combining the create, restore, and setting update work into one container exec keeps the same isolation semantics while reducing repeated Docker exec overhead.
@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

This PR refactors the test database setup in mysql-manager.ts to consolidate initialization steps. Previously, setupTestDatabase called createDatabase, restoreDatabaseFromSnapshot, updateSiteUuid, and updateStripeSettings sequentially. The refactoring introduces a new setupDatabaseFromSnapshot helper that chains these operations into a single shell command: create database, restore from snapshot, and update settings via generated SQL. Supporting helpers provide SQL identifier and string literal escaping, shell argument quoting, and settings SQL generation using INSERT ... ON DUPLICATE KEY UPDATE for atomic Stripe settings updates.

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: combining MySQL setup operations to improve E2E test performance through reduced Docker exec overhead.
Description check ✅ Passed The description is well-related to the changeset, clearly explaining the motivation (reducing Docker exec overhead), implementation approach (combining operations), and testing performed.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/e2e-combine-mysql-setup

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@nx-cloud

nx-cloud Bot commented Jun 11, 2026

Copy link
Copy Markdown

🤖 Nx Cloud AI Fix

Ensure the fix-ci command is configured to always run in your CI pipeline to get automatic fixes in future runs. For more information, please see https://nx.dev/ci/features/self-healing-ci


View your CI Pipeline Execution ↗ for commit 6b7bffb

Command Status Duration Result
nx run @tryghost/admin:build ✅ Succeeded 5s View ↗
nx run-many -t lint -p @tryghost/e2e ✅ Succeeded 4s View ↗
nx run ghost:build:assets ✅ Succeeded 2s View ↗
nx run ghost:build:tsc ✅ Succeeded 5s View ↗
nx run-many --target=build --projects=@tryghost... ✅ Succeeded <1s View ↗

💡 Verify your cache is correct by running tasks in a sandbox. Read docs ↗


☁️ Nx Cloud last updated this comment at 2026-06-11 22:17:45 UTC

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
e2e/helpers/environment/service-managers/mysql-manager.ts (1)

245-249: 💤 Low value

Consider documenting the limited escaping scope.

The escapeSqlString function handles \ and ', which is sufficient for the controlled inputs (UUIDs and Stripe test keys). For clarity, consider adding a brief doc comment noting this is intentionally minimal for known-safe inputs:

+    /**
+     * Escapes a string for use in a SQL single-quoted literal.
+     * Sufficient for controlled inputs like UUIDs and Stripe test keys.
+     */
     private escapeSqlString(value: string): string {

This helps future maintainers understand the escaping is scoped to expected inputs rather than being a general-purpose SQL escape function.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@e2e/helpers/environment/service-managers/mysql-manager.ts` around lines 245 -
249, Add a short JSDoc above the private method escapeSqlString explaining that
it only escapes backslashes and single quotes (via .replace(/\\/g, '\\\\') and
.replace(/'/g, '\\\'')) and that this minimal escaping is intentional because
inputs are constrained (UUIDs and Stripe test keys); explicitly note it is NOT a
general-purpose SQL-escaping function and should not be used for untrusted or
arbitrary input.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@e2e/helpers/environment/service-managers/mysql-manager.ts`:
- Around line 245-249: Add a short JSDoc above the private method
escapeSqlString explaining that it only escapes backslashes and single quotes
(via .replace(/\\/g, '\\\\') and .replace(/'/g, '\\\'')) and that this minimal
escaping is intentional because inputs are constrained (UUIDs and Stripe test
keys); explicitly note it is NOT a general-purpose SQL-escaping function and
should not be used for untrusted or arbitrary input.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 2f485af9-4ef1-48bf-a9d6-5b484856c0b8

📥 Commits

Reviewing files that changed from the base of the PR and between 735320d and 6b7bffb.

📒 Files selected for processing (1)
  • e2e/helpers/environment/service-managers/mysql-manager.ts

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant