Creating Per-Pull Request Environments on Digital Ocean's App Platform With Github Actions
Below is a quick template I use when deploying new static site apps to Digital Ocean App Platform. This quickly sets up auto-deploying staging environments for each PR opened to the main branch.
Some limitations:
- The
create_review_app
step triggers the initial build on App Platform, but returns while the app is still building. An improvement would be to poll DO to see when the app is finished building. Ideally, we would then add a comment to the open PR with build url. - As of today, creating build notification alerts via the doctl command line is incomplete. You can turn alerts on or off, but you cannot specify the type (email, slack) or configure it further (select a specific slack chat or email).
name: Deploy Review App to DO App Platform
on:
# only run this workflow on pull request events
pull_request:
# Since DO Apps auto build on new push once an app is created, the synchronize type is not needed
types: [opened, reopened, closed, labeled]
branches:
- main
env:
APP_NAME: my-app-name-pr-${{github.event.pull_request.number}}
jobs:
create_review_app:
runs-on: ubuntu-latest
# only run when a pull request label of build is added
if: github.event.action == 'labeled' && github.event.label.name == 'build'
# Alternatively, you can run this action when a pull request is opened
# if: github.event_name == 'pull_request' && github.event.action != 'closed'
steps:
- name: Cloning repo
uses: actions/checkout@v2
- name: Install doctl
uses: digitalocean/action-doctl@v2
with:
token: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }}
- name: create-json
id: create-json
uses: jsdaniell/create-json@1.1.2
with:
name: "app_spec.json"
json: >
{
"name": "${{env.APP_NAME}}",
"region": "nyc",
"envs": [
{
"key": "REACT_APP_API_URL",
"scope": "RUN_AND_BUILD_TIME",
"value": "my build secret"
}
],
"static_sites": [
{
"build_command": "npm install && npm run build",
"catchall_document": "index.html",
"environment_slug": "node-js",
"github": {
"branch": "${{ github.event.pull_request.head.ref }}",
"deploy_on_push": true,
"repo": "cfu288/my-app-name"
},
"name": "${{env.APP_NAME}}",
"routes": [
{
"path": "/"
}
],
"source_dir": "/"
}
]
}
- name: Create review app
id: create-review-app
run: >
doctl apps create --spec app_spec.json
- name: Comment on PR
uses: unsplash/comment-on-pr@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
msg: Review app ${{ env.APP_NAME }} is currently being created 🚀. Check out https://cloud.digitalocean.com/apps to see if it has been deployed.
check_for_duplicate_msg: false # OPTIONAL
destroy_review_app:
runs-on: ubuntu-latest
# only run when a pull request is closed
if: github.event_name == 'pull_request' && github.event.action == 'closed'
steps:
- name: Install doctl
uses: digitalocean/action-doctl@v2
with:
token: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }}
- name: Get app id
id: get-app-id
run: |
echo "::set-output name=appid::$(doctl apps list -o json | jq '.[] | select(.spec.name=="${{env.APP_NAME}}")' | jq '.id')"
- name: Destroy review app
run: >
doctl apps delete --force ${{steps.get-app-id.outputs.appid}}
- name: Comment on PR
uses: unsplash/comment-on-pr@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
msg: Review app ${{ env.APP_NAME }} has been destoyed 🗑️.
check_for_duplicate_msg: false # OPTIONAL