From f30eb9d99e786814bc208ad4644606b2ed022e1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B4=CF=85=CF=82?= Date: Sun, 6 Feb 2022 07:52:26 -0500 Subject: [PATCH] Break GitHub Deployment Action Into Jobs (#1103) --- .github/workflows/PR-CI.yml | 50 --- .github/workflows/gcp-deploy.yaml | 521 ++++++++++++++++++---- README.md | 2 +- guides/BACKEND.md | 2 +- hasura/{seed-local-db.mjs => seed-db.mjs} | 24 +- package.json | 2 +- 6 files changed, 439 insertions(+), 162 deletions(-) rename hasura/{seed-local-db.mjs => seed-db.mjs} (89%) diff --git a/.github/workflows/PR-CI.yml b/.github/workflows/PR-CI.yml index 033479c8..51b8adb0 100644 --- a/.github/workflows/PR-CI.yml +++ b/.github/workflows/PR-CI.yml @@ -49,53 +49,3 @@ jobs: run: yarn test --ci --coverage env: CI: true - - build: - name: Build - runs-on: ubuntu-latest - - steps: - - name: Cancel Previous Runs - uses: styfle/cancel-workflow-action@0.4.0 - with: - access_token: ${{ github.token }} - - - uses: actions/checkout@v2 - - - uses: actions/setup-node@v1 - with: - node-version: 16.x - - - uses: actions/cache@v2 - with: - path: '**/node_modules' - key: nodeModules-${{ runner.os }}-${{ hashFiles('**/yarn.lock') }} - - - name: Install packages - run: yarn --frozen-lockfile - env: - CI: true - - - name: Build Backend - run: yarn backend:build - env: - CI: true - - # Spin up the backend / hasura / DB for the web build to point to - - name: Run docker-compose - run: docker-compose up --build -d - env: - DATABASE_USER: metagame - DATABASE_PASSWORD: postgres - DATABASE_DB: metagame-db - HASURA_GRAPHQL_ADMIN_SECRET: so-secretish - HASURA_PORT: 8080 - - - name: Wait for Hasura - run: yarn wait-on --timeout 60000 http-get://localhost:8080/healthz || (docker-compose ps hasura && docker-compose logs --tail 20 hasura) - - - name: Build Web - run: yarn web:build - env: - CI: true - NEXT_PUBLIC_GRAPHQL_URL: http://localhost:8080/v1/graphql diff --git a/.github/workflows/gcp-deploy.yaml b/.github/workflows/gcp-deploy.yaml index 485a3afa..363983b2 100644 --- a/.github/workflows/gcp-deploy.yaml +++ b/.github/workflows/gcp-deploy.yaml @@ -19,186 +19,513 @@ env: BACKEND_PORT: 4000 HASURA_PORT: 8080 FRONTEND_PORT: 3000 + HASURA_SECRET: metagame_secret jobs: - build-and-deploy: - name: Build and Deploy + start-deployment: + name: Generate Deployment Start Message + runs-on: ubuntu-latest + + outputs: + deployment_id: ${{steps.create-message.outputs.deployment_id}} + + steps: + - name: Start Deployment + uses: bobheadxi/deployments@v0.6.2 + id: create-message + with: + step: start + token: ${{github.token}} + env: test + desc: | + "Test instance deployment for PR #${{github.event.number}} \ + of ${{github.event.pull_request.head.label}} \ + by ${{github.event.pull_request.user.login}}" + ref: ${{github.event.pull_request.head.sha}} + + cancel-previous: + name: Cancel Existing Runs runs-on: ubuntu-latest + steps: + - name: Cancel Existing Runs + uses: styfle/cancel-workflow-action@0.4.0 + with: + access_token: ${{github.token}} + + env: + name: Environment Variables + runs-on: ubuntu-latest + needs: [cancel-previous] + + outputs: + PROJECT_ID: ${{env.PROJECT_ID}} + REGISTRY_REGION: ${{env.REGISTRY_REGION}} + REGISTRY_REPO: ${{env.REGISTRY_REPO}} + DEPLOYMENT_DOMAIN: ${{env.DEPLOYMENT_DOMAIN}} + CLOUDRUN_SUFFIX: ${{env.CLOUDRUN_SUFFIX}} + DB_NAME: ${{env.DB_NAME}} + BACKEND_SERVICE: ${{env.BACKEND_SERVICE}} + FRONTEND_SERVICE: ${{env.FRONTEND_SERVICE}} + BACKEND_PORT: ${{env.BACKEND_PORT}} + HASURA_PORT: ${{env.HASURA_PORT}} + FRONTEND_PORT: ${{env.FRONTEND_PORT}} + HASURA_SECRET: ${{env.HASURA_SECRET}} + CLOUDRUN_REGION: ${{steps.first.outputs.CLOUDRUN_REGION}} + CLOUDSQL_INSTANCE_NAME: ${{steps.first.outputs.CLOUDSQL_INSTANCE_NAME}} + CLOUDSQL_CONNECTION_NAME: ${{steps.first.outputs.CLOUDSQL_CONNECTION_NAME}} + HASURA_SERVICE: ${{steps.first.outputs.HASURA_SERVICE}} + DOCKER_REGISTRY: ${{steps.first.outputs.DOCKER_REGISTRY}} + BACKEND_HOST: ${{steps.first.outputs.BACKEND_HOST}} + FRONTEND_URL: ${{steps.first.outputs.FRONTEND_URL}} + DB_PASSWORD: ${{steps.first.outputs.DB_PASSWORD}} + HASURA_HOST: ${{steps.second.outputs.HASURA_HOST}} + DOCKER_PATH: ${{steps.second.outputs.DOCKER_PATH}} + SC_MIGRATE_URL: ${{steps.second.outputs.SC_MIGRATE_URL}} + DB_HOST: ${{steps.second.outputs.DB_HOST}} + GRAPHQL_URL: ${{steps.third.outputs.GRAPHQL_URL}} + BACKEND_TAG: ${{steps.third.outputs.BACKEND_TAG}} + HASURA_TAG: ${{steps.third.outputs.HASURA_TAG}} + FRONTEND_TAG: ${{steps.third.outputs.FRONTEND_TAG}} + steps: - name: First Intepolation of Variables + id: first run: | - echo "CLOUDRUN_REGION=${{env.REGISTRY_REGION}}" >> $GITHUB_ENV - echo "CLOUDSQL_INSTANCE_NAME=${{env.REGISTRY_REPO}}" >> $GITHUB_ENV - echo "CLOUDSQL_CONNECTION_NAME=${{env.PROJECT_ID}}:${{env.REGISTRY_REGION}}:${{env.REGISTRY_REPO}}" >> $GITHUB_ENV - echo "HASURA_SERVICE=${{env.DB_NAME}}" >> $GITHUB_ENV - echo "DOCKER_REGISTRY=${{env.REGISTRY_REGION}}-docker.pkg.dev" >> $GITHUB_ENV - echo "BACKEND_HOST=${{env.BACKEND_SERVICE}}-${{env.CLOUDRUN_SUFFIX}}.${{env.DEPLOYMENT_DOMAIN}}" >> $GITHUB_ENV + echo "::set-output name=CLOUDRUN_REGION::${{env.REGISTRY_REGION}}" + echo "::set-output name=CLOUDSQL_INSTANCE_NAME::${{env.REGISTRY_REPO}}" + echo "::set-output name=CLOUDSQL_CONNECTION_NAME::\ + ${{env.PROJECT_ID}}:${{env.REGISTRY_REGION}}:${{env.REGISTRY_REPO}}" + echo "::set-output name=HASURA_SERVICE::${{env.DB_NAME}}" + echo "::set-output name=DOCKER_REGISTRY::${{env.REGISTRY_REGION}}-docker.pkg.dev" + echo "::set-output name=BACKEND_HOST::\ + ${{env.BACKEND_SERVICE}}-${{env.CLOUDRUN_SUFFIX}}.${{env.DEPLOYMENT_DOMAIN}}" + echo "::set-output name=FRONTEND_URL::\ + https://${{env.FRONTEND_SERVICE}}-${{env.CLOUDRUN_SUFFIX}}.${{env.DEPLOYMENT_DOMAIN}}" + echo "::set-output name=DB_PASSWORD::$(head -c 48 /dev/urandom | tr -cd [:alnum:])" - - name: Those Varaiables May Now Be Interpolated + - name: Those Variables May Now Be Interpolated + id: second run: | - echo "HASURA_HOST=${{env.HASURA_SERVICE}}-${{env.CLOUDRUN_SUFFIX}}.${{env.DEPLOYMENT_DOMAIN}}" >> $GITHUB_ENV - echo "DOCKER_PATH=${{env.DOCKER_REGISTRY}}/${{env.PROJECT_ID}}/${{env.REGISTRY_REPO}}" >> $GITHUB_ENV - echo "SC_MIGRATE_URL=https://${{env.BACKEND_HOST}}/actions/migrateSourceCredAccounts?force=true" >> $GITHUB_ENV - echo "FRONTEND_URL=https://${{env.FRONTEND_SERVICE}}-${{env.CLOUDRUN_SUFFIX}}.${{env.DEPLOYMENT_DOMAIN}}" >> $GITHUB_ENV + echo "::set-output name=HASURA_HOST::\ + ${{steps.first.outputs.HASURA_SERVICE}}-${{env.CLOUDRUN_SUFFIX}}.${{env.DEPLOYMENT_DOMAIN}}" + echo "::set-output name=DOCKER_PATH::\ + ${{steps.first.outputs.DOCKER_REGISTRY}}/${{env.PROJECT_ID}}/${{env.REGISTRY_REPO}}" + echo "::set-output name=SC_MIGRATE_URL::\ + https://${{steps.first.outputs.BACKEND_HOST}}/actions/migrateSourceCredAccounts?force=true" + echo "::set-output name=DB_HOST::\ + /${{env.DB_NAME}}?host=/cloudsql/${{steps.first.outputs.CLOUDSQL_CONNECTION_NAME}}" - - name: And Again In Another Step + - name: And That Result Again In Another Step + id: third run: | - echo "GRAPHQL_URL=https://${{env.HASURA_HOST}}/v1/graphql" >> $GITHUB_ENV - echo "BACKEND_TAG=${{env.DOCKER_PATH}}/backend:pr-${{github.event.number}}" >> $GITHUB_ENV - echo "HASURA_TAG=${{env.DOCKER_PATH}}/hasura:pr-${{github.event.number}}" >> $GITHUB_ENV - echo "FRONTEND_TAG=${{env.DOCKER_PATH}}/frontend:pr-${{github.event.number}}" >> $GITHUB_ENV - echo "DB_PASSWORD=$(cat /dev/urandom | tr -cd [:alnum:] | head -c 16)" >> $GITHUB_ENV + echo "::set-output name=GRAPHQL_URL::\ + https://${{steps.second.outputs.HASURA_HOST}}/v1/graphql" + echo "::set-output name=BACKEND_TAG::\ + ${{steps.second.outputs.DOCKER_PATH}}/backend:pr-${{github.event.number}}" + echo "::set-output name=HASURA_TAG::\ + ${{steps.second.outputs.DOCKER_PATH}}/hasura:pr-${{github.event.number}}" + echo "::set-output name=FRONTEND_TAG::\ + ${{steps.second.outputs.DOCKER_PATH}}/frontend:pr-${{github.event.number}}" - - name: Checkout - uses: actions/checkout@v2 - with: - ref: ${{github.event.pull_request.head.sha}} + delete-db: + name: Delete SQL User & Database + runs-on: ubuntu-latest + needs: [env] - - name: Login to Registry - uses: docker/login-action@v1 - with: - registry: ${{env.DOCKER_REGISTRY}} - username: _json_key - password: ${{secrets.GCP_SA_KEY}} - - - name: Set up gcloud CLI + steps: + - name: Set Up gcloud CLI uses: google-github-actions/setup-gcloud@v0.2.1 with: - project_id: ${{env.PROJECT_ID}} + project_id: ${{needs.env.outputs.PROJECT_ID}} service_account_key: ${{secrets.GCP_SA_KEY}} export_default_credentials: true - - name: Delete Database of Hasura + - name: "Delete SQL User: ${{needs.env.outputs.DB_NAME}}" + continue-on-error: true + run: | + gcloud -q sql users delete ${{needs.env.outputs.DB_NAME}} \ + -i ${{needs.env.outputs.CLOUDSQL_INSTANCE_NAME}} + + - name: "Delete Database: ${{needs.env.outputs.DB_NAME}}" continue-on-error: true run: | wget -q https://dl.google.com/cloudsql/cloud_sql_proxy.linux.amd64 -O cloud_sql_proxy chmod u+x cloud_sql_proxy - ./cloud_sql_proxy -instances ${{env.CLOUDSQL_CONNECTION_NAME}} -dir /tmp/cloudsql & + ./cloud_sql_proxy -instances ${{needs.env.outputs.CLOUDSQL_CONNECTION_NAME}} \ + -dir /tmp/cloudsql & PID=$! sleep 10 - PGPASSWORD=${{secrets.GCP_POSTGRES_PASSWORD}} dropdb -h /tmp/cloudsql/${{env.CLOUDSQL_CONNECTION_NAME}} -U postgres ${{env.DB_NAME}} -f + PGPASSWORD=${{secrets.GCP_POSTGRES_PASSWORD}} \ + dropdb -h /tmp/cloudsql/${{needs.env.outputs.CLOUDSQL_CONNECTION_NAME}} \ + -U postgres ${{needs.env.outputs.DB_NAME}} -f kill $PID - - name: Create User and Database for Hasura + create-db: + name: Create New SQL User & Database + runs-on: ubuntu-latest + needs: [env, delete-db] + + steps: + - name: Set Up gcloud CLI + uses: google-github-actions/setup-gcloud@v0.2.1 + with: + project_id: ${{needs.env.outputs.PROJECT_ID}} + service_account_key: ${{secrets.GCP_SA_KEY}} + export_default_credentials: true + + - name: "Create SQL User: ${{needs.env.outputs.DB_NAME}}" run: | - gcloud -q sql users create ${{env.DB_NAME}} -i ${{env.CLOUDSQL_INSTANCE_NAME}} --password ${{env.DB_PASSWORD}} - gcloud -q sql databases create ${{env.DB_NAME}} -i ${{env.CLOUDSQL_INSTANCE_NAME}} + gcloud -q sql users create ${{needs.env.outputs.DB_NAME}} \ + -i ${{needs.env.outputs.CLOUDSQL_INSTANCE_NAME}} \ + --password ${{needs.env.outputs.DB_PASSWORD}} - - name: Undeploy Backend + - name: "Create Database: ${{needs.env.outputs.DB_NAME}}" + run: | + gcloud -q sql databases create ${{needs.env.outputs.DB_NAME}} \ + -i ${{needs.env.outputs.CLOUDSQL_INSTANCE_NAME}} + + undeploy-backend: + name: Undeploy Backend + runs-on: ubuntu-latest + needs: [env] + + steps: + - name: Set Up gcloud CLI + uses: google-github-actions/setup-gcloud@v0.2.1 + with: + project_id: ${{needs.env.outputs.PROJECT_ID}} + service_account_key: ${{secrets.GCP_SA_KEY}} + export_default_credentials: true + + - name: "Delete Service: ${{needs.env.outputs.BACKEND_SERVICE}}" continue-on-error: true - run: gcloud -q run services delete ${{env.BACKEND_SERVICE}} --region ${{env.CLOUDRUN_REGION}} + run: | + gcloud -q run services delete ${{needs.env.outputs.BACKEND_SERVICE}} \ + --region ${{needs.env.outputs.CLOUDRUN_REGION}} - - name: Delete Backend Image + delete-backend: + name: Delete Backend Container Image + runs-on: ubuntu-latest + needs: [env] + + steps: + - name: "Login to Registry: ${{needs.env.outputs.DOCKER_REGISTRY}}" + uses: docker/login-action@v1 + with: + registry: ${{needs.env.outputs.DOCKER_REGISTRY}} + username: _json_key + password: ${{secrets.GCP_SA_KEY}} + + - name: Set Up gcloud CLI + uses: google-github-actions/setup-gcloud@v0.2.1 + with: + project_id: ${{needs.env.outputs.PROJECT_ID}} + service_account_key: ${{secrets.GCP_SA_KEY}} + export_default_credentials: true + + - name: "Delete Container Image: ${{needs.env.outputs.BACKEND_TAG}}" continue-on-error: true - run: gcloud -q artifacts docker images delete ${{env.BACKEND_TAG}} + run: gcloud -q artifacts docker images delete ${{needs.env.outputs.BACKEND_TAG}} - - name: Build Backend Container + build-backend: + name: Build Backend Container Image + runs-on: ubuntu-latest + needs: [env, delete-backend, undeploy-backend] + + steps: + - name: "Checkout: ${{github.event.pull_request.head.label}}" + uses: actions/checkout@v2 + with: + ref: ${{github.event.pull_request.head.sha}} + + - name: "Build Container Image: ${{needs.env.outputs.BACKEND_TAG}}" uses: mattes/cached-docker-build-action@v1 with: - args: '. -f ./docker/backend/Dockerfile --tag ${{env.BACKEND_TAG}} --build-arg GRAPHQL_URL=${{env.GRAPHQL_URL}}' + args: | + . -f docker/backend/Dockerfile \ + --tag ${{needs.env.outputs.BACKEND_TAG}} \ + --build-arg GRAPHQL_URL=${{needs.env.outputs.GRAPHQL_URL}} cache_key: "${{hashFiles('packages/backend/**')}}" - - name: Push Backend Container - run: docker push ${{env.BACKEND_TAG}} + - name: "Login to Registry: ${{needs.env.outputs.DOCKER_REGISTRY}}" + uses: docker/login-action@v1 + with: + registry: ${{needs.env.outputs.DOCKER_REGISTRY}} + username: _json_key + password: ${{secrets.GCP_SA_KEY}} - - name: Deploy Backend + - name: "Push Container Image: ${{needs.env.outputs.BACKEND_TAG}}" + run: docker push ${{needs.env.outputs.BACKEND_TAG}} + + deploy-backend: + name: Deploy Backend + runs-on: ubuntu-latest + needs: [env, create-db, build-backend] + + steps: + - name: Set Up gcloud CLI + uses: google-github-actions/setup-gcloud@v0.2.1 + with: + project_id: ${{needs.env.outputs.PROJECT_ID}} + service_account_key: ${{secrets.GCP_SA_KEY}} + export_default_credentials: true + + - name: "Deploy Container Image: ${{needs.env.outputs.BACKEND_TAG}}" run: | - gcloud -q run deploy ${{env.BACKEND_SERVICE}} \ - --image ${{env.BACKEND_TAG}} \ - --region ${{env.CLOUDRUN_REGION}} \ - --port ${{env.BACKEND_PORT}} \ + gcloud -q run deploy ${{needs.env.outputs.BACKEND_SERVICE}} \ + --image ${{needs.env.outputs.BACKEND_TAG}} \ + --region ${{needs.env.outputs.CLOUDRUN_REGION}} \ + --port ${{needs.env.outputs.BACKEND_PORT}} \ --cpu 1 \ --memory 512Mi \ --ingress all \ --allow-unauthenticated \ --max-instances 1 \ - --set-env-vars HASURA_GRAPHQL_ADMIN_SECRET=metagame_secret \ + --set-env-vars HASURA_GRAPHQL_ADMIN_SECRET=${{needs.env.outputs.HASURA_SECRET}} \ --set-env-vars GITHUB_API_TOKEN=${{secrets.GH_API_TOKEN}} \ --set-env-vars SOURCECRED_LEDGER_BRANCH=master \ - --set-env-vars GRAPHQL_URL=${{env.GRAPHQL_URL}} + --set-env-vars GRAPHQL_URL=${{needs.env.outputs.GRAPHQL_URL}} - - name: Undeploy Hasura + undeploy-hasura: + name: Undeploy Hasura + runs-on: ubuntu-latest + needs: [env] + + steps: + - name: Set Up gcloud CLI + uses: google-github-actions/setup-gcloud@v0.2.1 + with: + project_id: ${{needs.env.outputs.PROJECT_ID}} + service_account_key: ${{secrets.GCP_SA_KEY}} + export_default_credentials: true + + - name: "Delete Service: ${{needs.env.outputs.HASURA_SERVICE}}" continue-on-error: true - run: gcloud -q run services delete ${{env.HASURA_SERVICE}} --region ${{env.CLOUDRUN_REGION}} + run: | + gcloud -q run services delete ${{needs.env.outputs.HASURA_SERVICE}} \ + --region ${{needs.env.outputs.CLOUDRUN_REGION}} - - name: Delete Hasura Image + delete-hasura: + name: Delete Hasura Container Image + runs-on: ubuntu-latest + needs: [env] + + steps: + - name: "Login to Registry: ${{needs.env.outputs.DOCKER_REGISTRY}}" + uses: docker/login-action@v1 + with: + registry: ${{needs.env.outputs.DOCKER_REGISTRY}} + username: _json_key + password: ${{secrets.GCP_SA_KEY}} + + - name: Set Up gcloud CLI + uses: google-github-actions/setup-gcloud@v0.2.1 + with: + project_id: ${{needs.env.outputs.PROJECT_ID}} + service_account_key: ${{secrets.GCP_SA_KEY}} + export_default_credentials: true + + - name: "Delete Container Image: ${{needs.env.outputs.HASURA_TAG}}" continue-on-error: true - run: gcloud -q artifacts docker images delete ${{env.HASURA_TAG}} + run: gcloud -q artifacts docker images delete ${{needs.env.outputs.HASURA_TAG}} - - name: Build Hasura Container + build-hasura: + name: Build Hasura Container Image + runs-on: ubuntu-latest + needs: [env, delete-hasura, undeploy-hasura] + + steps: + - name: "Checkout: ${{github.event.pull_request.head.label}}" + uses: actions/checkout@v2 + with: + ref: ${{github.event.pull_request.head.sha}} + + - name: "Build Container Image: ${{needs.env.outputs.HASURA_TAG}}" uses: mattes/cached-docker-build-action@v1 with: - args: './hasura -f ./hasura/Dockerfile --tag ${{env.HASURA_TAG}} --build-arg BACKEND_HOST=${{env.BACKEND_HOST}} --build-arg BACKEND_PROTOCOL=https' + args: | + ./hasura -f hasura/Dockerfile \ + --tag ${{needs.env.outputs.HASURA_TAG}} \ + --build-arg BACKEND_HOST=${{needs.env.outputs.BACKEND_HOST}} \ + --build-arg BACKEND_PROTOCOL=https cache_key: "${{hashFiles('hasura/**')}}" - - name: Push Hasura Container - run: docker push ${{env.HASURA_TAG}} + - name: "Login to Registry: ${{needs.env.outputs.DOCKER_REGISTRY}}" + uses: docker/login-action@v1 + with: + registry: ${{needs.env.outputs.DOCKER_REGISTRY}} + username: _json_key + password: ${{secrets.GCP_SA_KEY}} - - name: Deploy Hasura + - name: "Push Container Image: ${{needs.env.outputs.HASURA_TAG}}" + run: docker push ${{needs.env.outputs.HASURA_TAG}} + + deploy-hasura: + name: Deploy Hasura + runs-on: ubuntu-latest + needs: [env, build-hasura, deploy-backend] + + env: + db: ${{needs.env.outputs.DB_NAME}} + pass: ${{needs.env.outputs.DB_PASSWORD}} + host: ${{needs.env.outputs.DB_HOST}} + + steps: + - name: Set Up gcloud CLI + uses: google-github-actions/setup-gcloud@v0.2.1 + with: + project_id: ${{needs.env.outputs.PROJECT_ID}} + service_account_key: ${{secrets.GCP_SA_KEY}} + export_default_credentials: true + + - name: "Deploy Container Image: ${{needs.env.outputs.HASURA_TAG}}" run: | - gcloud -q run deploy ${{env.HASURA_SERVICE}} \ - --image ${{env.HASURA_TAG}} \ - --region ${{env.CLOUDRUN_REGION}} \ - --port ${{env.HASURA_PORT}} \ + gcloud -q run deploy ${{needs.env.outputs.HASURA_SERVICE}} \ + --image ${{needs.env.outputs.HASURA_TAG}} \ + --region ${{needs.env.outputs.CLOUDRUN_REGION}} \ + --port ${{needs.env.outputs.HASURA_PORT}} \ --cpu 1 \ --memory 512Mi \ --ingress all \ --allow-unauthenticated \ - --add-cloudsql-instances ${{env.CLOUDSQL_CONNECTION_NAME}} \ + --add-cloudsql-instances ${{needs.env.outputs.CLOUDSQL_CONNECTION_NAME}} \ --max-instances 1 \ - --set-env-vars HASURA_GRAPHQL_DATABASE_URL=postgres://${{env.DB_NAME}}:${{env.DB_PASSWORD}}@/${{env.DB_NAME}}?host=/cloudsql/${{env.CLOUDSQL_CONNECTION_NAME}} \ - --set-env-vars HASURA_GRAPHQL_ADMIN_SECRET=metagame_secret \ - --set-env-vars HASURA_GRAPHQL_SERVER_PORT=${{env.HASURA_PORT}} \ + --set-env-vars HASURA_GRAPHQL_DATABASE_URL=postgres://${{env.db}}:${{env.pass}}@${{env.host}} \ + --set-env-vars HASURA_GRAPHQL_ADMIN_SECRET=${{needs.env.outputs.HASURA_SECRET}} \ + --set-env-vars HASURA_GRAPHQL_SERVER_PORT=${{needs.env.outputs.HASURA_PORT}} \ --set-env-vars HASURA_GRAPHQL_ENABLE_CONSOLE=true - - name: Undeploy Frontend - continue-on-error: true - run: gcloud -q run services delete ${{env.FRONTEND_SERVICE}} --region ${{env.CLOUDRUN_REGION}} + undeploy-frontend: + name: Undeploy Frontend + runs-on: ubuntu-latest + needs: [env] - - name: Delete Frontend Image - continue-on-error: true - run: gcloud -q artifacts docker images delete ${{env.FRONTEND_TAG}} + steps: + - name: Set Up gcloud CLI + uses: google-github-actions/setup-gcloud@v0.2.1 + with: + project_id: ${{needs.env.outputs.PROJECT_ID}} + service_account_key: ${{secrets.GCP_SA_KEY}} + export_default_credentials: true - - name: Build Frontend Container + - name: "Delete Service: ${{needs.env.outputs.FRONTEND_SERVICE}}" + continue-on-error: true + run: | + gcloud -q run services delete ${{needs.env.outputs.FRONTEND_SERVICE}} \ + --region ${{needs.env.outputs.CLOUDRUN_REGION}} + + delete-frontend: + name: Delete Frontend Container Image + runs-on: ubuntu-latest + needs: [env] + + steps: + - name: Set Up gcloud CLI + uses: google-github-actions/setup-gcloud@v0.2.1 + with: + project_id: ${{needs.env.outputs.PROJECT_ID}} + service_account_key: ${{secrets.GCP_SA_KEY}} + export_default_credentials: true + + - name: "Delete Container Image: ${{needs.env.outputs.FRONTEND_TAG}}" + continue-on-error: true + run: gcloud -q artifacts docker images delete ${{needs.env.outputs.FRONTEND_TAG}} + + build-frontend: + name: Build Frontend Container Image + runs-on: ubuntu-latest + needs: [env, delete-frontend, undeploy-frontend, deploy-hasura, seed-db] + + steps: + - name: "Checkout: ${{github.event.pull_request.head.label}}" + uses: actions/checkout@v2 + with: + ref: ${{github.event.pull_request.head.sha}} + + - name: "Build Container Image: ${{needs.env.outputs.FRONTEND_TAG}}" uses: mattes/cached-docker-build-action@v1 with: - args: '. -f ./docker/frontend/Dockerfile --tag ${{env.FRONTEND_TAG}} --build-arg GRAPHQL_URL=${{env.GRAPHQL_URL}}' + args: | + . -f docker/frontend/Dockerfile \ + --tag ${{needs.env.outputs.FRONTEND_TAG}} \ + --build-arg GRAPHQL_URL=${{needs.env.outputs.GRAPHQL_URL}} cache_key: "${{hashFiles('packages/web/**', 'packages/design-system/**')}}" - - name: Push Frontend Container - run: docker push ${{env.FRONTEND_TAG}} + - name: "Login to Registry: ${{needs.env.outputs.DOCKER_REGISTRY}}" + uses: docker/login-action@v1 + with: + registry: ${{needs.env.outputs.DOCKER_REGISTRY}} + username: _json_key + password: ${{secrets.GCP_SA_KEY}} - - name: Deploy Frontend + - name: "Push Container Image: ${{needs.env.outputs.FRONTEND_TAG}}" + run: docker push ${{needs.env.outputs.FRONTEND_TAG}} + + deploy-frontend: + name: Deploy Frontend + runs-on: ubuntu-latest + needs: [env, build-frontend] + + steps: + - name: Set Up gcloud CLI + uses: google-github-actions/setup-gcloud@v0.2.1 + with: + project_id: ${{needs.env.outputs.PROJECT_ID}} + service_account_key: ${{secrets.GCP_SA_KEY}} + export_default_credentials: true + + - name: "Deploy Container Image: ${{needs.env.outputs.FRONTEND_SERVICE}}" run: | - gcloud -q run deploy ${{env.FRONTEND_SERVICE}} \ - --image ${{env.FRONTEND_TAG}} \ - --region ${{env.CLOUDRUN_REGION}} \ - --port ${{env.FRONTEND_PORT}} \ + gcloud -q run deploy ${{needs.env.outputs.FRONTEND_SERVICE}} \ + --image ${{needs.env.outputs.FRONTEND_TAG}} \ + --region ${{needs.env.outputs.CLOUDRUN_REGION}} \ + --port ${{needs.env.outputs.FRONTEND_PORT}} \ --cpu 1 \ --memory 512Mi \ --ingress all \ --max-instances 1 \ --allow-unauthenticated \ - --set-env-vars NEXT_PUBLIC_GRAPHQL_URL=${{env.GRAPHQL_URL}} \ + --set-env-vars NEXT_PUBLIC_GRAPHQL_URL=${{needs.env.outputs.GRAPHQL_URL}} \ --set-env-vars WEB3_STORAGE_TOKEN=${{secrets.WEB3_STORAGE_TOKEN}} \ --set-env-vars NEXT_PUBLIC_IMGIX_TOKEN=${{secrets.IMGIX_TOKEN}} + seed-db: + name: Seed Database + runs-on: ubuntu-latest + needs: [env, deploy-hasura] + + steps: + - name: "Checkout: ${{github.event.pull_request.head.label}}" + uses: actions/checkout@v2 + with: + ref: ${{github.event.pull_request.head.sha}} + - name: Seed Database + continue-on-error: true run: | mv package.json package.json.temp npm install --no-package-lock --no-save node-fetch bottleneck mv package.json.temp package.json - LOCAL_GRAPHQL_URL="${{env.GRAPHQL_URL}}" \ - LOCAL_BACKEND_ACCOUNT_MIGRATION_URL="${{env.SC_MIGRATE_URL}}" \ - yarn hasura:seed-local-db + SOURCE_GRAPHQL_URL="${{needs.env.outputs.GRAPHQL_URL}}" \ + ACCOUNT_MIGRATION_URL="${{needs.env.outputs.SC_MIGRATE_URL}}" \ + yarn hasura:seed-db - - name: Comment on Pull Request - uses: thollander/actions-comment-pull-request@v1 + finish-deployment: + name: Finish Deployment + runs-on: ubuntu-latest + needs: [env, start-deployment, deploy-frontend] + if: always() + + env: + result: ${{needs.deploy-frontend.result}} + + steps: + - name: Finish Deployment + uses: bobheadxi/deployments@v0.6.2 with: - message: | - Successfully deployed a preview of this pull request: - - * [Frontend](${{env.FRONTEND_URL}}) - * [Hasura](//${{env.HASURA_HOST}}) - GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} + step: finish + token: ${{github.token}} + env_url: ${{needs.env.outputs.FRONTEND_URL}} + status: ${{env.result == 'skipped' && 'cancelled' || env.result}} + deployment_id: ${{needs.start-deployment.outputs.deployment_id}} diff --git a/README.md b/README.md index dc2f06b5..b475e2f6 100644 --- a/README.md +++ b/README.md @@ -105,7 +105,7 @@ are running you have two options to populate the database: 1. Populate the database with the production dataset: ```shell script -yarn hasura:seed-local-db +yarn hasura:seed-db ``` 2. Populate the database with the initial dataset: diff --git a/guides/BACKEND.md b/guides/BACKEND.md index 2d0e060f..c8db8098 100644 --- a/guides/BACKEND.md +++ b/guides/BACKEND.md @@ -82,7 +82,7 @@ backend_1 | @metafam/backend: [0] Listening on port 4000 After which you can run: ```bash -yarn hasura:seed-local-db +yarn hasura:seed-db ``` Which populates it with testing data. diff --git a/hasura/seed-local-db.mjs b/hasura/seed-db.mjs similarity index 89% rename from hasura/seed-local-db.mjs rename to hasura/seed-db.mjs index 1fe21ecb..21a6f207 100644 --- a/hasura/seed-local-db.mjs +++ b/hasura/seed-db.mjs @@ -7,11 +7,11 @@ const PRODUCTION_GRAPHQL_URL = ( process.env.PRODUCTION_GRAPHQL_URL || 'https://api.metagame.wtf/v1/graphql' ); -const LOCAL_GRAPHQL_URL = ( - process.env.LOCAL_GRAPHQL_URL || 'http://localhost:8080/v1/graphql' +const SOURCE_GRAPHQL_URL = ( + process.env.SOURCE_GRAPHQL_URL || 'http://localhost:8080/v1/graphql' ); -const LOCAL_BACKEND_ACCOUNT_MIGRATION_URL = ( - process.env.LOCAL_BACKEND_ACCOUNT_MIGRATION_URL +const ACCOUNT_MIGRATION_URL = ( + process.env.ACCOUNT_MIGRATION_URL || 'http://localhost:4000/actions/migrateSourceCredAccounts?force=true' ); const HASURA_GRAPHQL_ADMIN_SECRET = ( @@ -106,7 +106,7 @@ const getPlayerIdsAndSkillsQuery = /* GraphQL */` async function fetchPlayerIdsAndSkills(addresses) { const { errors, data } = await fetchGraphQL( - LOCAL_GRAPHQL_URL, + SOURCE_GRAPHQL_URL, getPlayerIdsAndSkillsQuery, 'GetPlayerIds', { addresses }, @@ -134,7 +134,7 @@ const deleteSkillsMutation = /* GraphQL */` async function deleteSkills() { const { errors } = await fetchGraphQL( - LOCAL_GRAPHQL_URL, + SOURCE_GRAPHQL_URL, deleteSkillsMutation, 'DeleteSkills', {}, @@ -200,7 +200,7 @@ const upsertPlayerMutation = /* GraphQL */` async function upsertPlayer(variables) { const { errors, data } = await fetchGraphQL( - LOCAL_GRAPHQL_URL, + SOURCE_GRAPHQL_URL, upsertPlayerMutation, 'UpsertPlayer', variables, @@ -228,7 +228,7 @@ function getSkillId(skills, { Skill: { category, name } }) { } async function forceMigrateAccounts() { - const result = await fetch(LOCAL_BACKEND_ACCOUNT_MIGRATION_URL, { + const result = await fetch(ACCOUNT_MIGRATION_URL, { method: 'POST', }); const json = await result.json(); @@ -236,13 +236,13 @@ async function forceMigrateAccounts() { } async function startSeeding() { - console.debug(`Force migrating sourcecred users with: ${LOCAL_BACKEND_ACCOUNT_MIGRATION_URL}`); + console.debug(`Force migrating sourcecred users with: ${ACCOUNT_MIGRATION_URL}`); const result = await forceMigrateAccounts(); console.debug(result); console.debug(`Fetching players from: ${PRODUCTION_GRAPHQL_URL}`); const players = await fetchTopPlayers(); const addresses = players.map(({ ethereum_address }) => ethereum_address); - console.debug(`Fetching player ids for players from ${LOCAL_GRAPHQL_URL} for ${addresses.length} addresses`); + console.debug(`Fetching player ids for players from ${SOURCE_GRAPHQL_URL} for ${addresses.length} addresses`); const { ids, skills } = await fetchPlayerIdsAndSkills(addresses); console.debug(`Fetched ${Object.keys(ids).length} player ids for players from addresses.`); const mutations = ( @@ -271,7 +271,7 @@ async function startSeeding() { .filter(m => !!m) ); console.debug( - `Updating ${mutations.length} players information in ${LOCAL_GRAPHQL_URL}`, + `Updating ${mutations.length} players information in ${SOURCE_GRAPHQL_URL}`, ); await deleteSkills(); const limiter = new Bottleneck({ @@ -284,7 +284,7 @@ async function startSeeding() { return limiter.schedule(() => upsertPlayer(variables)) } )); - console.debug(`Successfully seeded local db with ${updated.length} players`); + console.debug(`Successfully seeded db with ${updated.length} players`); } startSeeding() diff --git a/package.json b/package.json index 84dff3b1..f078611e 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "hasura": "hasura --project ./hasura", "hasura:console": "yarn hasura console --no-browser", "hasura:migrate:init": "yarn hasura migrate create \"init\" --from-server", - "hasura:seed-local-db": "node hasura/seed-local-db.mjs", + "hasura:seed-db": "node hasura/seed-db.mjs", "test": "lerna run test --parallel --", "generate": "lerna run generate --parallel --", "test:full": "yarn lint && yarn typecheck && yarn test",