Deploy a Preview Environment (AKA "Ephemeral Environment") for every pull request. Supports APIs, frontends, backends, databases, microservices, binaries and command-line tools.
Uffizzi integrates as a step in your GitHub Actions pipeline to manage on-demand, ephemeral test environments for every feature branch/pull request. Preview Environments are deployed on Uffizzi Cloud (SaaS) or your own installation of open-source Uffizzi (self-hosting requires Kubernetes).
We've published a Reusable Workflow for your GitHub Actions. This can handle creating, updating, and deleting Uffizzi Preview Environments. It will also publish Preview Environment URLs as a comment to your pull request issues.
💡 We recommend using this reusable workflow instead of using the individual actions for create, update, and delete.
uses: UffizziCloud/preview-action/.github/workflows/reusable.yaml@v2
if: ${{ github.event_name == 'pull_request' && github.event.action != 'closed' }}
with:
compose-file-cache-key: ${{ needs.render-compose-file.outputs.compose-file-cache-key }}
compose-file-cache-path: ${{ needs.render-compose-file.outputs.compose-file-cache-path }}
server: https://app.uffizzi.com/
This example builds and publishes an image to Docker Hub for pull request events. It then renders a Docker Compose file from a template and caches it. Finally, it calls the reusable workflow to create, update, or delete the Preview Environment associated with the pull request.
name: Build Images and Handle Uffizzi Previews.
on:
pull_request:
types: [opened,reopened,synchronize,closed]
jobs:
build-image:
name: Build and Push image
runs-on: ubuntu-22.04
outputs:
# You'll need this output later to render the Compose file.
tags: ${{ steps.meta.outputs.tags }}
steps:
- name: Login to DockerHub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}
- name: Checkout git repo
uses: actions/checkout@v3
- name: Docker metadata
id: meta
uses: docker/metadata-action@v3
with:
images: example/image
- name: Build and Push Image to Docker Hub
uses: docker/build-push-action@v2
with:
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
render-compose-file:
name: Render Docker Compose File
runs-on: ubuntu-22.04
needs:
- build-image
outputs:
compose-file-cache-key: ${{ steps.hash.outputs.hash }}
compose-file-cache-path: docker-compose.rendered.yml
steps:
- name: Checkout git repo
uses: actions/checkout@v3
- name: Render Compose File
run: |
IMAGE=$(echo ${{ needs.build-image.outputs.tags }})
export IMAGE
# Render simple template from environment variables.
envsubst < docker-compose.template.yml > docker-compose.rendered.yml
cat docker-compose.rendered.yml
- name: Hash Rendered Compose File
id: hash
run: echo "::set-output name=hash::$(md5sum docker-compose.rendered.yml | awk '{ print $1 }')"
- name: Cache Rendered Compose File
uses: actions/cache@v3
with:
path: docker-compose.rendered.yml
key: ${{ steps.hash.outputs.hash }}
deploy-uffizzi-preview:
name: Use Remote Workflow to Preview on Uffizzi
needs: render-compose-file
uses: UffizziCloud/preview-action/.github/workflows/reusable.yaml@v2
if: ${{ github.event_name == 'pull_request' && github.event.action != 'closed' }}
with:
compose-file-cache-key: ${{ needs.render-compose-file.outputs.compose-file-cache-key }}
compose-file-cache-path: ${{ needs.render-compose-file.outputs.compose-file-cache-path }}
server: https://app.uffizzi.com/
permissions:
contents: read
pull-requests: write
id-token: write
delete-uffizzi-preview:
name: Use Remote Workflow to Delete an Existing Preview
uses: UffizziCloud/preview-action/.github/workflows/reusable.yaml@v2
if: ${{ github.event_name == 'pull_request' && github.event.action == 'closed' }}
with:
compose-file-cache-key: ''
compose-file-cache-path: docker-compose.rendered.yml
server: https://app.uffizzi.com/
permissions:
contents: read
pull-requests: write
id-token: write
(Required) Key of hashed compose file, using GitHub's cache
action
Note that if this is an emtpy string, the reusable workflow will delete the preview associated with this Pull Request.
(Required) Path of hashed compose file, using GitHub's cache
action
(Required) https://app.uffizzi.com/
or the URL of your Uffizzi installation
(Optional) If you're calling this workflow from a workflow that's not triggered by pull_request
, you may want to specify the PR number here.
(Optional) If you're calling this workflow from a workflow that's not triggered by pull_request
, you may want to specify the branch or other git reference here.
(Optional) If you're controlling access to the URLs of your Preview Environments, set the credentials here so the workflow can confirm successful deployment.
URL path that will be appended to the preview URL where the reusable workflow will check for the health of the preview. URL path has to start with /
. Use this if the root URL of your application does not return an HTTP response code below 400.
If specified, this text string will be added to each comment this workflow makes on the pull request issue. The default is a link to learn more about Uffizzi.
If you're using the reusable workflow with Uffizzi Cloud, an account and project will be created from your GitHub user and repository information when the workflow runs. If you're self-hosting open-source Uffizzi, you will need to create a Uffizzi user and project before running the workflow, then set username
, password
, and project
inputs, where project
is the Uffizzi project slug.
uses: UffizziCloud/preview-action@v2
with:
compose-file: 'docker-compose.uffizzi.yaml'
server: 'https://app.uffizzi.com'
secrets:
access-token: ${{ secrets.GITHUB_TOKEN }}
url-username: admin
url-password: ${{ secrets.URL_PASSWORD }}
permissions:
contents: read
pull-requests: write
id-token: write
uses: UffizziCloud/preview-action@v2
with:
compose-file: 'docker-compose.uffizzi.yaml'
server: 'https://uffizzi.example.com'
username: 'j.doe@example.com'
password: ${{ secrets.UFFIZZI_PASSWORD }}
project: 'default'
permissions:
contents: read
pull-requests: write
id-token: write
If you wish to use this action by itself outside of the reusable workflow described above, you can. It will only create new previews, not update nor delete them.
(Required) Path to a compose file within your repository
(Required) https://app.uffizzi.com/
or the URL of your Uffizzi installation
(Self-hosted only) Uffizzi username
(Self-hosted only) Your Uffizzi password, specified as a GitHub Secret
(Self-hosted only) Uffizzi project slug
(Optional) The value of the ${{ secrets.GITHUB_TOKEN }}
. Used to avoid hitting the Github request rate limit.
Your GitHub username and the value of a Github personal access token with access to the read:packages
scope.
This option is provided as a convenience to get started quickly. For sensitive repositories, we recommend instead connecting your Uffizzi account to GHCR via the web interface or by executing uffizzi connect ghcr
from a trusted environment.
Your DockerHub username and password.
Your Azure Container Registry url, username and password.
Your Amazon Web Services registry url, access key id and secret access key.
Your Google Cloud service key.
Your custom docker registry url, username and password.
uses: UffizziCloud/preview-action@v2
with:
compose-file: 'docker-compose.uffizzi.yaml'
username: 'admin@uffizzi.com'
server: 'https://app.uffizzi.com'
project: 'default'
password: ${{ secrets.UFFIZZI_PASSWORD }}
permissions:
contents: read
pull-requests: write
id-token: write
If you don't have a Uffizzi account, leave the username, password and project inputs blank. Uffizzi will create a Uffizzi account based on the information about the current repository and Github user.
Example usage without an account:
uses: UffizziCloud/preview-action@v2
with:
compose-file: 'docker-compose.uffizzi.yaml'
server: 'https://app.uffizzi.com'
permissions:
contents: read
pull-requests: write
id-token: write