Deploy to DigitalOcean Dev #1282
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Deploy to DigitalOcean Dev | |
| on: | |
| workflow_run: | |
| workflows: ["Build and Publish Docker Images Dev"] | |
| branches: [develop] | |
| types: | |
| - completed | |
| jobs: | |
| deploy-demo: | |
| runs-on: ubicloud-standard-2 | |
| environment: dev | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Install doctl | |
| uses: digitalocean/action-doctl@v2 | |
| with: | |
| token: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }} | |
| - name: Log in to DigitalOcean Container Registry with short-lived credentials | |
| run: doctl registry login --expiry-seconds 600 | |
| - name: Save DigitalOcean kubeconfig with short-lived credentials | |
| run: doctl kubernetes cluster kubeconfig save --expiry-seconds 600 k8s-gauzy | |
| - name: Generate TLS Secrets | |
| run: | | |
| rm -f ${HOME}/ingress.webapp.crt ${HOME}/ingress.webapp.key | |
| echo "${{ secrets.INGRESS_CERT }}" | base64 --decode > ${HOME}/ingress.webapp.crt | |
| echo "${{ secrets.INGRESS_CERT_KEY }}" | base64 --decode > ${HOME}/ingress.webapp.key | |
| kubectl create secret tls demo.ever.team-tls --save-config --dry-run=client --cert=${HOME}/ingress.webapp.crt --key=${HOME}/ingress.webapp.key -o yaml | kubectl --context do-sfo2-k8s-gauzy apply -f - | |
| - name: Validate required secrets | |
| run: | | |
| echo "==> Validating secrets for DEV environment..." | |
| missing_critical=() | |
| missing_optional=() | |
| # Critical secrets (deployment will fail without these) | |
| critical_secrets=( | |
| "GAUZY_API_SERVER_URL" | |
| "NEXT_PUBLIC_GAUZY_API_SERVER_URL" | |
| ) | |
| # Optional secrets (deployment will work with defaults/disabled features) | |
| optional_secrets=( | |
| "APP_NAME" | |
| "COMPANY_NAME" | |
| "SENTRY_DSN" | |
| "NEXT_PUBLIC_SENTRY_DSN" | |
| ) | |
| # Check critical secrets | |
| for secret in "${critical_secrets[@]}"; do | |
| if [ -z "${!secret}" ]; then | |
| missing_critical+=("$secret") | |
| fi | |
| done | |
| # Check optional secrets | |
| for secret in "${optional_secrets[@]}"; do | |
| if [ -z "${!secret}" ]; then | |
| missing_optional+=("$secret") | |
| fi | |
| done | |
| # Show warnings for missing optional secrets | |
| if [ ${#missing_optional[@]} -gt 0 ]; then | |
| echo "⚠️ Missing optional secrets (using defaults):" | |
| printf ' - %s\n' "${missing_optional[@]}" | |
| echo "" | |
| fi | |
| # Fail only if critical secrets are missing | |
| if [ ${#missing_critical[@]} -gt 0 ]; then | |
| echo "❌ Missing critical secrets for DEV deployment:" | |
| printf ' - %s\n' "${missing_critical[@]}" | |
| echo "" | |
| echo "Please configure these critical secrets in GitHub repository settings." | |
| echo "See DEPLOYMENT_SECRETS.md for details." | |
| exit 1 | |
| fi | |
| echo "✅ All critical secrets validated successfully for DEV" | |
| env: | |
| # Pass secrets for validation | |
| GAUZY_API_SERVER_URL: '${{ secrets.GAUZY_API_SERVER_URL }}' | |
| NEXT_PUBLIC_GAUZY_API_SERVER_URL: '${{ secrets.NEXT_PUBLIC_GAUZY_API_SERVER_URL }}' | |
| APP_NAME: '${{ secrets.APP_NAME }}' | |
| COMPANY_NAME: '${{ secrets.COMPANY_NAME }}' | |
| SENTRY_DSN: '${{ secrets.SENTRY_DSN }}' | |
| NEXT_PUBLIC_SENTRY_DSN: '${{ secrets.NEXT_PUBLIC_SENTRY_DSN }}' | |
| - name: Apply k8s manifests changes in DigitalOcean k8s cluster (if any) | |
| run: | | |
| envsubst < $GITHUB_WORKSPACE/.deploy/k8s/k8s-manifest.dev.yaml | kubectl --context do-sfo2-k8s-gauzy apply -f - | |
| env: | |
| # below we are using GitHub secrets for both frontend and backend | |
| CLOUD_PROVIDER: 'DO' | |
| NEXT_PUBLIC_SENTRY_DSN: '${{ secrets.NEXT_PUBLIC_SENTRY_DSN }}' | |
| SENTRY_DSN: '${{ secrets.SENTRY_DSN }}' | |
| NEXT_PUBLIC_JITSU_BROWSER_WRITE_KEY: '${{ secrets.NEXT_PUBLIC_JITSU_BROWSER_WRITE_KEY }}' | |
| NEXT_PUBLIC_JITSU_BROWSER_URL: '${{ secrets.NEXT_PUBLIC_JITSU_BROWSER_URL }}' | |
| SENTRY_AUTH_TOKEN: '${{ secrets.SENTRY_AUTH_TOKEN }}' | |
| NEXT_PUBLIC_CHATWOOT_API_KEY: '${{ secrets.NEXT_PUBLIC_CHATWOOT_API_KEY }}' | |
| NEXT_PUBLIC_SENTRY_DEBUG: '${{ secrets.NEXT_PUBLIC_SENTRY_DEBUG }}' | |
| SENTRY_PROJECT: '${{ secrets.SENTRY_PROJECT }}' | |
| SENTRY_ORG: '${{ secrets.SENTRY_ORG }}' | |
| SMTP_FROM_ADDRESS: '${{ secrets.SMTP_FROM_ADDRESS }}' | |
| JITSU_SERVER_WRITE_KEY: '${{ secrets.JITSU_SERVER_WRITE_KEY }}' | |
| JITSU_SERVER_URL: '${{ secrets.JITSU_SERVER_URL }}' | |
| NEXT_PUBLIC_COOKIE_DOMAINS: '${{ secrets.NEXT_PUBLIC_COOKIE_DOMAINS }}' | |
| NEXT_PUBLIC_BOARD_FIREBASE_CONFIG: '${{ secrets.NEXT_PUBLIC_BOARD_FIREBASE_CONFIG }}' | |
| NEXT_PUBLIC_BOARD_BACKEND_POST_URL: '${{ secrets.NEXT_PUBLIC_BOARD_BACKEND_POST_URL }}' | |
| NEXT_PUBLIC_BOARD_APP_DOMAIN: '${{ secrets.NEXT_PUBLIC_BOARD_APP_DOMAIN }}' | |
| MEET_JWT_APP_SECRET: '${{ secrets.MEET_JWT_APP_SECRET }}' | |
| MEET_JWT_APP_ID: '${{ secrets.MEET_JWT_APP_ID }}' | |
| NEXT_PUBLIC_MEET_DOMAIN: '${{ secrets.NEXT_PUBLIC_MEET_DOMAIN }}' | |
| GAUZY_API_SERVER_URL: '${{ secrets.GAUZY_API_SERVER_URL }}' | |
| NEXT_PUBLIC_GAUZY_API_SERVER_URL: '${{ secrets.NEXT_PUBLIC_GAUZY_API_SERVER_URL }}' | |
| MAILCHIMP_LIST_ID: '${{ secrets.MAILCHIMP_LIST_ID }}' | |
| MAILCHIMP_API_KEY: '${{ secrets.MAILCHIMP_API_KEY }}' | |
| POSTMARK_SERVER_API_TOKEN: '${{ secrets.POSTMARK_SERVER_API_TOKEN }}' | |
| NEXT_PUBLIC_GA_MEASUREMENT_ID: '${{ secrets.NEXT_PUBLIC_GA_MEASUREMENT_ID }}' | |
| SMTP_HOST: '${{ secrets.SMTP_HOST }}' | |
| SMTP_SECURE: '${{ secrets.SMTP_SECURE }}' | |
| SMTP_USERNAME: '${{ secrets.SMTP_USERNAME }}' | |
| SMTP_PASSWORD: '${{ secrets.SMTP_PASSWORD }}' | |
| CAPTCHA_SECRET_KEY: '${{ secrets.CAPTCHA_SECRET_KEY }}' | |
| NEXT_PUBLIC_CAPTCHA_SITE_KEY: '${{ secrets.NEXT_PUBLIC_CAPTCHA_SITE_KEY }}' | |
| AUTH_SECRET: '${{ secrets.AUTH_SECRET }}' | |
| # App Branding Variables | |
| APP_NAME: '${{ secrets.APP_NAME }}' | |
| APP_SIGNATURE: '${{ secrets.APP_SIGNATURE }}' | |
| APP_LOGO_URL: '${{ secrets.APP_LOGO_URL }}' | |
| APP_LINK: '${{ secrets.APP_LINK }}' | |
| APP_SLOGAN_TEXT: '${{ secrets.APP_SLOGAN_TEXT }}' | |
| COMPANY_NAME: '${{ secrets.COMPANY_NAME }}' | |
| COMPANY_LINK: '${{ secrets.COMPANY_LINK }}' | |
| TERMS_LINK: '${{ secrets.TERMS_LINK }}' | |
| PRIVACY_POLICY_LINK: '${{ secrets.PRIVACY_POLICY_LINK }}' | |
| MAIN_PICTURE: '${{ secrets.MAIN_PICTURE }}' | |
| MAIN_PICTURE_DARK: '${{ secrets.MAIN_PICTURE_DARK }}' | |
| # Site Metadata Variables | |
| NEXT_PUBLIC_SITE_NAME: '${{ secrets.NEXT_PUBLIC_SITE_NAME }}' | |
| NEXT_PUBLIC_SITE_TITLE: '${{ secrets.NEXT_PUBLIC_SITE_TITLE }}' | |
| NEXT_PUBLIC_SITE_DESCRIPTION: '${{ secrets.NEXT_PUBLIC_SITE_DESCRIPTION }}' | |
| NEXT_PUBLIC_SITE_KEYWORDS: '${{ secrets.NEXT_PUBLIC_SITE_KEYWORDS }}' | |
| NEXT_PUBLIC_TWITTER_USERNAME: '${{ secrets.NEXT_PUBLIC_TWITTER_USERNAME }}' | |
| NEXT_PUBLIC_IMAGES_HOSTS: '${{ secrets.NEXT_PUBLIC_IMAGES_HOSTS }}' | |
| # Additional Environment Variables | |
| RECOIL_DUPLICATE_ATOM_KEY_CHECKING_ENABLED: '${{ secrets.RECOIL_DUPLICATE_ATOM_KEY_CHECKING_ENABLED }}' | |
| LOG_FOLDER_MAX_SIZE: '${{ secrets.LOG_FOLDER_MAX_SIZE }}' | |
| NEXT_PUBLIC_LOG_FOLDER_MAX_SIZE: '${{ secrets.NEXT_PUBLIC_LOG_FOLDER_MAX_SIZE }}' | |
| ACTIVE_LOCAL_LOG_SYSTEM: '${{ secrets.ACTIVE_LOCAL_LOG_SYSTEM }}' | |
| NEXT_PUBLIC_ACTIVE_LOCAL_LOG_SYSTEM: '${{ secrets.NEXT_PUBLIC_ACTIVE_LOCAL_LOG_SYSTEM }}' | |
| IS_DESKTOP_APP: '${{ secrets.IS_DESKTOP_APP }}' | |
| # OAuth Configuration | |
| NEXT_PUBLIC_GOOGLE_APP_NAME: '${{ secrets.NEXT_PUBLIC_GOOGLE_APP_NAME }}' | |
| GOOGLE_CLIENT_ID: '${{ secrets.GOOGLE_CLIENT_ID }}' | |
| GOOGLE_CLIENT_SECRET: '${{ secrets.GOOGLE_CLIENT_SECRET }}' | |
| NEXT_PUBLIC_GITHUB_APP_NAME: '${{ secrets.NEXT_PUBLIC_GITHUB_APP_NAME }}' | |
| GITHUB_CLIENT_ID: '${{ secrets.GITHUB_CLIENT_ID }}' | |
| GITHUB_CLIENT_SECRET: '${{ secrets.GITHUB_CLIENT_SECRET }}' | |
| NEXT_PUBLIC_FACEBOOK_APP_NAME: '${{ secrets.NEXT_PUBLIC_FACEBOOK_APP_NAME }}' | |
| FACEBOOK_CLIENT_ID: '${{ secrets.FACEBOOK_CLIENT_ID }}' | |
| FACEBOOK_CLIENT_SECRET: '${{ secrets.FACEBOOK_CLIENT_SECRET }}' | |
| NEXT_PUBLIC_TWITTER_APP_NAME: '${{ secrets.NEXT_PUBLIC_TWITTER_APP_NAME }}' | |
| TWITTER_CLIENT_ID: '${{ secrets.TWITTER_CLIENT_ID }}' | |
| TWITTER_CLIENT_SECRET: '${{ secrets.TWITTER_CLIENT_SECRET }}' | |
| # Additional Configuration | |
| NEXT_PUBLIC_DEMO: '${{ secrets.NEXT_PUBLIC_DEMO }}' | |
| NEXT_PUBLIC_CAPTCHA_TYPE: '${{ secrets.NEXT_PUBLIC_CAPTCHA_TYPE }}' | |
| NEXT_PUBLIC_MEET_TYPE: '${{ secrets.NEXT_PUBLIC_MEET_TYPE }}' | |
| LIVEKIT_API_SECRET: '${{ secrets.LIVEKIT_API_SECRET }}' | |
| LIVEKIT_API_KEY: '${{ secrets.LIVEKIT_API_KEY }}' | |
| NEXT_PUBLIC_LIVEKIT_URL: '${{ secrets.NEXT_PUBLIC_LIVEKIT_URL }}' | |
| INVITE_CALLBACK_URL: '${{ secrets.INVITE_CALLBACK_URL }}' | |
| VERIFY_EMAIL_CALLBACK_URL: '${{ secrets.VERIFY_EMAIL_CALLBACK_URL }}' | |
| SMTP_PORT: '${{ secrets.SMTP_PORT }}' | |
| NEXT_PUBLIC_DISABLE_AUTO_REFRESH: '${{ secrets.NEXT_PUBLIC_DISABLE_AUTO_REFRESH }}' | |
| SENTRY_LOG_LEVEL: '${{ secrets.SENTRY_LOG_LEVEL }}' | |
| NEXT_PUBLIC_POSTHOG_KEY: '${{ secrets.NEXT_PUBLIC_POSTHOG_KEY }}' | |
| NEXT_PUBLIC_POSTHOG_HOST: '${{ secrets.NEXT_PUBLIC_POSTHOG_HOST }}' | |
| NEXT_IGNORE_ESLINT_ERROR_ON_BUILD: '${{ secrets.NEXT_IGNORE_ESLINT_ERROR_ON_BUILD }}' | |
| ANALYZE: '${{ secrets.ANALYZE }}' | |
| NEXT_PUBLIC_WEB_APP_URL: '${{ vars.NEXT_PUBLIC_WEB_APP_URL }}' | |
| API_BASE_URL: '${{ vars.API_BASE_URL }}' | |
| CLIENT_BASE_URL: '${{ vars.CLIENT_BASE_URL }}' | |
| # we need this step because for now we just use :latest tag | |
| # note: for production we will use different strategy later | |
| - name: Restart Pods to pick up :latest tag version | |
| run: | | |
| kubectl --context do-sfo2-k8s-gauzy rollout restart deployment/ever-teams-dev-webapp |