diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 56df65ea0..ff149b6bc 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -4,7 +4,7 @@ on: push: branches: - master - # - 4451-new-deployment-with-base-and-code # for testing while developing + # - 5065-automatic-deployment-to-stage.ocelot.social-on-push-to-master-branch # for testing while developing jobs: ############################################################################## @@ -246,6 +246,71 @@ jobs: - name: Push maintenance run: docker push --all-tags ocelotsocialnetwork/maintenance + ############################################################################## + # JOB: KUBERNETES DEPLOY ACTUAL/LATEST VERSION ###################################### + ############################################################################## + kubernetes_deploy: + # see example https://github.com/do-community/example-doctl-action + # see example https://github.com/do-community/example-doctl-action/blob/main/.github/workflows/workflow.yaml + name: Kubernetes deploy of latest version to stage.ocelot.social cluster at DigitalOcean + runs-on: ubuntu-latest + needs: [upload_to_dockerhub] + steps: + ########################################################################## + # CHECKOUT CODE ########################################################## + ########################################################################## + - name: Checkout code + uses: actions/checkout@v2 + ########################################################################## + # SET ENVS ############################################################### + ########################################################################## + - name: ENV - VERSION + run: echo "VERSION=$(node -p -e "require('./package.json').version")" >> $GITHUB_ENV + - name: ENV - BUILD_VERSION + run: echo "BUILD_VERSION=${VERSION}-${GITHUB_RUN_NUMBER}" >> $GITHUB_ENV + ########################################################################## + # Install DigitalOceans doctl and set kubeconfig ######################### + ########################################################################## + - name: Install doctl + uses: digitalocean/action-doctl@v2 + with: + token: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }} + - name: Save DigitalOcean kubeconfig with short-lived credentials + run: doctl kubernetes cluster kubeconfig save --expiry-seconds 600 cluster-stage-ocelot-social + ########################################################################## + # Deploy new Docker images to DigitalOcean Kubernetes cluster ############ + ########################################################################## + # - name: Deploy 'latest' to DigitalOcean Kubernetes + # run: | + # kubectl -n default set image deployment/ocelot-webapp container-ocelot-webapp=ocelotsocialnetwork/webapp:latest + # kubectl -n default rollout restart deployment/ocelot-webapp + # kubectl -n default set image deployment/ocelot-backend container-ocelot-backend=ocelotsocialnetwork/backend:latest + # kubectl -n default rollout restart deployment/ocelot-backend + # kubectl -n default set image deployment/ocelot-maintenance container-ocelot-maintenance=ocelotsocialnetwork/maintenance:latest + # kubectl -n default rollout restart deployment/ocelot-maintenance + # kubectl -n default set image deployment/ocelot-neo4j container-ocelot-neo4j=ocelotsocialnetwork/neo4j-community:latest + # kubectl -n default rollout restart deployment/ocelot-neo4j + - name: Deploy actual version '$BUILD_VERSION' to DigitalOcean Kubernetes + run: | + kubectl -n default set image deployment/ocelot-webapp container-ocelot-webapp=ocelotsocialnetwork/webapp:$BUILD_VERSION + kubectl -n default rollout restart deployment/ocelot-webapp + kubectl -n default set image deployment/ocelot-backend container-ocelot-backend=ocelotsocialnetwork/backend:$BUILD_VERSION + kubectl -n default rollout restart deployment/ocelot-backend + kubectl -n default set image deployment/ocelot-maintenance container-ocelot-maintenance=ocelotsocialnetwork/maintenance:$BUILD_VERSION + kubectl -n default rollout restart deployment/ocelot-maintenance + kubectl -n default set image deployment/ocelot-neo4j container-ocelot-neo4j=ocelotsocialnetwork/neo4j-community:$BUILD_VERSION + kubectl -n default rollout restart deployment/ocelot-neo4j + - name: Verify deployment and wait for the pods of each deplyment to get ready for cleaning and seeding of the database + run: | + kubectl -n default rollout status deployment/ocelot-backend --timeout=600s + kubectl -n default rollout status deployment/ocelot-neo4j --timeout=600s + # kubectl -n default rollout status deployment/ocelot-maintenance --timeout=600s + # kubectl -n default rollout status deployment/ocelot-webapp --timeout=600s + - name: Reset and seed Neo4j database via backend for staging + # db cleaning and seeding is only possible in production if env 'PRODUCTION_DB_CLEAN_ALLOW=true' is set in deployment + run: | + kubectl -n default exec -it $(kubectl -n default get pods | grep ocelot-backend | awk '{ print $1 }') -- /bin/sh -c "node --experimental-repl-await dist/db/clean.js && node --experimental-repl-await dist/db/seed.js" + ############################################################################## # JOB: GITHUB TAG LATEST VERSION ############################################# ############################################################################## @@ -313,4 +378,4 @@ jobs: release_name: ${{ env.VERSION }} body_path: ./CHANGELOG.md draft: false - prerelease: false \ No newline at end of file + prerelease: false diff --git a/backend/src/config/index.js b/backend/src/config/index.js index d6d8cc166..6ad8c578b 100644 --- a/backend/src/config/index.js +++ b/backend/src/config/index.js @@ -22,6 +22,8 @@ const environment = { DEBUG: env.NODE_ENV !== 'production' && env.DEBUG, TEST: env.NODE_ENV === 'test', PRODUCTION: env.NODE_ENV === 'production', + // used for staging enviroments if 'PRODUCTION=true' and 'PRODUCTION_DB_CLEAN_ALLOW=true' + PRODUCTION_DB_CLEAN_ALLOW: env.PRODUCTION_DB_CLEAN_ALLOW === 'true' || false, // default = false DISABLED_MIDDLEWARES: (env.NODE_ENV !== 'production' && env.DISABLED_MIDDLEWARES) || false, } diff --git a/backend/src/db/clean.js b/backend/src/db/clean.js index db8e8aad6..eac26036c 100644 --- a/backend/src/db/clean.js +++ b/backend/src/db/clean.js @@ -1,8 +1,8 @@ -import { cleanDatabase } from '../db/factories' import CONFIG from '../config' +import { cleanDatabase } from '../db/factories' -if (CONFIG.PRODUCTION) { - throw new Error(`You cannot clean the database in production environment!`) +if (CONFIG.PRODUCTION && !CONFIG.PRODUCTION_DB_CLEAN_ALLOW) { + throw new Error(`You cannot clean the database in a non-staging and real production environment!`) } ;(async function () { diff --git a/backend/src/db/seed.js b/backend/src/db/seed.js index 7bfd4f159..46c5870e0 100644 --- a/backend/src/db/seed.js +++ b/backend/src/db/seed.js @@ -1,11 +1,16 @@ import sample from 'lodash/sample' import { createTestClient } from 'apollo-server-testing' +import CONFIG from '../config' import createServer from '../server' import faker from '@faker-js/faker' import Factory from '../db/factories' import { getNeode, getDriver } from '../db/neo4j' import { gql } from '../helpers/jest' +if (CONFIG.PRODUCTION && !CONFIG.PRODUCTION_DB_CLEAN_ALLOW) { + throw new Error(`You cannot seed the database in a non-staging and real production environment!`) +} + const languages = ['de', 'en', 'es', 'fr', 'it', 'pt', 'pl'] /* eslint-disable no-multi-spaces */