How to Get Preview Environments for Every Pull Request

Pradumna SarafPradumna Saraf
5 min read

TL;DR

In this article you’ll learn:

  • What preview environments are and how they can help you

  • How to easily set up preview environments

  • How to add this capability to your CI pipeline and get automatically produced environments for every pull request

What is an ephemeral preview environment?

Ephemeral preview environments are production-like environments that are created per commit so that the branch in question can be easily reviewed and tested before it gets merged.

Preview environments enable dev teams to shift the review process to “pre-merge” where it’s easier to identify bugs and avoid the single staging-server roadblock. They give you the ability to “preview” the code changes present in a pull request BEFORE you merge it to master, which is why it’s called “preview environment” or “deploy preview”. Some people prefer to call it an “ephemeral environment” because unlike production environments, it is ephemeral and temporary by design.

You can think of a preview environment as a feature-specific version of the staging or production environment, giving teams the ability to see changes in “live” mode before merging to production. This is a powerful capability that carries many potential benefits.

And with the right tooling, preview environments can be set up to be generated automatically for every pull request, so review cycles can gt started automatically without DevOps backlogs and other human delays.

Sound too good to be true?

It’s not.

And in this article, we’ll show you how you can use Livecycle’s open source tool “Preevy” to easily add preview environments to your workflow.

An easy way to create preview environments

Preevy is a CLI Tool built by Livecycle that is designed to easily provision, manage, and expose ephemeral environments for containerized applications in the cloud.

These environments are inexpensive, easy to integrate, customizable, and accessible for both technical and non-technical users.

It’s simple, flexible, and doesn’t require deep DevOps knowledge, making it ideal for adding preview environments to your “pull/merge request” flows.

terminal gif

Let’s walk through the steps of using Preevy to adding preview environments to your “pull/merge request” workflows.

Prerequisites

Preevy is designed to be easily run in CI/CD workflows, such as GH Actions, Circle CI and others.

The most common use-case for a CI job that runs Preevy is to have a live preview environment for every Pull Request as part of the review process. This allows for more collaborative and inclusive review workflows

Walkthrough: Running Preevy in your GitHub actions CI

In this example, we'll use GitHub Actions CI and AWS Lightsail as a cloud provider.

For GitHub Actions with Google Cloud, see a complete recipe at the livecycle/preevy-gha-gce-demo repo.

1. Install Preevy and create a profile

The Preevy profile provides a mechanism for storing and sharing configuration and state between different machines. This allows sharing of environments between different CI jobs, or different developers. Using the same profile between different CI runs ensures a consistent configuration and allows for stable URLs for your preview environments.

Preevy includes built-in support for saving profiles on AWS S3 and Google Cloud Storage. You can also store the profile on the local filesystem and copy it manually before running Preevy - we won't show this method here.

  • To create the Preevy profile, first install the Preevy CLI locally:
# npm:
npm install -g preevy
# yarn:
yarn add -g preevy
# or use npx to run the CLI without installing it:
npx preevy ...
  • Then, set up a Preevy profile:
preevy init [profile-name]
  • When asked to choose a cloud provider, choose either AWS Lightsail.

You will be asked for the default AWS region in which to create AWS resources.

  • Next, choose where to store your profile.

The profile needs to be stored in the cloud where it can be accessed by your CI machines.

When asked where to store the profile, choose AWS S3. The URL displayed in your terminal should look something like s3://preevy-12345678-my-profile?region=eu-west-1

gif screenshot

  • Note the URL displayed in your terminal - this is the Preevy profile URL which we'll use in the actions below.

2. Make sure GitHub Actions workflows have AWS permissions

In this example, we'll be using the aws-actions/configure-aws-credentials action with GitHub's OIDC provider. Make sure the configured role has the required permissions.

3. Create your GitHub Actions workflows

We'll create two workflows:

The Deploy Preevy environment workflow will create the preview environments when a PR is opened or updated.

The Teardown Preevy environment workflow will bring down the running preview environments when the PR is closed.

  • For the Deploy Preevy environment workflow, create the file preevy-up.yaml in the .github/workflows directory of your repo:
name: Deploy Preevy environment
on:
  pull_request:
    types:
      - opened
      - reopened
      - synchronize

permissions:
  id-token: write
  contents: read

  # Needed to write a PR comment with the environment URLs
  pull-requests: write

jobs:
  deploy:
    timeout-minutes: 15

    # allow a single job to run per PR
    concurrency: preevy-${{ github.event.number }}

    runs-on: ubuntu-latest
    steps:
      - uses: aws-actions/configure-aws-credentials@v2
        with:
          role-to-assume: arn:aws:iam::12345678:role/my-role
          aws-region: eu-west-1

      - uses: actions/checkout@v3

      - uses: livecycle/preevy-up-action@v2.0.0
        id: preevy
        with:
          profile-url: "${{ vars.PREEVY_PROFILE_URL }}"
          docker-compose-yaml-paths: "./docker/docker-compose.yaml"

      # Change `frontend` and `3000` in this step to your main service and port
      # This will appear as the GH environment URL
      - id: store_url
        name: Store URL of frontend
        run: |
          echo url=$(jq -r '.[] | select(.service=="frontend" and .port==3000).url' "${{ steps.preevy_up.outputs.urls-file }}") >> "$GITHUB_OUTPUT"
  • For the Teardown Preevy environment workflow, create the file preevy-down.yaml in the .github/workflows directory of your repo:
name: Teardown Preevy environment
on:
  pull_request:
    types:
      - closed
permissions:
  id-token: write
  contents: read

  # needed to update the PR comment with the environment URLs
  pull-requests: write
jobs:
  teardown:
    runs-on: ubuntu-latest
    steps:
      - uses: aws-actions/configure-aws-credentials@v2
        with:
          role-to-assume: arn:aws:iam::12345678:role/my-role
          aws-region: eu-west-1

      - uses: actions/checkout@v3
      - uses: livecycle/preevy-down-action@v1.1.0
        id: preevy
        with:
          profile-url: "${{ vars.PREEVY_PROFILE_URL }}"
          docker-compose-yaml-paths: "./docker/docker-compose.yaml"

4. Get Automatic GitHub Notifications

You're all set! When you open a PR, Preevy will now build preview environments.

The Preevy Github Plugin will automatically detect the GitHub context and post a comment on your PR with the links to each of the relevant services when they are available for review. Teammates can simply click these links and preview your latest changes in their browser.

Learn more about Livecycle here.

Feel free to star the Preevy repo here.

Good luck!

30
Subscribe to my newsletter

Read articles from Pradumna Saraf directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Pradumna Saraf
Pradumna Saraf

Pradumna is a Developer Advocate, Docker Captain, and a DevOps and Go Developer. He is passionate about Open Source and has mentored hundreds of people to break into the ecosystem. He also creates content on X (formerly Twitter) and LinkedIn, educating others about Open Source and DevOps tools. Pradumna enjoys engaging with people in person and delivering talks.