Skip to content

Create new github action to handle auto creation and destruction of test VMs #6

Create new github action to handle auto creation and destruction of test VMs

Create new github action to handle auto creation and destruction of test VMs #6

name: Create/Destroy Test VM
on:
pull_request:
types: [opened, reopened, synchronize, labeled, unlabeled, closed]
jobs:
create_test_vm:
if: |
(
(
github.event.action == 'opened' ||
github.event.action == 'reopened' ||
github.event.action == 'synchronize'
) && contains(github.event.pull_request.labels.*.name, 'create-test-vm')
) ||
(
github.event.action == 'labeled' &&
github.event.label.name == 'create-test-vm'
)
runs-on: ubuntu-latest
steps:
- name: Checkout files
uses: actions/checkout@v2
- name: Install doctl
uses: digitalocean/action-doctl@v2
with:
token: ${{ secrets.DO_ACCESS_TOKEN }}
- name: Create new droplet
run: |
NEW_DROPLET_NAME=zubhub-test-${{ github.event.pull_request.number }}
echo "NEW_DROPLET_NAME=$(($NEW_DROPLET_NAME))" >> $GITHUB_ENV
# check if droplet already exists and exit script if it does
NEW_DROPLET_IP=$(doctl compute droplet get $NEW_DROPLET_NAME \
--template "{{(index .Networks.V4 1).IPAddress}}")
if [ -n "$NEW_DROPLET_IP" ] ; then
echo "Droplet already exists. Save droplet IP to env variable and exit..."
echo "NEW_DROPLET_IP=$(($NEW_DROPLET_IP))" >> $GITHUB_ENV
exit 1
fi
# create new droplet
doctl compute droplet create $NEW_DROPLET_NAME --image \
${{ secrets.SOURCE_SNAPSHOT_ID }} --tag-name zubhub-test --size s-1vcpu-1gb \
--region nyc1 --enable-monitoring --ssh-keys ${{ secrets.DO_PUBLIC_SSHKEY_FP }} --wait
sleep 30s
echo "NEW_DROPLET_IP=$(doctl compute droplet get $NEW_DROPLET_NAME \
--template "{{(index .Networks.V4 1).IPAddress}}")" >> $GITHUB_ENV
- name: create DNS records
run: |
# we only need records for frontend, media server and api server
FRONTEND_DOMAIN=${{ env.NEW_DROPLET_NAME }}.unstructured.studio
API_DOMAIN=api.${FRONTEND_DOMAIN}
MEDIA_DOMAIN=media.${FRONTEND_DOMAIN}
echo "FRONTEND_DOMAIN=$(($FRONTEND_DOMAIN))" >> $GITHUB_ENV
echo "API_DOMAIN=$(($API_DOMAIN))" >> $GITHUB_ENV
echo "MEDIA_DOMAIN=$(($MEDIA_DOMAIN))" >> $GITHUB_ENV
doctl compute domain records create unstructured.studio --record-type A --record-name \
${{ env.FRONTEND_DOMAIN }} --record-data ${{ env.NEW_DROPLET_IP }} --record-ttl 60
doctl compute domain records create unstructured.studio --record-type A --record-name \
${{ env.API_DOMAIN }} --record-data ${{ env.NEW_DROPLET_IP }} --record-ttl 60
doctl compute domain records create unstructured.studio --record-type A --record-name \
${{ env.MEDIA_DOMAIN }} --record-data ${{ env.NEW_DROPLET_IP }} --record-ttl 60
- name: Copy file via scp
uses: appleboy/scp-action@master
with:
host: ${{ env.NEW_DROPLET_IP }}
username: ${{ secrets.DO_BACKEND_USERNAME }}
key: ${{ secrets.DO_SSHKEY }}
source: "."
target: "/home/zubhub"
- name: Executing remote command
uses: appleboy/ssh-action@master
with:
host: ${{ env.NEW_DROPLET_IP }}
username: ${{ secrets.DO_BACKEND_USERNAME }}
key: ${{ secrets.DO_SSHKEY }}
script: |
# create env file for backend
cat << EOF > /home/zubhub/zubhub_backend/.env
ENVIRONMENT=production
DEFAULT_FRONTEND_DOMAIN=${{ env.FRONTEND_DOMAIN }}
DEFAULT_BACKEND_DOMAIN=${{ env.API_DOMAIN }}
DEFAULT_DISPLAY_NAME=ZubHub
DEFAULT_FRONTEND_PROTOCOL=https
DEFAULT_BACKEND_PROTOCOL=https
SECRET_KEY=random string
DEBUG=1
STORE_MEDIA_LOCALLY=1
MEDIA_SECRET=random string
DEFAULT_MEDIA_SERVER_PROTOCOL=https
DEFAULT_MEDIA_SERVER_DOMAIN=${{ env.MEDIA_DOMAIN }}
POSTGRES_NAME=postgres
POSTGRES_USER=postgres
POSTGRES_PASSWORD=postgres
POSTGRES_HOST=db
GF_ADMIN_USER=admin
GF_ADMIN_PASSWORD=admin
RABBITMQ_DEFAULT_USER=admin
RABBITMQ_DEFAULT_PASS=admin
CELERY_BROKER=amqp://admin:admin@rabbitmq:5672/
CELERY_BACKEND=django-db
CELERY_FLOWER_USER=admin
CELERY_FLOWER_PASSWORD=admin
PROXY_COUNT=0
DETECT_MISCONFIG=0
SUPERUSER_PASSWORD=dummy_password
EOF
# create env file for frontend
cat << EOF > /home/zubhub/zubhub_frontend/zubhub/.env
REACT_APP_NODE_ENV=production
REACT_APP_BACKEND_DEVELOPMENT_URL=
REACT_APP_BACKEND_PRODUCTION_URL=https://${{ env.API_DOMAIN }}
REACT_APP_DOSPACE_ACCESS_KEY_ID=
REACT_APP_DOSPACE_ACCESS_SECRET_KEY=
REACT_APP_VIDEO_UPLOAD_URL=
REACT_APP_VIDEO_FOLDER_NAME=videos
REACT_APP_DEV_VIDEO_FOLDER_NAME=dev_videos
REACT_APP_VIDEO_UPLOAD_PRESET_NAME=video_upload_preset
REACT_APP_DEV_VIDEO_UPLOAD_PRESET_NAME=dev_video_upload_preset
EOF
# deploy project
sudo bash /home/zubhub/deploy_unscalable_fullstack.sh
destroy_test_vm:
if: |
github.event.action == 'closed' || (
github.event.action == 'unlabeled' && github.event.label.name == 'create-test-vm'
)
runs-on: ubuntu-latest
steps:
- name: Install doctl
uses: digitalocean/action-doctl@v2
with:
token: ${{ secrets.DO_ACCESS_TOKEN }}
- name: Get pr number
run: |
# for events like unlabelled, github.event.pull_request.number is available
if [ -n ${{ github.event.pull_request.number }} ] ; then
echo "PR_NUMBER=${{ github.event.pull_request.number }}" >> $GITHUB_ENV
exit 1
fi
# github.event.pull_request.number is not available in closed event
sudo apt-get install jq -y
PR_NUMBER=$(curl --silent --show-error -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
https://api.github.com/repos/${{ github.repository }}/commits/${{ github.sha }}/pulls | \
jq -r '.[0].number')
echo "PR_NUMBER=$(($PR_NUMBER))" >> $GITHUB_ENV
- name: Delete test droplet
run: |
NEW_DROPLET_NAME=zubhub-test-${{ env.PR_NUMBER }}
echo "NEW_DROPLET_NAME=$(($NEW_DROPLET_NAME))" >> $GITHUB_ENV
doctl compute droplet delete ${{ env.NEW_DROPLET_NAME }} --force
- name: delete DNS records
run: |
FRONTEND_DOMAIN=${{ env.NEW_DROPLET_NAME }}.unstructured.studio
API_DOMAIN=api.${FRONTEND_DOMAIN}
MEDIA_DOMAIN=media.${FRONTEND_DOMAIN}
echo "FRONTEND_DOMAIN=$(($FRONTEND_DOMAIN))" >> $GITHUB_ENV
echo "API_DOMAIN=$(($API_DOMAIN))" >> $GITHUB_ENV
echo "MEDIA_DOMAIN=$(($MEDIA_DOMAIN))" >> $GITHUB_ENV
doctl compute domain records delete unstructured.studio --record-name \
${{ env.FRONTEND_DOMAIN }}
doctl compute domain records delete unstructured.studio --record-name \
${{ env.API_DOMAIN }}
doctl compute domain records delete unstructured.studio --record-name \
${{ env.MEDIA_DOMAIN }}