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:
- Checks the shared variables
- Collects the deployment logs
- 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:
# 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_deploymentskips 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:
.envholds 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:
| Variable | Required | Default | Location | Description |
|---|---|---|---|---|
VORTEX_NOTIFY_CHANNELS | No | email | .env | Notification channels (comma-separated) |
VORTEX_NOTIFY_PROJECT | No | VORTEX_PROJECT | Hosting | Notification project name; the Lagoon tasks set it to LAGOON_PROJECT and the Acquia hook to the site name |
VORTEX_NOTIFY_SKIP | No | None | Hosting | Set 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:
| Variable | Required | Description |
|---|---|---|
VORTEX_NOTIFY_BRANCH | Yes | Git 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_SHA | Yes | Deployed 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_NUMBER | No | Pull request number. Lagoon: LAGOON_PR_NUMBER. Empty on Acquia and for branch deployments |
VORTEX_NOTIFY_LABEL | Yes | Human-readable deployment label. Lagoon: PR-<number> for pull requests, the branch name otherwise. Acquia: the same value as VORTEX_NOTIFY_BRANCH |
VORTEX_NOTIFY_ENVIRONMENT_URL | Yes | URL 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_URL | No | Login URL for the %login_url% token; defaults to <environment_url>/user/login |
VORTEX_NOTIFY_EVENT | No | Deployment 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:
| Token | Description | Example |
|---|---|---|
%project% | Project name | My Project |
%label% | Deployment label | main or PR-123 |
%timestamp% | Current timestamp | 15/11/2025 14:30:45 UTC |
%environment_url% | Environment URL | https://example.com |
%login_url% | Login URL | https://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 ofmessage. 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_LOGVORTEX_NOTIFY_SLACK_LOGVORTEX_NOTIFY_JIRA_LOGVORTEX_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.
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-provisionmakes its log directory andprovision.logowner-only (700/600), on a best-effort basis.- The router's collected file,
combinedin 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:
| Variable | Required | Default | Location | Description |
|---|---|---|---|---|
VORTEX_PROVISION_LOG | No | 0 | .env or Hosting | Set to 1 to write the provision log for collection |
VORTEX_NOTIFY_LOG | No | 0 | .env or Hosting | Set to 1 to collect and include deployment logs |
VORTEX_NOTIFY_LOG_DIR | No | /tmp/vortex-logs | .env | Directory the logs are collected from |