Skip to content
Skip to main content

Send email from CI/CD pipelines

Last updated:

Build and deploy notifications are application mail, not personal mail. When a pipeline finishes, the message comes from your release system, so routing it through a developer’s connected inbox is the wrong model. This recipe sends those alerts with transactional send, which goes out from a verified domain instead of a user account.

You run the send as a single curl step inside your pipeline. The API key lives in your CI secret store, never in the repository, and the same step works for a green deploy or a red build.

Why use transactional send for pipeline notifications?

Section titled “Why use transactional send for pipeline notifications?”

Pipeline alerts are system messages triggered by an event, so they fit the transactional model rather than a user mailbox. Transactional send uses a POST /v3/domains/{domain_name}/messages/send route keyed on a verified domain, which means no OAuth grant and no per-developer authentication. One API key sends from your release domain.

This keeps the pipeline simple. A typical workflow needs just 1 curl step and 2 stored values: your API key and your verified domain. There is no token refresh to manage, which matters in a CI runner that starts cold and exits in under 60 seconds. For the domain verification steps, see transactional send. If you would rather send from a real connected mailbox, use the grant route at POST /v3/grants/{grant_id}/messages/send instead.

How do I store the Nylas API key in CI secrets?

Section titled “How do I store the Nylas API key in CI secrets?”

Never hardcode the API key in a workflow file, because pipeline definitions are committed to the repository and visible to anyone with read access. Store the key as an encrypted CI secret and read it as an environment variable at runtime. Both major platforms encrypt secrets at rest and mask them in logs.

In GitHub, open Settings, then Secrets and variables, then Actions, and add a repository secret named NYLAS_API_KEY. Add NYLAS_DOMAIN for your verified domain as a repository variable, since it isn’t sensitive, which is why the workflow below reads it as vars.NYLAS_DOMAIN rather than secrets. In GitLab, open Settings, then CI/CD, then Variables, and add both, with the Masked flag enabled on NYLAS_API_KEY so it never prints in job output. Reference the key as ${{ secrets.NYLAS_API_KEY }} in GitHub or $NYLAS_API_KEY in GitLab. Rotate the key from the Nylas Dashboard if a runner is ever compromised.

How do I send a deploy notification from GitHub Actions?

Section titled “How do I send a deploy notification from GitHub Actions?”

Add a job step that runs after your deploy step and reads the secrets from the environment. The step below sends a success notification, mapping secrets.NYLAS_API_KEY and vars.NYLAS_DOMAIN into environment variables that curl reads. This is the only place the send call appears in this recipe.

The job runs in about 5 seconds and exits after the single request returns.

The from address must belong to the same verified domain in the path, so with NYLAS_DOMAIN=acme.com the sender has to be an @acme.com address or the send returns a 4xx. The if: success() condition runs the step only when every earlier step passed, so the “succeeded” notice never fires on a broken deploy. For failure alerts, add a second step with if: failure() and a subject that says so. The GitLab example below shows the failure side.

How do I send a build-failure alert from GitLab CI?

Section titled “How do I send a build-failure alert from GitLab CI?”

GitLab uses the same domain route, so you only change the variable syntax and the trigger rule. The job below runs only when an earlier stage fails, using the on_failure rule, and reuses the masked CI variables you stored earlier. The send takes roughly 1 HTTP round trip and adds under 10 seconds to the pipeline.

Define the job in .gitlab-ci.yml after your build and deploy stages.

Reuse the predefined CI variables like CI_PIPELINE_URL so the alert links straight back to the failed run.

Things to know about sending from pipelines

Section titled “Things to know about sending from pipelines”

The sending address in from must belong to a domain Nylas has verified, or the request returns a 4xx error before any mail leaves. Keep these alerts to 1 message per pipeline event, since transactional send targets system mail rather than bulk delivery. JSON payloads follow the same 3 MB limit as a grant send, which is more than enough for a status line.

Treat a non-200 response as a pipeline warning rather than a hard failure, so a notification outage never blocks a real deploy. Transactional send is in beta, so confirm delivery during rollout. If you run scheduled jobs outside CI, the bash and cron recipe and the PowerShell recipe cover the same send from a shell.