Skip to main content
Version: v1

Notifications

Vortex announces each deployment on the channels you turn on, so your team hears about a new environment and gets a link to log in to it, without watching CI.

This page is for the lead or DevOps engineer who sets up deployment notifications. It explains when notifications go out, how to pick the channels and the settings that every channel shares. Each channel's own page covers its setup and its variables.

The vendor/bin/vortex-notify router script dispatches the notifications in 3 steps:

  1. Checks the shared variables
  2. Collects the deployment logs
  3. Runs the script of each channel you turn on

The hosting platform runs the router around a deployment, from the Lagoon post-rollout tasks or the Acquia Cloud Hooks. The CI deploy job never runs it. The environment's URL comes from the hosting side: the Lagoon tasks read it from LAGOON_ROUTE, and the Acquia hook builds it from the site name.

On Lagoon, the router runs twice per deployment: with the pre_deployment event before provisioning, and with post_deployment after it. The Acquia hook runs it once, after the deployment, with the default post_deployment event.

Channels​

Configure notification channels in your .env file:

.env
# Enable notification channels (comma-separated list)
VORTEX_NOTIFY_CHANNELS=email,slack,github

The router supports 7 channels and runs them in the following order, whatever order you list them in:

  • email - sends an email to a list of recipients.
  • slack - posts a message to a Slack channel.
  • newrelic - records a deployment marker in New Relic APM.
  • github - reports the deployment through the GitHub Deployments API.
  • jira - comments on the Jira issue named in the branch.
  • webhook - sends a JSON payload to a URL you choose.
  • diffy - starts a Diffy visual regression run through GitHub Actions.

An unset or empty VORTEX_NOTIFY_CHANNELS means email, so to turn notifications off, set VORTEX_NOTIFY_SKIP. The installer offers every channel except diffy, which you add by hand. The router matches the names as substrings and doesn't validate them, so a misspelled channel sends nothing and raises no error.

When a channel fails, the router stops with an error, and the channels after it don't run. The effect depends on the hosting platform:

  • On Lagoon, the failed notification task stops the post-rollout tasks after it, and Lagoon notifies you about the failure. A failure at pre_deployment skips provisioning too.
  • On Acquia, the notification hook runs last. Acquia marks the deployment task as failed, and the hook's output appears in the task log.

Global environment variables​

These variables apply to every channel unless a channel-specific variable overrides them. The Variables reference has the full generated list of VORTEX_NOTIFY_* variables, with the script that reads each variable.

The Location column in this section and on the channel pages says where a value usually lives:

  • .env holds project-wide settings that you commit.
  • Hosting means secrets and per-deployment values: you set them in the hosting platform's environment variables, or the hosting hook and the router set them at run time.

The following table lists the global variables:

VariableRequiredDefaultLocationDescription
VORTEX_NOTIFY_CHANNELSNoemail.envNotification channels (comma-separated)
VORTEX_NOTIFY_PROJECTNoVORTEX_PROJECTHostingNotification project name; the Lagoon tasks set it to LAGOON_PROJECT and the Acquia hook to the site name
VORTEX_NOTIFY_SKIPNoNoneHostingSet to any non-empty value, for example 1, to skip notifications

Deployment context variables​

These variables hold the deployment details that the channels read. The hosting platform sets them before it calls the router, and the shipped Lagoon post-rollout tasks and Acquia hook already do. When a required variable is empty, the router stops with Missing required value for and the variable name.

The following table lists the deployment context variables and what the Lagoon tasks and the Acquia hook put in them:

VariableRequiredDescription
VORTEX_NOTIFY_BRANCHYesGit branch name. Lagoon: the pull request's head branch, or LAGOON_GIT_BRANCH. Acquia: the source branch argument that Acquia passes to the hook
VORTEX_NOTIFY_SHAYesDeployed reference. Lagoon: the commit SHA in LAGOON_GIT_SHA. Acquia: the deployed tag argument that Acquia passes to the hook, a name and not a commit SHA
VORTEX_NOTIFY_PR_NUMBERNoPull request number. Lagoon: LAGOON_PR_NUMBER. Empty on Acquia and for branch deployments
VORTEX_NOTIFY_LABELYesHuman-readable deployment label. Lagoon: PR-<number> for pull requests, the branch name otherwise. Acquia: the same value as VORTEX_NOTIFY_BRANCH
VORTEX_NOTIFY_ENVIRONMENT_URLYesURL of the deployed environment, used by the %environment_url% token. Lagoon: LAGOON_ROUTE. Acquia: built from AH_SITE_NAME and AH_REALM, or from VORTEX_NOTIFY_ENVIRONMENT_DOMAIN
VORTEX_NOTIFY_LOGIN_URLNoLogin URL for the %login_url% token; defaults to <environment_url>/user/login
VORTEX_NOTIFY_EVENTNoDeployment event: post_deployment (default) or pre_deployment; any other value fails the run. Lagoon: pre_deployment, then post_deployment. Acquia: not set, so post_deployment

Only Slack and GitHub act on pre_deployment, and the other 5 channels skip it.

Branch filtering​

