Product articles Redgate Flyway Configuration, Authentication
Color-coded Checks for your Current…

Color-coded Checks for your Current Flyway Environment

This article shows how to provide clearer feedback from the Flyway CLI by using environment-specific placeholders to provide details about the environment's purpose. It then illustrates how you might use this information to allow a scripted Flyway pipeline to give a simple code-coded message confirming the connected environment.

Guest post

This is a guest post from Phil Factor. Phil Factor (real name withheld to protect the guilty), aka Database Mole, has 30 years of experience with database-intensive applications.

Despite having once been shouted at by a furious Bill Gates at an exhibition in the early 1980s, he has remained resolutely anonymous throughout his career.

He is a regular contributor to Simple Talk and SQLServerCentral.

By adding extra placeholders to your environment definitions, you can give your migrations and callbacks access to useful environment-specific information. This might include the environment name, branch, project description…and even what color the console text should be!

Inspired by SQL Prompt’s ability to color‑code SSMS tabs, I’ll show how we can use this extra context in a beforeConnect callback to persuade a Flyway scripted process to write text messages to its console that are color-coded according to the environment. In big, bold colors, it will tell you exactly which environment it’s pointing at before you run a migration.

Why is this useful? For one thing, you’ll get a bright red “proceed with caution” warning when connected to Staging or Production. Beyond preventing mishaps, these color‑coded messages are a simple, reassuring way to confirm “yes, I’m definitely in the right place” when juggling multiple databases, branches, and environments in team development.

How Flyway environments might trip you up

When you are developing a database interactively and operating several console screens at once, it’s scarily possible to make a change to the wrong database – I’ve done it myself. One tired late-night session, one distraction, and suddenly you’ve dropped a table in production instead of development.

In enterprise-scale developments, you’re usually protected from making serious errors by process – developers simply don’t have production logins. In smaller shops, though, the same person might do both, and therein lies the danger.

There was a time when it was difficult to ‘accidentally’ switch between databases with Flyway without realizing it, but with the greater power of Flyway environments also comes a greater chance of this happening. Flyway’s configuration system is highly flexible and adaptable; we can specify or override the current environment settings in several places:

  • User-level – Flyway reads any environment definitions it finds in a user-level TOML file, along with any value for the flyway.environment configuration item, specifying the current environment.
  • Project-level – next, if Flyway finds a TOML file in its working directory (usually the project you’re working on), any environment definitions there will be added or take precedence. So also, the assignment to the current environment.
  • Command-line – if you specify a different TOML file on the command line, it overrides both and can change the environment setting. An environment variable could also change the setting of the flyway environment, as I once found out to my cost! Finally, a direct -environment= option on the command line will have the last say.

I suspect you could easily end up in the wrong environment, just by accidentally running Flyway from the wrong working directory, or because an automated process picked up an unexpected config, or by specifying the wrong TOML file at the command line. The risk increases further when you’re working under pressure or fixing bugs late at night.

A clear visual reminder of the current environment significantly lowers the risk and does no harm at all to the process.

Getting the Environment details into the Session

Flyway passes resolved configuration values like URL, user, and schemas automatically to migrations and callbacks. However, it doesn’t pass on the name of the environment (e.g. Staging), or any additional context to the callbacks. You need to explicitly define it as a placeholder in your environment’s definition if you want to know what the current environment is. This may change with new releases.

So, if you want your callback to use the name of the environment to build a “Careful! This is Staging!” warning message, in bright red, you need to explicitly provide a “current environment” placeholder, as well as placeholders for message colors, like this:

[environments.PubsStaging.flyway]
# per-environment Placeholders for migrations & callbacks
placeholders.currentEnvironment = "PubsStaging"
placeholders.foregroundColour = "Red"
placeholders.backgroundColour = "DarkRed"

From environment placeholders to Flyway console warnings

Our Flyway callback will read our environment placeholders, extract the details of the current environment and the associated color-coding, construct a big, red “Watch out! This is STAGING!” message and somehow send it to the Flyway console.

It sounds simple, but there are a couple of hurdles to overcome. Firstly, for this system to work, we need to be certain that we’ll see the warning messages before any ‘consequential’ Flyway command runs, not after!

Secondly, it’s not entirely straightforward to persuade the Flyway console to burst into different colors at the switch of an environment switch. We need to do a bit of extra scripting

Let’s jump those hurdles one at a time.

Ensuring timely warnings: the beforeConnect callback

On the face of it, it sounds like we’ll need to add a whole range of callbacks (beforeMigrate, beforeClean, beforeUndo etc.) to every project, each one containing the special code that constructs and sends these warning messages.

Fortunately, there’s one callback that can save us from all this trouble: beforeConnect. It is unusual because, like afterxxxError, it isn’t associated with a specific command and instead runs before almost every Flyway command. This gives us a single “entry point” to announce the current environment to the user, before anything else happens.

