Running MailHog in Github Actions

For the impatient:

# .github/workflows/test.yml
    name: Test
    runs-on: ubuntu-latest
      # ...
      - name: Install & Run MailHog
        run: >
          wget -q
          && sudo chmod +x MailHog_linux_amd64
          && ./MailHog &
      # ...

The step consistently takes <1s to run and gives you a MailHog SMTP+API server running with default configuration (SMTP on localhost:1025 and the HTTP API on localhost:8025).

The Motivation

MailHog has been my go-to SMTP server for local development. It has a few features that have consistently made it invaluable:

  1. It's installable as a single, standalone, binary - i.e., I don't need to run Docker, Python, Java, etc. to use it

  2. The web UI is essentially a stripped-down inbox, allowing you to see mail as it is likely to be seen by the user

  3. Messages are logged to the console by default, which is invaluable for troubleshooting templates and attachments

  4. You can make it do odd things with the Chaos Monkey, and test your code against real-enough SMTP failures

  5. The API enables programmatic inspection of mail after it has been sent (hint, perhaps a useful feature in CI/CD tests)

Instead of having to worry about having a different SMTP sink for use in testing, I wanted to get MailHog working in GitHub actions. Therefore, no need to learn how to configure a different tool or rewrite tests that depend on the MailHog API.

Unfortunately, Googling "MailHog in GitHub actions" didn't yield anything useful. The top result was just a link to the actions page for MailHog, which is empty.

What Didn't Work

Scrolling down a little further in the results, the most obvious answer seems to be to follow the installation instructions for MailHog - e.g., something like:

sudo apt-get -y install golang-go
go install

This should work but seems to only make it halfway through the install step when the action is run on GitHub. I gave up troubleshooting once I realized my local approach is probably the best option for CI/CD as well - use the standalone binary.

The Solution

Ultimately, I implemented the snippet at the start of the article - explained here:

# Download the appropriate binary from releases on GitHub
wget -q

# Make the binary executable
sudo chmod +x MailHog_linux_amd64

# Execute and send to the background (the `&` is the background part)
./MailHog &

The server stays running until the test machine is torn down by GitHub after your test steps are completed.

Of course, you can configure MailHog as you like, either with command line arguments or by interacting with it through the API - e.g.:

# Bind the SMTP service to port 465 instead of the default 1025
./MailHog -smtp-bind-addr

Anyways - this setup is working great to test a single-file backend that I've been working on. I hope you get some great mileage as well!

Further Reading