Each channel has a VORTEX_NOTIFY_<CHANNEL>_BRANCHES variable that limits it to specific branches. When the variable is set, the channel sends notifications only for deployments on the listed branches. When it's empty or unset, the channel runs on all branches.

The list is comma-separated, without spaces. Each entry is an exact branch name, without patterns. Every channel compares the entries with VORTEX_NOTIFY_BRANCH, except Diffy. Diffy uses its own VORTEX_NOTIFY_DIFFY_BRANCH, which defaults to VORTEX_NOTIFY_BRANCH.

For example, to restrict New Relic notifications to main and staging:

VORTEX_NOTIFY_NEWRELIC_BRANCHES=main,staging

New Relic defaults to main,master,develop, and all other channels default to no filter. An empty New Relic value falls back to that default, so to let New Relic run on other branches, list every branch you want.

Message templates and tokens​

The following channels take a custom message template:

  • Email: VORTEX_NOTIFY_EMAIL_MESSAGE
  • Slack: VORTEX_NOTIFY_SLACK_MESSAGE
  • Jira: VORTEX_NOTIFY_JIRA_MESSAGE
  • New Relic: VORTEX_NOTIFY_NEWRELIC_DESCRIPTION
  • Webhook: VORTEX_NOTIFY_WEBHOOK_PAYLOAD

GitHub and Diffy send fixed payloads. The templates use the replacement tokens in the following table:

TokenDescriptionExample
%project%Project nameMy Project
%label%Deployment labelmain or PR-123
%timestamp%Current timestamp15/11/2025 14:30:45 UTC
%environment_url%Environment URLhttps://example.com
%login_url%Login URLhttps://example.com/user/login
%deployment_log%Collected deployment logs, when enabled (email and webhook only)A ## provision.log ## heading, then the log text
%message%The default message with the other tokens replaced (webhook payload only)The default message, filled in

The default message template is:

## This is an automated message ##

Site %project% %label% has been deployed at %timestamp% and is available at %environment_url%.

Login at: %login_url%

Each channel uses the default template in its own way:

  • Slack uses it as the message's fallback text, shown where attachments can't display.
  • The email default adds %deployment_log% at the end.
  • Jira posts the same text as a formatted comment.
  • New Relic's default description is the Site %project% ... line, without the final period.

Deployment log​

Notifications can include the logs that deployment scripts write. Each producing script writes its own <name>.log into VORTEX_NOTIFY_LOG_DIR. When VORTEX_PROVISION_LOG=1, vortex-provision writes provision.log there and truncates it at the start of each run.

When VORTEX_NOTIFY_LOG=1, the router collects every non-empty log in that directory, each as its own titled section. It passes the path of the collected file to the channels as VORTEX_NOTIFY_LOG_FILE, which stays empty when it collected nothing.

The email, Slack, Jira and webhook channels add the collected logs to their message, each in its own way:

  • Email and webhook templates insert them at the %deployment_log% token. The default email template ends with that token. The default webhook payload carries it at the end of message. A custom template without the token leaves the logs out.
  • Slack adds them to the message attachment.
  • Jira posts them as a code block after the comment text.

GitHub, New Relic and Diffy never include logs.

To include the provision log in notifications, set both VORTEX_PROVISION_LOG=1 and VORTEX_NOTIFY_LOG=1, in .env or per environment.

Each of those 4 channels also reads a flag of its own:

  • VORTEX_NOTIFY_EMAIL_LOG
  • VORTEX_NOTIFY_SLACK_LOG
  • VORTEX_NOTIFY_JIRA_LOG
  • VORTEX_NOTIFY_WEBHOOK_LOG

A flag set to 1 includes the collected logs in that channel, and 0 leaves them out. Each flag defaults to the value of VORTEX_NOTIFY_LOG, so with VORTEX_NOTIFY_LOG=1, all 4 channels include the logs. To leave the logs out of a single channel, set its flag to 0, for example VORTEX_NOTIFY_SLACK_LOG=0. A channel flag set to 1 has no effect unless VORTEX_NOTIFY_LOG=1, because only then does the router collect logs.

warning

Deployment logs go out verbatim. Make sure producing scripts don't print secrets. Turn the feature on only for the channels and environments where showing the full logs is acceptable.

Producing scripts write their logs to VORTEX_NOTIFY_LOG_DIR (default /tmp/vortex-logs). The files get these permissions:

  • vortex-provision makes its log directory and provision.log owner-only (700/600), on a best-effort basis.
  • The router's collected file, combined in the same directory, is owner-only too.
  • Any other producing script sets the permissions of its own log file.

If you point VORTEX_NOTIFY_LOG_DIR at a custom directory, make sure other users can't read that location.

The following table lists the deployment log variables:

VariableRequiredDefaultLocationDescription
VORTEX_PROVISION_LOGNo0.env or HostingSet to 1 to write the provision log for collection
VORTEX_NOTIFY_LOGNo0.env or HostingSet to 1 to collect and include deployment logs
VORTEX_NOTIFY_LOG_DIRNo/tmp/vortex-logs.envDirectory the logs are collected from