Skip to content

Block outgoing mail on non-production instances - #135

Merged
shiny-code-app[bot] merged 1 commit into
mainfrom
work/non-prod-mail-off
Sep 29, 2026
Merged

shiny-code-app[bot] merged 1 commit into
mainfrom
work/non-prod-mail-off

Conversation

@shiny-code-app

Copy link
Copy Markdown
Contributor

Why

The CM website testing lane sent real mail through the Cell Mechanic Google Workspace server during an ordinary deploy on 2026-09-29. Devkit already has Odoo-style mail neutralization (an active dummy ir_mail_server that also blocks the SMTP fallback), but it only runs on sanitized restores. Fresh bootstrap deliberately leaves the fallback open, and post-deploy maintenance never neutralizes. Any non-production lane that receives SMTP settings from Launchplane can therefore email real people.

Contact-form delivery for CM was verified once on 2026-09-24 (launchplane#2485), so testing no longer needs live mail. The owner approved turning mail off outside production.

What changed

  • New block_outgoing_mail_outside_production() runs on bootstrap, on every post-deploy maintenance run, and on restore (right after the copy lands, and again after the Launchplane settings apply). It runs even with --no-sanitize, the same way credential neutralization already does.
    • On any instance other than prod/production (an empty PLATFORM_INSTANCE counts as non-production), it deactivates real mail servers, clears their SMTP user and password, and activates the dummy server.
    • It reuses an existing dummy server, so repeated deploys don't pile up rows. Sanitize now shares the same helper.
  • Production behavior is unchanged: production bootstrap still leaves the operator-supplied mail configuration in place.
  • The README runtime notes describe the new rule.

This affects every tenant using devkit: OPW and CM testing/preview lanes, and local instances, will stop sending mail after their next deploy.

Verification

  • New tests cover these cases:
    • Non-production bootstrap blocks mail.
    • Repeated blocking keeps exactly one dummy server and clears copied credentials.
    • Production mail is left alone.
    • Production bootstrap still allows configured mail.
    • A restore clears the copied production server even when sanitize is skipped.
  • The post-deploy order test includes the new step.
  • Full suite: 317 tests OK. Ruff check and format are clean.
  • JetBrains inspection: UNKNOWN (language_sdk_missing) in the fresh worktree, which is the known preparation debt in Make linked-worktree Python inspection preparation reproducible #111.

Owner test notes

Nothing for the owner to test. After a testing deploy picks this up, contact-form submissions on testing will record the mail but not deliver it. Delivery checks happen on prod.

Refs #134

Sanitization only ran on fresh bootstrap and restore, and bootstrap left
Odoo's SMTP fallback open, so a testing lane with SMTP settings sent real
mail on every deploy. Activate the neutralization dummy server and clear
copied SMTP credentials on bootstrap, post-deploy maintenance, and restore
(including --no-sanitize) for every non-production instance. Reuse an
existing dummy server so repeated deploys do not add rows. Production is
unchanged.
@shiny-code-app
shiny-code-app Bot merged commit dbcb211 into main Sep 29, 2026
5 checks passed
@shiny-code-app
shiny-code-app Bot deleted the work/non-prod-mail-off branch September 29, 2026 16:28
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