feat: add e2e tests to backup/restore databases.#292
Conversation
This reverts commit b28bb44.
📝 WalkthroughWalkthroughThis PR establishes end-to-end testing infrastructure for validating backup and restore functionality across multiple database engines and versions. It introduces Docker Compose services for PostgreSQL, MySQL, MariaDB, MongoDB, Redis, Valkey, MSSQL, and SQLite, an E2E environment configuration file with test-specific settings for authentication and notifications, Playwright helpers to automate backup/restore workflows in the dashboard UI, and a make target that orchestrates the multi-database stack with Playwright tests. ChangesE2E Multi-Database Testing Infrastructure
Sequence Diagram(s)sequenceDiagram
participant Orchestrator as e2e-backup<br/>make target
participant DockerStacks as Docker<br/>Stacks
participant Playwright as Playwright<br/>Test
participant Dashboard as Dashboard UI
participant Database as Database<br/>Service
Orchestrator->>DockerStacks: compose up (e2e + database)
Orchestrator->>Playwright: execute tests in --ui mode
Playwright->>Dashboard: createProjectWithAllDatabases
Dashboard->>Database: provision databases
Playwright->>Dashboard: openProjectDatabase(dbms)
Playwright->>Dashboard: createBackup()
Dashboard->>Database: trigger backup
Database-->>Dashboard: backup complete
Playwright->>Dashboard: waitForBackupSuccess()
Playwright->>Dashboard: createRestoreFromBackup()
Dashboard->>Database: restore from backup
Database-->>Dashboard: restore complete
Playwright->>Dashboard: waitForRestoreSuccess()
Playwright-->>Orchestrator: test results
Orchestrator->>DockerStacks: compose down
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
e2e/helpers/backup.tsOops! Something went wrong! :( ESLint: 9.39.4 TypeError [ERR_IMPORT_ATTRIBUTE_MISSING]: Module "file:///.eslintrc.json?mtime=1779306805948" needs an import attribute of "type: json" src/lib/logger.tsOops! Something went wrong! :( ESLint: 9.39.4 TypeError [ERR_IMPORT_ATTRIBUTE_MISSING]: Module "file:///.eslintrc.json?mtime=1779306805948" needs an import attribute of "type: json" 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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 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.
Inline comments:
In `@Makefile`:
- Line 60: Update the Docker Compose startup command used in the Makefile target
that runs "docker compose -f docker-compose.database.yml up -d" to include the
"--wait" flag so the command blocks until services' healthchecks pass; locate
the Makefile target invoking docker compose with "-f docker-compose.database.yml
up -d" and change it to use "docker compose -f docker-compose.database.yml up
--wait -d" (or equivalent ordering) so subsequent Playwright tests run only
after the database services are healthy.
- Line 61: The e2e-backup Make target currently runs Playwright with the
interactive --ui flag; remove --ui and run Playwright non-interactively instead
by invoking pnpm playwright test with CI=true and the appropriate project flag
(for example CI=true pnpm playwright test --project=chromium) while keeping the
existing error/cleanup chaining (the docker compose down --volumes && exit 1
sequence) intact; update the command in the e2e-backup target to use this
non-interactive invocation and ensure no other interactive flags remain.
In `@src/lib/logger.ts`:
- Line 5: The logger currently reads process.env.LOG_LEVEL and casts it to
pino.Level via the const level = (process.env.LOG_LEVEL ?? defaultLevel) as
pino.Level; which bypasses validation and can crash startup; replace this by
importing the validated env object from "`@/env.mjs`" and use env.LOG_LEVEL
(falling back to defaultLevel if needed) when setting level, or alternatively
expand the env schema in env.mjs to include all pino levels and then use
env.LOG_LEVEL; update the code that defines level and any references to ensure
they use the validated value (identify the const level, defaultLevel, and any
exports from src/lib/logger.ts to modify).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 53a9047e-25fa-4c97-bcfc-5cd717a75861
📒 Files selected for processing (8)
.env.e2e.gitignoreMakefiledocker-compose.database.ymldocker-compose.e2e.ymle2e/helpers/agent-cli.tse2e/helpers/backup.tssrc/lib/logger.ts
💤 Files with no reviewable changes (1)
- e2e/helpers/agent-cli.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build-and-test
🧰 Additional context used
🪛 checkmake (0.3.2)
Makefile
[warning] 57-57: Target body for "e2e-backup" exceeds allowed length of 5 lines (7).
(maxbodylength)
🪛 Checkov (3.2.529)
docker-compose.database.yml
[low] 54-55: Base64 High Entropy String
(CKV_SECRET_6)
🪛 dotenv-linter (4.0.0)
.env.e2e
[warning] 14-14: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 16-16: [UnorderedKey] The PROJECT_SECRET key should go before the PROJECT_URL key
(UnorderedKey)
[warning] 22-22: [UnorderedKey] The SMTP_PASSWORD key should go before the SMTP_PORT key
(UnorderedKey)
[warning] 23-23: [UnorderedKey] The SMTP_FROM key should go before the SMTP_HOST key
(UnorderedKey)
[warning] 30-30: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 31-31: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 32-32: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 32-32: [UnorderedKey] The AUTH_OIDC_DESC key should go before the AUTH_OIDC_ID key
(UnorderedKey)
[warning] 33-33: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 33-33: [UnorderedKey] The AUTH_OIDC_ICON key should go before the AUTH_OIDC_ID key
(UnorderedKey)
[warning] 34-34: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 34-34: [UnorderedKey] The AUTH_OIDC_CLIENT key should go before the AUTH_OIDC_DESC key
(UnorderedKey)
[warning] 35-35: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 35-35: [UnorderedKey] The AUTH_OIDC_SECRET key should go before the AUTH_OIDC_TITLE key
(UnorderedKey)
[warning] 36-36: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 36-36: [UnorderedKey] The AUTH_OIDC_ISSUER_URL key should go before the AUTH_OIDC_SECRET key
(UnorderedKey)
[warning] 37-37: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 37-37: [UnorderedKey] The AUTH_OIDC_HOST key should go before the AUTH_OIDC_ICON key
(UnorderedKey)
[warning] 38-38: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 38-38: [UnorderedKey] The AUTH_OIDC_SCOPES key should go before the AUTH_OIDC_SECRET key
(UnorderedKey)
[warning] 39-39: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 39-39: [UnorderedKey] The AUTH_OIDC_DISCOVERY_ENDPOINT key should go before the AUTH_OIDC_HOST key
(UnorderedKey)
[warning] 40-40: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 40-40: [UnorderedKey] The AUTH_OIDC_JWKS_ENDPOINT key should go before the AUTH_OIDC_SCOPES key
(UnorderedKey)
[warning] 41-41: [UnorderedKey] The AUTH_OIDC_PKCE key should go before the AUTH_OIDC_SCOPES key
(UnorderedKey)
[warning] 42-42: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 42-42: [UnorderedKey] The ALLOWED_GROUP key should go before the AUTH_OIDC_CLIENT key
(UnorderedKey)
[warning] 43-43: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 43-43: [UnorderedKey] The AUTH_OIDC_ROLE_MAP key should go before the AUTH_OIDC_SCOPES key
(UnorderedKey)
[warning] 47-47: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 48-48: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 49-49: [UnorderedKey] The AUTH_OIDC_KEYCLOAK_DESC key should go before the AUTH_OIDC_KEYCLOAK_ID key
(UnorderedKey)
[warning] 50-50: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 50-50: [UnorderedKey] The AUTH_OIDC_KEYCLOAK_CLIENT key should go before the AUTH_OIDC_KEYCLOAK_DESC key
(UnorderedKey)
[warning] 51-51: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 51-51: [UnorderedKey] The AUTH_OIDC_KEYCLOAK_SECRET key should go before the AUTH_OIDC_KEYCLOAK_TITLE key
(UnorderedKey)
[warning] 52-52: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 52-52: [UnorderedKey] The AUTH_OIDC_KEYCLOAK_ISSUER_URL key should go before the AUTH_OIDC_KEYCLOAK_SECRET key
(UnorderedKey)
[warning] 53-53: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 53-53: [UnorderedKey] The AUTH_OIDC_KEYCLOAK_HOST key should go before the AUTH_OIDC_KEYCLOAK_ID key
(UnorderedKey)
[warning] 54-54: [UnorderedKey] The AUTH_OIDC_KEYCLOAK_SCOPES key should go before the AUTH_OIDC_KEYCLOAK_SECRET key
(UnorderedKey)
[warning] 55-55: [UnorderedKey] The AUTH_OIDC_KEYCLOAK_PKCE key should go before the AUTH_OIDC_KEYCLOAK_SCOPES key
(UnorderedKey)
[warning] 57-57: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 58-58: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 59-59: [UnorderedKey] The AUTH_OIDC_AUTHENTIK_DESC key should go before the AUTH_OIDC_AUTHENTIK_ID key
(UnorderedKey)
[warning] 60-60: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 60-60: [UnorderedKey] The AUTH_OIDC_AUTHENTIK_CLIENT key should go before the AUTH_OIDC_AUTHENTIK_DESC key
(UnorderedKey)
[warning] 61-61: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 61-61: [UnorderedKey] The AUTH_OIDC_AUTHENTIK_SECRET key should go before the AUTH_OIDC_AUTHENTIK_TITLE key
(UnorderedKey)
[warning] 62-62: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 62-62: [UnorderedKey] The AUTH_OIDC_AUTHENTIK_ISSUER_URL key should go before the AUTH_OIDC_AUTHENTIK_SECRET key
(UnorderedKey)
[warning] 63-63: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 63-63: [UnorderedKey] The AUTH_OIDC_AUTHENTIK_HOST key should go before the AUTH_OIDC_AUTHENTIK_ID key
(UnorderedKey)
[warning] 64-64: [UnorderedKey] The AUTH_OIDC_AUTHENTIK_SCOPES key should go before the AUTH_OIDC_AUTHENTIK_SECRET key
(UnorderedKey)
[warning] 65-65: [UnorderedKey] The AUTH_OIDC_AUTHENTIK_PKCE key should go before the AUTH_OIDC_AUTHENTIK_SCOPES key
(UnorderedKey)
[warning] 67-67: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 69-69: [UnorderedKey] The AUTH_OIDC_POCKET_DESC key should go before the AUTH_OIDC_POCKET_ID key
(UnorderedKey)
[warning] 70-70: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 70-70: [UnorderedKey] The AUTH_OIDC_POCKET_CLIENT key should go before the AUTH_OIDC_POCKET_DESC key
(UnorderedKey)
[warning] 71-71: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 71-71: [UnorderedKey] The AUTH_OIDC_POCKET_SECRET key should go before the AUTH_OIDC_POCKET_TITLE key
(UnorderedKey)
[warning] 72-72: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 72-72: [UnorderedKey] The AUTH_OIDC_POCKET_ISSUER_URL key should go before the AUTH_OIDC_POCKET_SECRET key
(UnorderedKey)
[warning] 73-73: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 73-73: [UnorderedKey] The AUTH_OIDC_POCKET_HOST key should go before the AUTH_OIDC_POCKET_ID key
(UnorderedKey)
[warning] 74-74: [UnorderedKey] The AUTH_OIDC_POCKET_SCOPES key should go before the AUTH_OIDC_POCKET_SECRET key
(UnorderedKey)
[warning] 75-75: [UnorderedKey] The AUTH_OIDC_POCKET_PKCE key should go before the AUTH_OIDC_POCKET_SCOPES key
(UnorderedKey)
[warning] 80-80: [ExtraBlankLine] Extra blank line detected
(ExtraBlankLine)
[warning] 82-82: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 83-83: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 84-84: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 84-84: [UnorderedKey] The AUTH_SOCIAL_DESC key should go before the AUTH_SOCIAL_ID key
(UnorderedKey)
[warning] 85-85: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 85-85: [UnorderedKey] The AUTH_SOCIAL_ICON key should go before the AUTH_SOCIAL_ID key
(UnorderedKey)
[warning] 86-86: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 86-86: [UnorderedKey] The AUTH_SOCIAL_CLIENT key should go before the AUTH_SOCIAL_DESC key
(UnorderedKey)
[warning] 87-87: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 87-87: [UnorderedKey] The AUTH_SOCIAL_SECRET key should go before the AUTH_SOCIAL_TITLE key
(UnorderedKey)
[warning] 88-88: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 88-88: [UnorderedKey] The AUTH_SOCIAL_APPLE_APP_BUNDLE_IDENTIFIER key should go before the AUTH_SOCIAL_CLIENT key
(UnorderedKey)
[warning] 93-93: [UnorderedKey] The AUTH_EMAIL_PASSWORD_ENABLED key should go before the AUTH_SYNC_OIDC_ROLES_ON_LOGIN key
(UnorderedKey)
[warning] 94-94: [UnorderedKey] The AUTH_SIGNUP_ENABLED key should go before the AUTH_SYNC_OIDC_ROLES_ON_LOGIN key
(UnorderedKey)
[warning] 95-95: [UnorderedKey] The AUTH_PASSKEY_ENABLED key should go before the AUTH_SIGNUP_ENABLED key
(UnorderedKey)
[warning] 102-102: [ExtraBlankLine] Extra blank line detected
(ExtraBlankLine)
[warning] 103-103: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 104-104: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 105-105: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 106-106: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 106-106: [UnorderedKey] The E2E_NOTIFICATION_SMTP_PASSWORD key should go before the E2E_NOTIFICATION_SMTP_PORT key
(UnorderedKey)
[warning] 107-107: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 107-107: [UnorderedKey] The E2E_NOTIFICATION_SMTP_FROM key should go before the E2E_NOTIFICATION_SMTP_HOST key
(UnorderedKey)
[warning] 108-108: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 108-108: [UnorderedKey] The E2E_NOTIFICATION_SMTP_TO key should go before the E2E_NOTIFICATION_SMTP_USER key
(UnorderedKey)
[warning] 110-110: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 112-112: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 114-114: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 115-115: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 116-116: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 118-118: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 119-119: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 119-119: [UnorderedKey] The E2E_NOTIFICATION_GOTIFY_APP_TOKEN key should go before the E2E_NOTIFICATION_GOTIFY_SERVER_URL key
(UnorderedKey)
[warning] 121-121: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 122-122: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 122-122: [UnorderedKey] The E2E_NOTIFICATION_NTFY_SERVER_URL key should go before the E2E_NOTIFICATION_NTFY_TOPIC key
(UnorderedKey)
[warning] 123-123: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 123-123: [UnorderedKey] The E2E_NOTIFICATION_NTFY_TOKEN key should go before the E2E_NOTIFICATION_NTFY_TOPIC key
(UnorderedKey)
[warning] 124-124: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 125-125: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 125-125: [UnorderedKey] The E2E_NOTIFICATION_NTFY_PASSWORD key should go before the E2E_NOTIFICATION_NTFY_SERVER_URL key
(UnorderedKey)
[warning] 127-127: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 128-128: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 128-128: [UnorderedKey] The E2E_NOTIFICATION_WEBHOOK_SECRET_HEADER key should go before the E2E_NOTIFICATION_WEBHOOK_URL key
(UnorderedKey)
[warning] 129-129: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 129-129: [UnorderedKey] The E2E_NOTIFICATION_WEBHOOK_SECRET key should go before the E2E_NOTIFICATION_WEBHOOK_SECRET_HEADER key
(UnorderedKey)
[warning] 131-131: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 132-132: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 133-133: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 133-133: [UnorderedKey] The E2E_STORAGE_AWS_S3_ACCESS_KEY key should go before the E2E_STORAGE_AWS_S3_ENDPOINT_URL key
(UnorderedKey)
[warning] 134-134: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 135-135: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 135-135: [UnorderedKey] The E2E_STORAGE_AWS_S3_BUCKET_NAME key should go before the E2E_STORAGE_AWS_S3_ENDPOINT_URL key
(UnorderedKey)
[warning] 136-136: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 136-136: [UnorderedKey] The E2E_STORAGE_AWS_S3_PORT key should go before the E2E_STORAGE_AWS_S3_REGION key
(UnorderedKey)
[warning] 138-138: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 139-139: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 140-140: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 140-140: [UnorderedKey] The E2E_STORAGE_R2_ACCESS_KEY key should go before the E2E_STORAGE_R2_ENDPOINT_URL key
(UnorderedKey)
[warning] 141-141: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 142-142: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 142-142: [UnorderedKey] The E2E_STORAGE_R2_BUCKET_NAME key should go before the E2E_STORAGE_R2_ENDPOINT_URL key
(UnorderedKey)
[warning] 143-143: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 143-143: [UnorderedKey] The E2E_STORAGE_R2_PORT key should go before the E2E_STORAGE_R2_REGION key
(UnorderedKey)
[warning] 145-145: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 146-146: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
[warning] 147-147: [EndingBlankLine] No blank line at the end of the file
(EndingBlankLine)
[warning] 147-147: [QuoteCharacter] The value has quote characters (', ")
(QuoteCharacter)
🔇 Additional comments (1)
docker-compose.e2e.yml (1)
24-24: ⚡ Quick winThe current mount path is correct for PostgreSQL 18—no change needed.
The project uses
postgres:18-alpine, and for PostgreSQL 18+, the official Docker image recommends mounting at/var/lib/postgresql, not/var/lib/postgresql/data. This change was introduced in PostgreSQL 18 to facilitate easier major version upgrades usingpg_upgrade --link. The current configuration is correct.> Likely an incorrect or invalid review comment.
| e2e-backup: | ||
| @echo "Starting backup E2E testing..." | ||
| @docker compose -f docker-compose.e2e.yml up -d | ||
| @docker compose -f docker-compose.database.yml up -d |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
Does docker compose up --wait block until healthchecks pass for services that define healthcheck?
💡 Result:
Yes—docker compose up --wait blocks until the project’s services are “running|healthy”, and it will use each service’s healthcheck to determine when that service is healthy (if a service has a healthcheck configured). This means services that define healthcheck can delay the command until their health status becomes healthy (subject to the global --wait-timeout). [1][2][3] Notes/nuances: 1) It waits “for services to be running|healthy” (implies detached mode) rather than only “running”. [1][2] 2) For dependencies, Compose’s documented startup-order mechanism is separate (depends_on: condition: service_healthy). But --wait is broader: it can wait for all services to become healthy, not just dependencies. [4][3] 3) If a service never becomes healthy (or becomes unhealthy), --wait will stop waiting and exit non-zero; healthcheck state is what drives that behavior. [5][2] Practical answer to your question: if your compose file includes a healthcheck for a service, and you run docker compose up --wait, that service’s healthcheck must pass for the command to return successfully (within --wait-timeout). [1][2][5]
Citations:
- 1: https://docs.docker.com/reference/cli/docker/compose/up/
- 2: https://docs.docker.com/reference/cli/docker/compose/up
- 3: https://docs.docker.com/compose/how-tos/startup-order/
- 4: [BUG] docker compose up -d waits even without --wait docker/compose#13426
- 5: [BUG] docker-compose up --wait --wait-timeout 300 docker/compose#12416
🏁 Script executed:
# Locate and read the Makefile around line 60
find . -name "Makefile" -type f | head -5Repository: Portabase/portabase
Length of output: 373
🏁 Script executed:
# Search for docker-compose.database.yml
find . -name "docker-compose.database.yml" -type fRepository: Portabase/portabase
Length of output: 93
🏁 Script executed:
# Read Makefile around line 60 to get full context of e2e-backup target
sed -n '50,75p' ./MakefileRepository: Portabase/portabase
Length of output: 1200
🏁 Script executed:
# Read docker-compose.database.yml to check for healthcheck definitions
cat ./docker-compose.database.ymlRepository: Portabase/portabase
Length of output: 8650
Add --wait flag to docker compose startup to wait for database services to be healthy.
The docker compose up -d command returns immediately without waiting for service healthchecks to pass. Since the next step runs Playwright tests, this creates a race condition where tests may execute against unstarted or unhealthy database services, causing flaky failures. All services in docker-compose.database.yml define healthchecks, so --wait will properly block until they are ready.
🔧 Proposed fix
- `@docker` compose -f docker-compose.database.yml up -d
+ `@docker` compose -f docker-compose.database.yml up -d --wait📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| @docker compose -f docker-compose.database.yml up -d | |
| `@docker` compose -f docker-compose.database.yml up -d --wait |
🤖 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 `@Makefile` at line 60, Update the Docker Compose startup command used in the
Makefile target that runs "docker compose -f docker-compose.database.yml up -d"
to include the "--wait" flag so the command blocks until services' healthchecks
pass; locate the Makefile target invoking docker compose with "-f
docker-compose.database.yml up -d" and change it to use "docker compose -f
docker-compose.database.yml up --wait -d" (or equivalent ordering) so subsequent
Playwright tests run only after the database services are healthy.
| @echo "Starting backup E2E testing..." | ||
| @docker compose -f docker-compose.e2e.yml up -d | ||
| @docker compose -f docker-compose.database.yml up -d | ||
| @pnpm playwright test --ui || (docker compose -f docker-compose.database.yml down --volumes && docker compose -f docker-compose.e2e.yml down --volumes && exit 1) |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
Is Playwright --ui mode intended for CI automation, or only for local interactive debugging?
💡 Result:
Playwright UI mode is intended for local interactive development and debugging, not for CI (Continuous Integration) automation [1][2]. Key distinctions include: Purpose and Design: UI mode is specifically designed to provide a better developer experience for active test development [1]. It combines features like watch mode, a time-travel debugging interface, live trace viewing, and a locator picker into a single interactive environment [1][2][3]. It is meant to help developers quickly iterate on tests, inspect the DOM, and debug failures locally [4][2]. CI/CD Compatibility: CI environments are typically headless and automated, designed to run test suites efficiently and report results without human intervention [2][5]. UI mode, conversely, requires a graphical interface and user interaction [4][1]. Official Playwright documentation explicitly recommends UI mode for local debugging and suggests using standard CLI test execution for CI pipelines [2]. Recommended CI Practices: For CI environments, Playwright recommends standard, headless test execution using the CLI (e.g., npx playwright test) [2][5]. To handle debugging in CI, developers should configure features like trace collection (e.g., trace: 'on-first-retry') [6]. These saved trace artifacts can then be opened in the Trace Viewer—a tool separate from UI mode—to perform post-mortem analysis of CI failures without requiring the interactive UI mode during the CI run itself [1][6].
Citations:
- 1: https://mintlify.com/microsoft/playwright/tools/ui-mode
- 2: https://playwright.dev/docs/running-tests
- 3: https://www.youtube.com/watch?v=d0u6XhXknzU
- 4: https://playwright.dev/docs/test-ui-mode
- 5: https://testgrid.io/blog/playwright-testing/
- 6: https://medium.com/webmaster-nexus/playwright-web-automation-b5fdaa62fd3f?source=rss-------1
🏁 Script executed:
# First, check the Makefile context around line 61
head -70 Makefile | tail -15Repository: Portabase/portabase
Length of output: 806
🏁 Script executed:
# Look for CI configuration files to understand if this target is used in automation
fd -e yml -e yaml -e json | grep -i -E "ci|github|gitlab|circleci|workflow" | head -20Repository: Portabase/portabase
Length of output: 45
🏁 Script executed:
# Search for references to this Make target in the codebase
rg "test.*ui|test-e2e" --type makefile -A 2 -B 2Repository: Portabase/portabase
Length of output: 96
🏁 Script executed:
# Search for CI workflow files
find . -type f \( -name "*.yml" -o -name "*.yaml" -o -name "*.json" \) | grep -i -E "workflow|github|gitlab|ci|action" | head -20Repository: Portabase/portabase
Length of output: 1428
🏁 Script executed:
# Search the entire Makefile for these targets and any related documentation
cat Makefile | head -100Repository: Portabase/portabase
Length of output: 3953
🏁 Script executed:
# Look for any documentation about e2e-backup or e2e-manual
rg "e2e-backup|e2e-manual" -iRepository: Portabase/portabase
Length of output: 105
🏁 Script executed:
# Check the e2e.yml workflow file
cat ./.github/workflows/e2e.ymlRepository: Portabase/portabase
Length of output: 5305
Remove --ui from the e2e-backup Make target.
The --ui flag makes Playwright tests interactive and unsuitable for automated/unattended runs. The target name e2e-backup indicates it should run automatically, and the existing end-to-end target already demonstrates the correct pattern using CI=true and --project=chromium.
🔧 Proposed fix
- `@pnpm` playwright test --ui || (docker compose -f docker-compose.database.yml down --volumes && docker compose -f docker-compose.e2e.yml down --volumes && exit 1)
+ `@CI`=true pnpm playwright test --project=chromium || (docker compose -f docker-compose.database.yml down --volumes && docker compose -f docker-compose.e2e.yml down --volumes && exit 1)🤖 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 `@Makefile` at line 61, The e2e-backup Make target currently runs Playwright
with the interactive --ui flag; remove --ui and run Playwright non-interactively
instead by invoking pnpm playwright test with CI=true and the appropriate
project flag (for example CI=true pnpm playwright test --project=chromium) while
keeping the existing error/cleanup chaining (the docker compose down --volumes
&& exit 1 sequence) intact; update the command in the e2e-backup target to use
this non-interactive invocation and ensure no other interactive flags remain.
| const isProd = process.env.NODE_ENV === "production"; | ||
| const defaultLevel = isProd ? "info" : "debug"; | ||
| const level = (env.LOG_LEVEL ?? defaultLevel) as pino.Level; | ||
| const level = (process.env.LOG_LEVEL ?? defaultLevel) as pino.Level; |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify whether LOG_LEVEL used to be schema-validated and where it's consumed now.
set -euo pipefail
echo "== LOG_LEVEL references =="
rg -n --hidden -C2 '\bLOG_LEVEL\b'
echo
echo "== env schema candidates =="
fd -i 'env.mjs|env.ts|env.js' -t f | xargs -r rg -n -C2 '\bLOG_LEVEL\b|z\.enum|enum'Repository: Portabase/portabase
Length of output: 3143
🏁 Script executed:
rg -n 'import.*env|from.*env' src/lib/logger.ts src/middleware/loggingMiddleware.ts src/app.ts -A2Repository: Portabase/portabase
Length of output: 114
🏁 Script executed:
# Check if env is imported anywhere that would run before logger.ts
rg -n 'import.*from.*env.mjs|env.mjs' --hidden -C2Repository: Portabase/portabase
Length of output: 7395
🏁 Script executed:
# Verify pino.Level type definition to confirm what values it accepts
rg -n 'type.*Level|pino.Level' src/lib/logger.ts -B2 -A2Repository: Portabase/portabase
Length of output: 276
Use validated env module for LOG_LEVEL instead of direct process.env cast.
src/lib/logger.ts reads process.env.LOG_LEVEL directly and casts to pino.Level without validation. The validated env module in src/env.mjs restricts LOG_LEVEL to ["debug", "info", "warn", "error"], but this validation is bypassed. An invalid LOG_LEVEL can crash logger startup.
Import and use the validated env object from @/env.mjs instead of reading process.env directly. Alternatively, if broader pino levels are intended, expand the env schema to match.
🔧 Proposed fix
Option 1: Use validated env (aligns with current schema):
-import pino from "pino";
+import pino from "pino";
+import { env } from "`@/env.mjs`";
const isProd = process.env.NODE_ENV === "production";
const defaultLevel = isProd ? "info" : "debug";
-const level = (process.env.LOG_LEVEL ?? defaultLevel) as pino.Level;
+const level = env.LOG_LEVEL as pino.Level;Option 2: Validate against all pino levels (requires expanding env schema):
const isProd = process.env.NODE_ENV === "production";
const defaultLevel = isProd ? "info" : "debug";
-const level = (process.env.LOG_LEVEL ?? defaultLevel) as pino.Level;
+const allowedLevels: ReadonlySet<pino.Level> = new Set([
+ "fatal", "error", "warn", "info", "debug", "trace", "silent"
+]);
+const requestedLevel = process.env.LOG_LEVEL;
+const level: pino.Level =
+ requestedLevel && allowedLevels.has(requestedLevel as pino.Level)
+ ? (requestedLevel as pino.Level)
+ : defaultLevel;Also applies to: 24-24
🤖 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 `@src/lib/logger.ts` at line 5, The logger currently reads
process.env.LOG_LEVEL and casts it to pino.Level via the const level =
(process.env.LOG_LEVEL ?? defaultLevel) as pino.Level; which bypasses validation
and can crash startup; replace this by importing the validated env object from
"`@/env.mjs`" and use env.LOG_LEVEL (falling back to defaultLevel if needed) when
setting level, or alternatively expand the env schema in env.mjs to include all
pino levels and then use env.LOG_LEVEL; update the code that defines level and
any references to ensure they use the validated value (identify the const level,
defaultLevel, and any exports from src/lib/logger.ts to modify).
Summary by CodeRabbit
Tests
Chores