All we need to do to make this system work is run a harmless Flyway command (like info) at the start of the process, so that Flyway immediately triggers our beforeConnect callback before any other command runs.

Persuading Flyway to burst into color

Flyway outputs everything to standard streams (stdout or stderr). It doesn’t provide separate verbose or debug streams. If you use JSON output, or quiet mode, you’ll suppress any helpful messages. So, if you try to have your callback print a color-coded message directly to the console, it won’t reliably appear.

Flyway will colorize its own output using standard ANSI codes (for example, green for success and red for errors) if you specify -color=auto or -color=always. However, when stdout is a terminal, any output from callbacks will likely just show the raw escape codes, like this..:

e[33;41mWatch out. You're in the production Environmente[0m

…instead of displaying the message in the intended colors.

To get around this problem, we will have the callback save the information as a tiny PowerShell script (current.ps1), which you run after Flyway finishes its info command. That script can safely take over the console and display a big, bold message. The advantage of saving a script is that you can put anything you like in it: a flashing warning, a bell sound…even distant screams if you’re making a change to Production.

Bringing it all together

Here’s how all the pieces fit together:

How to get color-coded Flyway messages per environment

(1) When executing Flyway interactively, from the console or more likely from a bash or PowerShell ‘driver’ script, we start by instructing Flyway to run a harmless command like info, and then our driver script immediately executes the saved script that will color code Flyway’s output messages.

(2) Behind the scenes, Flyway triggers our beforeConnect callback, which reads the environment placeholders in our TOML config file, constructs them into a color-coded message and saves the code as a tiny PowerShell script (.\reports\current.ps1), which will look something like this:

Note that Flyway makes all placeholder values available to callbacks as environment variables, using the pattern FP__<placeholder_name>, where dots are replaced with double underscores. For example, placeholders.projectName becomes FP__projectName__.

(3) After Flyway finishes running the callback and the info command, our driver script executes current.ps1 and this displays the big, colorful “HEY, THIS IS PRODUCTION!” (or Staging/Dev) message. Because this runs outside Flyway itself, it can safely take over the console.

So, let’s see it in action.

The demo

Enough theory. Here’s how it looks in practice.

The environment placeholders

Here’s an example of an extended staging environment called PubsStaging, showing how I use these placeholders to extend the definition of my Staging environment. I’ve used resolvers for the secrets, so this can be done safely in the project TOML file.

I’ve used the dotted notation to emphasize the fact that the Flyway and placeholder namespaces are within the environments namespace. My aim with the placeholders is just to have a nice informative message. No animated Gif or sounds.

This works fine, but if you want to keep connection details separate from Flyway-specific overrides, you can use the more conventional TOML layout with [environments.<name>.flyway].

The beforeConnect callback

Even if we use only a single type of callback (beforeConnect), we’d still need to update it in every project and every branch, each time we modified the color-coding logic. To avoid that maintenance overhead, I keep just a tiny stub (beforeConnect__Announce) in each branch/project. That stub simply calls a shared script containing the actual color‑coding logic.

The beforeConnect__Announce stub

Here’s the minimal beforeConnect__Announce stub:

All it does is check that the shared ColourCode.ps1 script exists, then load it.

The common callback code

By ‘common’ I mean that it is used by all the beforeConnect callbacks, one for each set of migrations you have. This shared script does the real work. It builds a message using placeholders (like the current environment, project name, and branch) and then writes out the tiny PowerShell script that can be executed after Flyway finishes.

The driver script

To demonstrate, here’s a simple driver script that loops through multiple environments defined in a TOML file, runs a harmless info command for each, and then immediately executes the warning script (current.ps1) that our beforeConnect callback generated, so that we see different colored messages each time we switch environments. Once the script completes we can immediately delete it:

And here’s the color-coded output:

A screen shot of a computer program AI-generated content may be incorrect.

Extending the idea

One case my solution doesn’t currently account for is the use of resolvers that change parts of the configuration automatically, such as using a Git resolver, ${git.branch:ad}, in your URL:

In this pattern, the actual database name (and therefore the connection target) changes when you switch Git branches. However, you’re still using the same static dev environment, so the color-coded warning, based on hardcoded placeholders in that environment, won’t reflect the change.

As a result, you could switch from featureA to Integration and still see a “safe” green message, even though you’re now connected to a shared integration database or something more dangerous.

To avoid this, you’d also need to dynamically populate the environment’s placeholders (like currentEnvironment, foregroundColor, etc.) based on the branch name, perhaps by pre-processing your config or using a custom resolver.

Conclusion

Providing a little console color is a low-effort way to prevent high-impact mistakes. It illustrates some of the power of Flyway’s environment configuration feature, and it’s one more example of how Flyway gives you the hooks to build safe, visible, and elegant workflows around database changes with more focused and relevant feedback.

 

Tools in this post

Redgate Flyway

Bring stability and speed to database deployments

Find out more