Create Preview Environments from your GitHub pipeline
Preview Environments are dynamic environments, short-lived and disposable, created specifically for a given feature, so:
- testing can be performed in isolation and in parallel, before merging
- feedback can be given by any person within the team.
The easiest way to create environments is to use an Environments-as-a-Service platform to handle the orchestration, Bunnyshell.
Contents of this article
This article showcases how you can integrate Preview Environments in a Github workflow, by using GitHub Actions and the Bunnyshell CLI. We will go through the lifecycle of a Preview Environment and see how it gets:
- created
- stopped
- started
- deleted
In a previous article, we also explored how you can achieve 1-click Preview Environments by leveraging Bunnyshell’s integration with GitHub, with no need to configure anything on the repository side.
Also, if you want to find out more about the encompassing concept of Environments-as-a-Service (or EaaS), you can explore this EaaS introductory article. In short, EaaS helps software development teams easily create environments, so their working paradigm changes for the better, as they can now use short-lived, disposable environments in a reproducible manner.
Real-world Example
How Sylius Creates Automatic Preview Environments
Sylius is a popular Open Source Headless eCommerce Platform for mid-market and enterprise brands that need custom solutions, used by more than 7k merchants. GitHub numbers confirm its popularity: 7.6k stars and 2.1k forks.
They use Bunnyshell to create a dedicated isolated environment for each Pull Request, used for:
- Code reviews with a running application
- Testing features and fixes
- Getting feedback from the community
Each Pull Request creates a dedicated environment, which will be stopped automatically after 4 hours, but can be started again through just a simple comment in the Pull Request, with the text /bns:start
. Upon merging or closing the Pull Request, the environment is automatically deleted, to free up resources.
By opening the URL for the php
component, from the GitHub Pull Request comment posted by Bunnyshell, you will be able to see the replica of the Sylius project, having included changes from the source branch, and running with its separate database and file storage.
This is achieved by defining some GitHub workflows, which in turn leverage some reusable GitHub workflows created and maintained by Bunnyshell.
See the workflows in action
To keep things as simple as possible, we will look at a very simple demo repository.
Triggering the automatic creation and deployment of a new environment is done by a Github workflow defined in the repository, in the file located at .github/workflows/bunnyshell_deploy-preview-env.yaml
.
name: Bunnyshell - Deploy Preview Environment
on:
pull_request:
types: [ opened, reopened, synchronize ]
branches:
- '*'
paths-ignore:
- "*.md"
issue_comment:
types: [ created, edited ]
jobs:
deploy:
name: Deploy Environment
uses: bunnyshell/workflows/.github/workflows/prepare-and-deploy-env.yaml@v2
with:
pr-number: ${{ github.event.number || github.event.issue.number }}
git-ref: refs/pull/${{ github.event.number || github.event.issue.number }}/head
allowed-users: ${{ vars.BUNNYSHELL_ALLOWED_USERS }}
restricted-files: |
.bunnyshell/*
project-id: ${{ vars.BUNNYSHELL_PROJECT_ID }}
cluster-id: ${{ vars.BUNNYSHELL_CLUSTER_ID }}
env-name: "Demo PR #${{ github.event.number || github.event.issue.number }}"
bunnyshell-yaml-path: .bunnyshell/templates/preview/bunnyshell.yaml
comment-on-pr: true
deploy-as-stopped: false
secrets:
bunnyshell-access-token: ${{ secrets.BUNNYSHELL_ACCESS_TOKEN }}
You need to define 4 parameters to instruct Bunnyshell on where to create and deploy the environment:
- the access token for Bunnyshell (as a secret) — after logging in to Bunnyshell, click Profile > Access token and copy that value; or simply open this link.
- the Bunnyshell Project ID — public ID, like
ezXJKO6a43
- the Kubernetes Cluster ID — public ID, like
7A4GeLx3bk
- the list of users allowed to deploy environments with different configurations — either
*
for all users, or a JSON list for specific users, like.["githubUsername1", "githubUsername2"]
Next, we will go through the lifetime of a Preview Environment, to see how you can use one.
1. Create the Pull Request — and the environment
When creating a Pull Request, the deploy action will be triggered.
A comment will appear regarding the real-time status of the operation: first, it will announce that a Preview Environment will be created, then it will add URLs pointing to Bunnyshell, to see the environment and its current-running pipeline.
Opening the Bunnyshell URLs, you will be able to see the environment and its pipeline, with real-time build & deployment logs.
Finally, once the environment deployment is finished, you will be able to:
- open application URLs from the Pull Request comment
- see the completed pipeline’s logs
- control the environment directly from the Pull Request, by leaving a comment to stop, start, deploy, or delete the environment
The environment page from Bunnyshell will also get updated and opening the frontend application will allow you to see the working application and preview the backend-made changes (adding the ID to the book title).
2. Stop the environment
Stopping the environment is as simple as leaving a comment in the Pull Request with the message /bns:stop
. You will see the Bunnyshell comment being updated with the message that the environment was stopped.
3. Start the environment
Starting the environment is as simple as leaving a comment in the Pull Request with the message /bns:start
. You will see the Bunnyshell comment being updated with the message that the environment is deployed, and the application URLs.
4. Merge or Close the Pull Request — and delete the environment
An environment is no longer needed for a Pull Request if it is no longer open (was either merged or closed), so Bunnyshell will delete the associated environment as well.
The same outcome of deleting the environment can also be achieved manually, by leaving a comment with the text /bns:delete
.
Practical scenarios
Below, we will briefly see a few common use cases.
A. Prevent auto-deployment when modifying impactful files
When changing sensitive files, such as the environment definition (bunnyshell.yaml
) itself, or other infrastructure-related configuration files, credentials, etc, you probably want to prevent auto-deployment and require manual approval from a trusted user.
The workflows define two properties that help with this: restricted-files
and allowed-users
.
Upon detecting changes in the restricted files list (or pattern list), the automatic deployment is halted, and a manual comment is required to continue, from one of the users in the allowed-users
property.
After leaving a comment with the text /bns:deploy
(by one of the allowed users) the deployment will pass the verification stage and happen as any other deployment.
B. Troubleshoot a failed deployment
Whenever a deployment fails, you will also see this in the Pull Request comment, along with the links to the Bunnyshell environment and logs.
Opening the logs will reveal the failed job, and failed step within the job. In this case, the new Dockerfile does not exist, but any other error will be revealed the same way.
C. Create environments as stopped to save compute resources
If pickup times for Code Reviews or testing are long, you don’t want to have the compute resources reserved for these Preview Environments. A deploy-as-stopped
parameter exists, which will essentially perform a stop after the deployment has been completed successfully.
Starting the environments is considerably faster than a build + deploy workflow — in the tens of seconds, compared to minutes when building and deploying.
This is what an environment looks like after being deployed with thedeploy-as-stopped: true
parameter. It is very similar to the “deployed” comment — it just adds another URL to the stop’s pipeline logs.
To start the environment, simply leave a comment in the Pull Request with the text /bns:start
.
And the environment will be up and running in less than a minute.
D. Handle public repositories and fork-based workflows
For public repositories, the GitHub token injected in the forked repo when cloning the repository has read-only permissions, meaning it cannot post Pull Request comments.
For this reason, the workflow must be split into 2 parts, but fortunately, the demo repository contains an example for this scenario as well:
Conclusion
I hope you found the concept of Preview Environments useful, and that seeing a concrete implementation based on pipelines gave you a few ideas on how you could benefit from using them, either in code reviews, manual/automated testing, or improving collaboration.