fly-pr-review-apps
action, which will create and deploy our Django project with changes from the specific
pull request. It will also destroy it when it’s no longer needed, such as after closing
or merging a pull request. The entire staging process enclosed in one GitHub action, so
we don’t have to worry about anything else (NoOps).
Basic flow
GitHub action workflows are defined by YAML files in the.github/workflows/ directory of our repository. Let’s add a new flow that will
create and deploy staging environment for each pull request. But first we need to create
a new repository secret called FLY_API_TOKEN to use for authentication. Go to a GitHub
repository page and open:
Settings (tab) → Security → Secrets and variables → Actions → Repository secrets → New repository secret
next, create a new secret called FLY_API_TOKEN with a value from:
It’s also possible to create a token from the organization dashboard, under the “Tokens” tab.
.github/workflows/fly_pr_preview.yml file:
on → pull_request → types: specifies events on which a new staging project will be deployed:
concurrency: prevents concurrent deploys for the same PR (Pull Request). Thegroupname contains a PR number and workflow name to create a separate group for each workflow and PR:
env: makes theFLY_API_TOKENsecret available to use for authentication:
jobs → preview-app → if: skips deploy on PRs without the PR preview app label. Both for safety reasons and to avoid creating a staging environments when no needed:
jobs → preview-app → environment: describes the deployment target to show up in a pull request UI.steps.deploy.outputs.urlis filled by thesuperfly/fly-pr-review-appsand will contain the URL of a deployed staging project:
jobs → preview-app → steps → with: specifies all inputs that we want to pass to our flow. You can check available options in the README. We pass the Fly.io region and organization as a starting point:
pr-{{ PR number }}-{{ repository owner }}-{{ repository name }}https://{{ app name }}.fly.dev, e.g.
https://pr-9-felixxm-fly-pr-preview-example.fly.dev/pr-preview-example).
Using Postgres cluster
Using a dedicated staging database is a good practice for test environments. This gives us more control and appropriate separation from the production environment which eliminates a potential data leak vector. If you don’t have a Postgres cluster specifically for testing purposes you can create one withfly postgres create:
jobs → preview-app → steps → with)
using the postgres input:
DATABASE_URL environment variable available in the test
VM.
Additional release steps
For performing additional release steps when deploying our staging environment, we can use a custom Fly.io TOML configuration file dedicated for staging with a release script to run before a deployment. First, make a copy of an existing configuration:staging/post_deploy.sh) to prepare our staging database:
release_command to the TOML configuration calling our script:
jobs → preview-app → steps → with) using the config input:
release_command is run on a temporary VM and cannot modify the
local storage or state. It’s fine to run database operations but not to perform release
steps that attempt to modify a local storage, e.g. collecting static files. Such steps
should be added to the Dockerfile. For example, if we want to collect static files,
then add the collectstatic management command to the Dockerfile: